diff --git a/[refs] b/[refs] index dacbebffb9ff..6a521089e6dc 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 0efdf2626676db4b30d343ff88f8461ad09130da +refs/heads/master: 383956a9c59157db4c404d1c8bb9074b8dfe3ee0 diff --git a/trunk/Documentation/DocBook/Makefile b/trunk/Documentation/DocBook/Makefile index 36526a1e76d7..db9499adbed4 100644 --- a/trunk/Documentation/DocBook/Makefile +++ b/trunk/Documentation/DocBook/Makefile @@ -190,13 +190,9 @@ quiet_cmd_fig2png = FIG2PNG $@ ### # Help targets as used by the top-level makefile dochelp: - @echo ' Linux kernel internal documentation in different formats:' - @echo ' htmldocs - HTML' - @echo ' installmandocs - install man pages generated by mandocs' - @echo ' mandocs - man pages' - @echo ' pdfdocs - PDF' - @echo ' psdocs - Postscript' - @echo ' xmldocs - XML DocBook' + @echo ' Linux kernel internal documentation in different formats:' + @echo ' xmldocs (XML DocBook), psdocs (Postscript), pdfdocs (PDF)' + @echo ' htmldocs (HTML), mandocs (man pages, use installmandocs to install)' ### # Temporary files left by various tools 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/README b/trunk/README index c05561523029..3e264723b863 100644 --- a/trunk/README +++ b/trunk/README @@ -1,4 +1,4 @@ - Linux kernel release 2.6.xx + Linux kernel release 2.6.xx These are the release notes for Linux version 2.6. Read them carefully, as they tell you what this is all about, explain how to install the @@ -22,17 +22,15 @@ ON WHAT HARDWARE DOES IT RUN? Although originally developed first for 32-bit x86-based PCs (386 or higher), today Linux also runs on (at least) the Compaq Alpha AXP, Sun SPARC and - UltraSPARC, Motorola 68000, PowerPC, PowerPC64, ARM, Hitachi SuperH, Cell, + UltraSPARC, Motorola 68000, PowerPC, PowerPC64, ARM, Hitachi SuperH, IBM S/390, MIPS, HP PA-RISC, Intel IA-64, DEC VAX, AMD x86-64, AXIS CRIS, - Cris, Xtensa, AVR32 and Renesas M32R architectures. + and Renesas M32R architectures. Linux is easily portable to most general-purpose 32- or 64-bit architectures as long as they have a paged memory management unit (PMMU) and a port of the GNU C compiler (gcc) (part of The GNU Compiler Collection, GCC). Linux has also been ported to a number of architectures without a PMMU, although functionality is then obviously somewhat limited. - Linux has also been ported to itself. You can now run the kernel as a - userspace application - this is called UserMode Linux (UML). DOCUMENTATION: @@ -115,7 +113,6 @@ INSTALLING the kernel: version 2.6.12.2 and want to jump to 2.6.12.3, you must first reverse the 2.6.12.2 patch (that is, patch -R) _before_ applying the 2.6.12.3 patch. - You can read more on this in Documentation/applying-patches.txt - Make sure you have no stale .o files and dependencies lying around: @@ -164,7 +161,6 @@ CONFIGURING the kernel: only ask you for the answers to new questions. - Alternate configuration commands are: - "make config" Plain text interface. "make menuconfig" Text based color menus, radiolists & dialogs. "make xconfig" X windows (Qt) based configuration tool. "make gconfig" X windows (Gtk) based configuration tool. @@ -307,9 +303,8 @@ IF SOMETHING GOES WRONG: - If you compiled the kernel with CONFIG_KALLSYMS you can send the dump as is, otherwise you will have to use the "ksymoops" program to make - sense of the dump (but compiling with CONFIG_KALLSYMS is usually preferred). - This utility can be downloaded from - ftp://ftp..kernel.org/pub/linux/utils/kernel/ksymoops/ . + sense of the dump. This utility can be downloaded from + ftp://ftp..kernel.org/pub/linux/utils/kernel/ksymoops. Alternately you can do the dump lookup by hand: - In debugging dumps like the above, it helps enormously if you can @@ -341,7 +336,7 @@ IF SOMETHING GOES WRONG: If you for some reason cannot do the above (you have a pre-compiled kernel image or similar), telling me as much about your setup as - possible will help. Please read the REPORTING-BUGS document for details. + possible will help. - Alternately, you can use gdb on a running kernel. (read-only; i.e. you cannot change values or set break points.) To do this, first compile the 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/ia64/pci/pci.c b/trunk/arch/ia64/pci/pci.c index eb92cef9cd0d..f4edfbf27134 100644 --- a/trunk/arch/ia64/pci/pci.c +++ b/trunk/arch/ia64/pci/pci.c @@ -564,8 +564,8 @@ pcibios_enable_device (struct pci_dev *dev, int mask) void pcibios_disable_device (struct pci_dev *dev) { - BUG_ON(atomic_read(&dev->enable_cnt)); - acpi_pci_irq_disable(dev); + if (dev->is_enabled) + acpi_pci_irq_disable(dev); } void 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/Kconfig b/trunk/arch/mips/Kconfig index d8af858fe3f5..4d64960be035 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -242,7 +242,6 @@ config LASAT select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL select SYS_SUPPORTS_LITTLE_ENDIAN - select GENERIC_HARDIRQS_NO__DO_IRQ config MIPS_ATLAS bool "MIPS Atlas board" @@ -266,7 +265,6 @@ config MIPS_ATLAS select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_MULTITHREADING if EXPERIMENTAL - select GENERIC_HARDIRQS_NO__DO_IRQ help This enables support for the MIPS Technologies Atlas evaluation board. @@ -421,7 +419,6 @@ config MOMENCO_OCELOT_C select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN - select GENERIC_HARDIRQS_NO__DO_IRQ help The Ocelot is a MIPS-based Single Board Computer (SBC) made by Momentum Computer . @@ -572,7 +569,6 @@ config SGI_IP27 select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_NUMA select SYS_SUPPORTS_SMP - select GENERIC_HARDIRQS_NO__DO_IRQ help This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics workstations. To compile a Linux kernel that runs on these, say Y @@ -839,10 +835,6 @@ config SCHED_NO_NO_OMIT_FRAME_POINTER bool default y -config GENERIC_HARDIRQS_NO__DO_IRQ - bool - default n - # # Select some configuration options automatically based on user selections. # @@ -1004,7 +996,6 @@ config SOC_PNX8550 select HW_HAS_PCI select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_32BIT_KERNEL - select GENERIC_HARDIRQS_NO__DO_IRQ config SWAP_IO_SPACE bool diff --git a/trunk/arch/mips/dec/ecc-berr.c b/trunk/arch/mips/dec/ecc-berr.c index 6d55e8aab668..c8430c07355e 100644 --- a/trunk/arch/mips/dec/ecc-berr.c +++ b/trunk/arch/mips/dec/ecc-berr.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/mips/dec/ioasic-irq.c b/trunk/arch/mips/dec/ioasic-irq.c index 4c7cb4048d35..269b22b34313 100644 --- a/trunk/arch/mips/dec/ioasic-irq.c +++ b/trunk/arch/mips/dec/ioasic-irq.c @@ -67,6 +67,7 @@ static struct irq_chip ioasic_irq_type = { .mask = mask_ioasic_irq, .mask_ack = ack_ioasic_irq, .unmask = unmask_ioasic_irq, + .end = end_ioasic_irq, }; @@ -105,7 +106,8 @@ void __init init_ioasic_irqs(int base) set_irq_chip_and_handler(i, &ioasic_irq_type, handle_level_irq); for (; i < base + IO_IRQ_LINES; i++) - set_irq_chip(i, &ioasic_dma_irq_type); + set_irq_chip_and_handler(i, &ioasic_dma_irq_type, + handle_level_irq); ioasic_irq_base = base; } diff --git a/trunk/arch/mips/dec/kn01-berr.c b/trunk/arch/mips/dec/kn01-berr.c index d3b8002bf1e7..f19b4617a0a6 100644 --- a/trunk/arch/mips/dec/kn01-berr.c +++ b/trunk/arch/mips/dec/kn01-berr.c @@ -20,10 +20,8 @@ #include #include -#include #include #include -#include #include #include #include diff --git a/trunk/arch/mips/dec/kn02-irq.c b/trunk/arch/mips/dec/kn02-irq.c index 916e46b8ccd8..5a9be4c93584 100644 --- a/trunk/arch/mips/dec/kn02-irq.c +++ b/trunk/arch/mips/dec/kn02-irq.c @@ -57,12 +57,19 @@ static void ack_kn02_irq(unsigned int irq) iob(); } +static void end_kn02_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + unmask_kn02_irq(irq); +} + static struct irq_chip kn02_irq_type = { .typename = "KN02-CSR", .ack = ack_kn02_irq, .mask = mask_kn02_irq, .mask_ack = ack_kn02_irq, .unmask = unmask_kn02_irq, + .end = end_kn02_irq, }; diff --git a/trunk/arch/mips/emma2rh/common/irq_emma2rh.c b/trunk/arch/mips/emma2rh/common/irq_emma2rh.c index 8d880f0b06ec..59b98299c896 100644 --- a/trunk/arch/mips/emma2rh/common/irq_emma2rh.c +++ b/trunk/arch/mips/emma2rh/common/irq_emma2rh.c @@ -56,12 +56,19 @@ static void emma2rh_irq_disable(unsigned int irq) ll_emma2rh_irq_disable(irq - emma2rh_irq_base); } +static void emma2rh_irq_end(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + ll_emma2rh_irq_enable(irq - emma2rh_irq_base); +} + struct irq_chip emma2rh_irq_controller = { .typename = "emma2rh_irq", .ack = emma2rh_irq_disable, .mask = emma2rh_irq_disable, .mask_ack = emma2rh_irq_disable, .unmask = emma2rh_irq_enable, + .end = emma2rh_irq_end, }; void emma2rh_irq_init(u32 irq_base) diff --git a/trunk/arch/mips/emma2rh/markeins/irq_markeins.c b/trunk/arch/mips/emma2rh/markeins/irq_markeins.c index 2116d9be5fa9..3ac4e405ecdc 100644 --- a/trunk/arch/mips/emma2rh/markeins/irq_markeins.c +++ b/trunk/arch/mips/emma2rh/markeins/irq_markeins.c @@ -48,12 +48,19 @@ static void emma2rh_sw_irq_disable(unsigned int irq) ll_emma2rh_sw_irq_disable(irq - emma2rh_sw_irq_base); } +static void emma2rh_sw_irq_end(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + ll_emma2rh_sw_irq_enable(irq - emma2rh_sw_irq_base); +} + struct irq_chip emma2rh_sw_irq_controller = { .typename = "emma2rh_sw_irq", .ack = emma2rh_sw_irq_disable, .mask = emma2rh_sw_irq_disable, .mask_ack = emma2rh_sw_irq_disable, .unmask = emma2rh_sw_irq_enable, + .end = emma2rh_sw_irq_end, }; void emma2rh_sw_irq_init(u32 irq_base) diff --git a/trunk/arch/mips/jazz/irq.c b/trunk/arch/mips/jazz/irq.c index f8d417b5c2bb..5c4f50cdf157 100644 --- a/trunk/arch/mips/jazz/irq.c +++ b/trunk/arch/mips/jazz/irq.c @@ -39,12 +39,19 @@ void disable_r4030_irq(unsigned int irq) spin_unlock_irqrestore(&r4030_lock, flags); } +static void end_r4030_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_r4030_irq(irq); +} + static struct irq_chip r4030_irq_type = { .typename = "R4030", .ack = disable_r4030_irq, .mask = disable_r4030_irq, .mask_ack = disable_r4030_irq, .unmask = enable_r4030_irq, + .end = end_r4030_irq, }; void __init init_r4030_ints(void) diff --git a/trunk/arch/mips/kernel/i8259.c b/trunk/arch/mips/kernel/i8259.c index b59a676c6d0e..2526c0ca4d81 100644 --- a/trunk/arch/mips/kernel/i8259.c +++ b/trunk/arch/mips/kernel/i8259.c @@ -19,6 +19,9 @@ #include #include +void enable_8259A_irq(unsigned int irq); +void disable_8259A_irq(unsigned int irq); + /* * This is the 'legacy' 8259A Programmable Interrupt Controller, * present in the majority of PC/AT boxes. @@ -28,16 +31,23 @@ * moves to arch independent land */ -static int i8259A_auto_eoi; DEFINE_SPINLOCK(i8259A_lock); -/* some platforms call this... */ + +static void end_8259A_irq (unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)) && + irq_desc[irq].action) + enable_8259A_irq(irq); +} + void mask_and_ack_8259A(unsigned int); -static struct irq_chip i8259A_chip = { - .name = "XT-PIC", - .mask = disable_8259A_irq, - .unmask = enable_8259A_irq, - .mask_ack = mask_and_ack_8259A, +static struct irq_chip i8259A_irq_type = { + .typename = "XT-PIC", + .enable = enable_8259A_irq, + .disable = disable_8259A_irq, + .ack = mask_and_ack_8259A, + .end = end_8259A_irq, }; /* @@ -49,8 +59,8 @@ static struct irq_chip i8259A_chip = { */ static unsigned int cached_irq_mask = 0xffff; -#define cached_master_mask (cached_irq_mask) -#define cached_slave_mask (cached_irq_mask >> 8) +#define cached_21 (cached_irq_mask) +#define cached_A1 (cached_irq_mask >> 8) void disable_8259A_irq(unsigned int irq) { @@ -60,9 +70,9 @@ void disable_8259A_irq(unsigned int irq) spin_lock_irqsave(&i8259A_lock, flags); cached_irq_mask |= mask; if (irq & 8) - outb(cached_slave_mask, PIC_SLAVE_IMR); + outb(cached_A1,0xA1); else - outb(cached_master_mask, PIC_MASTER_IMR); + outb(cached_21,0x21); spin_unlock_irqrestore(&i8259A_lock, flags); } @@ -74,9 +84,9 @@ void enable_8259A_irq(unsigned int irq) spin_lock_irqsave(&i8259A_lock, flags); cached_irq_mask &= mask; if (irq & 8) - outb(cached_slave_mask, PIC_SLAVE_IMR); + outb(cached_A1,0xA1); else - outb(cached_master_mask, PIC_MASTER_IMR); + outb(cached_21,0x21); spin_unlock_irqrestore(&i8259A_lock, flags); } @@ -88,9 +98,9 @@ int i8259A_irq_pending(unsigned int irq) spin_lock_irqsave(&i8259A_lock, flags); if (irq < 8) - ret = inb(PIC_MASTER_CMD) & mask; + ret = inb(0x20) & mask; else - ret = inb(PIC_SLAVE_CMD) & (mask >> 8); + ret = inb(0xA0) & (mask >> 8); spin_unlock_irqrestore(&i8259A_lock, flags); return ret; @@ -99,7 +109,7 @@ int i8259A_irq_pending(unsigned int irq) void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); - set_irq_chip_and_handler(irq, &i8259A_chip, handle_level_irq); + set_irq_chip(irq, &i8259A_irq_type); enable_irq(irq); } @@ -115,14 +125,14 @@ static inline int i8259A_irq_real(unsigned int irq) int irqmask = 1 << irq; if (irq < 8) { - outb(0x0B,PIC_MASTER_CMD); /* ISR register */ - value = inb(PIC_MASTER_CMD) & irqmask; - outb(0x0A,PIC_MASTER_CMD); /* back to the IRR register */ + outb(0x0B,0x20); /* ISR register */ + value = inb(0x20) & irqmask; + outb(0x0A,0x20); /* back to the IRR register */ return value; } - outb(0x0B,PIC_SLAVE_CMD); /* ISR register */ - value = inb(PIC_SLAVE_CMD) & (irqmask >> 8); - outb(0x0A,PIC_SLAVE_CMD); /* back to the IRR register */ + outb(0x0B,0xA0); /* ISR register */ + value = inb(0xA0) & (irqmask >> 8); + outb(0x0A,0xA0); /* back to the IRR register */ return value; } @@ -139,19 +149,17 @@ void mask_and_ack_8259A(unsigned int irq) spin_lock_irqsave(&i8259A_lock, flags); /* - * Lightweight spurious IRQ detection. We do not want - * to overdo spurious IRQ handling - it's usually a sign - * of hardware problems, so we only do the checks we can - * do without slowing down good hardware unnecessarily. + * Lightweight spurious IRQ detection. We do not want to overdo + * spurious IRQ handling - it's usually a sign of hardware problems, so + * we only do the checks we can do without slowing down good hardware + * nnecesserily. * - * Note that IRQ7 and IRQ15 (the two spurious IRQs - * usually resulting from the 8259A-1|2 PICs) occur - * even if the IRQ is masked in the 8259A. Thus we - * can check spurious 8259A IRQs without doing the - * quite slow i8259A_irq_real() call for every IRQ. - * This does not cover 100% of spurious interrupts, - * but should be enough to warn the user that there - * is something bad going on ... + * Note that IRQ7 and IRQ15 (the two spurious IRQs usually resulting + * rom the 8259A-1|2 PICs) occur even if the IRQ is masked in the 8259A. + * Thus we can check spurious 8259A IRQs without doing the quite slow + * i8259A_irq_real() call for every IRQ. This does not cover 100% of + * spurious interrupts, but should be enough to warn the user that + * there is something bad going on ... */ if (cached_irq_mask & irqmask) goto spurious_8259A_irq; @@ -159,14 +167,14 @@ void mask_and_ack_8259A(unsigned int irq) handle_real_irq: if (irq & 8) { - inb(PIC_SLAVE_IMR); /* DUMMY - (do we need this?) */ - outb(cached_slave_mask, PIC_SLAVE_IMR); - outb(0x60+(irq&7),PIC_SLAVE_CMD);/* 'Specific EOI' to slave */ - outb(0x60+PIC_CASCADE_IR,PIC_MASTER_CMD); /* 'Specific EOI' to master-IRQ2 */ + inb(0xA1); /* DUMMY - (do we need this?) */ + outb(cached_A1,0xA1); + outb(0x60+(irq&7),0xA0);/* 'Specific EOI' to slave */ + outb(0x62,0x20); /* 'Specific EOI' to master-IRQ2 */ } else { - inb(PIC_MASTER_IMR); /* DUMMY - (do we need this?) */ - outb(cached_master_mask, PIC_MASTER_IMR); - outb(0x60+irq,PIC_MASTER_CMD); /* 'Specific EOI to master */ + inb(0x21); /* DUMMY - (do we need this?) */ + outb(cached_21,0x21); + outb(0x60+irq,0x20); /* 'Specific EOI' to master */ } #ifdef CONFIG_MIPS_MT_SMTC if (irq_hwmask[irq] & ST0_IM) @@ -187,7 +195,7 @@ void mask_and_ack_8259A(unsigned int irq) goto handle_real_irq; { - static int spurious_irq_mask; + static int spurious_irq_mask = 0; /* * At this point we can be sure the IRQ is spurious, * lets ACK and report it. [once per IRQ] @@ -208,25 +216,13 @@ void mask_and_ack_8259A(unsigned int irq) static int i8259A_resume(struct sys_device *dev) { - init_8259A(i8259A_auto_eoi); - return 0; -} - -static int i8259A_shutdown(struct sys_device *dev) -{ - /* Put the i8259A into a quiescent state that - * the kernel initialization code can get it - * out of. - */ - outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ - outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */ + init_8259A(0); return 0; } static struct sysdev_class i8259_sysdev_class = { set_kset_name("i8259"), .resume = i8259A_resume, - .shutdown = i8259A_shutdown, }; static struct sys_device device_i8259A = { @@ -248,41 +244,41 @@ void __init init_8259A(int auto_eoi) { unsigned long flags; - i8259A_auto_eoi = auto_eoi; - spin_lock_irqsave(&i8259A_lock, flags); - outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ - outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */ + outb(0xff, 0x21); /* mask all of 8259A-1 */ + outb(0xff, 0xA1); /* mask all of 8259A-2 */ /* * outb_p - this has to work on a wide range of PC hardware. */ - outb_p(0x11, PIC_MASTER_CMD); /* ICW1: select 8259A-1 init */ - outb_p(I8259A_IRQ_BASE + 0, PIC_MASTER_IMR); /* ICW2: 8259A-1 IR0 mapped to I8259A_IRQ_BASE + 0x00 */ - outb_p(1U << PIC_CASCADE_IR, PIC_MASTER_IMR); /* 8259A-1 (the master) has a slave on IR2 */ - if (auto_eoi) /* master does Auto EOI */ - outb_p(MASTER_ICW4_DEFAULT | PIC_ICW4_AEOI, PIC_MASTER_IMR); - else /* master expects normal EOI */ - outb_p(MASTER_ICW4_DEFAULT, PIC_MASTER_IMR); - - outb_p(0x11, PIC_SLAVE_CMD); /* ICW1: select 8259A-2 init */ - outb_p(I8259A_IRQ_BASE + 8, PIC_SLAVE_IMR); /* ICW2: 8259A-2 IR0 mapped to I8259A_IRQ_BASE + 0x08 */ - outb_p(PIC_CASCADE_IR, PIC_SLAVE_IMR); /* 8259A-2 is a slave on master's IR2 */ - outb_p(SLAVE_ICW4_DEFAULT, PIC_SLAVE_IMR); /* (slave's support for AEOI in flat mode is to be investigated) */ + outb_p(0x11, 0x20); /* ICW1: select 8259A-1 init */ + outb_p(0x00, 0x21); /* ICW2: 8259A-1 IR0-7 mapped to 0x00-0x07 */ + outb_p(0x04, 0x21); /* 8259A-1 (the master) has a slave on IR2 */ + if (auto_eoi) + outb_p(0x03, 0x21); /* master does Auto EOI */ + else + outb_p(0x01, 0x21); /* master expects normal EOI */ + + outb_p(0x11, 0xA0); /* ICW1: select 8259A-2 init */ + outb_p(0x08, 0xA1); /* ICW2: 8259A-2 IR0-7 mapped to 0x08-0x0f */ + outb_p(0x02, 0xA1); /* 8259A-2 is a slave on master's IR2 */ + outb_p(0x01, 0xA1); /* (slave's support for AEOI in flat mode + is to be investigated) */ + if (auto_eoi) /* - * In AEOI mode we just have to mask the interrupt + * in AEOI mode we just have to mask the interrupt * when acking. */ - i8259A_chip.mask_ack = disable_8259A_irq; + i8259A_irq_type.ack = disable_8259A_irq; else - i8259A_chip.mask_ack = mask_and_ack_8259A; + i8259A_irq_type.ack = mask_and_ack_8259A; udelay(100); /* wait for 8259A to initialize */ - outb(cached_master_mask, PIC_MASTER_IMR); /* restore master IRQ mask */ - outb(cached_slave_mask, PIC_SLAVE_IMR); /* restore slave IRQ mask */ + outb(cached_21, 0x21); /* restore master IRQ mask */ + outb(cached_A1, 0xA1); /* restore slave IRQ mask */ spin_unlock_irqrestore(&i8259A_lock, flags); } @@ -295,17 +291,11 @@ static struct irqaction irq2 = { }; static struct resource pic1_io_resource = { - .name = "pic1", - .start = PIC_MASTER_CMD, - .end = PIC_MASTER_IMR, - .flags = IORESOURCE_BUSY + .name = "pic1", .start = 0x20, .end = 0x21, .flags = IORESOURCE_BUSY }; static struct resource pic2_io_resource = { - .name = "pic2", - .start = PIC_SLAVE_CMD, - .end = PIC_SLAVE_IMR, - .flags = IORESOURCE_BUSY + .name = "pic2", .start = 0xa0, .end = 0xa1, .flags = IORESOURCE_BUSY }; /* @@ -323,7 +313,7 @@ void __init init_i8259_irqs (void) init_8259A(0); for (i = 0; i < 16; i++) - set_irq_chip_and_handler(i, &i8259A_chip, handle_level_irq); + set_irq_chip(i, &i8259A_irq_type); - setup_irq(PIC_CASCADE_IR, &irq2); + setup_irq(2, &irq2); } diff --git a/trunk/arch/mips/kernel/irq-mv6434x.c b/trunk/arch/mips/kernel/irq-mv6434x.c index efbd219845b5..6cfb31cafde2 100644 --- a/trunk/arch/mips/kernel/irq-mv6434x.c +++ b/trunk/arch/mips/kernel/irq-mv6434x.c @@ -66,6 +66,15 @@ static inline void unmask_mv64340_irq(unsigned int irq) } } +/* + * End IRQ processing + */ +static void end_mv64340_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + unmask_mv64340_irq(irq); +} + /* * Interrupt handler for interrupts coming from the Marvell chip. * It could be built in ethernet ports etc... @@ -97,6 +106,7 @@ struct irq_chip mv64340_irq_type = { .mask = mask_mv64340_irq, .mask_ack = mask_mv64340_irq, .unmask = unmask_mv64340_irq, + .end = end_mv64340_irq, }; void __init mv64340_irq_init(unsigned int base) diff --git a/trunk/arch/mips/kernel/irq-rm7000.c b/trunk/arch/mips/kernel/irq-rm7000.c index 123324ba8c14..ddcc2a5f8a06 100644 --- a/trunk/arch/mips/kernel/irq-rm7000.c +++ b/trunk/arch/mips/kernel/irq-rm7000.c @@ -29,12 +29,19 @@ static inline void mask_rm7k_irq(unsigned int irq) clear_c0_intcontrol(0x100 << (irq - irq_base)); } +static void rm7k_cpu_irq_end(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + unmask_rm7k_irq(irq); +} + static struct irq_chip rm7k_irq_controller = { .typename = "RM7000", .ack = mask_rm7k_irq, .mask = mask_rm7k_irq, .mask_ack = mask_rm7k_irq, .unmask = unmask_rm7k_irq, + .end = rm7k_cpu_irq_end, }; void __init rm7k_cpu_irq_init(int base) diff --git a/trunk/arch/mips/kernel/irq-rm9000.c b/trunk/arch/mips/kernel/irq-rm9000.c index 0e6f4c5349d2..ba6440c88abd 100644 --- a/trunk/arch/mips/kernel/irq-rm9000.c +++ b/trunk/arch/mips/kernel/irq-rm9000.c @@ -80,12 +80,19 @@ static void rm9k_perfcounter_irq_shutdown(unsigned int irq) on_each_cpu(local_rm9k_perfcounter_irq_shutdown, (void *) irq, 0, 1); } +static void rm9k_cpu_irq_end(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + unmask_rm9k_irq(irq); +} + static struct irq_chip rm9k_irq_controller = { .typename = "RM9000", .ack = mask_rm9k_irq, .mask = mask_rm9k_irq, .mask_ack = mask_rm9k_irq, .unmask = unmask_rm9k_irq, + .end = rm9k_cpu_irq_end, }; static struct irq_chip rm9k_perfcounter_irq = { @@ -96,6 +103,7 @@ static struct irq_chip rm9k_perfcounter_irq = { .mask = mask_rm9k_irq, .mask_ack = mask_rm9k_irq, .unmask = unmask_rm9k_irq, + .end = rm9k_cpu_irq_end, }; unsigned int rm9000_perfcount_irq; diff --git a/trunk/arch/mips/kernel/irq.c b/trunk/arch/mips/kernel/irq.c index 2fe4c868a801..b339798b3172 100644 --- a/trunk/arch/mips/kernel/irq.c +++ b/trunk/arch/mips/kernel/irq.c @@ -117,7 +117,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].chip->name); + seq_printf(p, " %14s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) diff --git a/trunk/arch/mips/kernel/irq_cpu.c b/trunk/arch/mips/kernel/irq_cpu.c index fcc86b96ccf6..be5ac23d3812 100644 --- a/trunk/arch/mips/kernel/irq_cpu.c +++ b/trunk/arch/mips/kernel/irq_cpu.c @@ -50,6 +50,12 @@ static inline void mask_mips_irq(unsigned int irq) irq_disable_hazard(); } +static void mips_cpu_irq_end(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + unmask_mips_irq(irq); +} + static struct irq_chip mips_cpu_irq_controller = { .typename = "MIPS", .ack = mask_mips_irq, @@ -57,6 +63,7 @@ static struct irq_chip mips_cpu_irq_controller = { .mask_ack = mask_mips_irq, .unmask = unmask_mips_irq, .eoi = unmask_mips_irq, + .end = mips_cpu_irq_end, }; /* @@ -89,6 +96,8 @@ static void mips_mt_cpu_irq_ack(unsigned int irq) mask_mips_mt_irq(irq); } +#define mips_mt_cpu_irq_end mips_cpu_irq_end + static struct irq_chip mips_mt_cpu_irq_controller = { .typename = "MIPS", .startup = mips_mt_cpu_irq_startup, @@ -97,6 +106,7 @@ static struct irq_chip mips_mt_cpu_irq_controller = { .mask_ack = mips_mt_cpu_irq_ack, .unmask = unmask_mips_mt_irq, .eoi = unmask_mips_mt_irq, + .end = mips_mt_cpu_irq_end, }; void __init mips_cpu_irq_init(int irq_base) 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/mips/lasat/interrupt.c b/trunk/arch/mips/lasat/interrupt.c index 2affa5ff171c..4a84a7beac53 100644 --- a/trunk/arch/mips/lasat/interrupt.c +++ b/trunk/arch/mips/lasat/interrupt.c @@ -44,12 +44,19 @@ void enable_lasat_irq(unsigned int irq_nr) *lasat_int_mask |= (1 << irq_nr) << lasat_int_mask_shift; } +static void end_lasat_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_lasat_irq(irq); +} + static struct irq_chip lasat_irq_type = { .typename = "Lasat", .ack = disable_lasat_irq, .mask = disable_lasat_irq, .mask_ack = disable_lasat_irq, .unmask = enable_lasat_irq, + .end = end_lasat_irq, }; static inline int ls1bit32(unsigned int x) diff --git a/trunk/arch/mips/momentum/ocelot_c/cpci-irq.c b/trunk/arch/mips/momentum/ocelot_c/cpci-irq.c index bb11fef08472..e5a4a0a8a7f0 100644 --- a/trunk/arch/mips/momentum/ocelot_c/cpci-irq.c +++ b/trunk/arch/mips/momentum/ocelot_c/cpci-irq.c @@ -65,6 +65,15 @@ static inline void unmask_cpci_irq(unsigned int irq) value = OCELOT_FPGA_READ(INTMASK); } +/* + * End IRQ processing + */ +static void end_cpci_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + unmask_cpci_irq(irq); +} + /* * Interrupt handler for interrupts coming from the FPGA chip. * It could be built in ethernet ports etc... @@ -89,6 +98,7 @@ struct irq_chip cpci_irq_type = { .mask = mask_cpci_irq, .mask_ack = mask_cpci_irq, .unmask = unmask_cpci_irq, + .end = end_cpci_irq, }; void cpci_irq_init(void) diff --git a/trunk/arch/mips/momentum/ocelot_c/uart-irq.c b/trunk/arch/mips/momentum/ocelot_c/uart-irq.c index a7a80c0da569..0029f0008dea 100644 --- a/trunk/arch/mips/momentum/ocelot_c/uart-irq.c +++ b/trunk/arch/mips/momentum/ocelot_c/uart-irq.c @@ -59,6 +59,15 @@ static inline void unmask_uart_irq(unsigned int irq) value = OCELOT_FPGA_READ(UART_INTMASK); } +/* + * End IRQ processing + */ +static void end_uart_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + unmask_uart_irq(irq); +} + /* * Interrupt handler for interrupts coming from the FPGA chip. */ @@ -82,6 +91,7 @@ struct irq_chip uart_irq_type = { .mask = mask_uart_irq, .mask_ack = mask_uart_irq, .unmask = unmask_uart_irq, + .end = end_uart_irq, }; void uart_irq_init(void) diff --git a/trunk/arch/mips/philips/pnx8550/common/int.c b/trunk/arch/mips/philips/pnx8550/common/int.c index 2c36c108c4d6..0dc23930edbd 100644 --- a/trunk/arch/mips/philips/pnx8550/common/int.c +++ b/trunk/arch/mips/philips/pnx8550/common/int.c @@ -158,12 +158,20 @@ int pnx8550_set_gic_priority(int irq, int priority) return prev_priority; } +static void end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + unmask_irq(irq); + } +} + static struct irq_chip level_irq_type = { .typename = "PNX Level IRQ", .ack = mask_irq, .mask = mask_irq, .mask_ack = mask_irq, .unmask = unmask_irq, + .end = end_irq, }; static struct irqaction gic_action = { diff --git a/trunk/arch/mips/sgi-ip22/ip22-int.c b/trunk/arch/mips/sgi-ip22/ip22-int.c index c44f8be0644f..c7b138053159 100644 --- a/trunk/arch/mips/sgi-ip22/ip22-int.c +++ b/trunk/arch/mips/sgi-ip22/ip22-int.c @@ -51,12 +51,19 @@ static void disable_local0_irq(unsigned int irq) sgint->imask0 &= ~(1 << (irq - SGINT_LOCAL0)); } +static void end_local0_irq (unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_local0_irq(irq); +} + static struct irq_chip ip22_local0_irq_type = { .typename = "IP22 local 0", .ack = disable_local0_irq, .mask = disable_local0_irq, .mask_ack = disable_local0_irq, .unmask = enable_local0_irq, + .end = end_local0_irq, }; static void enable_local1_irq(unsigned int irq) @@ -72,12 +79,19 @@ void disable_local1_irq(unsigned int irq) sgint->imask1 &= ~(1 << (irq - SGINT_LOCAL1)); } +static void end_local1_irq (unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_local1_irq(irq); +} + static struct irq_chip ip22_local1_irq_type = { .typename = "IP22 local 1", .ack = disable_local1_irq, .mask = disable_local1_irq, .mask_ack = disable_local1_irq, .unmask = enable_local1_irq, + .end = end_local1_irq, }; static void enable_local2_irq(unsigned int irq) @@ -93,12 +107,19 @@ void disable_local2_irq(unsigned int irq) sgint->imask0 &= ~(1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0)); } +static void end_local2_irq (unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_local2_irq(irq); +} + static struct irq_chip ip22_local2_irq_type = { .typename = "IP22 local 2", .ack = disable_local2_irq, .mask = disable_local2_irq, .mask_ack = disable_local2_irq, .unmask = enable_local2_irq, + .end = end_local2_irq, }; static void enable_local3_irq(unsigned int irq) @@ -114,12 +135,19 @@ void disable_local3_irq(unsigned int irq) sgint->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1)); } +static void end_local3_irq (unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_local3_irq(irq); +} + static struct irq_chip ip22_local3_irq_type = { .typename = "IP22 local 3", .ack = disable_local3_irq, .mask = disable_local3_irq, .mask_ack = disable_local3_irq, .unmask = enable_local3_irq, + .end = end_local3_irq, }; static void indy_local0_irqdispatch(void) diff --git a/trunk/arch/mips/sgi-ip27/ip27-irq.c b/trunk/arch/mips/sgi-ip27/ip27-irq.c index 319f8803ef6f..5f8835b4e84a 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-irq.c +++ b/trunk/arch/mips/sgi-ip27/ip27-irq.c @@ -332,6 +332,13 @@ static inline void disable_bridge_irq(unsigned int irq) intr_disconnect_level(cpu, swlevel); } +static void end_bridge_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)) && + irq_desc[irq].action) + enable_bridge_irq(irq); +} + static struct irq_chip bridge_irq_type = { .typename = "bridge", .startup = startup_bridge_irq, @@ -340,6 +347,7 @@ static struct irq_chip bridge_irq_type = { .mask = disable_bridge_irq, .mask_ack = disable_bridge_irq, .unmask = enable_bridge_irq, + .end = end_bridge_irq, }; void __devinit register_bridge_irq(unsigned int irq) diff --git a/trunk/arch/mips/sgi-ip27/ip27-timer.c b/trunk/arch/mips/sgi-ip27/ip27-timer.c index c20e9899b34b..7d361726bbfb 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-timer.c +++ b/trunk/arch/mips/sgi-ip27/ip27-timer.c @@ -180,6 +180,10 @@ static void disable_rt_irq(unsigned int irq) { } +static void end_rt_irq(unsigned int irq) +{ +} + static struct irq_chip rt_irq_type = { .typename = "SN HUB RT timer", .ack = disable_rt_irq, @@ -187,6 +191,7 @@ static struct irq_chip rt_irq_type = { .mask_ack = disable_rt_irq, .unmask = enable_rt_irq, .eoi = enable_rt_irq, + .end = end_rt_irq, }; static struct irqaction rt_irqaction = { diff --git a/trunk/arch/mips/tx4927/common/tx4927_irq.c b/trunk/arch/mips/tx4927/common/tx4927_irq.c index ed4a19adf361..21873de49aa8 100644 --- a/trunk/arch/mips/tx4927/common/tx4927_irq.c +++ b/trunk/arch/mips/tx4927/common/tx4927_irq.c @@ -66,10 +66,12 @@ #define TX4927_IRQ_CP0_INIT ( 1 << 10 ) #define TX4927_IRQ_CP0_ENABLE ( 1 << 13 ) #define TX4927_IRQ_CP0_DISABLE ( 1 << 14 ) +#define TX4927_IRQ_CP0_ENDIRQ ( 1 << 16 ) #define TX4927_IRQ_PIC_INIT ( 1 << 20 ) #define TX4927_IRQ_PIC_ENABLE ( 1 << 23 ) #define TX4927_IRQ_PIC_DISABLE ( 1 << 24 ) +#define TX4927_IRQ_PIC_ENDIRQ ( 1 << 26 ) #define TX4927_IRQ_ALL 0xffffffff #endif @@ -80,10 +82,12 @@ static const u32 tx4927_irq_debug_flag = (TX4927_IRQ_NONE | TX4927_IRQ_WARN | TX4927_IRQ_EROR // | TX4927_IRQ_CP0_INIT // | TX4927_IRQ_CP0_ENABLE +// | TX4927_IRQ_CP0_DISABLE // | TX4927_IRQ_CP0_ENDIRQ // | TX4927_IRQ_PIC_INIT // | TX4927_IRQ_PIC_ENABLE // | TX4927_IRQ_PIC_DISABLE +// | TX4927_IRQ_PIC_ENDIRQ // | TX4927_IRQ_INIT // | TX4927_IRQ_NEST1 // | TX4927_IRQ_NEST2 @@ -110,9 +114,11 @@ static const u32 tx4927_irq_debug_flag = (TX4927_IRQ_NONE static void tx4927_irq_cp0_enable(unsigned int irq); static void tx4927_irq_cp0_disable(unsigned int irq); +static void tx4927_irq_cp0_end(unsigned int irq); static void tx4927_irq_pic_enable(unsigned int irq); static void tx4927_irq_pic_disable(unsigned int irq); +static void tx4927_irq_pic_end(unsigned int irq); /* * Kernel structs for all pic's @@ -125,6 +131,7 @@ static struct irq_chip tx4927_irq_cp0_type = { .mask = tx4927_irq_cp0_disable, .mask_ack = tx4927_irq_cp0_disable, .unmask = tx4927_irq_cp0_enable, + .end = tx4927_irq_cp0_end, }; #define TX4927_PIC_NAME "TX4927-PIC" @@ -134,6 +141,7 @@ static struct irq_chip tx4927_irq_pic_type = { .mask = tx4927_irq_pic_disable, .mask_ack = tx4927_irq_pic_disable, .unmask = tx4927_irq_pic_enable, + .end = tx4927_irq_pic_end, }; #define TX4927_PIC_ACTION(s) { no_action, 0, CPU_MASK_NONE, s, NULL, NULL } @@ -206,6 +214,15 @@ static void tx4927_irq_cp0_disable(unsigned int irq) tx4927_irq_cp0_modify(CCP0_STATUS, tx4927_irq_cp0_mask(irq), 0); } +static void tx4927_irq_cp0_end(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_ENDIRQ, "irq=%d \n", irq); + + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + tx4927_irq_cp0_enable(irq); + } +} + /* * Functions for pic */ @@ -359,6 +376,15 @@ static void tx4927_irq_pic_disable(unsigned int irq) tx4927_irq_pic_mask(irq), 0); } +static void tx4927_irq_pic_end(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_ENDIRQ, "irq=%d\n", irq); + + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + tx4927_irq_pic_enable(irq); + } +} + /* * Main init functions */ diff --git a/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c b/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c index 5a5ea6c0b9f6..34cdb2a240e9 100644 --- a/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c +++ b/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c @@ -153,6 +153,7 @@ JP7 is not bus master -- do NOT use -- only 4 pci bus master's allowed -- SouthB #define TOSHIBA_RBTX4927_IRQ_IOC_INIT ( 1 << 10 ) #define TOSHIBA_RBTX4927_IRQ_IOC_ENABLE ( 1 << 13 ) #define TOSHIBA_RBTX4927_IRQ_IOC_DISABLE ( 1 << 14 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ ( 1 << 16 ) #define TOSHIBA_RBTX4927_IRQ_ISA_INIT ( 1 << 20 ) #define TOSHIBA_RBTX4927_IRQ_ISA_ENABLE ( 1 << 23 ) @@ -171,6 +172,7 @@ static const u32 toshiba_rbtx4927_irq_debug_flag = // | TOSHIBA_RBTX4927_IRQ_IOC_INIT // | TOSHIBA_RBTX4927_IRQ_IOC_ENABLE // | TOSHIBA_RBTX4927_IRQ_IOC_DISABLE +// | TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ // | TOSHIBA_RBTX4927_IRQ_ISA_INIT // | TOSHIBA_RBTX4927_IRQ_ISA_ENABLE // | TOSHIBA_RBTX4927_IRQ_ISA_DISABLE @@ -221,6 +223,7 @@ extern void mask_and_ack_8259A(unsigned int irq); static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq); static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq); +static void toshiba_rbtx4927_irq_ioc_end(unsigned int irq); #ifdef CONFIG_TOSHIBA_FPCIB0 static void toshiba_rbtx4927_irq_isa_enable(unsigned int irq); @@ -236,6 +239,7 @@ static struct irq_chip toshiba_rbtx4927_irq_ioc_type = { .mask = toshiba_rbtx4927_irq_ioc_disable, .mask_ack = toshiba_rbtx4927_irq_ioc_disable, .unmask = toshiba_rbtx4927_irq_ioc_enable, + .end = toshiba_rbtx4927_irq_ioc_end, }; #define TOSHIBA_RBTX4927_IOC_INTR_ENAB 0xbc002000 #define TOSHIBA_RBTX4927_IOC_INTR_STAT 0xbc002006 @@ -384,6 +388,23 @@ static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq) TOSHIBA_RBTX4927_WR08(TOSHIBA_RBTX4927_IOC_INTR_ENAB, v); } +static void toshiba_rbtx4927_irq_ioc_end(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + toshiba_rbtx4927_irq_ioc_enable(irq); + } +} + /**********************************************************************************/ /* Functions for isa */ diff --git a/trunk/arch/mips/tx4938/common/irq.c b/trunk/arch/mips/tx4938/common/irq.c index a347b424d91c..42e127683ae9 100644 --- a/trunk/arch/mips/tx4938/common/irq.c +++ b/trunk/arch/mips/tx4938/common/irq.c @@ -39,9 +39,11 @@ static void tx4938_irq_cp0_enable(unsigned int irq); static void tx4938_irq_cp0_disable(unsigned int irq); +static void tx4938_irq_cp0_end(unsigned int irq); static void tx4938_irq_pic_enable(unsigned int irq); static void tx4938_irq_pic_disable(unsigned int irq); +static void tx4938_irq_pic_end(unsigned int irq); /**********************************************************************************/ /* Kernel structs for all pic's */ @@ -54,6 +56,7 @@ static struct irq_chip tx4938_irq_cp0_type = { .mask = tx4938_irq_cp0_disable, .mask_ack = tx4938_irq_cp0_disable, .unmask = tx4938_irq_cp0_enable, + .end = tx4938_irq_cp0_end, }; #define TX4938_PIC_NAME "TX4938-PIC" @@ -63,6 +66,7 @@ static struct irq_chip tx4938_irq_pic_type = { .mask = tx4938_irq_pic_disable, .mask_ack = tx4938_irq_pic_disable, .unmask = tx4938_irq_pic_enable, + .end = tx4938_irq_pic_end, }; static struct irqaction tx4938_irq_pic_action = { @@ -100,6 +104,14 @@ tx4938_irq_cp0_disable(unsigned int irq) clear_c0_status(tx4938_irq_cp0_mask(irq)); } +static void +tx4938_irq_cp0_end(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + tx4938_irq_cp0_enable(irq); + } +} + /**********************************************************************************/ /* Functions for pic */ /**********************************************************************************/ @@ -257,6 +269,14 @@ tx4938_irq_pic_disable(unsigned int irq) tx4938_irq_pic_mask(irq), 0); } +static void +tx4938_irq_pic_end(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + tx4938_irq_pic_enable(irq); + } +} + /**********************************************************************************/ /* Main init functions */ /**********************************************************************************/ diff --git a/trunk/arch/mips/tx4938/toshiba_rbtx4938/irq.c b/trunk/arch/mips/tx4938/toshiba_rbtx4938/irq.c index b6f363d08011..8c87a35f3068 100644 --- a/trunk/arch/mips/tx4938/toshiba_rbtx4938/irq.c +++ b/trunk/arch/mips/tx4938/toshiba_rbtx4938/irq.c @@ -89,6 +89,7 @@ IRQ Device static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq); static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq); +static void toshiba_rbtx4938_irq_ioc_end(unsigned int irq); #define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC" static struct irq_chip toshiba_rbtx4938_irq_ioc_type = { @@ -97,6 +98,7 @@ static struct irq_chip toshiba_rbtx4938_irq_ioc_type = { .mask = toshiba_rbtx4938_irq_ioc_disable, .mask_ack = toshiba_rbtx4938_irq_ioc_disable, .unmask = toshiba_rbtx4938_irq_ioc_enable, + .end = toshiba_rbtx4938_irq_ioc_end, }; #define TOSHIBA_RBTX4938_IOC_INTR_ENAB 0xb7f02000 @@ -165,6 +167,14 @@ toshiba_rbtx4938_irq_ioc_disable(unsigned int irq) TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB); } +static void +toshiba_rbtx4938_irq_ioc_end(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + toshiba_rbtx4938_irq_ioc_enable(irq); + } +} + extern void __init txx9_spi_irqinit(int irc_irq); void __init arch_init_irq(void) diff --git a/trunk/arch/mips/vr41xx/Kconfig b/trunk/arch/mips/vr41xx/Kconfig index c8dfd8092cab..92f41f6f934a 100644 --- a/trunk/arch/mips/vr41xx/Kconfig +++ b/trunk/arch/mips/vr41xx/Kconfig @@ -6,7 +6,6 @@ config CASIO_E55 select ISA select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN - select GENERIC_HARDIRQS_NO__DO_IRQ config IBM_WORKPAD bool "Support for IBM WorkPad z50" @@ -16,7 +15,6 @@ config IBM_WORKPAD select ISA select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN - select GENERIC_HARDIRQS_NO__DO_IRQ config NEC_CMBVR4133 bool "Support for NEC CMB-VR4133" @@ -41,7 +39,6 @@ config TANBAC_TB022X select IRQ_CPU select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN - select GENERIC_HARDIRQS_NO__DO_IRQ help The TANBAC VR4131 multichip module(TB0225) and the TANBAC VR4131DIMM(TB0229) are MIPS-based platforms @@ -74,7 +71,6 @@ config VICTOR_MPC30X select IRQ_CPU select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN - select GENERIC_HARDIRQS_NO__DO_IRQ config ZAO_CAPCELLA bool "Support for ZAO Networks Capcella" @@ -84,7 +80,6 @@ config ZAO_CAPCELLA select IRQ_CPU select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN - select GENERIC_HARDIRQS_NO__DO_IRQ config PCI_VR41XX bool "Add PCI control unit support of NEC VR4100 series" diff --git a/trunk/arch/mips/vr41xx/common/icu.c b/trunk/arch/mips/vr41xx/common/icu.c index c075261976c5..54b92a74c7ac 100644 --- a/trunk/arch/mips/vr41xx/common/icu.c +++ b/trunk/arch/mips/vr41xx/common/icu.c @@ -427,12 +427,19 @@ static void enable_sysint1_irq(unsigned int irq) icu1_set(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(irq)); } +static void end_sysint1_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + icu1_set(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(irq)); +} + static struct irq_chip sysint1_irq_type = { .typename = "SYSINT1", .ack = disable_sysint1_irq, .mask = disable_sysint1_irq, .mask_ack = disable_sysint1_irq, .unmask = enable_sysint1_irq, + .end = end_sysint1_irq, }; static void disable_sysint2_irq(unsigned int irq) @@ -445,12 +452,19 @@ static void enable_sysint2_irq(unsigned int irq) icu2_set(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(irq)); } +static void end_sysint2_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + icu2_set(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(irq)); +} + static struct irq_chip sysint2_irq_type = { .typename = "SYSINT2", .ack = disable_sysint2_irq, .mask = disable_sysint2_irq, .mask_ack = disable_sysint2_irq, .unmask = enable_sysint2_irq, + .end = end_sysint2_irq, }; static inline int set_sysint1_assign(unsigned int irq, unsigned char assign) 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 d83d64af31f2..bffc7e176970 100644 --- a/trunk/arch/sh/Kconfig +++ b/trunk/arch/sh/Kconfig @@ -51,14 +51,6 @@ config GENERIC_TIME config ARCH_MAY_HAVE_PC_FDC bool -config STACKTRACE_SUPPORT - bool - default y - -config LOCKDEP_SUPPORT - bool - default y - source "init/Kconfig" menu "System type" @@ -227,20 +219,6 @@ 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 @@ -302,20 +280,12 @@ config CF_BASE_ADDR menu "Processor features" -choice - prompt "Endianess selection" - default CPU_LITTLE_ENDIAN - help - Some SuperH machines can be configured for either little or big - endian byte order. These modes require different kernels. - config CPU_LITTLE_ENDIAN bool "Little Endian" - -config CPU_BIG_ENDIAN - bool "Big Endian" - -endchoice + help + Some SuperH machines can be configured for either little or big + endian byte order. These modes require different kernels. Say Y if + your machine is little endian, N if it's a big endian machine. config SH_FPU bool "FPU support" @@ -375,9 +345,6 @@ config CPU_HAS_MASKREG_IRQ config CPU_HAS_INTC2_IRQ bool -config CPU_HAS_IPR_IRQ - bool - config CPU_HAS_SR_RB bool "CPU has SR.RB" depends on CPU_SH3 || CPU_SH4 @@ -390,9 +357,6 @@ config CPU_HAS_SR_RB See for further information on SR.RB and register banking in the kernel in general. -config CPU_HAS_PTEA - bool - endmenu menu "Timer support" @@ -400,25 +364,10 @@ 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" @@ -427,52 +376,19 @@ source "arch/sh/boards/renesas/rts7751r2d/Kconfig" source "arch/sh/boards/renesas/r7780rp/Kconfig" -config SH_TIMER_IRQ - int - default "28" if CPU_SUBTYPE_SH7780 - default "86" if CPU_SUBTYPE_SH7619 - default "140" if CPU_SUBTYPE_SH7206 - default "16" - -config NO_IDLE_HZ - bool "Dynamic tick timer" - help - Select this option if you want to disable continuous timer ticks - and have them programmed to occur as required. This option saves - power as the system can remain in idle state for longer. - - By default dynamic tick is disabled during the boot, and can be - manually enabled with: - - echo 1 > /sys/devices/system/timer/timer0/dyn_tick - - Alternatively, if you want dynamic tick automatically enabled - during boot, pass "dyntick=enable" via the kernel command string. - - Please note that dynamic tick may affect the accuracy of - timekeeping on some platforms depending on the implementation. - 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" @@ -505,8 +421,6 @@ config HEARTBEAT behavior is platform-dependent, but normally the flash frequency is a hyperbolic function of the 5-minute load average. -source "arch/sh/drivers/Kconfig" - endmenu config ISA_DMA_API diff --git a/trunk/arch/sh/Kconfig.debug b/trunk/arch/sh/Kconfig.debug index 66a25ef4ef1b..48479e014dac 100644 --- a/trunk/arch/sh/Kconfig.debug +++ b/trunk/arch/sh/Kconfig.debug @@ -1,9 +1,5 @@ menu "Kernel hacking" -config TRACE_IRQFLAGS_SUPPORT - bool - default y - source "lib/Kconfig.debug" config SH_STANDARD_BIOS @@ -21,18 +17,7 @@ config SH_STANDARD_BIOS config EARLY_SCIF_CONSOLE bool "Use early SCIF console" - help - This enables an early console using a fixed SCIF port. This can - be used by platforms that are either not running the SH - standard BIOS, or do not wish to use the BIOS callbacks for the - serial I/O. - -config EARLY_SCIF_CONSOLE_PORT - hex "SCIF port for early console" - depends on EARLY_SCIF_CONSOLE - default "0xffe00000" if CPU_SUBTYPE_SH7780 - default "0xfffe9800" if CPU_SUBTYPE_SH72060 - default "0xffe80000" if CPU_SH4 + depends on CPU_SH4 || CPU_SH2A && !SH_STANDARD_BIOS config EARLY_PRINTK bool "Early printk support" @@ -45,11 +30,6 @@ config EARLY_PRINTK when the kernel may crash or hang before the serial console is initialised. If unsure, say N. - On devices that are running SH-IPL and want to keep the port - initialization consistent while not using the BIOS callbacks, - select both the EARLY_SCIF_CONSOLE and SH_STANDARD_BIOS, using - the kernel command line option to toggle back and forth. - config DEBUG_STACKOVERFLOW bool "Check for stack overflows" depends on DEBUG_KERNEL diff --git a/trunk/arch/sh/Makefile b/trunk/arch/sh/Makefile index d10bba5e1074..26d62ff51a64 100644 --- a/trunk/arch/sh/Makefile +++ b/trunk/arch/sh/Makefile @@ -13,6 +13,10 @@ # for "archclean" and "archdep" for cleaning up and making dependencies for # this architecture # + +cflags-y := -mb +cflags-$(CONFIG_CPU_LITTLE_ENDIAN) := -ml + isa-y := any isa-$(CONFIG_SH_DSP) := sh isa-$(CONFIG_CPU_SH2) := sh2 @@ -34,16 +38,13 @@ isa-y := $(isa-y)-nofpu endif endif -cflags-$(CONFIG_CPU_SH2) := -m2 -cflags-$(CONFIG_CPU_SH3) := -m3 -cflags-$(CONFIG_CPU_SH4) := -m4 \ - $(call cc-option,-mno-implicit-fp,-m4-nofpu) -cflags-$(CONFIG_CPU_SH4A) := -m4a $(call cc-option,-m4a-nofpu,) - -cflags-$(CONFIG_CPU_BIG_ENDIAN) += -mb -cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -ml +cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),) -cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),) -ffreestanding +cflags-$(CONFIG_CPU_SH2) += -m2 +cflags-$(CONFIG_CPU_SH3) += -m3 +cflags-$(CONFIG_CPU_SH4) += -m4 \ + $(call cc-option,-mno-implicit-fp,-m4-nofpu) +cflags-$(CONFIG_CPU_SH4A) += $(call cc-option,-m4a-nofpu,) cflags-$(CONFIG_SH_DSP) += -Wa,-dsp cflags-$(CONFIG_SH_KGDB) += -g @@ -58,9 +59,7 @@ OBJCOPYFLAGS := -O binary -R .note -R .comment -R .stab -R .stabstr -S # never be used by anyone. Use a board-specific defconfig that has a # reasonable chance of being current instead. # -KBUILD_DEFCONFIG := r7780rp_defconfig - -KBUILD_IMAGE := arch/sh/boot/zImage +KBUILD_DEFCONFIG := rts7751r2d_defconfig # # Choosing incompatible machines durings configuration will result in @@ -110,8 +109,6 @@ 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)) @@ -127,7 +124,6 @@ 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/boards/renesas/r7780rp/Makefile b/trunk/arch/sh/boards/renesas/r7780rp/Makefile index 574b0316ed56..f1776d027978 100644 --- a/trunk/arch/sh/boards/renesas/r7780rp/Makefile +++ b/trunk/arch/sh/boards/renesas/r7780rp/Makefile @@ -3,6 +3,4 @@ # obj-y := setup.o io.o irq.o - -obj-$(CONFIG_HEARTBEAT) += led.o -obj-$(CONFIG_PUSH_SWITCH) += psw.o +obj-$(CONFIG_HEARTBEAT) += led.o diff --git a/trunk/arch/sh/boards/renesas/r7780rp/irq.c b/trunk/arch/sh/boards/renesas/r7780rp/irq.c index cc381e197783..aa15ec5bc69e 100644 --- a/trunk/arch/sh/boards/renesas/r7780rp/irq.c +++ b/trunk/arch/sh/boards/renesas/r7780rp/irq.c @@ -10,7 +10,6 @@ */ #include #include -#include #include #include diff --git a/trunk/arch/sh/boards/renesas/r7780rp/psw.c b/trunk/arch/sh/boards/renesas/r7780rp/psw.c deleted file mode 100644 index c844dfa5d58d..000000000000 --- a/trunk/arch/sh/boards/renesas/r7780rp/psw.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * arch/sh/boards/renesas/r7780rp/psw.c - * - * push switch support for RDBRP-1/RDBREVRP-1 debug boards. - * - * Copyright (C) 2006 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 -#include - -static irqreturn_t psw_irq_handler(int irq, void *arg) -{ - struct platform_device *pdev = arg; - struct push_switch *psw = platform_get_drvdata(pdev); - struct push_switch_platform_info *psw_info = pdev->dev.platform_data; - unsigned int l, mask; - int ret = 0; - - l = ctrl_inw(PA_DBSW); - - /* Nothing to do if there's no state change */ - if (psw->state) { - ret = 1; - goto out; - } - - mask = l & 0x70; - /* Figure out who raised it */ - if (mask & (1 << psw_info->bit)) { - psw->state = !!(mask & (1 << psw_info->bit)); - if (psw->state) /* debounce */ - mod_timer(&psw->debounce, jiffies + 50); - - ret = 1; - } - -out: - /* Clear the switch IRQs */ - l |= (0x7 << 12); - ctrl_outw(l, PA_DBSW); - - return IRQ_RETVAL(ret); -} - -static struct resource psw_resources[] = { - [0] = { - .start = IRQ_PSW, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct push_switch_platform_info s2_platform_data = { - .name = "s2", - .bit = 6, - .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | - IRQF_SHARED, - .irq_handler = psw_irq_handler, -}; - -static struct platform_device s2_switch_device = { - .name = "push-switch", - .id = 0, - .num_resources = ARRAY_SIZE(psw_resources), - .resource = psw_resources, - .dev = { - .platform_data = &s2_platform_data, - }, -}; - -static struct push_switch_platform_info s3_platform_data = { - .name = "s3", - .bit = 5, - .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | - IRQF_SHARED, - .irq_handler = psw_irq_handler, -}; - -static struct platform_device s3_switch_device = { - .name = "push-switch", - .id = 1, - .num_resources = ARRAY_SIZE(psw_resources), - .resource = psw_resources, - .dev = { - .platform_data = &s3_platform_data, - }, -}; - -static struct push_switch_platform_info s4_platform_data = { - .name = "s4", - .bit = 4, - .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | - IRQF_SHARED, - .irq_handler = psw_irq_handler, -}; - -static struct platform_device s4_switch_device = { - .name = "push-switch", - .id = 2, - .num_resources = ARRAY_SIZE(psw_resources), - .resource = psw_resources, - .dev = { - .platform_data = &s4_platform_data, - }, -}; - -static struct platform_device *psw_devices[] = { - &s2_switch_device, &s3_switch_device, &s4_switch_device, -}; - -static int __init psw_init(void) -{ - return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices)); -} -module_init(psw_init); diff --git a/trunk/arch/sh/boards/renesas/r7780rp/setup.c b/trunk/arch/sh/boards/renesas/r7780rp/setup.c index 9f89c8de9db9..c331caeb694b 100644 --- a/trunk/arch/sh/boards/renesas/r7780rp/setup.c +++ b/trunk/arch/sh/boards/renesas/r7780rp/setup.c @@ -44,37 +44,8 @@ static struct platform_device m66596_usb_host_device = { .resource = m66596_usb_host_resources, }; -static struct resource cf_ide_resources[] = { - [0] = { - .start = 0x1f0, - .end = 0x1f0 + 8, - .flags = IORESOURCE_IO, - }, - [1] = { - .start = 0x1f0 + 0x206, - .end = 0x1f0 + 8 + 0x206 + 8, - .flags = IORESOURCE_IO, - }, - [2] = { -#ifdef CONFIG_SH_R7780MP - .start = 1, -#else - .start = 4, -#endif - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device cf_ide_device = { - .name = "pata_platform", - .id = -1, - .num_resources = ARRAY_SIZE(cf_ide_resources), - .resource = cf_ide_resources, -}; - static struct platform_device *r7780rp_devices[] __initdata = { &m66596_usb_host_device, - &cf_ide_device, }; static int __init r7780rp_devices_setup(void) diff --git a/trunk/arch/sh/boards/se/7206/Makefile b/trunk/arch/sh/boards/se/7206/Makefile deleted file mode 100644 index 63950f4f2453..000000000000 --- a/trunk/arch/sh/boards/se/7206/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for the 7206 SolutionEngine specific parts of the kernel -# - -obj-y := setup.o io.o irq.o -obj-$(CONFIG_HEARTBEAT) += led.o - diff --git a/trunk/arch/sh/boards/se/7206/io.c b/trunk/arch/sh/boards/se/7206/io.c deleted file mode 100644 index b557273e0cbe..000000000000 --- a/trunk/arch/sh/boards/se/7206/io.c +++ /dev/null @@ -1,123 +0,0 @@ -/* $Id: io.c,v 1.5 2004/02/22 23:08:43 kkojima Exp $ - * - * linux/arch/sh/boards/se/7206/io.c - * - * Copyright (C) 2006 Yoshinori Sato - * - * I/O routine for Hitachi 7206 SolutionEngine. - * - */ - -#include -#include -#include -#include - - -static inline void delay(void) -{ - ctrl_inw(0x20000000); /* P2 ROM Area */ -} - -/* MS7750 requires special versions of in*, out* routines, since - PC-like io ports are located at upper half byte of 16-bit word which - can be accessed only with 16-bit wide. */ - -static inline volatile __u16 * -port2adr(unsigned int port) -{ - if (port >= 0x2000) - return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); - else if (port >= 0x300 || port < 0x310) - return (volatile __u16 *) (PA_SMSC + (port - 0x300)); -} - -unsigned char se7206_inb(unsigned long port) -{ - return (*port2adr(port))&0xff; -} - -unsigned char se7206_inb_p(unsigned long port) -{ - unsigned long v; - - v = (*port2adr(port))&0xff; - delay(); - return v; -} - -unsigned short se7206_inw(unsigned long port) -{ - return *port2adr(port);; -} - -unsigned int se7206_inl(unsigned long port) -{ - maybebadio(port); - return 0; -} - -void se7206_outb(unsigned char value, unsigned long port) -{ - *(port2adr(port)) = value; -} - -void se7206_outb_p(unsigned char value, unsigned long port) -{ - *(port2adr(port)) = value; - delay(); -} - -void se7206_outw(unsigned short value, unsigned long port) -{ - *port2adr(port) = value; -} - -void se7206_outl(unsigned int value, unsigned long port) -{ - maybebadio(port); -} - -void se7206_insb(unsigned long port, void *addr, unsigned long count) -{ - volatile __u16 *p = port2adr(port); - __u8 *ap = addr; - - while (count--) - *ap++ = *p; -} - -void se7206_insw(unsigned long port, void *addr, unsigned long count) -{ - volatile __u16 *p = port2adr(port); - __u16 *ap = addr; - while (count--) - *ap++ = *p; -} - -void se7206_insl(unsigned long port, void *addr, unsigned long count) -{ - maybebadio(port); -} - -void se7206_outsb(unsigned long port, const void *addr, unsigned long count) -{ - volatile __u16 *p = port2adr(port); - const __u8 *ap = addr; - - while (count--) - *p = *ap++; -} - -void se7206_outsw(unsigned long port, const void *addr, unsigned long count) -{ - volatile __u16 *p = port2adr(port); - const __u16 *ap = addr; - while (count--) - *p = *ap++; -} - -void se7206_outsl(unsigned long port, const void *addr, unsigned long count) -{ - maybebadio(port); -} diff --git a/trunk/arch/sh/boards/se/7206/irq.c b/trunk/arch/sh/boards/se/7206/irq.c deleted file mode 100644 index 3fb0c5f5b23a..000000000000 --- a/trunk/arch/sh/boards/se/7206/irq.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * linux/arch/sh/boards/se/7206/irq.c - * - * Copyright (C) 2005,2006 Yoshinori Sato - * - * Hitachi SolutionEngine Support. - * - */ -#include -#include -#include -#include -#include - -#define INTSTS0 0x31800000 -#define INTSTS1 0x31800002 -#define INTMSK0 0x31800004 -#define INTMSK1 0x31800006 -#define INTSEL 0x31800008 - -static void disable_se7206_irq(unsigned int irq) -{ - unsigned short val; - unsigned short mask = 0xffff ^ (0x0f << 4 * (3 - (IRQ0_IRQ - irq))); - unsigned short msk0,msk1; - - /* Set the priority in IPR to 0 */ - val = ctrl_inw(INTC_IPR01); - val &= mask; - ctrl_outw(val, INTC_IPR01); - /* FPGA mask set */ - msk0 = ctrl_inw(INTMSK0); - msk1 = ctrl_inw(INTMSK1); - - switch (irq) { - case IRQ0_IRQ: - msk0 |= 0x0010; - break; - case IRQ1_IRQ: - msk0 |= 0x000f; - break; - case IRQ2_IRQ: - msk0 |= 0x0f00; - msk1 |= 0x00ff; - break; - } - ctrl_outw(msk0, INTMSK0); - ctrl_outw(msk1, INTMSK1); -} - -static void enable_se7206_irq(unsigned int irq) -{ - unsigned short val; - unsigned short value = (0x0001 << 4 * (3 - (IRQ0_IRQ - irq))); - unsigned short msk0,msk1; - - /* Set priority in IPR back to original value */ - val = ctrl_inw(INTC_IPR01); - val |= value; - ctrl_outw(val, INTC_IPR01); - - /* FPGA mask reset */ - msk0 = ctrl_inw(INTMSK0); - msk1 = ctrl_inw(INTMSK1); - - switch (irq) { - case IRQ0_IRQ: - msk0 &= ~0x0010; - break; - case IRQ1_IRQ: - msk0 &= ~0x000f; - break; - case IRQ2_IRQ: - msk0 &= ~0x0f00; - msk1 &= ~0x00ff; - break; - } - ctrl_outw(msk0, INTMSK0); - ctrl_outw(msk1, INTMSK1); -} - -static void eoi_se7206_irq(unsigned int irq) -{ - unsigned short sts0,sts1; - - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_se7206_irq(irq); - /* FPGA isr clear */ - sts0 = ctrl_inw(INTSTS0); - sts1 = ctrl_inw(INTSTS1); - - switch (irq) { - case IRQ0_IRQ: - sts0 &= ~0x0010; - break; - case IRQ1_IRQ: - sts0 &= ~0x000f; - break; - case IRQ2_IRQ: - sts0 &= ~0x0f00; - sts1 &= ~0x00ff; - break; - } - ctrl_outw(sts0, INTSTS0); - ctrl_outw(sts1, INTSTS1); -} - -static struct irq_chip se7206_irq_chip __read_mostly = { - .name = "SE7206-FPGA-IRQ", - .mask = disable_se7206_irq, - .unmask = enable_se7206_irq, - .mask_ack = disable_se7206_irq, - .eoi = eoi_se7206_irq, -}; - -static void make_se7206_irq(unsigned int irq) -{ - disable_irq_nosync(irq); - set_irq_chip_and_handler_name(irq, &se7206_irq_chip, - handle_level_irq, "level"); - disable_se7206_irq(irq); -} - -/* - * Initialize IRQ setting - */ -void __init init_se7206_IRQ(void) -{ - make_se7206_irq(IRQ0_IRQ); /* SMC91C111 */ - make_se7206_irq(IRQ1_IRQ); /* ATA */ - make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */ - ctrl_outw(inw(INTC_ICR1) | 0x000b ,INTC_ICR1 ) ; /* ICR1 */ - - /* FPGA System register setup*/ - ctrl_outw(0x0000,INTSTS0); /* Clear INTSTS0 */ - ctrl_outw(0x0000,INTSTS1); /* Clear INTSTS1 */ - /* IRQ0=LAN, IRQ1=ATA, IRQ3=SLT,PCM */ - ctrl_outw(0x0001,INTSEL); -} diff --git a/trunk/arch/sh/boards/se/7206/led.c b/trunk/arch/sh/boards/se/7206/led.c deleted file mode 100644 index ef794601ab86..000000000000 --- a/trunk/arch/sh/boards/se/7206/led.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * linux/arch/sh/kernel/led_se.c - * - * Copyright (C) 2000 Stuart Menefy - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * This file contains Solution Engine specific LED code. - */ - -#include -#include - -#ifdef CONFIG_HEARTBEAT - -#include - -/* Cycle the LED's in the clasic Knightrider/Sun pattern */ -void heartbeat_se(void) -{ - static unsigned int cnt = 0, period = 0; - volatile unsigned short* p = (volatile unsigned short*)PA_LED; - static unsigned bit = 0, up = 1; - - cnt += 1; - if (cnt < period) { - return; - } - - cnt = 0; - - /* Go through the points (roughly!): - * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110 - */ - period = 110 - ( (300< -#include -#include -#include -#include - -static struct resource smc91x_resources[] = { - [0] = { - .start = 0x300, - .end = 0x300 + 0x020 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 64, - .end = 64, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device smc91x_device = { - .name = "smc91x", - .id = -1, - .num_resources = ARRAY_SIZE(smc91x_resources), - .resource = smc91x_resources, -}; - -static int __init se7206_devices_setup(void) -{ - return platform_device_register(&smc91x_device); -} - -__initcall(se7206_devices_setup); - -void heartbeat_se(void); - -/* - * The Machine Vector - */ - -struct sh_machine_vector mv_se __initmv = { - .mv_name = "SolutionEngine", - .mv_nr_irqs = 256, - .mv_inb = se7206_inb, - .mv_inw = se7206_inw, - .mv_inl = se7206_inl, - .mv_outb = se7206_outb, - .mv_outw = se7206_outw, - .mv_outl = se7206_outl, - - .mv_inb_p = se7206_inb_p, - .mv_inw_p = se7206_inw, - .mv_inl_p = se7206_inl, - .mv_outb_p = se7206_outb_p, - .mv_outw_p = se7206_outw, - .mv_outl_p = se7206_outl, - - .mv_insb = se7206_insb, - .mv_insw = se7206_insw, - .mv_insl = se7206_insl, - .mv_outsb = se7206_outsb, - .mv_outsw = se7206_outsw, - .mv_outsl = se7206_outsl, - - .mv_init_irq = init_se7206_IRQ, -#ifdef CONFIG_HEARTBEAT - .mv_heartbeat = heartbeat_se, -#endif -}; -ALIAS_MV(se) diff --git a/trunk/arch/sh/boards/se/7619/Makefile b/trunk/arch/sh/boards/se/7619/Makefile deleted file mode 100644 index 3666eca8a658..000000000000 --- a/trunk/arch/sh/boards/se/7619/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the 7619 SolutionEngine specific parts of the kernel -# - -obj-y := setup.o io.o diff --git a/trunk/arch/sh/boards/se/7619/io.c b/trunk/arch/sh/boards/se/7619/io.c deleted file mode 100644 index 176f1f39cd9d..000000000000 --- a/trunk/arch/sh/boards/se/7619/io.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * - * linux/arch/sh/boards/se/7619/io.c - * - * Copyright (C) 2006 Yoshinori Sato - * - * I/O routine for Hitachi 7619 SolutionEngine. - * - */ - -#include -#include -#include -#include -#include - -/* FIXME: M3A-ZAB7 Compact Flash Slot support */ - -static inline void delay(void) -{ - ctrl_inw(0xa0000000); /* Uncached ROM area (P2) */ -} - -#define badio(name,port) \ - printk("bad I/O operation (%s) for port 0x%lx at 0x%08x\n", \ - #name, (port), (__u32) __builtin_return_address(0)) - -unsigned char se7619___inb(unsigned long port) -{ - badio(inb, port); - return 0; -} - -unsigned char se7619___inb_p(unsigned long port) -{ - badio(inb_p, port); - delay(); - return 0; -} - -unsigned short se7619___inw(unsigned long port) -{ - badio(inw, port); - return 0; -} - -unsigned int se7619___inl(unsigned long port) -{ - badio(inl, port); - return 0; -} - -void se7619___outb(unsigned char value, unsigned long port) -{ - badio(outb, port); -} - -void se7619___outb_p(unsigned char value, unsigned long port) -{ - badio(outb_p, port); - delay(); -} - -void se7619___outw(unsigned short value, unsigned long port) -{ - badio(outw, port); -} - -void se7619___outl(unsigned int value, unsigned long port) -{ - badio(outl, port); -} - -void se7619___insb(unsigned long port, void *addr, unsigned long count) -{ - badio(inw, port); -} - -void se7619___insw(unsigned long port, void *addr, unsigned long count) -{ - badio(inw, port); -} - -void se7619___insl(unsigned long port, void *addr, unsigned long count) -{ - badio(insl, port); -} - -void se7619___outsb(unsigned long port, const void *addr, unsigned long count) -{ - badio(insl, port); -} - -void se7619___outsw(unsigned long port, const void *addr, unsigned long count) -{ - badio(insl, port); -} - -void se7619___outsl(unsigned long port, const void *addr, unsigned long count) -{ - badio(outsw, port); -} diff --git a/trunk/arch/sh/boards/se/7619/setup.c b/trunk/arch/sh/boards/se/7619/setup.c deleted file mode 100644 index e627b26de0d0..000000000000 --- a/trunk/arch/sh/boards/se/7619/setup.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * arch/sh/boards/se/7619/setup.c - * - * Copyright (C) 2006 Yoshinori Sato - * - * Hitachi SH7619 SolutionEngine Support. - */ - -#include -#include -#include -#include -#include - -/* - * The Machine Vector - */ - -struct sh_machine_vector mv_se __initmv = { - .mv_name = "SolutionEngine", - .mv_nr_irqs = 108, - .mv_inb = se7619___inb, - .mv_inw = se7619___inw, - .mv_inl = se7619___inl, - .mv_outb = se7619___outb, - .mv_outw = se7619___outw, - .mv_outl = se7619___outl, - - .mv_inb_p = se7619___inb_p, - .mv_inw_p = se7619___inw, - .mv_inl_p = se7619___inl, - .mv_outb_p = se7619___outb_p, - .mv_outw_p = se7619___outw, - .mv_outl_p = se7619___outl, - - .mv_insb = se7619___insb, - .mv_insw = se7619___insw, - .mv_insl = se7619___insl, - .mv_outsb = se7619___outsb, - .mv_outsw = se7619___outsw, - .mv_outsl = se7619___outsl, -}; -ALIAS_MV(se) diff --git a/trunk/arch/sh/boards/titan/setup.c b/trunk/arch/sh/boards/titan/setup.c index 6bcd939bfaed..a6046d93758b 100644 --- a/trunk/arch/sh/boards/titan/setup.c +++ b/trunk/arch/sh/boards/titan/setup.c @@ -1,30 +1,26 @@ /* - * arch/sh/boards/titan/setup.c - Setup for Titan - * - * Copyright (C) 2006 Jamie Lenehan - * - * 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. + * Setup for Titan */ + #include -#include +#include #include #include +extern void __init pcibios_init_platform(void); + static struct ipr_data titan_ipr_map[] = { - /* IRQ, IPR idx, shift, prio */ - { TITAN_IRQ_WAN, 3, 12, 8 }, /* eth0 (WAN) */ - { TITAN_IRQ_LAN, 3, 8, 8 }, /* eth1 (LAN) */ - { TITAN_IRQ_MPCIA, 3, 4, 8 }, /* mPCI A (top) */ - { TITAN_IRQ_USB, 3, 0, 8 }, /* mPCI B (bottom), USB */ + { TITAN_IRQ_WAN, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY }, + { TITAN_IRQ_LAN, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY }, + { TITAN_IRQ_MPCIA, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY }, + { TITAN_IRQ_USB, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY }, }; static void __init init_titan_irq(void) { /* enable individual interrupt mode for externals */ - ipr_irq_enable_irlm(); - /* register ipr irqs */ + ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); + make_ipr_irq(titan_ipr_map, ARRAY_SIZE(titan_ipr_map)); } @@ -51,5 +47,6 @@ struct sh_machine_vector mv_titan __initmv = { .mv_ioport_map = titan_ioport_map, .mv_init_irq = init_titan_irq, + .mv_init_pci = pcibios_init_platform, }; ALIAS_MV(titan) diff --git a/trunk/arch/sh/boot/compressed/misc.c b/trunk/arch/sh/boot/compressed/misc.c index 35452d85b7f7..f2fed5ce5cc3 100644 --- a/trunk/arch/sh/boot/compressed/misc.c +++ b/trunk/arch/sh/boot/compressed/misc.c @@ -12,7 +12,6 @@ */ #include -#include #ifdef CONFIG_SH_STANDARD_BIOS #include #endif @@ -229,7 +228,7 @@ long* stack_start = &user_stack[STACK_SIZE]; void decompress_kernel(void) { output_data = 0; - output_ptr = P2SEGADDR((unsigned long)&_text+0x1000); + output_ptr = (unsigned long)&_text+0x20001000; free_mem_ptr = (unsigned long)&_end; free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; diff --git a/trunk/arch/sh/configs/r7780rp_defconfig b/trunk/arch/sh/configs/r7780rp_defconfig index 2b75b4896ba5..34e2046c3213 100644 --- a/trunk/arch/sh/configs/r7780rp_defconfig +++ b/trunk/arch/sh/configs/r7780rp_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19 -# Wed Dec 6 11:59:38 2006 +# Linux kernel version: 2.6.19-rc3 +# Tue Oct 31 12:32:06 2006 # CONFIG_SUPERH=y CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -11,8 +11,6 @@ CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_CALIBRATE_DELAY=y # CONFIG_GENERIC_TIME is not set -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -39,7 +37,6 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y -# CONFIG_SYSFS_DEPRECATED is not set # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y @@ -121,8 +118,6 @@ CONFIG_SH_R7780RP=y # CONFIG_SH_LANDISK is not set # CONFIG_SH_TITAN is not set # CONFIG_SH_SHMIN is not set -# CONFIG_SH_7206_SOLUTION_ENGINE is not set -# CONFIG_SH_7619_SOLUTION_ENGINE is not set # CONFIG_SH_UNKNOWN is not set # @@ -135,12 +130,6 @@ CONFIG_CPU_SH4A=y # SH-2 Processor Support # # CONFIG_CPU_SUBTYPE_SH7604 is not set -# CONFIG_CPU_SUBTYPE_SH7619 is not set - -# -# SH-2A Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7206 is not set # # SH-3 Processor Support @@ -176,7 +165,6 @@ CONFIG_CPU_SH4A=y # # CONFIG_CPU_SUBTYPE_SH7770 is not set CONFIG_CPU_SUBTYPE_SH7780=y -# CONFIG_CPU_SUBTYPE_SH7785 is not set # # SH4AL-DSP Processor Support @@ -193,14 +181,8 @@ CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x08000000 # CONFIG_32BIT is not set CONFIG_VSYSCALL=y -CONFIG_PAGE_SIZE_4KB=y -# CONFIG_PAGE_SIZE_8KB is not set -# CONFIG_PAGE_SIZE_64KB is not set CONFIG_HUGETLB_PAGE_SIZE_64K=y -# CONFIG_HUGETLB_PAGE_SIZE_256K is not set # CONFIG_HUGETLB_PAGE_SIZE_1MB is not set -# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set -# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y # CONFIG_DISCONTIGMEM_MANUAL is not set @@ -222,14 +204,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # Processor features # CONFIG_CPU_LITTLE_ENDIAN=y -# CONFIG_CPU_BIG_ENDIAN is not set CONFIG_SH_FPU=y # CONFIG_SH_DSP is not set CONFIG_SH_STORE_QUEUES=y CONFIG_CPU_HAS_INTEVT=y CONFIG_CPU_HAS_INTC2_IRQ=y CONFIG_CPU_HAS_SR_RB=y -CONFIG_CPU_HAS_PTEA=y # # Timer support @@ -240,8 +220,6 @@ CONFIG_SH_TMU=y # R7780RP options # CONFIG_SH_R7780MP=y -CONFIG_SH_TIMER_IRQ=28 -CONFIG_NO_IDLE_HZ=y CONFIG_SH_PCLK_FREQ=32000000 # @@ -259,11 +237,6 @@ CONFIG_SH_PCLK_FREQ=32000000 # # CONFIG_HD6446X_SERIES is not set -# -# Additional SuperH Device Drivers -# -CONFIG_PUSH_SWITCH=y - # # Kernel features # @@ -271,7 +244,7 @@ CONFIG_PUSH_SWITCH=y CONFIG_HZ_250=y # CONFIG_HZ_1000 is not set CONFIG_HZ=250 -CONFIG_KEXEC=y +# CONFIG_KEXEC is not set # CONFIG_SMP is not set # CONFIG_PREEMPT_NONE is not set # CONFIG_PREEMPT_VOLUNTARY is not set @@ -305,7 +278,10 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y # # PCI Hotplug Support # -# CONFIG_HOTPLUG_PCI is not set +CONFIG_HOTPLUG_PCI=y +# CONFIG_HOTPLUG_PCI_FAKE is not set +# CONFIG_HOTPLUG_PCI_CPCI is not set +# CONFIG_HOTPLUG_PCI_SHPC is not set # # Executable file formats @@ -365,7 +341,6 @@ CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set @@ -581,7 +556,6 @@ CONFIG_SATA_SIL=y # CONFIG_PATA_IT821X is not set # CONFIG_PATA_JMICRON is not set # CONFIG_PATA_TRIFLEX is not set -# CONFIG_PATA_MARVELL is not set # CONFIG_PATA_MPIIX is not set # CONFIG_PATA_OLDPIIX is not set # CONFIG_PATA_NETCELL is not set @@ -598,7 +572,6 @@ CONFIG_SATA_SIL=y # CONFIG_PATA_SIS is not set # CONFIG_PATA_VIA is not set # CONFIG_PATA_WINBOND is not set -CONFIG_PATA_PLATFORM=y # # Multi-device support (RAID and LVM) @@ -715,7 +688,6 @@ CONFIG_R8169=y # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set -# CONFIG_NETXEN_NIC is not set # # Token Ring devices @@ -858,6 +830,10 @@ CONFIG_HW_RANDOM=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# # CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set @@ -1044,7 +1020,7 @@ CONFIG_INOTIFY_USER=y CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set -CONFIG_FUSE_FS=m +# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -1076,7 +1052,7 @@ CONFIG_TMPFS=y CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_RAMFS=y -CONFIG_CONFIGFS_FS=m +# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -1177,33 +1153,28 @@ CONFIG_NLS_ISO8859_1=y # # Profiling support # -CONFIG_PROFILING=y -CONFIG_OPROFILE=m +# CONFIG_PROFILING is not set # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_PRINTK_TIME=y +# CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_MUST_CHECK=y -CONFIG_MAGIC_SYSRQ=y +# CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_PREEMPT is not set -# CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_SPINLOCK=y # CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_RWSEMS is not set -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_INFO is not set CONFIG_DEBUG_FS=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set @@ -1213,7 +1184,7 @@ CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_SH_STANDARD_BIOS is not set # CONFIG_EARLY_SCIF_CONSOLE is not set -CONFIG_DEBUG_STACKOVERFLOW=y +# CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_4KSTACKS is not set # CONFIG_KGDB is not set diff --git a/trunk/arch/sh/configs/se7206_defconfig b/trunk/arch/sh/configs/se7206_defconfig deleted file mode 100644 index 36cec0b6e7c1..000000000000 --- a/trunk/arch/sh/configs/se7206_defconfig +++ /dev/null @@ -1,826 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc4 -# Sun Nov 5 16:20:10 2006 -# -CONFIG_SUPERH=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -# CONFIG_GENERIC_TIME is not set -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -# CONFIG_LOCALVERSION_AUTO is not set -# CONFIG_SYSVIPC is not set -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -# CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_UID16=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -# CONFIG_HOTPLUG is not set -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -# CONFIG_FUTEX is not set -# CONFIG_EPOLL is not set -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_TINY_SHMEM=y -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -# CONFIG_MODULES is not set - -# -# Block layer -# -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -CONFIG_DEFAULT_NOOP=y -CONFIG_DEFAULT_IOSCHED="noop" - -# -# System type -# -# CONFIG_SH_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SOLUTION_ENGINE is not set -# CONFIG_SH_7300_SOLUTION_ENGINE is not set -# CONFIG_SH_7343_SOLUTION_ENGINE is not set -# CONFIG_SH_73180_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SYSTEMH is not set -# CONFIG_SH_HP6XX is not set -# CONFIG_SH_EC3104 is not set -# CONFIG_SH_SATURN is not set -# CONFIG_SH_DREAMCAST is not set -# CONFIG_SH_BIGSUR is not set -# CONFIG_SH_MPC1211 is not set -# CONFIG_SH_SH03 is not set -# CONFIG_SH_SECUREEDGE5410 is not set -# CONFIG_SH_HS7751RVOIP is not set -# CONFIG_SH_7710VOIPGW is not set -# CONFIG_SH_RTS7751R2D is not set -# CONFIG_SH_R7780RP is not set -# CONFIG_SH_EDOSK7705 is not set -# CONFIG_SH_SH4202_MICRODEV is not set -# CONFIG_SH_LANDISK is not set -# CONFIG_SH_TITAN is not set -# CONFIG_SH_SHMIN is not set -CONFIG_SH_7206_SOLUTION_ENGINE=y -# CONFIG_SH_7619_SOLUTION_ENGINE is not set -# CONFIG_SH_UNKNOWN is not set - -# -# Processor selection -# -CONFIG_CPU_SH2=y -CONFIG_CPU_SH2A=y - -# -# SH-2 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7604 is not set -# CONFIG_CPU_SUBTYPE_SH7619 is not set - -# -# SH-2A Processor Support -# -CONFIG_CPU_SUBTYPE_SH7206=y - -# -# SH-3 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7300 is not set -# CONFIG_CPU_SUBTYPE_SH7705 is not set -# CONFIG_CPU_SUBTYPE_SH7706 is not set -# CONFIG_CPU_SUBTYPE_SH7707 is not set -# CONFIG_CPU_SUBTYPE_SH7708 is not set -# CONFIG_CPU_SUBTYPE_SH7709 is not set -# CONFIG_CPU_SUBTYPE_SH7710 is not set - -# -# SH-4 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7750 is not set -# CONFIG_CPU_SUBTYPE_SH7091 is not set -# CONFIG_CPU_SUBTYPE_SH7750R is not set -# CONFIG_CPU_SUBTYPE_SH7750S is not set -# CONFIG_CPU_SUBTYPE_SH7751 is not set -# CONFIG_CPU_SUBTYPE_SH7751R is not set -# CONFIG_CPU_SUBTYPE_SH7760 is not set -# CONFIG_CPU_SUBTYPE_SH4_202 is not set - -# -# ST40 Processor Support -# -# CONFIG_CPU_SUBTYPE_ST40STB1 is not set -# CONFIG_CPU_SUBTYPE_ST40GX1 is not set - -# -# SH-4A Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7770 is not set -# CONFIG_CPU_SUBTYPE_SH7780 is not set - -# -# SH4AL-DSP Processor Support -# -# CONFIG_CPU_SUBTYPE_SH73180 is not set -# CONFIG_CPU_SUBTYPE_SH7343 is not set - -# -# Memory management options -# -CONFIG_PAGE_OFFSET=0x00000000 -CONFIG_MEMORY_START=0x0c000000 -CONFIG_MEMORY_SIZE=0x02000000 -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set - -# -# Cache configuration -# -# CONFIG_SH_DIRECT_MAPPED is not set -# CONFIG_SH_WRITETHROUGH is not set -# CONFIG_SH_OCRAM is not set - -# -# Processor features -# -# CONFIG_CPU_LITTLE_ENDIAN is not set -# CONFIG_SH_FPU is not set -# CONFIG_SH_FPU_EMU is not set -# CONFIG_SH_DSP is not set - -# -# Timer support -# -CONFIG_SH_CMT=y -# CONFIG_SH_MTU2 is not set -CONFIG_SH_PCLK_FREQ=33333333 -CONFIG_SH_CLK_MD=6 - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - -# -# DMA support -# -# CONFIG_SH_DMA is not set - -# -# Companion Chips -# -# CONFIG_HD6446X_SERIES is not set - -# -# Kernel features -# -CONFIG_HZ_100=y -# CONFIG_HZ_250 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=100 -# CONFIG_KEXEC is not set -# CONFIG_SMP is not set -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set - -# -# Boot options -# -CONFIG_ZERO_PAGE_OFFSET=0x00001000 -CONFIG_BOOT_LINK_OFFSET=0x00800000 -# CONFIG_UBC_WAKEUP is not set -# CONFIG_CMDLINE_BOOL is not set - -# -# Bus options -# -# CONFIG_PCI is not set - -# -# PCCARD (PCMCIA/CardBus) support -# - -# -# PCI Hotplug Support -# - -# -# Executable file formats -# -CONFIG_BINFMT_FLAT=y -CONFIG_BINFMT_ZFLAT=y -# CONFIG_BINFMT_SHARED_FLAT is not set -# CONFIG_BINFMT_MISC is not set - -# -# Power management options (EXPERIMENTAL) -# -# CONFIG_PM is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -# CONFIG_PACKET is not set -# CONFIG_UNIX is not set -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_DIAG is not set -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -# CONFIG_STANDALONE is not set -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_REDBOOT_PARTS=y -CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 -# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set -# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set -# CONFIG_MTD_CMDLINE_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_CFI_INTELEXT is not set -CONFIG_MTD_CFI_AMDSTD=y -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0x20000000 -CONFIG_MTD_PHYSMAP_LEN=0x1000000 -CONFIG_MTD_PHYSMAP_BANKWIDTH=4 -# CONFIG_MTD_SOLUTIONENGINE is not set -# CONFIG_MTD_UCLINUX is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -# CONFIG_BLK_DEV_INITRD is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# -# CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Network device support -# -# CONFIG_NETDEVICES is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -# CONFIG_INPUT is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_SH_SCI=y -CONFIG_SERIAL_SH_SCI_NR_UARTS=4 -CONFIG_SERIAL_SH_SCI_CONSOLE=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_UNIX98_PTYS is not set -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -CONFIG_HW_RANDOM=y -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -CONFIG_FIRMWARE_EDID=y -# CONFIG_FB is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -# CONFIG_USB_ARCH_HAS_HCD is not set -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -# CONFIG_RTC_CLASS is not set - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT3_FS is not set -# CONFIG_EXT4DEV_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_MINIX_FS is not set -CONFIG_ROMFS_FS=y -# CONFIG_INOTIFY is not set -# CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_SYSCTL=y -# CONFIG_SYSFS is not set -# CONFIG_TMPFS is not set -# CONFIG_HUGETLBFS is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set -CONFIG_CRAMFS=y -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -# CONFIG_NFS_FS is not set -# CONFIG_NFSD is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_UNWIND_INFO is not set -# CONFIG_HEADERS_CHECK is not set -# CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set -# CONFIG_KGDB is not set - -# -# Security options -# -# CONFIG_KEYS is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Library routines -# -CONFIG_CRC_CCITT=y -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y diff --git a/trunk/arch/sh/drivers/Kconfig b/trunk/arch/sh/drivers/Kconfig deleted file mode 100644 index c54c758e6243..000000000000 --- a/trunk/arch/sh/drivers/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -menu "Additional SuperH Device Drivers" - -config PUSH_SWITCH - tristate "Push switch support" - help - This enables support for the push switch framework, a simple - framework that allows for sysfs driven switch status reporting. - -endmenu diff --git a/trunk/arch/sh/drivers/Makefile b/trunk/arch/sh/drivers/Makefile index bf18dbfb6787..338c3729d270 100644 --- a/trunk/arch/sh/drivers/Makefile +++ b/trunk/arch/sh/drivers/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_PCI) += pci/ obj-$(CONFIG_SH_DMA) += dma/ obj-$(CONFIG_SUPERHYWAY) += superhyway/ -obj-$(CONFIG_PUSH_SWITCH) += push-switch.o + diff --git a/trunk/arch/sh/drivers/dma/Makefile b/trunk/arch/sh/drivers/dma/Makefile index db1295d32268..065d4c90970e 100644 --- a/trunk/arch/sh/drivers/dma/Makefile +++ b/trunk/arch/sh/drivers/dma/Makefile @@ -2,8 +2,8 @@ # Makefile for the SuperH DMA specific kernel interface routines under Linux. # -obj-y += dma-api.o -obj-$(CONFIG_ISA_DMA_API) += dma-isa.o +obj-y += dma-api.o dma-isa.o obj-$(CONFIG_SYSFS) += dma-sysfs.o obj-$(CONFIG_SH_DMA) += dma-sh.o obj-$(CONFIG_SH_DREAMCAST) += dma-pvr2.o dma-g2.o + diff --git a/trunk/arch/sh/drivers/dma/dma-api.c b/trunk/arch/sh/drivers/dma/dma-api.c index e062067edd24..47c3e837599b 100644 --- a/trunk/arch/sh/drivers/dma/dma-api.c +++ b/trunk/arch/sh/drivers/dma/dma-api.c @@ -11,27 +11,61 @@ */ #include #include +#include #include #include #include #include -#include #include DEFINE_SPINLOCK(dma_spin_lock); static LIST_HEAD(registered_dmac_list); +/* + * A brief note about the reasons for this API as it stands. + * + * For starters, the old ISA DMA API didn't work for us for a number of + * reasons, for one, the vast majority of channels on the SH DMAC are + * dual-address mode only, and both the new and the old DMA APIs are after the + * concept of managing a DMA buffer, which doesn't overly fit this model very + * well. In addition to which, the new API is largely geared at IOMMUs and + * GARTs, and doesn't even support the channel notion very well. + * + * The other thing that's a marginal issue, is the sheer number of random DMA + * engines that are present (ie, in boards like the Dreamcast), some of which + * cascade off of the SH DMAC, and others do not. As such, there was a real + * need for a scalable subsystem that could deal with both single and + * dual-address mode usage, in addition to interoperating with cascaded DMACs. + * + * There really isn't any reason why this needs to be SH specific, though I'm + * not aware of too many other processors (with the exception of some MIPS) + * that have the same concept of a dual address mode, or any real desire to + * actually make use of the DMAC even if such a subsystem were exposed + * elsewhere. + * + * The idea for this was derived from the ARM port, which acted as an excellent + * reference when trying to address these issues. + * + * It should also be noted that the decision to add Yet Another DMA API(tm) to + * the kernel wasn't made easily, and was only decided upon after conferring + * with jejb with regards to the state of the old and new APIs as they applied + * to these circumstances. Philip Blundell was also a great help in figuring + * out some single-address mode DMA semantics that were otherwise rather + * confusing. + */ + struct dma_info *get_dma_info(unsigned int chan) { struct dma_info *info; + unsigned int total = 0; /* * Look for each DMAC's range to determine who the owner of * the channel is. */ list_for_each_entry(info, ®istered_dmac_list, list) { - if ((chan < info->first_channel_nr) || - (chan >= info->first_channel_nr + info->nr_channels)) + total += info->nr_channels; + if (chan > total) continue; return info; @@ -39,22 +73,6 @@ struct dma_info *get_dma_info(unsigned int chan) return NULL; } -EXPORT_SYMBOL(get_dma_info); - -struct dma_info *get_dma_info_by_name(const char *dmac_name) -{ - struct dma_info *info; - - list_for_each_entry(info, ®istered_dmac_list, list) { - if (dmac_name && (strcmp(dmac_name, info->name) != 0)) - continue; - else - return info; - } - - return NULL; -} -EXPORT_SYMBOL(get_dma_info_by_name); static unsigned int get_nr_channels(void) { @@ -73,161 +91,63 @@ static unsigned int get_nr_channels(void) struct dma_channel *get_dma_channel(unsigned int chan) { struct dma_info *info = get_dma_info(chan); - struct dma_channel *channel; - int i; - if (unlikely(!info)) + if (!info) return ERR_PTR(-EINVAL); - for (i = 0; i < info->nr_channels; i++) { - channel = &info->channels[i]; - if (channel->chan == chan) - return channel; - } - - return NULL; + return info->channels + chan; } -EXPORT_SYMBOL(get_dma_channel); int get_dma_residue(unsigned int chan) { struct dma_info *info = get_dma_info(chan); - struct dma_channel *channel = get_dma_channel(chan); + struct dma_channel *channel = &info->channels[chan]; if (info->ops->get_residue) return info->ops->get_residue(channel); return 0; } -EXPORT_SYMBOL(get_dma_residue); - -static int search_cap(const char **haystack, const char *needle) -{ - const char **p; - - for (p = haystack; *p; p++) - if (strcmp(*p, needle) == 0) - return 1; - - return 0; -} - -/** - * request_dma_bycap - Allocate a DMA channel based on its capabilities - * @dmac: List of DMA controllers to search - * @caps: List of capabilites - * - * Search all channels of all DMA controllers to find a channel which - * matches the requested capabilities. The result is the channel - * number if a match is found, or %-ENODEV if no match is found. - * - * Note that not all DMA controllers export capabilities, in which - * case they can never be allocated using this API, and so - * request_dma() must be used specifying the channel number. - */ -int request_dma_bycap(const char **dmac, const char **caps, const char *dev_id) -{ - unsigned int found = 0; - struct dma_info *info; - const char **p; - int i; - - BUG_ON(!dmac || !caps); - - list_for_each_entry(info, ®istered_dmac_list, list) - if (strcmp(*dmac, info->name) == 0) { - found = 1; - break; - } - if (!found) - return -ENODEV; - - for (i = 0; i < info->nr_channels; i++) { - struct dma_channel *channel = &info->channels[i]; - - if (unlikely(!channel->caps)) - continue; - - for (p = caps; *p; p++) { - if (!search_cap(channel->caps, *p)) - break; - if (request_dma(channel->chan, dev_id) == 0) - return channel->chan; - } - } - - return -EINVAL; -} -EXPORT_SYMBOL(request_dma_bycap); - -int dmac_search_free_channel(const char *dev_id) +int request_dma(unsigned int chan, const char *dev_id) { - struct dma_channel *channel = { 0 }; - struct dma_info *info = get_dma_info(0); - int i; - - for (i = 0; i < info->nr_channels; i++) { - channel = &info->channels[i]; - if (unlikely(!channel)) - return -ENODEV; - - if (atomic_read(&channel->busy) == 0) - break; - } + struct dma_info *info = get_dma_info(chan); + struct dma_channel *channel = &info->channels[chan]; - if (info->ops->request) { - int result = info->ops->request(channel); - if (result) - return result; + down(&channel->sem); - atomic_set(&channel->busy, 1); - return channel->chan; + if (!info->ops || chan >= MAX_DMA_CHANNELS) { + up(&channel->sem); + return -EINVAL; } - return -ENOSYS; -} - -int request_dma(unsigned int chan, const char *dev_id) -{ - struct dma_channel *channel = { 0 }; - struct dma_info *info = get_dma_info(chan); - int result; - - channel = get_dma_channel(chan); - if (atomic_xchg(&channel->busy, 1)) - return -EBUSY; + atomic_set(&channel->busy, 1); strlcpy(channel->dev_id, dev_id, sizeof(channel->dev_id)); - if (info->ops->request) { - result = info->ops->request(channel); - if (result) - atomic_set(&channel->busy, 0); + up(&channel->sem); - return result; - } + if (info->ops->request) + return info->ops->request(channel); return 0; } -EXPORT_SYMBOL(request_dma); void free_dma(unsigned int chan) { struct dma_info *info = get_dma_info(chan); - struct dma_channel *channel = get_dma_channel(chan); + struct dma_channel *channel = &info->channels[chan]; if (info->ops->free) info->ops->free(channel); atomic_set(&channel->busy, 0); } -EXPORT_SYMBOL(free_dma); void dma_wait_for_completion(unsigned int chan) { struct dma_info *info = get_dma_info(chan); - struct dma_channel *channel = get_dma_channel(chan); + struct dma_channel *channel = &info->channels[chan]; if (channel->flags & DMA_TEI_CAPABLE) { wait_event(channel->wait_queue, @@ -238,52 +158,21 @@ void dma_wait_for_completion(unsigned int chan) while (info->ops->get_residue(channel)) cpu_relax(); } -EXPORT_SYMBOL(dma_wait_for_completion); - -int register_chan_caps(const char *dmac, struct dma_chan_caps *caps) -{ - struct dma_info *info; - unsigned int found = 0; - int i; - - list_for_each_entry(info, ®istered_dmac_list, list) - if (strcmp(dmac, info->name) == 0) { - found = 1; - break; - } - - if (unlikely(!found)) - return -ENODEV; - - for (i = 0; i < info->nr_channels; i++, caps++) { - struct dma_channel *channel; - - if ((info->first_channel_nr + i) != caps->ch_num) - return -EINVAL; - - channel = &info->channels[i]; - channel->caps = caps->caplist; - } - - return 0; -} -EXPORT_SYMBOL(register_chan_caps); void dma_configure_channel(unsigned int chan, unsigned long flags) { struct dma_info *info = get_dma_info(chan); - struct dma_channel *channel = get_dma_channel(chan); + struct dma_channel *channel = &info->channels[chan]; if (info->ops->configure) info->ops->configure(channel, flags); } -EXPORT_SYMBOL(dma_configure_channel); int dma_xfer(unsigned int chan, unsigned long from, unsigned long to, size_t size, unsigned int mode) { struct dma_info *info = get_dma_info(chan); - struct dma_channel *channel = get_dma_channel(chan); + struct dma_channel *channel = &info->channels[chan]; channel->sar = from; channel->dar = to; @@ -292,20 +181,8 @@ int dma_xfer(unsigned int chan, unsigned long from, return info->ops->xfer(channel); } -EXPORT_SYMBOL(dma_xfer); - -int dma_extend(unsigned int chan, unsigned long op, void *param) -{ - struct dma_info *info = get_dma_info(chan); - struct dma_channel *channel = get_dma_channel(chan); - - if (info->ops->extend) - return info->ops->extend(channel, op, param); - - return -ENOSYS; -} -EXPORT_SYMBOL(dma_extend); +#ifdef CONFIG_PROC_FS static int dma_read_proc(char *buf, char **start, off_t off, int len, int *eof, void *data) { @@ -337,6 +214,8 @@ static int dma_read_proc(char *buf, char **start, off_t off, return p - buf; } +#endif + int register_dmac(struct dma_info *info) { @@ -345,7 +224,8 @@ int register_dmac(struct dma_info *info) INIT_LIST_HEAD(&info->list); printk(KERN_INFO "DMA: Registering %s handler (%d channel%s).\n", - info->name, info->nr_channels, info->nr_channels > 1 ? "s" : ""); + info->name, info->nr_channels, + info->nr_channels > 1 ? "s" : ""); BUG_ON((info->flags & DMAC_CHANNELS_CONFIGURED) && !info->channels); @@ -362,26 +242,28 @@ int register_dmac(struct dma_info *info) size = sizeof(struct dma_channel) * info->nr_channels; - info->channels = kzalloc(size, GFP_KERNEL); + info->channels = kmalloc(size, GFP_KERNEL); if (!info->channels) return -ENOMEM; + + memset(info->channels, 0, size); } total_channels = get_nr_channels(); for (i = 0; i < info->nr_channels; i++) { - struct dma_channel *chan = &info->channels[i]; - - atomic_set(&chan->busy, 0); + struct dma_channel *chan = info->channels + i; - chan->chan = info->first_channel_nr + i; - chan->vchan = info->first_channel_nr + i + total_channels; + chan->chan = i; + chan->vchan = i + total_channels; memcpy(chan->dev_id, "Unused", 7); if (info->flags & DMAC_CHANNELS_TEI_CAPABLE) chan->flags |= DMA_TEI_CAPABLE; + init_MUTEX(&chan->sem); init_waitqueue_head(&chan->wait_queue); + dma_create_sysfs_files(chan, info); } @@ -389,7 +271,6 @@ int register_dmac(struct dma_info *info) return 0; } -EXPORT_SYMBOL(register_dmac); void unregister_dmac(struct dma_info *info) { @@ -404,16 +285,31 @@ void unregister_dmac(struct dma_info *info) list_del(&info->list); platform_device_unregister(info->pdev); } -EXPORT_SYMBOL(unregister_dmac); static int __init dma_api_init(void) { - printk(KERN_NOTICE "DMA: Registering DMA API.\n"); + printk("DMA: Registering DMA API.\n"); + +#ifdef CONFIG_PROC_FS create_proc_read_entry("dma", 0, 0, dma_read_proc, 0); +#endif + return 0; } + subsys_initcall(dma_api_init); MODULE_AUTHOR("Paul Mundt "); MODULE_DESCRIPTION("DMA API for SuperH"); MODULE_LICENSE("GPL"); + +EXPORT_SYMBOL(request_dma); +EXPORT_SYMBOL(free_dma); +EXPORT_SYMBOL(register_dmac); +EXPORT_SYMBOL(get_dma_residue); +EXPORT_SYMBOL(get_dma_info); +EXPORT_SYMBOL(get_dma_channel); +EXPORT_SYMBOL(dma_xfer); +EXPORT_SYMBOL(dma_wait_for_completion); +EXPORT_SYMBOL(dma_configure_channel); + diff --git a/trunk/arch/sh/drivers/dma/dma-sh.c b/trunk/arch/sh/drivers/dma/dma-sh.c index f63721ed86c2..660786013350 100644 --- a/trunk/arch/sh/drivers/dma/dma-sh.c +++ b/trunk/arch/sh/drivers/dma/dma-sh.c @@ -94,13 +94,20 @@ static int sh_dmac_request_dma(struct dma_channel *chan) if (unlikely(!chan->flags & DMA_TEI_CAPABLE)) return 0; + chan->name = kzalloc(32, GFP_KERNEL); + if (unlikely(chan->name == NULL)) + return -ENOMEM; + snprintf(chan->name, 32, "DMAC Transfer End (Channel %d)", + chan->chan); + return request_irq(get_dmte_irq(chan->chan), dma_tei, - IRQF_DISABLED, chan->dev_id, chan); + IRQF_DISABLED, chan->name, chan); } static void sh_dmac_free_dma(struct dma_channel *chan) { free_irq(get_dmte_irq(chan->chan), chan); + kfree(chan->name); } static void diff --git a/trunk/arch/sh/drivers/dma/dma-sysfs.c b/trunk/arch/sh/drivers/dma/dma-sysfs.c index eebcd4768bbf..29b8ef9873d1 100644 --- a/trunk/arch/sh/drivers/dma/dma-sysfs.c +++ b/trunk/arch/sh/drivers/dma/dma-sysfs.c @@ -3,7 +3,7 @@ * * sysfs interface for SH DMA API * - * Copyright (C) 2004 - 2006 Paul Mundt + * 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 @@ -21,6 +21,7 @@ static struct sysdev_class dma_sysclass = { set_kset_name("dma"), }; + EXPORT_SYMBOL(dma_sysclass); static ssize_t dma_show_devices(struct sys_device *dev, char *buf) @@ -30,10 +31,7 @@ static ssize_t dma_show_devices(struct sys_device *dev, char *buf) for (i = 0; i < MAX_DMA_CHANNELS; i++) { struct dma_info *info = get_dma_info(i); - struct dma_channel *channel = get_dma_channel(i); - - if (unlikely(!info) || !channel) - continue; + struct dma_channel *channel = &info->channels[i]; len += sprintf(buf + len, "%2d: %14s %s\n", channel->chan, info->name, @@ -127,16 +125,11 @@ int dma_create_sysfs_files(struct dma_channel *chan, struct dma_info *info) if (ret) return ret; - ret |= sysdev_create_file(dev, &attr_dev_id); - ret |= sysdev_create_file(dev, &attr_count); - ret |= sysdev_create_file(dev, &attr_mode); - ret |= sysdev_create_file(dev, &attr_flags); - ret |= sysdev_create_file(dev, &attr_config); - - if (unlikely(ret)) { - dev_err(&info->pdev->dev, "Failed creating attrs\n"); - return ret; - } + sysdev_create_file(dev, &attr_dev_id); + sysdev_create_file(dev, &attr_count); + sysdev_create_file(dev, &attr_mode); + sysdev_create_file(dev, &attr_flags); + sysdev_create_file(dev, &attr_config); snprintf(name, sizeof(name), "dma%d", chan->chan); return sysfs_create_link(&info->pdev->dev.kobj, &dev->kobj, name); diff --git a/trunk/arch/sh/drivers/pci/ops-titan.c b/trunk/arch/sh/drivers/pci/ops-titan.c index ac8ee2312cd8..cd56d53375e7 100644 --- a/trunk/arch/sh/drivers/pci/ops-titan.c +++ b/trunk/arch/sh/drivers/pci/ops-titan.c @@ -15,21 +15,25 @@ #include #include #include -#include +#include #include #include "pci-sh4.h" -static char titan_irq_tab[] __initdata = { - TITAN_IRQ_WAN, - TITAN_IRQ_LAN, - TITAN_IRQ_MPCIA, - TITAN_IRQ_MPCIB, - TITAN_IRQ_USB, -}; - int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) { - int irq = titan_irq_tab[slot]; + int irq = -1; + + switch (slot) { + case 0: irq = TITAN_IRQ_WAN; break; /* eth0 (WAN) */ + case 1: irq = TITAN_IRQ_LAN; break; /* eth1 (LAN) */ + case 2: irq = TITAN_IRQ_MPCIA; break; /* mPCI A */ + case 3: irq = TITAN_IRQ_MPCIB; break; /* mPCI B */ + case 4: irq = TITAN_IRQ_USB; break; /* USB */ + default: + printk(KERN_INFO "PCI: Bad IRQ mapping " + "request for slot %d\n", slot); + return -1; + } printk("PCI: Mapping TITAN IRQ for slot %d, pin %c to irq %d\n", slot, pin - 1 + 'A', irq); diff --git a/trunk/arch/sh/drivers/pci/pci-sh7780.c b/trunk/arch/sh/drivers/pci/pci-sh7780.c index 602b644c35ad..d6e635296534 100644 --- a/trunk/arch/sh/drivers/pci/pci-sh7780.c +++ b/trunk/arch/sh/drivers/pci/pci-sh7780.c @@ -22,20 +22,6 @@ #include #include "pci-sh4.h" -#define INTC_BASE 0xffd00000 -#define INTC_ICR0 (INTC_BASE+0x0) -#define INTC_ICR1 (INTC_BASE+0x1c) -#define INTC_INTPRI (INTC_BASE+0x10) -#define INTC_INTREQ (INTC_BASE+0x24) -#define INTC_INTMSK0 (INTC_BASE+0x44) -#define INTC_INTMSK1 (INTC_BASE+0x48) -#define INTC_INTMSK2 (INTC_BASE+0x40080) -#define INTC_INTMSKCLR0 (INTC_BASE+0x64) -#define INTC_INTMSKCLR1 (INTC_BASE+0x68) -#define INTC_INTMSKCLR2 (INTC_BASE+0x40084) -#define INTC_INT2MSKR (INTC_BASE+0x40038) -#define INTC_INT2MSKCR (INTC_BASE+0x4003c) - /* * Initialization. Try all known PCI access methods. Note that we support * using both PCI BIOS and direct access: in such cases, we use I/O ports diff --git a/trunk/arch/sh/drivers/push-switch.c b/trunk/arch/sh/drivers/push-switch.c deleted file mode 100644 index f2b9157c314f..000000000000 --- a/trunk/arch/sh/drivers/push-switch.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Generic push-switch framework - * - * Copyright (C) 2006 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 - -#define DRV_NAME "push-switch" -#define DRV_VERSION "0.1.0" - -static ssize_t switch_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct push_switch_platform_info *psw_info = dev->platform_data; - return sprintf(buf, "%s\n", psw_info->name); -} -static DEVICE_ATTR(switch, S_IRUGO, switch_show, NULL); - -static void switch_timer(unsigned long data) -{ - struct push_switch *psw = (struct push_switch *)data; - - schedule_work(&psw->work); -} - -static void switch_work_handler(void *data) -{ - struct platform_device *pdev = data; - struct push_switch *psw = platform_get_drvdata(pdev); - - psw->state = 0; - - kobject_uevent(&pdev->dev.kobj, KOBJ_CHANGE); -} - -static int switch_drv_probe(struct platform_device *pdev) -{ - struct push_switch_platform_info *psw_info; - struct push_switch *psw; - int ret, irq; - - psw = kzalloc(sizeof(struct push_switch), GFP_KERNEL); - if (unlikely(!psw)) - return -ENOMEM; - - irq = platform_get_irq(pdev, 0); - if (unlikely(irq < 0)) { - ret = -ENODEV; - goto err; - } - - psw_info = pdev->dev.platform_data; - BUG_ON(!psw_info); - - ret = request_irq(irq, psw_info->irq_handler, - IRQF_DISABLED | psw_info->irq_flags, - psw_info->name ? psw_info->name : DRV_NAME, pdev); - if (unlikely(ret < 0)) - goto err; - - if (psw_info->name) { - ret = device_create_file(&pdev->dev, &dev_attr_switch); - if (unlikely(ret)) { - dev_err(&pdev->dev, "Failed creating device attrs\n"); - ret = -EINVAL; - goto err_irq; - } - } - - INIT_WORK(&psw->work, switch_work_handler, pdev); - init_timer(&psw->debounce); - - psw->debounce.function = switch_timer; - psw->debounce.data = (unsigned long)psw; - - platform_set_drvdata(pdev, psw); - - return 0; - -err_irq: - free_irq(irq, pdev); -err: - kfree(psw); - return ret; -} - -static int switch_drv_remove(struct platform_device *pdev) -{ - struct push_switch *psw = platform_get_drvdata(pdev); - struct push_switch_platform_info *psw_info = pdev->dev.platform_data; - int irq = platform_get_irq(pdev, 0); - - if (psw_info->name) - device_remove_file(&pdev->dev, &dev_attr_switch); - - platform_set_drvdata(pdev, NULL); - flush_scheduled_work(); - del_timer_sync(&psw->debounce); - free_irq(irq, pdev); - - kfree(psw); - - return 0; -} - -static struct platform_driver switch_driver = { - .probe = switch_drv_probe, - .remove = switch_drv_remove, - .driver = { - .name = DRV_NAME, - }, -}; - -static int __init switch_init(void) -{ - printk(KERN_NOTICE DRV_NAME ": version %s loaded\n", DRV_VERSION); - return platform_driver_register(&switch_driver); -} - -static void __exit switch_exit(void) -{ - platform_driver_unregister(&switch_driver); -} -module_init(switch_init); -module_exit(switch_exit); - -MODULE_VERSION(DRV_VERSION); -MODULE_AUTHOR("Paul Mundt"); -MODULE_LICENSE("GPLv2"); diff --git a/trunk/arch/sh/kernel/Makefile b/trunk/arch/sh/kernel/Makefile index 99c7e5249f7a..5da88a43d350 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 traps.o irq.o \ +obj-y := process.o signal.o entry.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 @@ -21,4 +21,3 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o obj-$(CONFIG_APM) += apm.o obj-$(CONFIG_PM) += pm.o -obj-$(CONFIG_STACKTRACE) += stacktrace.o diff --git a/trunk/arch/sh/kernel/cpu/Makefile b/trunk/arch/sh/kernel/cpu/Makefile index 0582e6712b79..fb5dac069382 100644 --- a/trunk/arch/sh/kernel/cpu/Makefile +++ b/trunk/arch/sh/kernel/cpu/Makefile @@ -2,12 +2,11 @@ # Makefile for the Linux/SuperH CPU-specifc backends. # -obj-$(CONFIG_CPU_SH2) = sh2/ -obj-$(CONFIG_CPU_SH2A) = sh2a/ -obj-$(CONFIG_CPU_SH3) = sh3/ -obj-$(CONFIG_CPU_SH4) = sh4/ +obj-y += irq/ init.o clock.o + +obj-$(CONFIG_CPU_SH2) += sh2/ +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/clock.c b/trunk/arch/sh/kernel/cpu/clock.c index abb586b12565..51ec64cdf348 100644 --- a/trunk/arch/sh/kernel/cpu/clock.c +++ b/trunk/arch/sh/kernel/cpu/clock.c @@ -5,11 +5,9 @@ * * This clock framework is derived from the OMAP version by: * - * Copyright (C) 2004 - 2005 Nokia Corporation + * Copyright (C) 2004 Nokia Corporation * Written by Tuukka Tikkanen * - * Modified for omap shared clock framework by Tony Lindgren - * * 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. @@ -22,7 +20,6 @@ #include #include #include -#include #include #include @@ -198,37 +195,17 @@ void clk_recalc_rate(struct clk *clk) propagate_rate(clk); } -/* - * Returns a clock. Note that we first try to use device id on the bus - * and clock name. If this fails, we try to use clock name only. - */ -struct clk *clk_get(struct device *dev, const char *id) +struct clk *clk_get(const char *id) { struct clk *p, *clk = ERR_PTR(-ENOENT); - int idno; - - if (dev == NULL || dev->bus != &platform_bus_type) - idno = -1; - else - idno = to_platform_device(dev)->id; mutex_lock(&clock_list_sem); - list_for_each_entry(p, &clock_list, node) { - if (p->id == idno && - strcmp(id, p->name) == 0 && try_module_get(p->owner)) { - clk = p; - goto found; - } - } - list_for_each_entry(p, &clock_list, node) { if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { clk = p; break; } } - -found: mutex_unlock(&clock_list_sem); return clk; diff --git a/trunk/arch/sh/kernel/cpu/init.c b/trunk/arch/sh/kernel/cpu/init.c index 48121766e8d2..bfb90eb0b7a6 100644 --- a/trunk/arch/sh/kernel/cpu/init.c +++ b/trunk/arch/sh/kernel/cpu/init.c @@ -68,14 +68,12 @@ 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/Makefile b/trunk/arch/sh/kernel/cpu/irq/Makefile index 0049d217561a..1c034c283f59 100644 --- a/trunk/arch/sh/kernel/cpu/irq/Makefile +++ b/trunk/arch/sh/kernel/cpu/irq/Makefile @@ -1,9 +1,8 @@ # # Makefile for the Linux/SuperH CPU-specifc IRQ handlers. # -obj-y += imask.o +obj-y += ipr.o imask.o -obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o diff --git a/trunk/arch/sh/kernel/cpu/irq/imask.c b/trunk/arch/sh/kernel/cpu/irq/imask.c index 301b505c4278..a33ae3e0a5a5 100644 --- a/trunk/arch/sh/kernel/cpu/irq/imask.c +++ b/trunk/arch/sh/kernel/cpu/irq/imask.c @@ -53,10 +53,7 @@ void static inline set_interrupt_registers(int ip) { unsigned long __dummy; - asm volatile( -#ifdef CONFIG_CPU_HAS_SR_RB - "ldc %2, r6_bank\n\t" -#endif + asm volatile("ldc %2, r6_bank\n\t" "stc sr, %0\n\t" "and #0xf0, %0\n\t" "shlr2 %0\n\t" diff --git a/trunk/arch/sh/kernel/cpu/irq/intc2.c b/trunk/arch/sh/kernel/cpu/irq/intc2.c index 74defe76a058..74ca576a7ce5 100644 --- a/trunk/arch/sh/kernel/cpu/irq/intc2.c +++ b/trunk/arch/sh/kernel/cpu/irq/intc2.c @@ -11,29 +11,22 @@ * Hitachi 7751, the STM ST40 STB1, SH7760, and SH7780. */ #include -#include +#include #include - -#if defined(CONFIG_CPU_SUBTYPE_SH7760) -#define INTC2_BASE 0xfe080000 -#define INTC2_INTMSK (INTC2_BASE + 0x40) -#define INTC2_INTMSKCLR (INTC2_BASE + 0x60) -#elif defined(CONFIG_CPU_SUBTYPE_SH7780) -#define INTC2_BASE 0xffd40000 -#define INTC2_INTMSK (INTC2_BASE + 0x38) -#define INTC2_INTMSKCLR (INTC2_BASE + 0x3c) -#endif +#include static void disable_intc2_irq(unsigned int irq) { struct intc2_data *p = get_irq_chip_data(irq); - ctrl_outl(1 << p->msk_shift, INTC2_INTMSK + p->msk_offset); + ctrl_outl(1 << p->msk_shift, + INTC2_BASE + INTC2_INTMSK_OFFSET + p->msk_offset); } static void enable_intc2_irq(unsigned int irq) { struct intc2_data *p = get_irq_chip_data(irq); - ctrl_outl(1 << p->msk_shift, INTC2_INTMSKCLR + p->msk_offset); + ctrl_outl(1 << p->msk_shift, + INTC2_BASE + INTC2_INTMSKCLR_OFFSET + p->msk_offset); } static struct irq_chip intc2_irq_chip = { @@ -68,10 +61,12 @@ void make_intc2_irq(struct intc2_data *table, unsigned int nr_irqs) /* Set the priority level */ local_irq_save(flags); - ipr = ctrl_inl(INTC2_BASE + p->ipr_offset); + ipr = ctrl_inl(INTC2_BASE + INTC2_INTPRI_OFFSET + + p->ipr_offset); ipr &= ~(0xf << p->ipr_shift); ipr |= p->priority << p->ipr_shift; - ctrl_outl(ipr, INTC2_BASE + p->ipr_offset); + ctrl_outl(ipr, INTC2_BASE + INTC2_INTPRI_OFFSET + + p->ipr_offset); local_irq_restore(flags); diff --git a/trunk/arch/sh/kernel/cpu/irq/ipr.c b/trunk/arch/sh/kernel/cpu/irq/ipr.c index 35eb5751a3aa..a0089563cbfc 100644 --- a/trunk/arch/sh/kernel/cpu/irq/ipr.c +++ b/trunk/arch/sh/kernel/cpu/irq/ipr.c @@ -19,21 +19,25 @@ #include #include #include -#include -#include +#include +#include +#include + static void disable_ipr_irq(unsigned int irq) { struct ipr_data *p = get_irq_chip_data(irq); + int shift = p->shift*4; /* Set the priority in IPR to 0 */ - ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr); + ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << shift)), p->addr); } static void enable_ipr_irq(unsigned int irq) { struct ipr_data *p = get_irq_chip_data(irq); + int shift = p->shift*4; /* Set priority in IPR back to original value */ - ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr); + ctrl_outw(ctrl_inw(p->addr) | (p->priority << shift), p->addr); } static struct irq_chip ipr_irq_chip = { @@ -49,10 +53,6 @@ void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs) for (i = 0; i < nr_irqs; i++) { unsigned int irq = table[i].irq; - table[i].addr = map_ipridx_to_addr(table[i].ipr_idx); - /* could the IPR index be mapped, if not we ignore this */ - if (table[i].addr == 0) - continue; disable_irq_nosync(irq); set_irq_chip_and_handler_name(irq, &ipr_irq_chip, handle_level_irq, "level"); @@ -62,6 +62,83 @@ void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs) } EXPORT_SYMBOL(make_ipr_irq); +static struct ipr_data sys_ipr_map[] = { +#ifndef CONFIG_CPU_SUBTYPE_SH7780 + { TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY }, + { TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY }, +#ifdef RTC_IRQ + { RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY }, +#endif +#ifdef SCI_ERI_IRQ + { SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY }, + { SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY }, + { SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY }, +#endif +#ifdef SCIF1_ERI_IRQ + { SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY }, + { SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY }, + { SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY }, + { SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_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 }, + { DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, + { VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY }, +#endif +#ifdef SCIF_ERI_IRQ + { SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY }, + { SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY }, + { SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY }, + { SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY }, +#endif +#ifdef IRDA_ERI_IRQ + { IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY }, + { IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY }, + { IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY }, + { IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY }, +#endif +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ + defined(CONFIG_CPU_SUBTYPE_SH7706) || \ + defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) + /* + * Initialize the Interrupt Controller (INTC) + * registers to their power on values + */ + + /* + * Enable external irq (INTC IRQ mode). + * You should set corresponding bits of PFC to "00" + * to enable these interrupts. + */ + { IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY }, + { IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY }, + { IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY }, + { IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY }, + { IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY }, + { IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY }, +#endif +#endif +}; + +void __init init_IRQ(void) +{ + make_ipr_irq(sys_ipr_map, ARRAY_SIZE(sys_ipr_map)); + +#ifdef CONFIG_CPU_HAS_PINT_IRQ + init_IRQ_pint(); +#endif + +#ifdef CONFIG_CPU_HAS_INTC2_IRQ + init_IRQ_intc2(); +#endif + /* Perform the machine specific initialisation */ + if (sh_mv.mv_init_irq != NULL) + sh_mv.mv_init_irq(); + + irq_ctx_init(smp_processor_id()); +} + #if !defined(CONFIG_CPU_HAS_PINT_IRQ) int ipr_irq_demux(int irq) { diff --git a/trunk/arch/sh/kernel/cpu/sh2/Makefile b/trunk/arch/sh/kernel/cpu/sh2/Makefile index f0f059acfcfb..389353fba608 100644 --- a/trunk/arch/sh/kernel/cpu/sh2/Makefile +++ b/trunk/arch/sh/kernel/cpu/sh2/Makefile @@ -2,6 +2,5 @@ # Makefile for the Linux/SuperH SH-2 backends. # -obj-y := ex.o probe.o entry.o +obj-y := probe.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 deleted file mode 100644 index d0440b269702..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh2/clock-sh7619.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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/entry.S b/trunk/arch/sh/kernel/cpu/sh2/entry.S deleted file mode 100644 index 34d51b3745ea..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh2/entry.S +++ /dev/null @@ -1,341 +0,0 @@ -/* - * arch/sh/kernel/cpu/sh2/entry.S - * - * The SH-2 exception entry - * - * Copyright (C) 2005,2006 Yoshinori Sato - * Copyright (C) 2005 AXE,Inc. - * - * 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 - -/* Offsets to the stack */ -OFF_R0 = 0 /* Return value. New ABI also arg4 */ -OFF_R1 = 4 /* New ABI: arg5 */ -OFF_R2 = 8 /* New ABI: arg6 */ -OFF_R3 = 12 /* New ABI: syscall_nr */ -OFF_R4 = 16 /* New ABI: arg0 */ -OFF_R5 = 20 /* New ABI: arg1 */ -OFF_R6 = 24 /* New ABI: arg2 */ -OFF_R7 = 28 /* New ABI: arg3 */ -OFF_SP = (15*4) -OFF_PC = (16*4) -OFF_SR = (16*4+2*4) -OFF_TRA = (16*4+6*4) - -#include - -ENTRY(exception_handler) - ! already saved r0/r1 - mov.l r2,@-sp - mov.l r3,@-sp - mov r0,r1 - cli - mov.l $cpu_mode,r2 - mov.l @r2,r0 - mov.l @(5*4,r15),r3 ! previous SR - shll2 r3 ! set "S" flag - rotl r0 ! T <- "S" flag - rotl r0 ! "S" flag is LSB - rotcr r3 ! T -> r3:b30 - shlr r3 - shlr r0 - bt/s 1f - mov.l r3,@(5*4,r15) ! copy cpu mode to SR - ! switch to kernel mode - mov #1,r0 - rotr r0 - rotr r0 - mov.l r0,@r2 ! enter kernel mode - mov.l $current_thread_info,r2 - mov.l @r2,r2 - mov #0x20,r0 - shll8 r0 - add r2,r0 - mov r15,r2 ! r2 = user stack top - mov r0,r15 ! switch kernel stack - add #-4,r15 ! dummy - mov.l r1,@-r15 ! TRA - sts.l macl, @-r15 - sts.l mach, @-r15 - stc.l gbr, @-r15 - mov.l @(4*4,r2),r0 - mov.l @(5*4,r2),r1 - mov.l r1,@-r15 ! original SR - sts.l pr,@-r15 - mov.l r0,@-r15 ! original PC - mov r2,r3 - add #(4+2)*4,r3 ! rewind r0 - r3 + exception frame - mov.l r3,@-r15 ! original SP - mov.l r14,@-r15 - mov.l r13,@-r15 - mov.l r12,@-r15 - mov.l r11,@-r15 - mov.l r10,@-r15 - mov.l r9,@-r15 - mov.l r8,@-r15 - mov.l r7,@-r15 - mov.l r6,@-r15 - mov.l r5,@-r15 - mov.l r4,@-r15 - mov r2,r8 ! copy user -> kernel stack - mov.l @r8+,r3 - mov.l r3,@-r15 - mov.l @r8+,r2 - mov.l r2,@-r15 - mov.l @r8+,r1 - mov.l r1,@-r15 - mov.l @r8+,r0 - bra 2f - mov.l r0,@-r15 -1: - ! in kernel exception - mov #(22-4-4-1)*4+4,r0 - mov r15,r2 - sub r0,r15 - mov.l @r2+,r0 ! old R3 - mov.l r0,@-r15 - mov.l @r2+,r0 ! old R2 - mov.l r0,@-r15 - mov.l @r2+,r0 ! old R1 - mov.l r0,@-r15 - mov.l @r2+,r0 ! old R0 - mov.l r0,@-r15 - mov.l @r2+,r3 ! old PC - mov.l @r2+,r0 ! old SR - add #-4,r2 ! exception frame stub (sr) - mov.l r1,@-r2 ! TRA - sts.l macl, @-r2 - sts.l mach, @-r2 - stc.l gbr, @-r2 - mov.l r0,@-r2 ! save old SR - sts.l pr,@-r2 - mov.l r3,@-r2 ! save old PC - mov r2,r0 - add #8*4,r0 - mov.l r0,@-r2 ! save old SP - mov.l r14,@-r2 - mov.l r13,@-r2 - mov.l r12,@-r2 - mov.l r11,@-r2 - mov.l r10,@-r2 - mov.l r9,@-r2 - mov.l r8,@-r2 - mov.l r7,@-r2 - mov.l r6,@-r2 - mov.l r5,@-r2 - mov.l r4,@-r2 - mov.l @(OFF_R0,r15),r0 - mov.l @(OFF_R1,r15),r1 - mov.l @(OFF_R2,r15),r2 - mov.l @(OFF_R3,r15),r3 -2: - mov #OFF_TRA,r8 - add r15,r8 - mov.l @r8,r9 - mov #64,r8 - cmp/hs r8,r9 - bt interrupt_entry ! vec >= 64 is interrupt - mov #32,r8 - cmp/hs r8,r9 - bt trap_entry ! 64 > vec >= 32 is trap - mov.l 4f,r8 - mov r9,r4 - shll2 r9 - add r9,r8 - mov.l @r8,r8 - mov #0,r9 - cmp/eq r9,r8 - bf 3f - mov.l 8f,r8 ! unhandled exception -3: - mov.l 5f,r10 - jmp @r8 - lds r10,pr - -interrupt_entry: - mov r9,r4 - mov.l 6f,r9 - mov.l 7f,r8 - jmp @r8 - lds r9,pr - - .align 2 -4: .long exception_handling_table -5: .long ret_from_exception -6: .long ret_from_irq -7: .long do_IRQ -8: .long do_exception_error - -trap_entry: - add #-0x10,r9 - shll2 r9 ! TRA - mov #OFF_TRA,r8 - add r15,r8 - mov.l r9,@r8 - mov r9,r8 -#ifdef CONFIG_TRACE_IRQFLAGS - mov.l 5f, r9 - jsr @r9 - nop -#endif - sti - bra system_call - nop - - .align 2 -1: .long syscall_exit -2: .long break_point_trap_software -3: .long NR_syscalls -4: .long sys_call_table -#ifdef CONFIG_TRACE_IRQFLAGS -5: .long trace_hardirqs_on -#endif - -#if defined(CONFIG_SH_STANDARD_BIOS) - /* Unwind the stack and jmp to the debug entry */ -debug_kernel_fw: - mov r15,r0 - add #(22-4)*4-4,r0 - ldc.l @r0+,gbr - lds.l @r0+,mach - lds.l @r0+,macl - mov r15,r0 - mov.l @(OFF_SP,r0),r1 - mov #OFF_SR,r2 - mov.l @(r0,r2),r3 - mov.l r3,@-r1 - mov #OFF_SP,r2 - mov.l @(r0,r2),r3 - mov.l r3,@-r1 - mov r15,r0 - add #(22-4)*4-8,r0 - mov.l 1f,r2 - mov.l @r2,r2 - stc sr,r3 - mov.l r2,@r0 - mov.l r3,@r0 - mov.l r1,@(8,r0) - mov.l @r15+, r0 - mov.l @r15+, r1 - mov.l @r15+, r2 - mov.l @r15+, r3 - mov.l @r15+, r4 - mov.l @r15+, r5 - mov.l @r15+, r6 - mov.l @r15+, r7 - mov.l @r15+, r8 - mov.l @r15+, r9 - mov.l @r15+, r10 - mov.l @r15+, r11 - mov.l @r15+, r12 - mov.l @r15+, r13 - mov.l @r15+, r14 - add #8,r15 - lds.l @r15+, pr - rte - mov.l @r15+,r15 - .align 2 -1: .long gdb_vbr_vector -#endif /* CONFIG_SH_STANDARD_BIOS */ - -ENTRY(address_error_handler) - mov r15,r4 ! regs - add #4,r4 - mov #OFF_PC,r0 - mov.l @(r0,r15),r6 ! pc - mov.l 1f,r0 - jmp @r0 - mov #0,r5 ! writeaccess is unknown - .align 2 - -1: .long do_address_error - -restore_all: - cli -#ifdef CONFIG_TRACE_IRQFLAGS - mov.l 3f, r0 - jsr @r0 - nop -#endif - mov r15,r0 - mov.l $cpu_mode,r2 - mov #OFF_SR,r3 - mov.l @(r0,r3),r1 - mov.l r1,@r2 - shll2 r1 ! clear MD bit - shlr2 r1 - mov.l @(OFF_SP,r0),r2 - add #-8,r2 - mov.l r2,@(OFF_SP,r0) ! point exception frame top - mov.l r1,@(4,r2) ! set sr - mov #OFF_PC,r3 - mov.l @(r0,r3),r1 - mov.l r1,@r2 ! set pc - add #4*16+4,r0 - lds.l @r0+,pr - add #4,r0 ! skip sr - ldc.l @r0+,gbr - lds.l @r0+,mach - lds.l @r0+,macl - get_current_thread_info r0, r1 - mov.l $current_thread_info,r1 - mov.l r0,@r1 - mov.l @r15+,r0 - mov.l @r15+,r1 - mov.l @r15+,r2 - mov.l @r15+,r3 - mov.l @r15+,r4 - mov.l @r15+,r5 - mov.l @r15+,r6 - mov.l @r15+,r7 - mov.l @r15+,r8 - mov.l @r15+,r9 - mov.l @r15+,r10 - mov.l @r15+,r11 - mov.l @r15+,r12 - mov.l @r15+,r13 - mov.l @r15+,r14 - mov.l @r15,r15 - rte - nop -2: - mov.l 1f,r8 - mov.l 2f,r9 - jmp @r9 - lds r8,pr - - .align 2 -$current_thread_info: - .long __current_thread_info -$cpu_mode: - .long __cpu_mode -#ifdef CONFIG_TRACE_IRQFLAGS -3: .long trace_hardirqs_off -#endif - -! common exception handler -#include "../../entry-common.S" - - .data -! cpu operation mode -! bit30 = MD (compatible SH3/4) -__cpu_mode: - .long 0x40000000 - - .section .bss -__current_thread_info: - .long 0 - -ENTRY(exception_handling_table) - .space 4*32 diff --git a/trunk/arch/sh/kernel/cpu/sh2/ex.S b/trunk/arch/sh/kernel/cpu/sh2/ex.S deleted file mode 100644 index 6d285af7846c..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh2/ex.S +++ /dev/null @@ -1,46 +0,0 @@ -/* - * arch/sh/kernel/cpu/sh2/ex.S - * - * The SH-2 exception vector table - * - * 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 - -! -! convert Exception Vector to Exception Number -! -exception_entry: -no = 0 - .rept 256 - mov.l r0,@-sp - mov #no,r0 - bra exception_trampoline - and #0xff,r0 -no = no + 1 - .endr -exception_trampoline: - mov.l r1,@-sp - mov.l $exception_handler,r1 - jmp @r1 - - .align 2 -$exception_entry: - .long exception_entry -$exception_handler: - .long exception_handler -! -! Exception Vector Base -! - .align 2 -ENTRY(vbr_base) -vector = 0 - .rept 256 - .long exception_entry + vector * 8 -vector = vector + 1 - .endr diff --git a/trunk/arch/sh/kernel/cpu/sh2/probe.c b/trunk/arch/sh/kernel/cpu/sh2/probe.c index ba527d9b5024..f17a2a0d588e 100644 --- a/trunk/arch/sh/kernel/cpu/sh2/probe.c +++ b/trunk/arch/sh/kernel/cpu/sh2/probe.c @@ -17,23 +17,17 @@ int __init detect_cpu_and_cache_system(void) { -#if defined(CONFIG_CPU_SUBTYPE_SH7604) + /* + * For now, assume SH7604 .. fix this later. + */ cpu_data->type = CPU_SH7604; cpu_data->dcache.ways = 4; - cpu_data->dcache.way_incr = (1<<10); + cpu_data->dcache.way_shift = 6; 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 deleted file mode 100644 index 82c2d905152f..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 deleted file mode 100644 index 350972ae9410..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh2a/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# 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 deleted file mode 100644 index a9ad309c6a33..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh2a/clock-sh7206.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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 deleted file mode 100644 index 87c6c0542089..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh2a/probe.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 deleted file mode 100644 index cdfeef49e62e..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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/cpu/sh3/Makefile b/trunk/arch/sh/kernel/cpu/sh3/Makefile index 83905e4e4387..58d3815695ff 100644 --- a/trunk/arch/sh/kernel/cpu/sh3/Makefile +++ b/trunk/arch/sh/kernel/cpu/sh3/Makefile @@ -2,7 +2,7 @@ # Makefile for the Linux/SuperH SH-3 backends. # -obj-y := ex.o probe.o entry.o +obj-y := ex.o probe.o # CPU subtype setup obj-$(CONFIG_CPU_SUBTYPE_SH7705) += setup-sh7705.o diff --git a/trunk/arch/sh/kernel/cpu/sh3/clock-sh7709.c b/trunk/arch/sh/kernel/cpu/sh3/clock-sh7709.c index b791a29fdb62..10461a745e5f 100644 --- a/trunk/arch/sh/kernel/cpu/sh3/clock-sh7709.c +++ b/trunk/arch/sh/kernel/cpu/sh3/clock-sh7709.c @@ -24,7 +24,7 @@ static int pfc_divisors[] = { 1, 2, 4, 1, 3, 6, 1, 1 }; static void set_bus_parent(struct clk *clk) { - struct clk *bus_clk = clk_get(NULL, "bus_clk"); + struct clk *bus_clk = clk_get("bus_clk"); clk->parent = bus_clk; clk_put(bus_clk); } diff --git a/trunk/arch/sh/kernel/cpu/sh4/Makefile b/trunk/arch/sh/kernel/cpu/sh4/Makefile index 6e415baf04b4..8dbf3895ece7 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/Makefile +++ b/trunk/arch/sh/kernel/cpu/sh4/Makefile @@ -2,8 +2,7 @@ # Makefile for the Linux/SuperH SH-4 backends. # -obj-y := ex.o probe.o common.o -common-y += $(addprefix ../sh3/, entry.o) +obj-y := ex.o probe.o obj-$(CONFIG_SH_FPU) += fpu.o obj-$(CONFIG_SH_STORE_QUEUES) += sq.o diff --git a/trunk/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/trunk/arch/sh/kernel/cpu/sh4/clock-sh4-202.c index fa2019aabd74..bfdf5fe8d948 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/clock-sh4-202.c +++ b/trunk/arch/sh/kernel/cpu/sh4/clock-sh4-202.c @@ -97,7 +97,7 @@ static void shoc_clk_recalc(struct clk *clk) static int shoc_clk_verify_rate(struct clk *clk, unsigned long rate) { - struct clk *bclk = clk_get(NULL, "bus_clk"); + struct clk *bclk = clk_get("bus_clk"); unsigned long bclk_rate = clk_get_rate(bclk); clk_put(bclk); @@ -151,7 +151,7 @@ static struct clk *sh4202_onchip_clocks[] = { static int __init sh4202_clk_init(void) { - struct clk *clk = clk_get(NULL, "master_clk"); + struct clk *clk = clk_get("master_clk"); int i; for (i = 0; i < ARRAY_SIZE(sh4202_onchip_clocks); i++) { diff --git a/trunk/arch/sh/kernel/cpu/sh4/clock-sh7780.c b/trunk/arch/sh/kernel/cpu/sh4/clock-sh7780.c index 9e6a216750c8..93ad367342c9 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/clock-sh7780.c +++ b/trunk/arch/sh/kernel/cpu/sh4/clock-sh7780.c @@ -98,7 +98,7 @@ static struct clk *sh7780_onchip_clocks[] = { static int __init sh7780_clk_init(void) { - struct clk *clk = clk_get(NULL, "master_clk"); + struct clk *clk = clk_get("master_clk"); int i; for (i = 0; i < ARRAY_SIZE(sh7780_onchip_clocks); i++) { diff --git a/trunk/arch/sh/kernel/cpu/sh4/fpu.c b/trunk/arch/sh/kernel/cpu/sh4/fpu.c index 7624677f6628..f486c07e10e2 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/fpu.c +++ b/trunk/arch/sh/kernel/cpu/sh4/fpu.c @@ -282,8 +282,11 @@ ieee_fpe_handler (struct pt_regs *regs) grab_fpu(regs); restore_fpu(tsk); set_tsk_thread_flag(tsk, TIF_USEDFPU); - } else + } else { + tsk->thread.trap_no = 11; + tsk->thread.error_code = 0; force_sig(SIGFPE, tsk); + } regs->pc = nextpc; return 1; @@ -293,29 +296,29 @@ ieee_fpe_handler (struct pt_regs *regs) } asmlinkage void -do_fpu_error(unsigned long r4, unsigned long r5, unsigned long r6, - unsigned long r7, struct pt_regs __regs) +do_fpu_error(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, + struct pt_regs regs) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); struct task_struct *tsk = current; - if (ieee_fpe_handler(regs)) + if (ieee_fpe_handler (®s)) return; - regs->pc += 2; - save_fpu(tsk, regs); + regs.pc += 2; + save_fpu(tsk, ®s); + tsk->thread.trap_no = 11; + tsk->thread.error_code = 0; force_sig(SIGFPE, tsk); } asmlinkage void do_fpu_state_restore(unsigned long r4, unsigned long r5, unsigned long r6, - unsigned long r7, struct pt_regs __regs) + unsigned long r7, struct pt_regs regs) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); struct task_struct *tsk = current; - grab_fpu(regs); - if (!user_mode(regs)) { + grab_fpu(®s); + if (!user_mode(®s)) { printk(KERN_ERR "BUG: FPU is used in kernel mode.\n"); return; } diff --git a/trunk/arch/sh/kernel/cpu/sh4/probe.c b/trunk/arch/sh/kernel/cpu/sh4/probe.c index afe0f1b1c030..c294de1e14a3 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/probe.c +++ b/trunk/arch/sh/kernel/cpu/sh4/probe.c @@ -79,16 +79,16 @@ int __init detect_cpu_and_cache_system(void) case 0x205: cpu_data->type = CPU_SH7750; cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | - CPU_HAS_PERF_COUNTER; + CPU_HAS_PERF_COUNTER | CPU_HAS_PTEA; break; case 0x206: cpu_data->type = CPU_SH7750S; cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | - CPU_HAS_PERF_COUNTER; + CPU_HAS_PERF_COUNTER | CPU_HAS_PTEA; break; case 0x1100: cpu_data->type = CPU_SH7751; - cpu_data->flags |= CPU_HAS_FPU; + cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA; break; case 0x2000: cpu_data->type = CPU_SH73180; @@ -126,22 +126,23 @@ int __init detect_cpu_and_cache_system(void) break; case 0x8000: cpu_data->type = CPU_ST40RA; - cpu_data->flags |= CPU_HAS_FPU; + cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA; break; case 0x8100: cpu_data->type = CPU_ST40GX1; - cpu_data->flags |= CPU_HAS_FPU; + cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA; break; case 0x700: cpu_data->type = CPU_SH4_501; cpu_data->icache.ways = 2; cpu_data->dcache.ways = 2; + cpu_data->flags |= CPU_HAS_PTEA; break; case 0x600: cpu_data->type = CPU_SH4_202; cpu_data->icache.ways = 2; cpu_data->dcache.ways = 2; - cpu_data->flags |= CPU_HAS_FPU; + cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA; break; case 0x500 ... 0x501: switch (prr) { @@ -159,7 +160,7 @@ int __init detect_cpu_and_cache_system(void) cpu_data->icache.ways = 2; cpu_data->dcache.ways = 2; - cpu_data->flags |= CPU_HAS_FPU; + cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA; break; default: @@ -172,10 +173,6 @@ int __init detect_cpu_and_cache_system(void) cpu_data->dcache.ways = 1; #endif -#ifdef CONFIG_CPU_HAS_PTEA - cpu_data->flags |= CPU_HAS_PTEA; -#endif - /* * On anything that's not a direct-mapped cache, look to the CVR * for I/D-cache specifics. diff --git a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c index bbcb06f18b04..50812d57c1c1 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -2,7 +2,6 @@ * SH7750/SH7751 Setup * * Copyright (C) 2006 Paul Mundt - * Copyright (C) 2006 Jamie Lenehan * * 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 @@ -11,7 +10,6 @@ #include #include #include -#include #include static struct plat_sci_port sci_platform_data[] = { @@ -48,71 +46,3 @@ static int __init sh7750_devices_setup(void) ARRAY_SIZE(sh7750_devices)); } __initcall(sh7750_devices_setup); - -static struct ipr_data sh7750_ipr_map[] = { - /* IRQ, IPR-idx, shift, priority */ - { 16, 0, 12, 2 }, /* TMU0 TUNI*/ - { 17, 0, 12, 2 }, /* TMU1 TUNI */ - { 18, 0, 4, 2 }, /* TMU2 TUNI */ - { 19, 0, 4, 2 }, /* TMU2 TIPCI */ - { 27, 1, 12, 2 }, /* WDT ITI */ - { 20, 0, 0, 2 }, /* RTC ATI (alarm) */ - { 21, 0, 0, 2 }, /* RTC PRI (period) */ - { 22, 0, 0, 2 }, /* RTC CUI (carry) */ - { 23, 1, 4, 3 }, /* SCI ERI */ - { 24, 1, 4, 3 }, /* SCI RXI */ - { 25, 1, 4, 3 }, /* SCI TXI */ - { 40, 2, 4, 3 }, /* SCIF ERI */ - { 41, 2, 4, 3 }, /* SCIF RXI */ - { 42, 2, 4, 3 }, /* SCIF BRI */ - { 43, 2, 4, 3 }, /* SCIF TXI */ - { 34, 2, 8, 7 }, /* DMAC DMTE0 */ - { 35, 2, 8, 7 }, /* DMAC DMTE1 */ - { 36, 2, 8, 7 }, /* DMAC DMTE2 */ - { 37, 2, 8, 7 }, /* DMAC DMTE3 */ - { 28, 2, 8, 7 }, /* DMAC DMAE */ -}; - -static struct ipr_data sh7751_ipr_map[] = { - { 44, 2, 8, 7 }, /* DMAC DMTE4 */ - { 45, 2, 8, 7 }, /* DMAC DMTE5 */ - { 46, 2, 8, 7 }, /* DMAC DMTE6 */ - { 47, 2, 8, 7 }, /* DMAC DMTE7 */ - /* The following use INTC_INPRI00 for masking, which is a 32-bit - register, not a 16-bit register like the IPRx registers, so it - would need special support */ - /*{ 72, INTPRI00, 8, ? },*/ /* TMU3 TUNI */ - /*{ 76, INTPRI00, 12, ? },*/ /* TMU4 TUNI */ -}; - -static unsigned long ipr_offsets[] = { - 0xffd00004UL, /* 0: IPRA */ - 0xffd00008UL, /* 1: IPRB */ - 0xffd0000cUL, /* 2: IPRC */ - 0xffd00010UL, /* 3: IPRD */ -}; - -/* given the IPR index return the address of the IPR register */ -unsigned int map_ipridx_to_addr(int idx) -{ - if (idx >= ARRAY_SIZE(ipr_offsets)) - return 0; - return ipr_offsets[idx]; -} - -#define INTC_ICR 0xffd00000UL -#define INTC_ICR_IRLM (1<<7) - -/* enable individual interrupt mode for external interupts */ -void ipr_irq_enable_irlm(void) -{ - ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); -} - -void __init init_IRQ_ipr() -{ - make_ipr_irq(sh7750_ipr_map, ARRAY_SIZE(sh7750_ipr_map)); -#ifdef CONFIG_CPU_SUBTYPE_SH7751 - make_ipr_irq(sh7751_ipr_map, ARRAY_SIZE(sh7751_ipr_map)); -#endif -} diff --git a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7780.c b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7780.c index 9aeaa2ddaa28..814ddb226531 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7780.c +++ b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7780.c @@ -79,27 +79,25 @@ static int __init sh7780_devices_setup(void) __initcall(sh7780_devices_setup); static struct intc2_data intc2_irq_table[] = { - { 28, 0, 24, 0, 0, 2 }, /* TMU0 */ + { TIMER_IRQ, 0, 24, 0, INTC_TMU0_MSK, 2 }, + { 21, 1, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY }, + { 22, 1, 1, 0, INTC_RTC_MSK, TIMER_PRIORITY }, + { 23, 1, 2, 0, INTC_RTC_MSK, TIMER_PRIORITY }, + { SCIF0_ERI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, + { SCIF0_RXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, + { SCIF0_BRI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, + { SCIF0_TXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, - { 21, 1, 0, 0, 2, 2 }, - { 22, 1, 1, 0, 2, 2 }, - { 23, 1, 2, 0, 2, 2 }, + { SCIF1_ERI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, + { SCIF1_RXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, + { SCIF1_BRI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, + { SCIF1_TXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, - { 40, 8, 24, 0, 3, 3 }, /* SCIF0 ERI */ - { 41, 8, 24, 0, 3, 3 }, /* SCIF0 RXI */ - { 42, 8, 24, 0, 3, 3 }, /* SCIF0 BRI */ - { 43, 8, 24, 0, 3, 3 }, /* SCIF0 TXI */ - - { 76, 8, 16, 0, 4, 3 }, /* SCIF1 ERI */ - { 77, 8, 16, 0, 4, 3 }, /* SCIF1 RXI */ - { 78, 8, 16, 0, 4, 3 }, /* SCIF1 BRI */ - { 79, 8, 16, 0, 4, 3 }, /* SCIF1 TXI */ - - { 64, 0x10, 8, 0, 14, 2 }, /* PCIC0 */ - { 65, 0x10, 0, 0, 15, 2 }, /* PCIC1 */ - { 66, 0x14, 24, 0, 16, 2 }, /* PCIC2 */ - { 67, 0x14, 16, 0, 17, 2 }, /* PCIC3 */ - { 68, 0x14, 8, 0, 18, 2 }, /* PCIC4 */ + { PCIC0_IRQ, 0x10, 8, 0, INTC_PCIC0_MSK, PCIC0_PRIORITY }, + { PCIC1_IRQ, 0x10, 0, 0, INTC_PCIC1_MSK, PCIC1_PRIORITY }, + { PCIC2_IRQ, 0x14, 24, 0, INTC_PCIC2_MSK, PCIC2_PRIORITY }, + { PCIC3_IRQ, 0x14, 16, 0, INTC_PCIC3_MSK, PCIC3_PRIORITY }, + { PCIC4_IRQ, 0x14, 8, 0, INTC_PCIC4_MSK, PCIC4_PRIORITY }, }; void __init init_IRQ_intc2(void) diff --git a/trunk/arch/sh/kernel/cpu/sh4/sq.c b/trunk/arch/sh/kernel/cpu/sh4/sq.c index 55f43506995a..7bcc73f9b8df 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/sq.c +++ b/trunk/arch/sh/kernel/cpu/sh4/sq.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include @@ -67,7 +67,6 @@ void sq_flush_range(unsigned long start, unsigned int len) /* Wait for completion */ store_queue_barrier(); } -EXPORT_SYMBOL(sq_flush_range); static inline void sq_mapping_list_add(struct sq_mapping *map) { @@ -167,7 +166,7 @@ unsigned long sq_remap(unsigned long phys, unsigned int size, map->size = size; map->name = name; - page = bitmap_find_free_region(sq_bitmap, 0x04000000 >> PAGE_SHIFT, + page = bitmap_find_free_region(sq_bitmap, 0x04000000, get_order(map->size)); if (unlikely(page < 0)) { ret = -ENOSPC; @@ -194,7 +193,6 @@ unsigned long sq_remap(unsigned long phys, unsigned int size, kmem_cache_free(sq_cache, map); return ret; } -EXPORT_SYMBOL(sq_remap); /** * sq_unmap - Unmap a Store Queue allocation @@ -236,7 +234,6 @@ void sq_unmap(unsigned long vaddr) kmem_cache_free(sq_cache, map); } -EXPORT_SYMBOL(sq_unmap); /* * Needlessly complex sysfs interface. Unfortunately it doesn't seem like @@ -405,3 +402,7 @@ module_exit(sq_api_exit); MODULE_AUTHOR("Paul Mundt , M. R. Brown "); MODULE_DESCRIPTION("Simple API for SH-4 integrated Store Queues"); MODULE_LICENSE("GPL"); + +EXPORT_SYMBOL(sq_remap); +EXPORT_SYMBOL(sq_unmap); +EXPORT_SYMBOL(sq_flush_range); diff --git a/trunk/arch/sh/kernel/early_printk.c b/trunk/arch/sh/kernel/early_printk.c index 60340823798a..a00022722e9e 100644 --- a/trunk/arch/sh/kernel/early_printk.c +++ b/trunk/arch/sh/kernel/early_printk.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #ifdef CONFIG_SH_STANDARD_BIOS #include @@ -62,9 +62,17 @@ static struct console bios_console = { #include #include "../../../drivers/serial/sh-sci.h" +#ifdef CONFIG_CPU_SH4 +#define SCIF_REG 0xffe80000 +#elif defined(CONFIG_CPU_SUBTYPE_SH72060) +#define SCIF_REG 0xfffe9800 +#else +#error "Undefined SCIF for this subtype" +#endif + static struct uart_port scif_port = { - .mapbase = CONFIG_EARLY_SCIF_CONSOLE_PORT, - .membase = (char __iomem *)CONFIG_EARLY_SCIF_CONSOLE_PORT, + .mapbase = SCIF_REG, + .membase = (char __iomem *)SCIF_REG, }; static void scif_sercon_putc(int c) @@ -105,29 +113,23 @@ static struct console scif_console = { .index = -1, }; -#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS) -/* - * Simple SCIF init, primarily aimed at SH7750 and other similar SH-4 - * devices that aren't using sh-ipl+g. - */ static void scif_sercon_init(int baud) { - ctrl_outw(0, scif_port.mapbase + 8); - ctrl_outw(0, scif_port.mapbase); + ctrl_outw(0, SCIF_REG + 8); + ctrl_outw(0, SCIF_REG); /* Set baud rate */ ctrl_outb((CONFIG_SH_PCLK_FREQ + 16 * baud) / - (32 * baud) - 1, scif_port.mapbase + 4); - - ctrl_outw(12, scif_port.mapbase + 24); - ctrl_outw(8, scif_port.mapbase + 24); - ctrl_outw(0, scif_port.mapbase + 32); - ctrl_outw(0x60, scif_port.mapbase + 16); - ctrl_outw(0, scif_port.mapbase + 36); - ctrl_outw(0x30, scif_port.mapbase + 8); + (32 * baud) - 1, SCIF_REG + 4); + + ctrl_outw(12, SCIF_REG + 24); + ctrl_outw(8, SCIF_REG + 24); + ctrl_outw(0, SCIF_REG + 32); + ctrl_outw(0x60, SCIF_REG + 16); + ctrl_outw(0, SCIF_REG + 36); + ctrl_outw(0x30, SCIF_REG + 8); } -#endif /* CONFIG_CPU_SH4 && !CONFIG_SH_STANDARD_BIOS */ -#endif /* CONFIG_EARLY_SCIF_CONSOLE */ +#endif /* * Setup a default console, if more than one is compiled in, rely on the @@ -166,7 +168,7 @@ int __init setup_early_printk(char *opt) if (!strncmp(buf, "serial", 6)) { early_console = &scif_console; -#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS) +#ifdef CONFIG_CPU_SH4 scif_sercon_init(115200); #endif } diff --git a/trunk/arch/sh/kernel/entry-common.S b/trunk/arch/sh/kernel/entry-common.S deleted file mode 100644 index 29136a35d7c7..000000000000 --- a/trunk/arch/sh/kernel/entry-common.S +++ /dev/null @@ -1,433 +0,0 @@ -/* $Id: entry.S,v 1.37 2004/06/11 13:02:46 doyu Exp $ - * - * linux/arch/sh/entry.S - * - * Copyright (C) 1999, 2000, 2002 Niibe Yutaka - * Copyright (C) 2003 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. - * - */ - -! NOTE: -! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address -! to be jumped is too far, but it causes illegal slot exception. - -/* - * entry.S contains the system-call and fault low-level handling routines. - * This also contains the timer-interrupt handler, as well as all interrupts - * and faults that can result in a task-switch. - * - * NOTE: This code handles signal-recognition, which happens every time - * after a timer-interrupt and after each system call. - * - * NOTE: This code uses a convention that instructions in the delay slot - * of a transfer-control instruction are indented by an extra space, thus: - * - * jmp @k0 ! control-transfer instruction - * ldc k1, ssr ! delay slot - * - * Stack layout in 'ret_from_syscall': - * ptrace needs to have all regs on the stack. - * if the order here is changed, it needs to be - * updated in ptrace.c and ptrace.h - * - * r0 - * ... - * r15 = stack pointer - * spc - * pr - * ssr - * gbr - * mach - * macl - * syscall # - * - */ - -#if defined(CONFIG_PREEMPT) -# define preempt_stop() cli -#else -# define preempt_stop() -# define resume_kernel __restore_all -#endif - -#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) -! Handle kernel debug if either kgdb (SW) or gdb-stub (FW) is present. -! If both are configured, handle the debug traps (breakpoints) in SW, -! but still allow BIOS traps to FW. - - .align 2 -debug_kernel: -#if defined(CONFIG_SH_STANDARD_BIOS) && defined(CONFIG_SH_KGDB) - /* Force BIOS call to FW (debug_trap put TRA in r8) */ - mov r8,r0 - shlr2 r0 - cmp/eq #0x3f,r0 - bt debug_kernel_fw -#endif /* CONFIG_SH_STANDARD_BIOS && CONFIG_SH_KGDB */ - -debug_enter: -#if defined(CONFIG_SH_KGDB) - /* Jump to kgdb, pass stacked regs as arg */ -debug_kernel_sw: - mov.l 3f, r0 - jmp @r0 - mov r15, r4 - .align 2 -3: .long kgdb_handle_exception -#endif /* CONFIG_SH_KGDB */ - -#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */ - - - .align 2 -debug_trap: -#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) - mov #OFF_SR, r0 - mov.l @(r0,r15), r0 ! get status register - shll r0 - shll r0 ! kernel space? - bt/s debug_kernel -#endif - mov.l @r15, r0 ! Restore R0 value - mov.l 1f, r8 - jmp @r8 - nop - - .align 2 -ENTRY(exception_error) - ! -#ifdef CONFIG_TRACE_IRQFLAGS - mov.l 3f, r0 - jsr @r0 - nop -#endif - sti - mov.l 2f, r0 - jmp @r0 - nop - -! - .align 2 -1: .long break_point_trap_software -2: .long do_exception_error -#ifdef CONFIG_TRACE_IRQFLAGS -3: .long trace_hardirqs_on -#endif - - .align 2 -ret_from_exception: - preempt_stop() -#ifdef CONFIG_TRACE_IRQFLAGS - mov.l 4f, r0 - jsr @r0 - nop -#endif -ENTRY(ret_from_irq) - ! - mov #OFF_SR, r0 - mov.l @(r0,r15), r0 ! get status register - shll r0 - shll r0 ! kernel space? - get_current_thread_info r8, r0 - bt resume_kernel ! Yes, it's from kernel, go back soon - -#ifdef CONFIG_PREEMPT - bra resume_userspace - nop -ENTRY(resume_kernel) - mov.l @(TI_PRE_COUNT,r8), r0 ! current_thread_info->preempt_count - tst r0, r0 - bf noresched -need_resched: - mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags - tst #_TIF_NEED_RESCHED, r0 ! need_resched set? - bt noresched - - mov #OFF_SR, r0 - mov.l @(r0,r15), r0 ! get status register - and #0xf0, r0 ! interrupts off (exception path)? - cmp/eq #0xf0, r0 - bt noresched - - mov.l 1f, r0 - mov.l r0, @(TI_PRE_COUNT,r8) - -#ifdef CONFIG_TRACE_IRQFLAGS - mov.l 3f, r0 - jsr @r0 - nop -#endif - sti - mov.l 2f, r0 - jsr @r0 - nop - mov #0, r0 - mov.l r0, @(TI_PRE_COUNT,r8) - cli -#ifdef CONFIG_TRACE_IRQFLAGS - mov.l 4f, r0 - jsr @r0 - nop -#endif - - bra need_resched - nop - -noresched: - bra __restore_all - nop - - .align 2 -1: .long PREEMPT_ACTIVE -2: .long schedule -#ifdef CONFIG_TRACE_IRQFLAGS -3: .long trace_hardirqs_on -4: .long trace_hardirqs_off -#endif -#endif - -ENTRY(resume_userspace) - ! r8: current_thread_info - cli -#ifdef CONFIG_TRACE_IRQFLAGS - mov.l 5f, r0 - jsr @r0 - nop -#endif - mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags - tst #_TIF_WORK_MASK, r0 - bt/s __restore_all - tst #_TIF_NEED_RESCHED, r0 - - .align 2 -work_pending: - ! r0: current_thread_info->flags - ! r8: current_thread_info - ! t: result of "tst #_TIF_NEED_RESCHED, r0" - bf/s work_resched - tst #(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r0 -work_notifysig: - bt/s __restore_all - mov r15, r4 - mov r12, r5 ! set arg1(save_r0) - mov r0, r6 - mov.l 2f, r1 - mov.l 3f, r0 - jmp @r1 - lds r0, pr -work_resched: -#ifndef CONFIG_PREEMPT - ! gUSA handling - mov.l @(OFF_SP,r15), r0 ! get user space stack pointer - mov r0, r1 - shll r0 - bf/s 1f - shll r0 - bf/s 1f - mov #OFF_PC, r0 - ! SP >= 0xc0000000 : gUSA mark - mov.l @(r0,r15), r2 ! get user space PC (program counter) - mov.l @(OFF_R0,r15), r3 ! end point - cmp/hs r3, r2 ! r2 >= r3? - bt 1f - add r3, r1 ! rewind point #2 - mov.l r1, @(r0,r15) ! reset PC to rewind point #2 - ! -1: -#endif - mov.l 1f, r1 - jsr @r1 ! schedule - nop - cli -#ifdef CONFIG_TRACE_IRQFLAGS - mov.l 5f, r0 - jsr @r0 - nop -#endif - ! - mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags - tst #_TIF_WORK_MASK, r0 - bt __restore_all - bra work_pending - tst #_TIF_NEED_RESCHED, r0 - - .align 2 -1: .long schedule -2: .long do_notify_resume -3: .long restore_all -#ifdef CONFIG_TRACE_IRQFLAGS -4: .long trace_hardirqs_on -5: .long trace_hardirqs_off -#endif - - .align 2 -syscall_exit_work: - ! r0: current_thread_info->flags - ! r8: current_thread_info - tst #_TIF_SYSCALL_TRACE, r0 - bt/s work_pending - tst #_TIF_NEED_RESCHED, r0 -#ifdef CONFIG_TRACE_IRQFLAGS - mov.l 5f, r0 - jsr @r0 - nop -#endif - sti - ! XXX setup arguments... - mov.l 4f, r0 ! do_syscall_trace - jsr @r0 - nop - bra resume_userspace - nop - - .align 2 -syscall_trace_entry: - ! Yes it is traced. - ! XXX setup arguments... - mov.l 4f, r11 ! Call do_syscall_trace which notifies - jsr @r11 ! superior (will chomp R[0-7]) - nop - ! Reload R0-R4 from kernel stack, where the - ! parent may have modified them using - ! ptrace(POKEUSR). (Note that R0-R2 are - ! used by the system call handler directly - ! from the kernel stack anyway, so don't need - ! to be reloaded here.) This allows the parent - ! to rewrite system calls and args on the fly. - mov.l @(OFF_R4,r15), r4 ! arg0 - mov.l @(OFF_R5,r15), r5 - mov.l @(OFF_R6,r15), r6 - mov.l @(OFF_R7,r15), r7 ! arg3 - mov.l @(OFF_R3,r15), r3 ! syscall_nr - ! - mov.l 2f, r10 ! Number of syscalls - cmp/hs r10, r3 - bf syscall_call - mov #-ENOSYS, r0 - bra syscall_exit - mov.l r0, @(OFF_R0,r15) ! Return value - -__restore_all: - mov.l 1f, r0 - jmp @r0 - nop - - .align 2 -1: .long restore_all - - .align 2 -not_syscall_tra: - bra debug_trap - nop - - .align 2 -syscall_badsys: ! Bad syscall number - mov #-ENOSYS, r0 - bra resume_userspace - mov.l r0, @(OFF_R0,r15) ! Return value - - -/* - * Syscall interface: - * - * Syscall #: R3 - * Arguments #0 to #3: R4--R7 - * Arguments #4 to #6: R0, R1, R2 - * TRA: (number of arguments + 0x10) x 4 - * - * This code also handles delegating other traps to the BIOS/gdb stub - * according to: - * - * Trap number - * (TRA>>2) Purpose - * -------- ------- - * 0x0-0xf old syscall ABI - * 0x10-0x1f new syscall ABI - * 0x20-0xff delegated through debug_trap to BIOS/gdb stub. - * - * Note: When we're first called, the TRA value must be shifted - * right 2 bits in order to get the value that was used as the "trapa" - * argument. - */ - - .align 2 - .globl ret_from_fork -ret_from_fork: - mov.l 1f, r8 - jsr @r8 - mov r0, r4 - bra syscall_exit - nop - .align 2 -1: .long schedule_tail - ! -ENTRY(system_call) -#if !defined(CONFIG_CPU_SH2) - mov.l 1f, r9 - mov.l @r9, r8 ! Read from TRA (Trap Address) Register -#endif - ! - ! Is the trap argument >= 0x20? (TRA will be >= 0x80) - mov #0x7f, r9 - cmp/hi r9, r8 - bt/s not_syscall_tra - mov #OFF_TRA, r9 - add r15, r9 - mov.l r8, @r9 ! set TRA value to tra -#ifdef CONFIG_TRACE_IRQFLAGS - mov.l 5f, r10 - jsr @r10 - nop -#endif - sti - - ! - get_current_thread_info r8, r10 - mov.l @(TI_FLAGS,r8), r8 - mov #_TIF_SYSCALL_TRACE, r10 - tst r10, r8 - bf syscall_trace_entry - ! - mov.l 2f, r8 ! Number of syscalls - cmp/hs r8, r3 - bt syscall_badsys - ! -syscall_call: - shll2 r3 ! x4 - mov.l 3f, r8 ! Load the address of sys_call_table - add r8, r3 - mov.l @r3, r8 - jsr @r8 ! jump to specific syscall handler - nop - mov.l @(OFF_R0,r15), r12 ! save r0 - mov.l r0, @(OFF_R0,r15) ! save the return value - ! -syscall_exit: - cli -#ifdef CONFIG_TRACE_IRQFLAGS - mov.l 6f, r0 - jsr @r0 - nop -#endif - ! - get_current_thread_info r8, r0 - mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags - tst #_TIF_ALLWORK_MASK, r0 - bf syscall_exit_work - bra __restore_all - nop - .align 2 -#if !defined(CONFIG_CPU_SH2) -1: .long TRA -#endif -2: .long NR_syscalls -3: .long sys_call_table -4: .long do_syscall_trace -#ifdef CONFIG_TRACE_IRQFLAGS -5: .long trace_hardirqs_on -6: .long trace_hardirqs_off -#endif diff --git a/trunk/arch/sh/kernel/cpu/sh3/entry.S b/trunk/arch/sh/kernel/entry.S similarity index 58% rename from trunk/arch/sh/kernel/cpu/sh3/entry.S rename to trunk/arch/sh/kernel/entry.S index 8c0dc2700c69..39aaefb2d83f 100644 --- a/trunk/arch/sh/kernel/cpu/sh3/entry.S +++ b/trunk/arch/sh/kernel/entry.S @@ -1,5 +1,5 @@ /* - * arch/sh/kernel/entry.S + * linux/arch/sh/entry.S * * Copyright (C) 1999, 2000, 2002 Niibe Yutaka * Copyright (C) 2003 - 2006 Paul Mundt @@ -7,16 +7,15 @@ * 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 ! NOTE: ! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address @@ -82,8 +81,6 @@ OFF_TRA = (16*4+6*4) #define k_g_imask r6_bank /* r6_bank1 */ #define current r7 /* r7_bank1 */ -#include - /* * Kernel mode register usage: * k0 scratch @@ -110,6 +107,26 @@ OFF_TRA = (16*4+6*4) ! this first version depends *much* on C implementation. ! +#define CLI() \ + stc sr, r0; \ + or #0xf0, r0; \ + ldc r0, sr + +#define STI() \ + mov.l __INV_IMASK, r11; \ + stc sr, r10; \ + and r11, r10; \ + stc k_g_imask, r11; \ + or r11, r10; \ + ldc r10, sr + +#if defined(CONFIG_PREEMPT) +# define preempt_stop() CLI() +#else +# define preempt_stop() +# define resume_kernel restore_all +#endif + #if defined(CONFIG_MMU) .align 2 ENTRY(tlb_miss_load) @@ -138,14 +155,29 @@ ENTRY(tlb_protection_violation_store) call_dpf: mov.l 1f, r0 - mov.l @r0, r6 ! address + mov r5, r8 + mov.l @r0, r6 + mov r6, r9 + mov.l 2f, r0 + sts pr, r10 + jsr @r0 + mov r15, r4 + ! + tst r0, r0 + bf/s 0f + lds r10, pr + rts + nop +0: STI() mov.l 3f, r0 - + mov r9, r6 + mov r8, r5 jmp @r0 - mov r15, r4 ! regs + mov r15, r4 .align 2 1: .long MMU_TEA +2: .long __do_page_fault 3: .long do_page_fault .align 2 @@ -171,6 +203,32 @@ call_dae: 2: .long do_address_error #endif /* CONFIG_MMU */ +#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) +! Handle kernel debug if either kgdb (SW) or gdb-stub (FW) is present. +! If both are configured, handle the debug traps (breakpoints) in SW, +! but still allow BIOS traps to FW. + + .align 2 +debug_kernel: +#if defined(CONFIG_SH_STANDARD_BIOS) && defined(CONFIG_SH_KGDB) + /* Force BIOS call to FW (debug_trap put TRA in r8) */ + mov r8,r0 + shlr2 r0 + cmp/eq #0x3f,r0 + bt debug_kernel_fw +#endif /* CONFIG_SH_STANDARD_BIOS && CONFIG_SH_KGDB */ + +debug_enter: +#if defined(CONFIG_SH_KGDB) + /* Jump to kgdb, pass stacked regs as arg */ +debug_kernel_sw: + mov.l 3f, r0 + jmp @r0 + mov r15, r4 + .align 2 +3: .long kgdb_handle_exception +#endif /* CONFIG_SH_KGDB */ + #if defined(CONFIG_SH_STANDARD_BIOS) /* Unwind the stack and jmp to the debug entry */ debug_kernel_fw: @@ -211,6 +269,276 @@ debug_kernel_fw: 2: .long gdb_vbr_vector #endif /* CONFIG_SH_STANDARD_BIOS */ +#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */ + + + .align 2 +debug_trap: +#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) + mov #OFF_SR, r0 + mov.l @(r0,r15), r0 ! get status register + shll r0 + shll r0 ! kernel space? + bt/s debug_kernel +#endif + mov.l @r15, r0 ! Restore R0 value + mov.l 1f, r8 + jmp @r8 + nop + + .align 2 +ENTRY(exception_error) + ! + STI() + mov.l 2f, r0 + jmp @r0 + nop + +! + .align 2 +1: .long break_point_trap_software +2: .long do_exception_error + + .align 2 +ret_from_exception: + preempt_stop() +ENTRY(ret_from_irq) + ! + mov #OFF_SR, r0 + mov.l @(r0,r15), r0 ! get status register + shll r0 + shll r0 ! kernel space? + bt/s resume_kernel ! Yes, it's from kernel, go back soon + GET_THREAD_INFO(r8) + +#ifdef CONFIG_PREEMPT + bra resume_userspace + nop +ENTRY(resume_kernel) + mov.l @(TI_PRE_COUNT,r8), r0 ! current_thread_info->preempt_count + tst r0, r0 + bf noresched +need_resched: + mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags + tst #_TIF_NEED_RESCHED, r0 ! need_resched set? + bt noresched + + mov #OFF_SR, r0 + mov.l @(r0,r15), r0 ! get status register + and #0xf0, r0 ! interrupts off (exception path)? + cmp/eq #0xf0, r0 + bt noresched + + mov.l 1f, r0 + mov.l r0, @(TI_PRE_COUNT,r8) + + STI() + mov.l 2f, r0 + jsr @r0 + nop + mov #0, r0 + mov.l r0, @(TI_PRE_COUNT,r8) + CLI() + + bra need_resched + nop +noresched: + bra restore_all + nop + + .align 2 +1: .long PREEMPT_ACTIVE +2: .long schedule +#endif + +ENTRY(resume_userspace) + ! r8: current_thread_info + CLI() + mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags + tst #_TIF_WORK_MASK, r0 + bt/s restore_all + tst #_TIF_NEED_RESCHED, r0 + + .align 2 +work_pending: + ! r0: current_thread_info->flags + ! r8: current_thread_info + ! t: result of "tst #_TIF_NEED_RESCHED, r0" + bf/s work_resched + tst #(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r0 +work_notifysig: + bt/s restore_all + mov r15, r4 + mov r12, r5 ! set arg1(save_r0) + mov r0, r6 + mov.l 2f, r1 + mova restore_all, r0 + jmp @r1 + lds r0, pr +work_resched: +#ifndef CONFIG_PREEMPT + ! gUSA handling + mov.l @(OFF_SP,r15), r0 ! get user space stack pointer + mov r0, r1 + shll r0 + bf/s 1f + shll r0 + bf/s 1f + mov #OFF_PC, r0 + ! SP >= 0xc0000000 : gUSA mark + mov.l @(r0,r15), r2 ! get user space PC (program counter) + mov.l @(OFF_R0,r15), r3 ! end point + cmp/hs r3, r2 ! r2 >= r3? + bt 1f + add r3, r1 ! rewind point #2 + mov.l r1, @(r0,r15) ! reset PC to rewind point #2 + ! +1: +#endif + mov.l 1f, r1 + jsr @r1 ! schedule + nop + CLI() + ! + mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags + tst #_TIF_WORK_MASK, r0 + bt restore_all + bra work_pending + tst #_TIF_NEED_RESCHED, r0 + + .align 2 +1: .long schedule +2: .long do_notify_resume + + .align 2 +syscall_exit_work: + ! r0: current_thread_info->flags + ! r8: current_thread_info + tst #_TIF_SYSCALL_TRACE, r0 + bt/s work_pending + tst #_TIF_NEED_RESCHED, r0 + STI() + ! XXX setup arguments... + mov.l 4f, r0 ! do_syscall_trace + jsr @r0 + nop + bra resume_userspace + nop + + .align 2 +syscall_trace_entry: + ! Yes it is traced. + ! XXX setup arguments... + mov.l 4f, r11 ! Call do_syscall_trace which notifies + jsr @r11 ! superior (will chomp R[0-7]) + nop + ! Reload R0-R4 from kernel stack, where the + ! parent may have modified them using + ! ptrace(POKEUSR). (Note that R0-R2 are + ! used by the system call handler directly + ! from the kernel stack anyway, so don't need + ! to be reloaded here.) This allows the parent + ! to rewrite system calls and args on the fly. + mov.l @(OFF_R4,r15), r4 ! arg0 + mov.l @(OFF_R5,r15), r5 + mov.l @(OFF_R6,r15), r6 + mov.l @(OFF_R7,r15), r7 ! arg3 + mov.l @(OFF_R3,r15), r3 ! syscall_nr + ! Arrange for do_syscall_trace to be called + ! again as the system call returns. + mov.l 2f, r10 ! Number of syscalls + cmp/hs r10, r3 + bf syscall_call + mov #-ENOSYS, r0 + bra syscall_exit + mov.l r0, @(OFF_R0,r15) ! Return value + +/* + * Syscall interface: + * + * Syscall #: R3 + * Arguments #0 to #3: R4--R7 + * Arguments #4 to #6: R0, R1, R2 + * TRA: (number of arguments + 0x10) x 4 + * + * This code also handles delegating other traps to the BIOS/gdb stub + * according to: + * + * Trap number + * (TRA>>2) Purpose + * -------- ------- + * 0x0-0xf old syscall ABI + * 0x10-0x1f new syscall ABI + * 0x20-0xff delegated through debug_trap to BIOS/gdb stub. + * + * Note: When we're first called, the TRA value must be shifted + * right 2 bits in order to get the value that was used as the "trapa" + * argument. + */ + + .align 2 + .globl ret_from_fork +ret_from_fork: + mov.l 1f, r8 + jsr @r8 + mov r0, r4 + bra syscall_exit + nop + .align 2 +1: .long schedule_tail + ! +ENTRY(system_call) + mov.l 1f, r9 + mov.l @r9, r8 ! Read from TRA (Trap Address) Register + ! + ! Is the trap argument >= 0x20? (TRA will be >= 0x80) + mov #0x7f, r9 + cmp/hi r9, r8 + bt/s 0f + mov #OFF_TRA, r9 + add r15, r9 + ! + mov.l r8, @r9 ! set TRA value to tra + STI() + ! Call the system call handler through the table. + ! First check for bad syscall number + mov r3, r9 + mov.l 2f, r8 ! Number of syscalls + cmp/hs r8, r9 + bf/s good_system_call + GET_THREAD_INFO(r8) +syscall_badsys: ! Bad syscall number + mov #-ENOSYS, r0 + bra resume_userspace + mov.l r0, @(OFF_R0,r15) ! Return value + ! +0: + bra debug_trap + nop + ! +good_system_call: ! Good syscall number + mov.l @(TI_FLAGS,r8), r8 + mov #_TIF_SYSCALL_TRACE, r10 + tst r10, r8 + bf syscall_trace_entry + ! +syscall_call: + shll2 r9 ! x4 + mov.l 3f, r8 ! Load the address of sys_call_table + add r8, r9 + mov.l @r9, r8 + jsr @r8 ! jump to specific syscall handler + nop + mov.l @(OFF_R0,r15), r12 ! save r0 + mov.l r0, @(OFF_R0,r15) ! save the return value + ! +syscall_exit: + CLI() + ! + GET_THREAD_INFO(r8) + mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags + tst #_TIF_ALLWORK_MASK, r0 + bf syscall_exit_work restore_all: mov.l @r15+, r0 mov.l @r15+, r1 @@ -278,9 +606,7 @@ skip_restore: ! ! Calculate new SR value mov k3, k2 ! original SR value - mov #0xf0, k1 - extu.b k1, k1 - not k1, k1 + mov.l 9f, k1 and k1, k2 ! Mask orignal SR value ! mov k3, k0 ! Calculate IMASK-bits @@ -306,12 +632,16 @@ skip_restore: nop .align 2 +1: .long TRA +2: .long NR_syscalls +3: .long sys_call_table +4: .long do_syscall_trace 5: .long 0x00001000 ! DSP 7: .long 0x30000000 +9: +__INV_IMASK: + .long 0xffffff0f ! ~(IMASK) -! common exception handler -#include "../../entry-common.S" - ! Exception Vector Base ! ! Should be aligned page boundary. @@ -331,176 +661,9 @@ general_exception: 2: .long ret_from_exception ! ! - -/* This code makes some assumptions to improve performance. - * Make sure they are stil true. */ -#if PTRS_PER_PGD != PTRS_PER_PTE -#error PGD and PTE sizes don't match -#endif - -/* gas doesn't flag impossible values for mov #immediate as an error */ -#if (_PAGE_PRESENT >> 2) > 0x7f -#error cannot load PAGE_PRESENT as an immediate -#endif -#if _PAGE_DIRTY > 0x7f -#error cannot load PAGE_DIRTY as an immediate -#endif -#if (_PAGE_PRESENT << 2) != _PAGE_ACCESSED -#error cannot derive PAGE_ACCESSED from PAGE_PRESENT -#endif - -#if defined(CONFIG_CPU_SH4) -#define ldmmupteh(r) mov.l 8f, r -#else -#define ldmmupteh(r) mov #MMU_PTEH, r -#endif - .balign 1024,0,1024 tlb_miss: -#ifdef COUNT_EXCEPTIONS - ! Increment the counts - mov.l 9f, k1 - mov.l @k1, k2 - add #1, k2 - mov.l k2, @k1 -#endif - - ! k0 scratch - ! k1 pgd and pte pointers - ! k2 faulting address - ! k3 pgd and pte index masks - ! k4 shift - - ! Load up the pgd entry (k1) - - ldmmupteh(k0) ! 9 LS (latency=2) MMU_PTEH - - mov.w 4f, k3 ! 8 LS (latency=2) (PTRS_PER_PGD-1) << 2 - mov #-(PGDIR_SHIFT-2), k4 ! 6 EX - - mov.l @(MMU_TEA-MMU_PTEH,k0), k2 ! 18 LS (latency=2) - - mov.l @(MMU_TTB-MMU_PTEH,k0), k1 ! 18 LS (latency=2) - - mov k2, k0 ! 5 MT (latency=0) - shld k4, k0 ! 99 EX - - and k3, k0 ! 78 EX - - mov.l @(k0, k1), k1 ! 21 LS (latency=2) - mov #-(PAGE_SHIFT-2), k4 ! 6 EX - - ! Load up the pte entry (k2) - - mov k2, k0 ! 5 MT (latency=0) - shld k4, k0 ! 99 EX - - tst k1, k1 ! 86 MT - - bt 20f ! 110 BR - - and k3, k0 ! 78 EX - mov.w 5f, k4 ! 8 LS (latency=2) _PAGE_PRESENT - - mov.l @(k0, k1), k2 ! 21 LS (latency=2) - add k0, k1 ! 49 EX - -#ifdef CONFIG_CPU_HAS_PTEA - ! Test the entry for present and _PAGE_ACCESSED - - mov #-28, k3 ! 6 EX - mov k2, k0 ! 5 MT (latency=0) - - tst k4, k2 ! 68 MT - shld k3, k0 ! 99 EX - - bt 20f ! 110 BR - - ! Set PTEA register - ! MMU_PTEA = ((pteval >> 28) & 0xe) | (pteval & 0x1) - ! - ! k0=pte>>28, k1=pte*, k2=pte, k3=, k4=_PAGE_PRESENT - - and #0xe, k0 ! 79 EX - - mov k0, k3 ! 5 MT (latency=0) - mov k2, k0 ! 5 MT (latency=0) - - and #1, k0 ! 79 EX - - or k0, k3 ! 82 EX - - ldmmupteh(k0) ! 9 LS (latency=2) - shll2 k4 ! 101 EX _PAGE_ACCESSED - - tst k4, k2 ! 68 MT - - mov.l k3, @(MMU_PTEA-MMU_PTEH,k0) ! 27 LS - - mov.l 7f, k3 ! 9 LS (latency=2) _PAGE_FLAGS_HARDWARE_MASK - - ! k0=MMU_PTEH, k1=pte*, k2=pte, k3=_PAGE_FLAGS_HARDWARE, k4=_PAGE_ACCESSED -#else - - ! Test the entry for present and _PAGE_ACCESSED - - mov.l 7f, k3 ! 9 LS (latency=2) _PAGE_FLAGS_HARDWARE_MASK - tst k4, k2 ! 68 MT - - shll2 k4 ! 101 EX _PAGE_ACCESSED - ldmmupteh(k0) ! 9 LS (latency=2) - - bt 20f ! 110 BR - tst k4, k2 ! 68 MT - - ! k0=MMU_PTEH, k1=pte*, k2=pte, k3=_PAGE_FLAGS_HARDWARE, k4=_PAGE_ACCESSED - -#endif - - ! Set up the entry - - and k2, k3 ! 78 EX - bt/s 10f ! 108 BR - - mov.l k3, @(MMU_PTEL-MMU_PTEH,k0) ! 27 LS - - ldtlb ! 128 CO - - ! At least one instruction between ldtlb and rte - nop ! 119 NOP - - rte ! 126 CO - - nop ! 119 NOP - - -10: or k4, k2 ! 82 EX - - ldtlb ! 128 CO - - ! At least one instruction between ldtlb and rte - mov.l k2, @k1 ! 27 LS - - rte ! 126 CO - - ! Note we cannot execute mov here, because it is executed after - ! restoring SSR, so would be executed in user space. - nop ! 119 NOP - - - .align 5 - ! Once cache line if possible... -1: .long swapper_pg_dir -4: .short (PTRS_PER_PGD-1) << 2 -5: .short _PAGE_PRESENT -7: .long _PAGE_FLAGS_HARDWARE_MASK -8: .long MMU_PTEH -#ifdef COUNT_EXCEPTIONS -9: .long exception_count_miss -#endif - - ! Either pgd or pte not present -20: mov.l 1f, k2 + mov.l 1f, k2 mov.l 4f, k3 bra handle_exception mov.l @k2, k2 @@ -547,9 +710,8 @@ ENTRY(handle_exception) bt/s 1f ! It's a kernel to kernel transition. mov r15, k0 ! save original stack to k0 /* User space to kernel */ - mov #(THREAD_SIZE >> 10), k1 + mov #(THREAD_SIZE >> 8), k1 shll8 k1 ! k1 := THREAD_SIZE - shll2 k1 add current, k1 mov k1, r15 ! change to kernel stack ! @@ -599,7 +761,7 @@ skip_save: ! Save the user registers on the stack. mov.l k2, @-r15 ! EXPEVT - mov #-1, k4 + mov #-1, k4 mov.l k4, @-r15 ! set TRA (default: -1) ! sts.l macl, @-r15 @@ -651,15 +813,6 @@ skip_save: bf interrupt_exception shlr2 r8 shlr r8 - -#ifdef COUNT_EXCEPTIONS - mov.l 5f, r9 - add r8, r9 - mov.l @r9, r10 - add #1, r10 - mov.l r10, @r9 -#endif - mov.l 4f, r9 add r8, r9 mov.l @r9, r9 @@ -673,9 +826,6 @@ skip_save: 2: .long 0x000080f0 ! FD=1, IMASK=15 3: .long 0xcfffffff ! RB=0, BL=0 4: .long exception_handling_table -#ifdef COUNT_EXCEPTIONS -5: .long exception_count_table -#endif interrupt_exception: mov.l 1f, r9 diff --git a/trunk/arch/sh/kernel/head.S b/trunk/arch/sh/kernel/head.S index 6aca4bc6ec5d..f5f53d14f245 100644 --- a/trunk/arch/sh/kernel/head.S +++ b/trunk/arch/sh/kernel/head.S @@ -33,7 +33,7 @@ ENTRY(empty_zero_page) .long 0x00360000 /* INITRD_START */ .long 0x000a0000 /* INITRD_SIZE */ .long 0 - .balign PAGE_SIZE,0,PAGE_SIZE + .balign 4096,0,4096 .text /* @@ -53,10 +53,8 @@ ENTRY(_stext) ldc r0, sr ! Initialize global interrupt mask mov #0, r0 -#ifdef CONFIG_CPU_HAS_SR_RB ldc r0, r6_bank -#endif - + /* * Prefetch if possible to reduce cache miss penalty. * @@ -70,14 +68,11 @@ ENTRY(_stext) ! mov.l 2f, r0 mov r0, r15 ! Set initial r15 (stack pointer) - mov #(THREAD_SIZE >> 10), r1 + mov #(THREAD_SIZE >> 8), r1 shll8 r1 ! r1 = THREAD_SIZE - shll2 r1 sub r1, r0 ! -#ifdef CONFIG_CPU_HAS_SR_RB ldc r0, r7_bank ! ... and initial thread_info -#endif - + ! Clear BSS area mov.l 3f, r1 add #4, r1 @@ -100,11 +95,7 @@ ENTRY(_stext) nop .balign 4 -#if defined(CONFIG_CPU_SH2) -1: .long 0x000000F0 ! IMASK=0xF -#else 1: .long 0x400080F0 ! MD=1, RB=0, BL=0, FD=1, IMASK=0xF -#endif 2: .long init_thread_union+THREAD_SIZE 3: .long __bss_start 4: .long _end diff --git a/trunk/arch/sh/kernel/irq.c b/trunk/arch/sh/kernel/irq.c index 67be2b6e8cd1..944128ce9706 100644 --- a/trunk/arch/sh/kernel/irq.c +++ b/trunk/arch/sh/kernel/irq.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include @@ -78,16 +78,15 @@ union irq_ctx { u32 stack[THREAD_SIZE/sizeof(u32)]; }; -static union irq_ctx *hardirq_ctx[NR_CPUS] __read_mostly; -static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly; +static union irq_ctx *hardirq_ctx[NR_CPUS]; +static union irq_ctx *softirq_ctx[NR_CPUS]; #endif asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs __regs) + struct pt_regs regs) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); - struct pt_regs *old_regs = set_irq_regs(regs); + struct pt_regs *old_regs = set_irq_regs(®s); int irq; #ifdef CONFIG_4KSTACKS union irq_ctx *curctx, *irqctx; @@ -112,7 +111,7 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, #endif #ifdef CONFIG_CPU_HAS_INTEVT - irq = evt2irq(ctrl_inl(INTEVT)); + irq = (ctrl_inl(INTEVT) >> 5) - 16; #else irq = r4; #endif @@ -136,24 +135,17 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, irqctx->tinfo.task = curctx->tinfo.task; irqctx->tinfo.previous_sp = current_stack_pointer; - /* - * Copy the softirq bits in preempt_count so that the - * softirq checks work in the hardirq context. - */ - irqctx->tinfo.preempt_count = - (irqctx->tinfo.preempt_count & ~SOFTIRQ_MASK) | - (curctx->tinfo.preempt_count & SOFTIRQ_MASK); - __asm__ __volatile__ ( "mov %0, r4 \n" - "mov r15, r8 \n" + "mov r15, r9 \n" "jsr @%1 \n" /* swith to the irq stack */ " mov %2, r15 \n" /* restore the stack (ring zero) */ - "mov r8, r15 \n" + "mov r9, r15 \n" : /* no outputs */ : "r" (irq), "r" (generic_handle_irq), "r" (isp) + /* XXX: A somewhat excessive clobber list? -PFM */ : "memory", "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "t", "pr" ); @@ -201,7 +193,7 @@ void irq_ctx_init(int cpu) irqctx->tinfo.task = NULL; irqctx->tinfo.exec_domain = NULL; irqctx->tinfo.cpu = cpu; - irqctx->tinfo.preempt_count = 0; + irqctx->tinfo.preempt_count = SOFTIRQ_OFFSET; irqctx->tinfo.addr_limit = MAKE_MM_SEG(0); softirq_ctx[cpu] = irqctx; @@ -247,38 +239,13 @@ asmlinkage void do_softirq(void) "mov r9, r15 \n" : /* no outputs */ : "r" (__do_softirq), "r" (isp) + /* XXX: A somewhat excessive clobber list? -PFM */ : "memory", "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r15", "t", "pr" ); - - /* - * Shouldnt happen, we returned above if in_interrupt(): - */ - WARN_ON_ONCE(softirq_count()); } local_irq_restore(flags); } EXPORT_SYMBOL(do_softirq); #endif - -void __init init_IRQ(void) -{ -#ifdef CONFIG_CPU_HAS_PINT_IRQ - init_IRQ_pint(); -#endif - -#ifdef CONFIG_CPU_HAS_INTC2_IRQ - init_IRQ_intc2(); -#endif - -#ifdef CONFIG_CPU_HAS_IPR_IRQ - init_IRQ_ipr(); -#endif - - /* Perform the machine specific initialisation */ - if (sh_mv.mv_init_irq) - sh_mv.mv_init_irq(); - - irq_ctx_init(smp_processor_id()); -} diff --git a/trunk/arch/sh/kernel/process.c b/trunk/arch/sh/kernel/process.c index f3e2631be144..a52b13ac6b7f 100644 --- a/trunk/arch/sh/kernel/process.c +++ b/trunk/arch/sh/kernel/process.c @@ -385,11 +385,10 @@ struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *ne asmlinkage int sys_fork(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs __regs) + struct pt_regs regs) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); #ifdef CONFIG_MMU - return do_fork(SIGCHLD, regs->regs[15], regs, 0, NULL, NULL); + return do_fork(SIGCHLD, regs.regs[15], ®s, 0, NULL, NULL); #else /* fork almost works, enough to trick you into looking elsewhere :-( */ return -EINVAL; @@ -399,12 +398,11 @@ asmlinkage int sys_fork(unsigned long r4, unsigned long r5, asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, unsigned long parent_tidptr, unsigned long child_tidptr, - struct pt_regs __regs) + struct pt_regs regs) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); if (!newsp) - newsp = regs->regs[15]; - return do_fork(clone_flags, newsp, regs, 0, + newsp = regs.regs[15]; + return do_fork(clone_flags, newsp, ®s, 0, (int __user *)parent_tidptr, (int __user *)child_tidptr); } @@ -420,10 +418,9 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, */ asmlinkage int sys_vfork(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs __regs) + struct pt_regs regs) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->regs[15], regs, + return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.regs[15], ®s, 0, NULL, NULL); } @@ -432,9 +429,8 @@ asmlinkage int sys_vfork(unsigned long r4, unsigned long r5, */ asmlinkage int sys_execve(char *ufilename, char **uargv, char **uenvp, unsigned long r7, - struct pt_regs __regs) + struct pt_regs regs) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); int error; char *filename; @@ -446,7 +442,7 @@ asmlinkage int sys_execve(char *ufilename, char **uargv, error = do_execve(filename, (char __user * __user *)uargv, (char __user * __user *)uenvp, - regs); + ®s); if (error == 0) { task_lock(current); current->ptrace &= ~PT_DTRACE; @@ -476,7 +472,9 @@ unsigned long get_wchan(struct task_struct *p) return pc; } -asmlinkage void break_point_trap(void) +asmlinkage void break_point_trap(unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7, + struct pt_regs regs) { /* Clear tracing. */ #if defined(CONFIG_CPU_SH4A) @@ -494,10 +492,8 @@ asmlinkage void break_point_trap(void) asmlinkage void break_point_trap_software(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs __regs) + struct pt_regs regs) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); - - regs->pc -= 2; + regs.pc -= 2; force_sig(SIGTRAP, current); } diff --git a/trunk/arch/sh/kernel/relocate_kernel.S b/trunk/arch/sh/kernel/relocate_kernel.S index c66cb3209db5..8221b37c9773 100644 --- a/trunk/arch/sh/kernel/relocate_kernel.S +++ b/trunk/arch/sh/kernel/relocate_kernel.S @@ -7,9 +7,11 @@ * This source code is licensed under the GNU General Public License, * Version 2. See the file COPYING for more details. */ + #include -#include -#include + +#define PAGE_SIZE 4096 /* must be same value as in */ + .globl relocate_new_kernel relocate_new_kernel: @@ -18,8 +20,8 @@ relocate_new_kernel: /* r6 = start_address */ /* r7 = vbr_reg */ - mov.l 10f,r8 /* PAGE_SIZE */ - mov.l 11f,r9 /* P2SEG */ + mov.l 10f,r8 /* 4096 */ + mov.l 11f,r9 /* 0xa0000000 */ /* stack setting */ add r8,r5 @@ -30,7 +32,7 @@ relocate_new_kernel: 0: mov.l @r4+,r0 /* cmd = *ind++ */ -1: /* addr = (cmd | P2SEG) & 0xfffffff0 */ +1: /* addr = (cmd | 0xa0000000) & 0xfffffff0 */ mov r0,r2 or r9,r2 mov #-16,r1 @@ -90,7 +92,7 @@ relocate_new_kernel: 10: .long PAGE_SIZE 11: - .long P2SEG + .long 0xa0000000 relocate_new_kernel_end: diff --git a/trunk/arch/sh/kernel/setup.c b/trunk/arch/sh/kernel/setup.c index 696ca75752d9..36d86f9ac38a 100644 --- a/trunk/arch/sh/kernel/setup.c +++ b/trunk/arch/sh/kernel/setup.c @@ -392,7 +392,6 @@ static int __init topology_init(void) subsys_initcall(topology_init); static const char *cpu_name[] = { - [CPU_SH7206] = "SH7206", [CPU_SH7619] = "SH7619", [CPU_SH7604] = "SH7604", [CPU_SH7300] = "SH7300", [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706", [CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708", @@ -405,7 +404,6 @@ 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_SH7785] = "SH7785", [CPU_SH_NONE] = "Unknown" }; diff --git a/trunk/arch/sh/kernel/sh_ksyms.c b/trunk/arch/sh/kernel/sh_ksyms.c index c706f3bfd897..8a2fd19dc9eb 100644 --- a/trunk/arch/sh/kernel/sh_ksyms.c +++ b/trunk/arch/sh/kernel/sh_ksyms.c @@ -73,6 +73,8 @@ DECLARE_EXPORT(__lshrdi3); DECLARE_EXPORT(__movstr); DECLARE_EXPORT(__movstrSI16); +EXPORT_SYMBOL(strcpy); + #ifdef CONFIG_CPU_SH4 DECLARE_EXPORT(__movstr_i4_even); DECLARE_EXPORT(__movstr_i4_odd); diff --git a/trunk/arch/sh/kernel/signal.c b/trunk/arch/sh/kernel/signal.c index 50d7c4993bef..5213f5bc6ce0 100644 --- a/trunk/arch/sh/kernel/signal.c +++ b/trunk/arch/sh/kernel/signal.c @@ -37,7 +37,7 @@ asmlinkage int sys_sigsuspend(old_sigset_t mask, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs __regs) + struct pt_regs regs) { mask &= _BLOCKABLE; spin_lock_irq(¤t->sighand->siglock); @@ -52,7 +52,7 @@ sys_sigsuspend(old_sigset_t mask, return -ERESTARTNOHAND; } -asmlinkage int +asmlinkage int sys_sigaction(int sig, const struct old_sigaction __user *act, struct old_sigaction __user *oact) { @@ -87,11 +87,9 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, unsigned long r6, unsigned long r7, - struct pt_regs __regs) + struct pt_regs regs) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); - - return do_sigaltstack(uss, uoss, regs->regs[15]); + return do_sigaltstack(uss, uoss, regs.regs[15]); } @@ -100,11 +98,7 @@ 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 */ -#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 TRAP16 0xc310 /* Syscall w/no args (NR in R3) */ #define OR_R0_R0 0x200b /* or r0,r0 (insert to avoid hardware bug) */ struct sigframe @@ -200,10 +194,9 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs __regs) + struct pt_regs regs) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); - struct sigframe __user *frame = (struct sigframe __user *)regs->regs[15]; + struct sigframe __user *frame = (struct sigframe __user *)regs.regs[15]; sigset_t set; int r0; @@ -223,7 +216,7 @@ asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5, recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - if (restore_sigcontext(regs, &frame->sc, &r0)) + if (restore_sigcontext(®s, &frame->sc, &r0)) goto badframe; return r0; @@ -234,10 +227,9 @@ asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5, asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs __regs) + struct pt_regs regs) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); - struct rt_sigframe __user *frame = (struct rt_sigframe __user *)regs->regs[15]; + struct rt_sigframe __user *frame = (struct rt_sigframe __user *)regs.regs[15]; sigset_t set; stack_t st; int r0; @@ -254,14 +246,14 @@ asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5, recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0)) + if (restore_sigcontext(®s, &frame->uc.uc_mcontext, &r0)) goto badframe; if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) goto badframe; /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - do_sigaltstack(&st, NULL, regs->regs[15]); + do_sigaltstack(&st, NULL, regs.regs[15]); return r0; @@ -358,7 +350,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(TRAP_NOARG, &frame->retcode[1]); + err |= __put_user(TRAP16, &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]); @@ -438,7 +430,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(TRAP_NOARG, &frame->retcode[1]); + err |= __put_user(TRAP16, &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/stacktrace.c b/trunk/arch/sh/kernel/stacktrace.c deleted file mode 100644 index 0d5268afe80f..000000000000 --- a/trunk/arch/sh/kernel/stacktrace.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * arch/sh/kernel/stacktrace.c - * - * Stack trace management functions - * - * Copyright (C) 2006 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 - -/* - * Save stack-backtrace addresses into a stack_trace buffer. - */ -void save_stack_trace(struct stack_trace *trace, struct task_struct *task) -{ - unsigned long *sp; - - if (!task) - task = current; - if (task == current) - sp = (unsigned long *)current_stack_pointer; - else - sp = (unsigned long *)task->thread.sp; - - while (!kstack_end(sp)) { - unsigned long addr = *sp++; - - if (__kernel_text_address(addr)) { - if (trace->skip > 0) - trace->skip--; - else - trace->entries[trace->nr_entries++] = addr; - if (trace->nr_entries >= trace->max_entries) - break; - } - } -} diff --git a/trunk/arch/sh/kernel/sys_sh.c b/trunk/arch/sh/kernel/sys_sh.c index 5083b6ed4b39..8fde95001c34 100644 --- a/trunk/arch/sh/kernel/sys_sh.c +++ b/trunk/arch/sh/kernel/sys_sh.c @@ -33,15 +33,14 @@ */ asmlinkage int sys_pipe(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs __regs) + struct pt_regs regs) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); int fd[2]; int error; error = do_pipe(fd); if (!error) { - regs->regs[1] = fd[1]; + regs.regs[1] = fd[1]; return fd[0]; } return error; @@ -51,7 +50,6 @@ unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */ EXPORT_SYMBOL(shm_align_mask); -#ifdef CONFIG_MMU /* * To avoid cache aliases, we map the shared page with same color. */ @@ -137,7 +135,6 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, addr = COLOUR_ALIGN(addr, pgoff); } } -#endif /* CONFIG_MMU */ static inline long do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, diff --git a/trunk/arch/sh/kernel/time.c b/trunk/arch/sh/kernel/time.c index c206c9504c4b..57e708d7b52d 100644 --- a/trunk/arch/sh/kernel/time.c +++ b/trunk/arch/sh/kernel/time.c @@ -13,8 +13,6 @@ #include #include #include -#include -#include #include #include #include @@ -52,20 +50,15 @@ unsigned long long __attribute__ ((weak)) sched_clock(void) #ifndef CONFIG_GENERIC_TIME void do_gettimeofday(struct timeval *tv) { - unsigned long flags; unsigned long seq; unsigned long usec, sec; do { - /* - * Turn off IRQs when grabbing xtime_lock, so that - * the sys_timer get_offset code doesn't have to handle it. - */ - seq = read_seqbegin_irqsave(&xtime_lock, flags); + seq = read_seqbegin(&xtime_lock); usec = get_timer_offset(); sec = xtime.tv_sec; - usec += xtime.tv_nsec / NSEC_PER_USEC; - } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); + usec += xtime.tv_nsec / 1000; + } while (read_seqretry(&xtime_lock, seq)); while (usec >= 1000000) { usec -= 1000000; @@ -92,7 +85,7 @@ int do_settimeofday(struct timespec *tv) * wall time. Discover what correction gettimeofday() would have * made, and then undo it! */ - nsec -= get_timer_offset() * NSEC_PER_USEC; + nsec -= 1000 * get_timer_offset(); wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); @@ -176,108 +169,6 @@ static struct sysdev_class timer_sysclass = { .resume = timer_resume, }; -#ifdef CONFIG_NO_IDLE_HZ -static int timer_dyn_tick_enable(void) -{ - struct dyn_tick_timer *dyn_tick = sys_timer->dyn_tick; - unsigned long flags; - int ret = -ENODEV; - - if (dyn_tick) { - spin_lock_irqsave(&dyn_tick->lock, flags); - ret = 0; - if (!(dyn_tick->state & DYN_TICK_ENABLED)) { - ret = dyn_tick->enable(); - - if (ret == 0) - dyn_tick->state |= DYN_TICK_ENABLED; - } - spin_unlock_irqrestore(&dyn_tick->lock, flags); - } - - return ret; -} - -static int timer_dyn_tick_disable(void) -{ - struct dyn_tick_timer *dyn_tick = sys_timer->dyn_tick; - unsigned long flags; - int ret = -ENODEV; - - if (dyn_tick) { - spin_lock_irqsave(&dyn_tick->lock, flags); - ret = 0; - if (dyn_tick->state & DYN_TICK_ENABLED) { - ret = dyn_tick->disable(); - - if (ret == 0) - dyn_tick->state &= ~DYN_TICK_ENABLED; - } - spin_unlock_irqrestore(&dyn_tick->lock, flags); - } - - return ret; -} - -/* - * Reprogram the system timer for at least the calculated time interval. - * This function should be called from the idle thread with IRQs disabled, - * immediately before sleeping. - */ -void timer_dyn_reprogram(void) -{ - struct dyn_tick_timer *dyn_tick = sys_timer->dyn_tick; - unsigned long next, seq, flags; - - if (!dyn_tick) - return; - - spin_lock_irqsave(&dyn_tick->lock, flags); - if (dyn_tick->state & DYN_TICK_ENABLED) { - next = next_timer_interrupt(); - do { - seq = read_seqbegin(&xtime_lock); - dyn_tick->reprogram(next - jiffies); - } while (read_seqretry(&xtime_lock, seq)); - } - spin_unlock_irqrestore(&dyn_tick->lock, flags); -} - -static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf) -{ - return sprintf(buf, "%i\n", - (sys_timer->dyn_tick->state & DYN_TICK_ENABLED) >> 1); -} - -static ssize_t timer_set_dyn_tick(struct sys_device *dev, const char *buf, - size_t count) -{ - unsigned int enable = simple_strtoul(buf, NULL, 2); - - if (enable) - timer_dyn_tick_enable(); - else - timer_dyn_tick_disable(); - - return count; -} -static SYSDEV_ATTR(dyn_tick, 0644, timer_show_dyn_tick, timer_set_dyn_tick); - -/* - * dyntick=enable|disable - */ -static char dyntick_str[4] __initdata = ""; - -static int __init dyntick_setup(char *str) -{ - if (str) - strlcpy(dyntick_str, str, sizeof(dyntick_str)); - return 1; -} - -__setup("dyntick=", dyntick_setup); -#endif - static int __init timer_init_sysfs(void) { int ret = sysdev_class_register(&timer_sysclass); @@ -285,22 +176,7 @@ static int __init timer_init_sysfs(void) return ret; sys_timer->dev.cls = &timer_sysclass; - ret = sysdev_register(&sys_timer->dev); - -#ifdef CONFIG_NO_IDLE_HZ - if (ret == 0 && sys_timer->dyn_tick) { - ret = sysdev_create_file(&sys_timer->dev, &attr_dyn_tick); - - /* - * Turn on dynamic tick after calibrate delay - * for correct bogomips - */ - if (ret == 0 && dyntick_str[0] == 'e') - ret = timer_dyn_tick_enable(); - } -#endif - - return ret; + return sysdev_register(&sys_timer->dev); } device_initcall(timer_init_sysfs); @@ -324,11 +200,6 @@ void __init time_init(void) sys_timer = get_sys_timer(); printk(KERN_INFO "Using %s for system timer\n", sys_timer->name); -#ifdef CONFIG_NO_IDLE_HZ - if (sys_timer->dyn_tick) - spin_lock_init(&sys_timer->dyn_tick->lock); -#endif - #if defined(CONFIG_SH_KGDB) /* * Set up kgdb as requested. We do it here because the serial diff --git a/trunk/arch/sh/kernel/timers/Makefile b/trunk/arch/sh/kernel/timers/Makefile index bcf244ff6a12..151a6a304cec 100644 --- a/trunk/arch/sh/kernel/timers/Makefile +++ b/trunk/arch/sh/kernel/timers/Makefile @@ -5,6 +5,4 @@ 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 deleted file mode 100644 index a574b93a4e7b..000000000000 --- a/trunk/arch/sh/kernel/timers/timer-cmt.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * 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 - -#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 unsigned long cmt_timer_get_offset(void) -{ - int count; - 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; - - /* 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; - - count = ((LATCH-1) - count) * TICK_SIZE; - count = (count + LATCH/2) / LATCH; - - return count; -} - -static irqreturn_t cmt_timer_interrupt(int irq, void *dev_id) -{ - 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(); - write_sequnlock(&xtime_lock); - - return IRQ_HANDLED; -} - -static struct irqaction cmt_irq = { - .name = "timer", - .handler = cmt_timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER, - .mask = CPU_MASK_NONE, -}; - -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(NULL, "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(CONFIG_SH_TIMER_IRQ, &cmt_irq); - - cmt0_clk.parent = clk_get(NULL, "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, -#ifndef CONFIG_GENERIC_TIME - .get_offset = cmt_timer_get_offset, -#endif -}; - -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 deleted file mode 100644 index fffcd1c09873..000000000000 --- a/trunk/arch/sh/kernel/timers/timer-mtu2.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * 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 - -/* - * 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. - */ -#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; - 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; - - /* 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; - - count = ((LATCH-1) - count) * TICK_SIZE; - count = (count + LATCH/2) / LATCH; - - return count; -} - -static irqreturn_t mtu2_timer_interrupt(int irq, void *dev_id) -{ - 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(); - write_sequnlock(&xtime_lock); - - return IRQ_HANDLED; -} - -static struct irqaction mtu2_irq = { - .name = "timer", - .handler = mtu2_timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER, - .mask = CPU_MASK_NONE, -}; - -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(CONFIG_SH_TIMER_IRQ, &mtu2_irq); - - mtu2_clk1.parent = clk_get(NULL, "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, -#ifndef CONFIG_GENERIC_TIME - .get_offset = mtu2_timer_get_offset, -#endif -}; - -struct sys_timer mtu2_timer = { - .name = "mtu2", - .ops = &mtu2_timer_ops, -}; diff --git a/trunk/arch/sh/kernel/timers/timer-tmu.c b/trunk/arch/sh/kernel/timers/timer-tmu.c index e060e71d0785..24927015dc31 100644 --- a/trunk/arch/sh/kernel/timers/timer-tmu.c +++ b/trunk/arch/sh/kernel/timers/timer-tmu.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -30,9 +31,13 @@ #define TMU0_TCR_CALIB 0x0000 +static DEFINE_SPINLOCK(tmu0_lock); + static unsigned long tmu_timer_get_offset(void) { int count; + unsigned long flags; + static int count_p = 0x7fffffff; /* for the first call after boot */ static unsigned long jiffies_p = 0; @@ -41,6 +46,7 @@ static unsigned long tmu_timer_get_offset(void) */ unsigned long jiffies_t; + spin_lock_irqsave(&tmu0_lock, flags); /* timer count may underflow right here */ count = ctrl_inl(TMU0_TCNT); /* read the latched count */ @@ -66,6 +72,7 @@ static unsigned long tmu_timer_get_offset(void) jiffies_p = jiffies_t; count_p = count; + spin_unlock_irqrestore(&tmu0_lock, flags); count = ((LATCH-1) - count) * TICK_SIZE; count = (count + LATCH/2) / LATCH; @@ -99,7 +106,7 @@ static irqreturn_t tmu_timer_interrupt(int irq, void *dummy) static struct irqaction tmu_irq = { .name = "timer", .handler = tmu_timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER, + .flags = IRQF_DISABLED, .mask = CPU_MASK_NONE, }; @@ -142,9 +149,9 @@ static int tmu_timer_init(void) { unsigned long interval; - setup_irq(CONFIG_SH_TIMER_IRQ, &tmu_irq); + setup_irq(TIMER_IRQ, &tmu_irq); - tmu0_clk.parent = clk_get(NULL, "module_clk"); + tmu0_clk.parent = clk_get("module_clk"); /* Start TMU0 */ tmu_timer_stop(); diff --git a/trunk/arch/sh/kernel/timers/timer.c b/trunk/arch/sh/kernel/timers/timer.c index a6bcc913d25e..dc1f631053a8 100644 --- a/trunk/arch/sh/kernel/timers/timer.c +++ b/trunk/arch/sh/kernel/timers/timer.c @@ -16,12 +16,6 @@ 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/kernel/traps.c b/trunk/arch/sh/kernel/traps.c index 3762d9dc2046..53dfa55f3156 100644 --- a/trunk/arch/sh/kernel/traps.c +++ b/trunk/arch/sh/kernel/traps.c @@ -18,14 +18,13 @@ #include #include #include -#include #include #include #ifdef CONFIG_SH_KGDB #include -#define CHK_REMOTE_DEBUG(regs) \ -{ \ +#define CHK_REMOTE_DEBUG(regs) \ +{ \ if (kgdb_debug_hook && !user_mode(regs))\ (*kgdb_debug_hook)(regs); \ } @@ -34,13 +33,8 @@ #endif #ifdef CONFIG_CPU_SH2 -# define TRAP_RESERVED_INST 4 -# define TRAP_ILLEGAL_SLOT_INST 6 -# define TRAP_ADDRESS_ERROR 9 -# ifdef CONFIG_CPU_SH2A -# define TRAP_DIVZERO_ERROR 17 -# define TRAP_DIVOVF_ERROR 18 -# endif +#define TRAP_RESERVED_INST 4 +#define TRAP_ILLEGAL_SLOT_INST 6 #else #define TRAP_RESERVED_INST 12 #define TRAP_ILLEGAL_SLOT_INST 13 @@ -94,7 +88,7 @@ void die(const char * str, struct pt_regs * regs, long err) if (!user_mode(regs) || in_interrupt()) dump_mem("Stack: ", regs->regs[15], THREAD_SIZE + - (unsigned long)task_stack_page(current)); + (unsigned long)task_stack_page(current)); bust_spinlocks(0); spin_unlock_irq(&die_lock); @@ -108,6 +102,8 @@ static inline void die_if_kernel(const char *str, struct pt_regs *regs, die(str, regs, err); } +static int handle_unaligned_notify_count = 10; + /* * try and fix up kernelspace address errors * - userspace errors just cause EFAULT to be returned, resulting in SEGV @@ -202,7 +198,7 @@ static int handle_unaligned_ins(u16 instruction, struct pt_regs *regs) if (copy_to_user(dst,src,4)) goto fetch_fault; ret = 0; - break; + break; case 2: /* mov.[bwl] to memory, possibly with pre-decrement */ if (instruction & 4) @@ -226,7 +222,7 @@ static int handle_unaligned_ins(u16 instruction, struct pt_regs *regs) if (copy_from_user(dst,src,4)) goto fetch_fault; ret = 0; - break; + break; case 6: /* mov.[bwl] from memory, possibly with post-increment */ src = (unsigned char*) *rm; @@ -234,7 +230,7 @@ static int handle_unaligned_ins(u16 instruction, struct pt_regs *regs) *rm += count; dst = (unsigned char*) rn; *(unsigned long*)dst = 0; - + #ifdef __LITTLE_ENDIAN__ if (copy_from_user(dst, src, count)) goto fetch_fault; @@ -245,7 +241,7 @@ static int handle_unaligned_ins(u16 instruction, struct pt_regs *regs) } #else dst += 4-count; - + if (copy_from_user(dst, src, count)) goto fetch_fault; @@ -324,8 +320,7 @@ static inline int handle_unaligned_delayslot(struct pt_regs *regs) return -EFAULT; /* kernel */ - die("delay-slot-insn faulting in handle_unaligned_delayslot", - regs, 0); + die("delay-slot-insn faulting in handle_unaligned_delayslot", regs, 0); } return handle_unaligned_ins(instruction,regs); @@ -347,13 +342,6 @@ static inline int handle_unaligned_delayslot(struct pt_regs *regs) #define SH_PC_8BIT_OFFSET(instr) ((((signed char)(instr))*2) + 4) #define SH_PC_12BIT_OFFSET(instr) ((((signed short)(instr<<4))>>3) + 4) -/* - * XXX: SH-2A needs this too, but it needs an overhaul thanks to mixed 32-bit - * opcodes.. - */ -#ifndef CONFIG_CPU_SH2A -static int handle_unaligned_notify_count = 10; - static int handle_unaligned_access(u16 instruction, struct pt_regs *regs) { u_int rm; @@ -366,8 +354,7 @@ static int handle_unaligned_access(u16 instruction, struct pt_regs *regs) if (user_mode(regs) && handle_unaligned_notify_count>0) { handle_unaligned_notify_count--; - printk(KERN_NOTICE "Fixing up unaligned userspace access " - "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n", + printk("Fixing up unaligned userspace access in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n", current->comm,current->pid,(u16*)regs->pc,instruction); } @@ -491,58 +478,32 @@ static int handle_unaligned_access(u16 instruction, struct pt_regs *regs) regs->pc += 2; return ret; } -#endif /* CONFIG_CPU_SH2A */ - -#ifdef CONFIG_CPU_HAS_SR_RB -#define lookup_exception_vector(x) \ - __asm__ __volatile__ ("stc r2_bank, %0\n\t" : "=r" ((x))) -#else -#define lookup_exception_vector(x) \ - __asm__ __volatile__ ("mov r4, %0\n\t" : "=r" ((x))) -#endif /* - * Handle various address error exceptions: - * - instruction address error: - * misaligned PC - * PC >= 0x80000000 in user mode - * - data address error (read and write) - * misaligned data access - * access to >= 0x80000000 is user mode - * Unfortuntaly we can't distinguish between instruction address error - * and data address errors caused by read acceses. + * Handle various address error exceptions */ -asmlinkage void do_address_error(struct pt_regs *regs, +asmlinkage void do_address_error(struct pt_regs *regs, unsigned long writeaccess, unsigned long address) { - unsigned long error_code = 0; + unsigned long error_code; mm_segment_t oldfs; - siginfo_t info; -#ifndef CONFIG_CPU_SH2A u16 instruction; int tmp; -#endif - /* Intentional ifdef */ -#ifdef CONFIG_CPU_HAS_SR_RB - lookup_exception_vector(error_code); -#endif + asm volatile("stc r2_bank,%0": "=r" (error_code)); oldfs = get_fs(); if (user_mode(regs)) { - int si_code = BUS_ADRERR; - local_irq_enable(); + current->thread.error_code = error_code; + current->thread.trap_no = (writeaccess) ? 8 : 7; /* bad PC is not something we can fix */ - if (regs->pc & 1) { - si_code = BUS_ADRALN; + if (regs->pc & 1) goto uspace_segv; - } -#ifndef CONFIG_CPU_SH2A set_fs(USER_DS); if (copy_from_user(&instruction, (u16 *)(regs->pc), 2)) { /* Argh. Fault on the instruction itself. @@ -557,23 +518,14 @@ asmlinkage void do_address_error(struct pt_regs *regs, if (tmp==0) return; /* sorted */ -#endif - -uspace_segv: - printk(KERN_NOTICE "Sending SIGBUS to \"%s\" due to unaligned " - "access (PC %lx PR %lx)\n", current->comm, regs->pc, - regs->pr); - info.si_signo = SIGBUS; - info.si_errno = 0; - info.si_code = si_code; - info.si_addr = (void *) address; - force_sig_info(SIGBUS, &info, current); + uspace_segv: + printk(KERN_NOTICE "Killing process \"%s\" due to unaligned access\n", current->comm); + force_sig(SIGSEGV, current); } else { if (regs->pc & 1) die("unaligned program counter", regs, error_code); -#ifndef CONFIG_CPU_SH2A set_fs(KERNEL_DS); if (copy_from_user(&instruction, (u16 *)(regs->pc), 2)) { /* Argh. Fault on the instruction itself. @@ -585,12 +537,6 @@ asmlinkage void do_address_error(struct pt_regs *regs, handle_unaligned_access(instruction, regs); set_fs(oldfs); -#else - printk(KERN_NOTICE "Killing process \"%s\" due to unaligned " - "access\n", current->comm); - - force_sig(SIGSEGV, current); -#endif } } @@ -602,7 +548,7 @@ int is_dsp_inst(struct pt_regs *regs) { unsigned short inst; - /* + /* * Safe guard if DSP mode is already enabled or we're lacking * the DSP altogether. */ @@ -623,49 +569,27 @@ int is_dsp_inst(struct pt_regs *regs) #define is_dsp_inst(regs) (0) #endif /* CONFIG_SH_DSP */ -#ifdef CONFIG_CPU_SH2A -asmlinkage void do_divide_error(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs) -{ - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); - siginfo_t info; - - switch (r4) { - case TRAP_DIVZERO_ERROR: - info.si_code = FPE_INTDIV; - break; - case TRAP_DIVOVF_ERROR: - info.si_code = FPE_INTOVF; - break; - } - - force_sig_info(SIGFPE, &info, current); -} -#endif - /* arch/sh/kernel/cpu/sh4/fpu.c */ extern int do_fpu_inst(unsigned short, struct pt_regs *); extern asmlinkage void do_fpu_state_restore(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, struct pt_regs __regs); + unsigned long r6, unsigned long r7, struct pt_regs regs); asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs __regs) + struct pt_regs regs) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); unsigned long error_code; struct task_struct *tsk = current; #ifdef CONFIG_SH_FPU_EMU - unsigned short inst = 0; + unsigned short inst; int err; - get_user(inst, (unsigned short*)regs->pc); + get_user(inst, (unsigned short*)regs.pc); - err = do_fpu_inst(inst, regs); + err = do_fpu_inst(inst, ®s); if (!err) { - regs->pc += 2; + regs.pc += 2; return; } /* not a FPU inst. */ @@ -673,19 +597,20 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, #ifdef CONFIG_SH_DSP /* Check if it's a DSP instruction */ - if (is_dsp_inst(regs)) { + if (is_dsp_inst(®s)) { /* Enable DSP mode, and restart instruction. */ - regs->sr |= SR_DSP; + regs.sr |= SR_DSP; return; } #endif - lookup_exception_vector(error_code); - + asm volatile("stc r2_bank, %0": "=r" (error_code)); local_irq_enable(); - CHK_REMOTE_DEBUG(regs); + tsk->thread.error_code = error_code; + tsk->thread.trap_no = TRAP_RESERVED_INST; + CHK_REMOTE_DEBUG(®s); force_sig(SIGILL, tsk); - die_if_no_fixup("reserved instruction", regs, error_code); + die_if_no_fixup("reserved instruction", ®s, error_code); } #ifdef CONFIG_SH_FPU_EMU @@ -733,41 +658,39 @@ static int emulate_branch(unsigned short inst, struct pt_regs* regs) asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs __regs) + struct pt_regs regs) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); unsigned long error_code; struct task_struct *tsk = current; #ifdef CONFIG_SH_FPU_EMU - unsigned short inst = 0; + unsigned short inst; - get_user(inst, (unsigned short *)regs->pc + 1); - if (!do_fpu_inst(inst, regs)) { - get_user(inst, (unsigned short *)regs->pc); - if (!emulate_branch(inst, regs)) + get_user(inst, (unsigned short *)regs.pc + 1); + if (!do_fpu_inst(inst, ®s)) { + get_user(inst, (unsigned short *)regs.pc); + if (!emulate_branch(inst, ®s)) return; /* fault in branch.*/ } /* not a FPU inst. */ #endif - lookup_exception_vector(error_code); - + asm volatile("stc r2_bank, %0": "=r" (error_code)); local_irq_enable(); - CHK_REMOTE_DEBUG(regs); + tsk->thread.error_code = error_code; + tsk->thread.trap_no = TRAP_RESERVED_INST; + CHK_REMOTE_DEBUG(®s); force_sig(SIGILL, tsk); - die_if_no_fixup("illegal slot instruction", regs, error_code); + die_if_no_fixup("illegal slot instruction", ®s, error_code); } asmlinkage void do_exception_error(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs __regs) + struct pt_regs regs) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); long ex; - - lookup_exception_vector(ex); - die_if_kernel("exception", regs, ex); + asm volatile("stc r2_bank, %0" : "=r" (ex)); + die_if_kernel("exception", ®s, ex); } #if defined(CONFIG_SH_STANDARD_BIOS) @@ -812,16 +735,12 @@ void *set_exception_table_vec(unsigned int vec, void *handler) { extern void *exception_handling_table[]; void *old_handler; - + old_handler = exception_handling_table[vec]; exception_handling_table[vec] = handler; return old_handler; } -extern asmlinkage void address_error_handler(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs); - void __init trap_init(void) { set_exception_table_vec(TRAP_RESERVED_INST, do_reserved_inst); @@ -840,15 +759,7 @@ void __init trap_init(void) set_exception_table_evt(0x800, do_fpu_state_restore); set_exception_table_evt(0x820, do_fpu_state_restore); #endif - -#ifdef CONFIG_CPU_SH2 - set_exception_table_vec(TRAP_ADDRESS_ERROR, address_error_handler); -#endif -#ifdef CONFIG_CPU_SH2A - set_exception_table_vec(TRAP_DIVZERO_ERROR, do_divide_error); - set_exception_table_vec(TRAP_DIVOVF_ERROR, do_divide_error); -#endif - + /* Setup VBR for boot cpu */ per_cpu_trap_init(); } @@ -873,11 +784,6 @@ void show_trace(struct task_struct *tsk, unsigned long *sp, } printk("\n"); - - if (!tsk) - tsk = current; - - debug_show_held_locks(tsk); } void show_stack(struct task_struct *tsk, unsigned long *sp) diff --git a/trunk/arch/sh/mm/Kconfig b/trunk/arch/sh/mm/Kconfig index 4e0362f50384..9dd606464d23 100644 --- a/trunk/arch/sh/mm/Kconfig +++ b/trunk/arch/sh/mm/Kconfig @@ -4,12 +4,8 @@ menu "Processor selection" # Processor families # config CPU_SH2 - select SH_WRITETHROUGH if !CPU_SH2A bool - -config CPU_SH2A - bool - select CPU_SH2 + select SH_WRITETHROUGH config CPU_SH3 bool @@ -20,7 +16,6 @@ config CPU_SH4 bool select CPU_HAS_INTEVT select CPU_HAS_SR_RB - select CPU_HAS_PTEA if !CPU_SUBTYPE_ST40 config CPU_SH4A bool @@ -45,16 +40,6 @@ 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 @@ -104,7 +89,6 @@ comment "SH-4 Processor Support" config CPU_SUBTYPE_SH7750 bool "Support SH7750 processor" select CPU_SH4 - select CPU_HAS_IPR_IRQ help Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU. @@ -120,18 +104,15 @@ config CPU_SUBTYPE_SH7750R bool "Support SH7750R processor" select CPU_SH4 select CPU_SUBTYPE_SH7750 - select CPU_HAS_IPR_IRQ config CPU_SUBTYPE_SH7750S bool "Support SH7750S processor" select CPU_SH4 select CPU_SUBTYPE_SH7750 - select CPU_HAS_IPR_IRQ config CPU_SUBTYPE_SH7751 bool "Support SH7751 processor" select CPU_SH4 - select CPU_HAS_IPR_IRQ help Select SH7751 if you have a 166 Mhz SH-4 HD6417751 CPU, or if you have a HD6417751R CPU. @@ -140,7 +121,6 @@ config CPU_SUBTYPE_SH7751R bool "Support SH7751R processor" select CPU_SH4 select CPU_SUBTYPE_SH7751 - select CPU_HAS_IPR_IRQ config CPU_SUBTYPE_SH7760 bool "Support SH7760 processor" @@ -177,11 +157,6 @@ config CPU_SUBTYPE_SH7780 select CPU_SH4A select CPU_HAS_INTC2_IRQ -config CPU_SUBTYPE_SH7785 - bool "Support SH7785 processor" - select CPU_SH4A - select CPU_HAS_INTC2_IRQ - comment "SH4AL-DSP Processor Support" config CPU_SUBTYPE_SH73180 @@ -241,22 +216,13 @@ config MEMORY_SIZE config 32BIT bool "Support 32-bit physical addressing through PMB" - depends on CPU_SH4A && MMU && (!X2TLB || BROKEN) + depends on CPU_SH4A && MMU default y help If you say Y here, physical addressing will be extended to 32-bits through the SH-4A PMB. If this is not set, legacy 29-bit physical addressing will be used. -config X2TLB - bool "Enable extended TLB mode" - depends on CPU_SUBTYPE_SH7785 && MMU && EXPERIMENTAL - help - Selecting this option will enable the extended mode of the SH-X2 - TLB. For legacy SH-X behaviour and interoperability, say N. For - all of the fun new features and a willingless to submit bug reports, - say Y. - config VSYSCALL bool "Support vsyscall page" depends on MMU @@ -270,53 +236,17 @@ config VSYSCALL For systems with an MMU that can afford to give up a page, (the default value) say Y. -choice - prompt "Kernel page size" - default PAGE_SIZE_4KB - -config PAGE_SIZE_4KB - bool "4kB" - help - This is the default page size used by all SuperH CPUs. - -config PAGE_SIZE_8KB - bool "8kB" - depends on EXPERIMENTAL && X2TLB - help - This enables 8kB pages as supported by SH-X2 and later MMUs. - -config PAGE_SIZE_64KB - bool "64kB" - depends on EXPERIMENTAL && CPU_SH4 - help - This enables support for 64kB pages, possible on all SH-4 - CPUs and later. Highly experimental, not recommended. - -endchoice - choice prompt "HugeTLB page size" depends on HUGETLB_PAGE && CPU_SH4 && MMU default HUGETLB_PAGE_SIZE_64K config HUGETLB_PAGE_SIZE_64K - bool "64kB" - -config HUGETLB_PAGE_SIZE_256K - bool "256kB" - depends on X2TLB + bool "64K" config HUGETLB_PAGE_SIZE_1MB bool "1MB" -config HUGETLB_PAGE_SIZE_4MB - bool "4MB" - depends on X2TLB - -config HUGETLB_PAGE_SIZE_64MB - bool "64MB" - depends on X2TLB - endchoice source "mm/Kconfig" @@ -344,6 +274,7 @@ 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 6614033f6be9..2689cb24ea2b 100644 --- a/trunk/arch/sh/mm/cache-sh2.c +++ b/trunk/arch/sh/mm/cache-sh2.c @@ -5,7 +5,6 @@ * * Released under the terms of the GNU GPL v2.0. */ - #include #include @@ -15,43 +14,37 @@ #include #include -void __flush_wback_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) { - /* 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) +/* + * 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) { - 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); - } + 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); } diff --git a/trunk/arch/sh/mm/cache-sh4.c b/trunk/arch/sh/mm/cache-sh4.c index ae531affccbd..e48cc22724d9 100644 --- a/trunk/arch/sh/mm/cache-sh4.c +++ b/trunk/arch/sh/mm/cache-sh4.c @@ -11,8 +11,12 @@ */ #include #include -#include -#include +#include +#include +#include +#include +#include +#include #include #include @@ -79,9 +83,9 @@ static void __init emit_cache_params(void) */ /* Worst case assumed to be 64k cache, direct-mapped i.e. 4 synonym bits. */ -#define MAX_P3_MUTEXES 16 +#define MAX_P3_SEMAPHORES 16 -struct mutex p3map_mutex[MAX_P3_MUTEXES]; +struct semaphore p3map_sem[MAX_P3_SEMAPHORES]; void __init p3_cache_init(void) { @@ -111,7 +115,7 @@ void __init p3_cache_init(void) panic("%s failed.", __FUNCTION__); for (i = 0; i < cpu_data->dcache.n_aliases; i++) - mutex_init(&p3map_mutex[i]); + sema_init(&p3map_sem[i], 1); } /* @@ -225,7 +229,7 @@ static inline void flush_cache_4096(unsigned long start, */ if ((cpu_data->flags & CPU_HAS_P2_FLUSH_BUG) || (start < CACHE_OC_ADDRESS_ARRAY)) - exec_offset = 0x20000000; + exec_offset = 0x20000000; local_irq_save(flags); __flush_cache_4096(start | SH_CACHE_ASSOC, @@ -246,7 +250,7 @@ void flush_dcache_page(struct page *page) /* Loop all the D-cache */ n = cpu_data->dcache.n_aliases; - for (i = 0; i < n; i++, addr += 4096) + for (i = 0; i < n; i++, addr += PAGE_SIZE) flush_cache_4096(addr, phys); } diff --git a/trunk/arch/sh/mm/clear_page.S b/trunk/arch/sh/mm/clear_page.S index 8a706131e521..7b96425ae270 100644 --- a/trunk/arch/sh/mm/clear_page.S +++ b/trunk/arch/sh/mm/clear_page.S @@ -1,12 +1,12 @@ -/* +/* $Id: clear_page.S,v 1.13 2003/08/25 17:03:10 lethal Exp $ + * * __clear_user_page, __clear_user, clear_page implementation of SuperH * * Copyright (C) 2001 Kaz Kojima * Copyright (C) 2001, 2002 Niibe Yutaka - * Copyright (C) 2006 Paul Mundt + * */ #include -#include /* * clear_page_slow @@ -18,11 +18,11 @@ /* * r0 --- scratch * r4 --- to - * r5 --- to + PAGE_SIZE + * r5 --- to + 4096 */ ENTRY(clear_page_slow) mov r4,r5 - mov.l .Llimit,r0 + mov.w .Llimit,r0 add r0,r5 mov #0,r0 ! @@ -50,7 +50,7 @@ ENTRY(clear_page_slow) ! rts nop -.Llimit: .long (PAGE_SIZE-28) +.Llimit: .word (4096-28) ENTRY(__clear_user) ! @@ -164,10 +164,10 @@ ENTRY(__clear_user) * r0 --- scratch * r4 --- to * r5 --- orig_to - * r6 --- to + PAGE_SIZE + * r6 --- to + 4096 */ ENTRY(__clear_user_page) - mov.l .Lpsz,r0 + mov.w .L4096,r0 mov r4,r6 add r0,r6 mov #0,r0 @@ -191,7 +191,7 @@ ENTRY(__clear_user_page) ! rts nop -.Lpsz: .long PAGE_SIZE +.L4096: .word 4096 #endif diff --git a/trunk/arch/sh/mm/copy_page.S b/trunk/arch/sh/mm/copy_page.S index 397c94c97315..1addffe117c3 100644 --- a/trunk/arch/sh/mm/copy_page.S +++ b/trunk/arch/sh/mm/copy_page.S @@ -1,12 +1,12 @@ -/* +/* $Id: copy_page.S,v 1.8 2003/08/25 17:03:10 lethal Exp $ + * * copy_page, __copy_user_page, __copy_user implementation of SuperH * * Copyright (C) 2001 Niibe Yutaka & Kaz Kojima * Copyright (C) 2002 Toshinobu Sugioka - * Copyright (C) 2006 Paul Mundt + * */ #include -#include /* * copy_page_slow @@ -18,7 +18,7 @@ /* * r0, r1, r2, r3, r4, r5, r6, r7 --- scratch - * r8 --- from + PAGE_SIZE + * r8 --- from + 4096 * r9 --- not used * r10 --- to * r11 --- from @@ -30,7 +30,7 @@ ENTRY(copy_page_slow) mov r4,r10 mov r5,r11 mov r5,r8 - mov.l .Lpsz,r0 + mov.w .L4096,r0 add r0,r8 ! 1: mov.l @r11+,r0 @@ -80,7 +80,7 @@ ENTRY(copy_page_slow) /* * r0, r1, r2, r3, r4, r5, r6, r7 --- scratch - * r8 --- from + PAGE_SIZE + * r8 --- from + 4096 * r9 --- orig_to * r10 --- to * r11 --- from @@ -94,7 +94,7 @@ ENTRY(__copy_user_page) mov r5,r11 mov r6,r9 mov r5,r8 - mov.l .Lpsz,r0 + mov.w .L4096,r0 add r0,r8 ! 1: ocbi @r9 @@ -129,7 +129,7 @@ ENTRY(__copy_user_page) rts nop #endif -.Lpsz: .long PAGE_SIZE +.L4096: .word 4096 /* * __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n); * Return the number of bytes NOT copied diff --git a/trunk/arch/sh/mm/fault.c b/trunk/arch/sh/mm/fault.c index 716ebf568af2..68663b8f99ae 100644 --- a/trunk/arch/sh/mm/fault.c +++ b/trunk/arch/sh/mm/fault.c @@ -26,19 +26,13 @@ extern void die(const char *,struct pt_regs *,long); * and the problem, and then passes it off to one of the appropriate * routines. */ -asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, - unsigned long writeaccess, - unsigned long address) +asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, + unsigned long address) { struct task_struct *tsk; struct mm_struct *mm; struct vm_area_struct * vma; unsigned long page; - int si_code; - siginfo_t info; - - trace_hardirqs_on(); - local_irq_enable(); #ifdef CONFIG_SH_KGDB if (kgdb_nofault && kgdb_bus_err_hook) @@ -47,46 +41,6 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, tsk = current; mm = tsk->mm; - si_code = SEGV_MAPERR; - - if (unlikely(address >= TASK_SIZE)) { - /* - * Synchronize this task's top level page-table - * with the 'reference' page table. - * - * Do _not_ use "tsk" here. We might be inside - * an interrupt in the middle of a task switch.. - */ - int offset = pgd_index(address); - pgd_t *pgd, *pgd_k; - pud_t *pud, *pud_k; - pmd_t *pmd, *pmd_k; - - pgd = get_TTB() + offset; - pgd_k = swapper_pg_dir + offset; - - /* This will never happen with the folded page table. */ - if (!pgd_present(*pgd)) { - if (!pgd_present(*pgd_k)) - goto bad_area_nosemaphore; - set_pgd(pgd, *pgd_k); - return; - } - - pud = pud_offset(pgd, address); - pud_k = pud_offset(pgd_k, address); - if (pud_present(*pud) || !pud_present(*pud_k)) - goto bad_area_nosemaphore; - set_pud(pud, *pud_k); - - pmd = pmd_offset(pud, address); - pmd_k = pmd_offset(pud_k, address); - if (pmd_present(*pmd) || !pmd_present(*pmd_k)) - goto bad_area_nosemaphore; - set_pmd(pmd, *pmd_k); - - return; - } /* * If we're in an interrupt or have no user @@ -111,7 +65,6 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, * we can handle it.. */ good_area: - si_code = SEGV_ACCERR; if (writeaccess) { if (!(vma->vm_flags & VM_WRITE)) goto bad_area; @@ -151,13 +104,10 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, bad_area: up_read(&mm->mmap_sem); -bad_area_nosemaphore: if (user_mode(regs)) { - info.si_signo = SIGSEGV; - info.si_errno = 0; - info.si_code = si_code; - info.si_addr = (void *) address; - force_sig_info(SIGSEGV, &info, tsk); + tsk->thread.address = address; + tsk->thread.error_code = writeaccess; + force_sig(SIGSEGV, tsk); return; } @@ -177,9 +127,11 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, printk(KERN_ALERT "Unable to handle kernel paging request"); printk(" at virtual address %08lx\n", address); printk(KERN_ALERT "pc = %08lx\n", regs->pc); - page = (unsigned long)get_TTB(); + asm volatile("mov.l %1, %0" + : "=r" (page) + : "m" (__m(MMU_TTB))); if (page) { - page = ((unsigned long *) page)[address >> PGDIR_SHIFT]; + page = ((unsigned long *) page)[address >> 22]; printk(KERN_ALERT "*pde = %08lx\n", page); if (page & _PAGE_PRESENT) { page &= PAGE_MASK; @@ -214,13 +166,98 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, * Send a sigbus, regardless of whether we were in kernel * or user mode. */ - info.si_signo = SIGBUS; - info.si_errno = 0; - info.si_code = BUS_ADRERR; - info.si_addr = (void *)address; - force_sig_info(SIGBUS, &info, tsk); + tsk->thread.address = address; + tsk->thread.error_code = writeaccess; + tsk->thread.trap_no = 14; + force_sig(SIGBUS, tsk); /* Kernel mode? Handle exceptions or die */ if (!user_mode(regs)) goto no_context; } + +#ifdef CONFIG_SH_STORE_QUEUES +/* + * This is a special case for the SH-4 store queues, as pages for this + * space still need to be faulted in before it's possible to flush the + * store queue cache for writeout to the remapped region. + */ +#define P3_ADDR_MAX (P4SEG_STORE_QUE + 0x04000000) +#else +#define P3_ADDR_MAX P4SEG +#endif + +/* + * Called with interrupts disabled. + */ +asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs, + unsigned long writeaccess, + unsigned long address) +{ + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *pte; + pte_t entry; + struct mm_struct *mm = current->mm; + spinlock_t *ptl; + int ret = 1; + +#ifdef CONFIG_SH_KGDB + if (kgdb_nofault && kgdb_bus_err_hook) + kgdb_bus_err_hook(); +#endif + + /* + * We don't take page faults for P1, P2, and parts of P4, these + * are always mapped, whether it be due to legacy behaviour in + * 29-bit mode, or due to PMB configuration in 32-bit mode. + */ + if (address >= P3SEG && address < P3_ADDR_MAX) { + pgd = pgd_offset_k(address); + mm = NULL; + } else { + if (unlikely(address >= TASK_SIZE || !mm)) + return 1; + + pgd = pgd_offset(mm, address); + } + + pud = pud_offset(pgd, address); + if (pud_none_or_clear_bad(pud)) + return 1; + pmd = pmd_offset(pud, address); + if (pmd_none_or_clear_bad(pmd)) + return 1; + + if (mm) + pte = pte_offset_map_lock(mm, pmd, address, &ptl); + else + pte = pte_offset_kernel(pmd, address); + + entry = *pte; + if (unlikely(pte_none(entry) || pte_not_present(entry))) + goto unlock; + if (unlikely(writeaccess && !pte_write(entry))) + goto unlock; + + if (writeaccess) + entry = pte_mkdirty(entry); + entry = pte_mkyoung(entry); + +#ifdef CONFIG_CPU_SH4 + /* + * ITLB is not affected by "ldtlb" instruction. + * So, we need to flush the entry by ourselves. + */ + __flush_tlb_page(get_asid(), address & PAGE_MASK); +#endif + + set_pte(pte, entry); + update_mmu_cache(NULL, address, entry); + ret = 0; +unlock: + if (mm) + pte_unmap_unlock(pte, ptl); + return ret; +} diff --git a/trunk/arch/sh/mm/init.c b/trunk/arch/sh/mm/init.c index 59f4cc18235b..7154d1ce9785 100644 --- a/trunk/arch/sh/mm/init.c +++ b/trunk/arch/sh/mm/init.c @@ -84,22 +84,30 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) pmd_t *pmd; pte_t *pte; - pgd = pgd_offset_k(addr); + pgd = swapper_pg_dir + pgd_index(addr); if (pgd_none(*pgd)) { pgd_ERROR(*pgd); return; } - pud = pud_alloc(NULL, pgd, addr); - if (unlikely(!pud)) { - pud_ERROR(*pud); - return; + pud = pud_offset(pgd, addr); + if (pud_none(*pud)) { + pmd = (pmd_t *)get_zeroed_page(GFP_ATOMIC); + set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER)); + if (pmd != pmd_offset(pud, 0)) { + pud_ERROR(*pud); + return; + } } - pmd = pmd_alloc(NULL, pud, addr); - if (unlikely(!pmd)) { - pmd_ERROR(*pmd); - return; + pmd = pmd_offset(pud, addr); + if (pmd_none(*pmd)) { + pte = (pte_t *)get_zeroed_page(GFP_ATOMIC); + set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER)); + if (pte != pte_offset_kernel(pmd, 0)) { + pmd_ERROR(*pmd); + return; + } } pte = pte_offset_kernel(pmd, addr); @@ -147,6 +155,9 @@ extern char __init_begin, __init_end; /* * paging_init() sets up the page tables + * + * This routines also unmaps the page at virtual kernel address 0, so + * that we can trap those pesky NULL-reference errors in the kernel. */ void __init paging_init(void) { @@ -169,11 +180,14 @@ void __init paging_init(void) */ { unsigned long max_dma, low, start_pfn; + pgd_t *pg_dir; + int i; + + /* We don't need kernel mapping as hardware support that. */ + pg_dir = swapper_pg_dir; - /* We don't need to map the kernel through the TLB, as - * it is permanatly mapped using P1. So clear the - * entire pgd. */ - memset(swapper_pg_dir, 0, sizeof(swapper_pg_dir)); + for (i = 0; i < PTRS_PER_PGD; i++) + pgd_val(pg_dir[i]) = 0; /* Turn on the MMU */ enable_mmu(); @@ -192,10 +206,6 @@ void __init paging_init(void) } } - /* Set an initial value for the MMU.TTB so we don't have to - * check for a null value. */ - set_TTB(swapper_pg_dir); - #elif defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4) /* * If we don't have CONFIG_MMU set and the processor in question @@ -217,6 +227,7 @@ static struct kcore_list kcore_mem, kcore_vmalloc; void __init mem_init(void) { + extern unsigned long empty_zero_page[1024]; int codesize, reservedpages, datasize, initsize; int tmp; extern unsigned long memory_start; diff --git a/trunk/arch/sh/mm/ioremap.c b/trunk/arch/sh/mm/ioremap.c index 11d54c149821..a9fe80cfc233 100644 --- a/trunk/arch/sh/mm/ioremap.c +++ b/trunk/arch/sh/mm/ioremap.c @@ -28,7 +28,9 @@ static inline void remap_area_pte(pte_t * pte, unsigned long address, { unsigned long end; unsigned long pfn; - pgprot_t pgprot = __pgprot(pgprot_val(PAGE_KERNEL_NOCACHE) | flags); + pgprot_t pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW | + _PAGE_DIRTY | _PAGE_ACCESSED | + _PAGE_HW_SHARED | _PAGE_FLAGS_HARD | flags); address &= ~PMD_MASK; end = address + size; diff --git a/trunk/arch/sh/mm/pg-dma.c b/trunk/arch/sh/mm/pg-dma.c index bb23679369d6..1406d2e348ca 100644 --- a/trunk/arch/sh/mm/pg-dma.c +++ b/trunk/arch/sh/mm/pg-dma.c @@ -39,6 +39,8 @@ static void copy_page_dma(void *to, void *from) static void clear_page_dma(void *to) { + extern unsigned long empty_zero_page[1024]; + /* * We get invoked quite early on, if the DMAC hasn't been initialized * yet, fall back on the slow manual implementation. diff --git a/trunk/arch/sh/mm/pg-sh4.c b/trunk/arch/sh/mm/pg-sh4.c index 3f98d2a4f936..07371ed7a313 100644 --- a/trunk/arch/sh/mm/pg-sh4.c +++ b/trunk/arch/sh/mm/pg-sh4.c @@ -6,12 +6,22 @@ * * Released under the terms of the GNU GPL v2.0. */ +#include +#include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include -extern struct mutex p3map_mutex[]; +extern struct semaphore p3map_sem[]; #define CACHE_ALIAS (cpu_data->dcache.alias_mask) @@ -27,6 +37,10 @@ void clear_user_page(void *to, unsigned long address, struct page *page) if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) clear_page(to); else { + pgprot_t pgprot = __pgprot(_PAGE_PRESENT | + _PAGE_RW | _PAGE_CACHABLE | + _PAGE_DIRTY | _PAGE_ACCESSED | + _PAGE_HW_SHARED | _PAGE_FLAGS_HARD); unsigned long phys_addr = PHYSADDR(to); unsigned long p3_addr = P3SEG + (address & CACHE_ALIAS); pgd_t *pgd = pgd_offset_k(p3_addr); @@ -36,8 +50,8 @@ void clear_user_page(void *to, unsigned long address, struct page *page) pte_t entry; unsigned long flags; - entry = pfn_pte(phys_addr >> PAGE_SHIFT, PAGE_KERNEL); - mutex_lock(&p3map_mutex[(address & CACHE_ALIAS)>>12]); + entry = pfn_pte(phys_addr >> PAGE_SHIFT, pgprot); + down(&p3map_sem[(address & CACHE_ALIAS)>>12]); set_pte(pte, entry); local_irq_save(flags); __flush_tlb_page(get_asid(), p3_addr); @@ -45,7 +59,7 @@ void clear_user_page(void *to, unsigned long address, struct page *page) update_mmu_cache(NULL, p3_addr, entry); __clear_user_page((void *)p3_addr, to); pte_clear(&init_mm, p3_addr, pte); - mutex_unlock(&p3map_mutex[(address & CACHE_ALIAS)>>12]); + up(&p3map_sem[(address & CACHE_ALIAS)>>12]); } } @@ -63,6 +77,10 @@ void copy_user_page(void *to, void *from, unsigned long address, if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) copy_page(to, from); else { + pgprot_t pgprot = __pgprot(_PAGE_PRESENT | + _PAGE_RW | _PAGE_CACHABLE | + _PAGE_DIRTY | _PAGE_ACCESSED | + _PAGE_HW_SHARED | _PAGE_FLAGS_HARD); unsigned long phys_addr = PHYSADDR(to); unsigned long p3_addr = P3SEG + (address & CACHE_ALIAS); pgd_t *pgd = pgd_offset_k(p3_addr); @@ -72,8 +90,8 @@ void copy_user_page(void *to, void *from, unsigned long address, pte_t entry; unsigned long flags; - entry = pfn_pte(phys_addr >> PAGE_SHIFT, PAGE_KERNEL); - mutex_lock(&p3map_mutex[(address & CACHE_ALIAS)>>12]); + entry = pfn_pte(phys_addr >> PAGE_SHIFT, pgprot); + down(&p3map_sem[(address & CACHE_ALIAS)>>12]); set_pte(pte, entry); local_irq_save(flags); __flush_tlb_page(get_asid(), p3_addr); @@ -81,7 +99,7 @@ void copy_user_page(void *to, void *from, unsigned long address, update_mmu_cache(NULL, p3_addr, entry); __copy_user_page((void *)p3_addr, from, to); pte_clear(&init_mm, p3_addr, pte); - mutex_unlock(&p3map_mutex[(address & CACHE_ALIAS)>>12]); + up(&p3map_sem[(address & CACHE_ALIAS)>>12]); } } @@ -104,3 +122,4 @@ inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t } return pte; } + diff --git a/trunk/arch/sh/tools/mach-types b/trunk/arch/sh/tools/mach-types index 0571755e9a84..ac57638977ee 100644 --- a/trunk/arch/sh/tools/mach-types +++ b/trunk/arch/sh/tools/mach-types @@ -30,5 +30,3 @@ 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/istallion.c b/trunk/drivers/char/istallion.c index bd9195e17956..ffdf9df1a67a 100644 --- a/trunk/drivers/char/istallion.c +++ b/trunk/drivers/char/istallion.c @@ -663,7 +663,7 @@ static int stli_initopen(stlibrd_t *brdp, stliport_t *portp); static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait); static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait); static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *filp); -static void stli_dohangup(struct work_struct *); +static void stli_dohangup(void *arg); static int stli_setport(stliport_t *portp); static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback); static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback); @@ -1990,9 +1990,9 @@ static void stli_start(struct tty_struct *tty) * aren't that time critical). */ -static void stli_dohangup(struct work_struct *ugly_api) +static void stli_dohangup(void *arg) { - stliport_t *portp = container_of(ugly_api, stliport_t, tqhangup); + stliport_t *portp = (stliport_t *) arg; if (portp->tty != NULL) { tty_hangup(portp->tty); } @@ -2898,7 +2898,7 @@ static int stli_initports(stlibrd_t *brdp) portp->baud_base = STL_BAUDBASE; portp->close_delay = STL_CLOSEDELAY; portp->closing_wait = 30 * HZ; - INIT_WORK(&portp->tqhangup, stli_dohangup); + INIT_WORK(&portp->tqhangup, stli_dohangup, portp); init_waitqueue_head(&portp->open_wait); init_waitqueue_head(&portp->close_wait); init_waitqueue_head(&portp->raw_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/riscom8.c b/trunk/drivers/char/riscom8.c index 722dd3e74185..5ab32b38f45a 100644 --- a/trunk/drivers/char/riscom8.c +++ b/trunk/drivers/char/riscom8.c @@ -1516,9 +1516,9 @@ static void rc_start(struct tty_struct * tty) * do_rc_hangup() -> tty->hangup() -> rc_hangup() * */ -static void do_rc_hangup(struct work_struct *ugly_api) +static void do_rc_hangup(void *private_) { - struct riscom_port *port = container_of(ugly_api, struct riscom_port, tqueue_hangup); + struct riscom_port *port = (struct riscom_port *) private_; struct tty_struct *tty; tty = port->tty; @@ -1567,9 +1567,9 @@ static void rc_set_termios(struct tty_struct * tty, struct termios * old_termios } } -static void do_softint(struct work_struct *ugly_api) +static void do_softint(void *private_) { - struct riscom_port *port = container_of(ugly_api, struct riscom_port, tqueue); + struct riscom_port *port = (struct riscom_port *) private_; struct tty_struct *tty; if(!(tty = port->tty)) @@ -1632,8 +1632,8 @@ static inline int rc_init_drivers(void) memset(rc_port, 0, sizeof(rc_port)); for (i = 0; i < RC_NPORT * RC_NBOARD; i++) { rc_port[i].magic = RISCOM8_MAGIC; - INIT_WORK(&rc_port[i].tqueue, do_softint); - INIT_WORK(&rc_port[i].tqueue_hangup, do_rc_hangup); + INIT_WORK(&rc_port[i].tqueue, do_softint, &rc_port[i]); + INIT_WORK(&rc_port[i].tqueue_hangup, do_rc_hangup, &rc_port[i]); rc_port[i].close_delay = 50 * HZ/100; rc_port[i].closing_wait = 3000 * HZ/100; init_waitqueue_head(&rc_port[i].open_wait); diff --git a/trunk/drivers/char/serial167.c b/trunk/drivers/char/serial167.c index 9ba13af234be..3af7f0958c5d 100644 --- a/trunk/drivers/char/serial167.c +++ b/trunk/drivers/char/serial167.c @@ -706,9 +706,9 @@ cd2401_rx_interrupt(int irq, void *dev_id) * had to poll every port to see if that port needed servicing. */ static void -do_softint(struct work_struct *ugly_api) +do_softint(void *private_) { - struct cyclades_port *info = container_of(ugly_api, struct cyclades_port, tqueue); + struct cyclades_port *info = (struct cyclades_port *) private_; struct tty_struct *tty; tty = info->tty; @@ -2273,7 +2273,7 @@ scrn[1] = '\0'; 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); /* info->session */ 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/stallion.c b/trunk/drivers/char/stallion.c index 5e2de62bce70..522e88e395cc 100644 --- a/trunk/drivers/char/stallion.c +++ b/trunk/drivers/char/stallion.c @@ -500,7 +500,7 @@ static int stl_echatintr(stlbrd_t *brdp); static int stl_echmcaintr(stlbrd_t *brdp); static int stl_echpciintr(stlbrd_t *brdp); static int stl_echpci64intr(stlbrd_t *brdp); -static void stl_offintr(struct work_struct *); +static void stl_offintr(void *private); static stlbrd_t *stl_allocbrd(void); static stlport_t *stl_getport(int brdnr, int panelnr, int portnr); @@ -2081,12 +2081,14 @@ static int stl_echpci64intr(stlbrd_t *brdp) /* * Service an off-level request for some channel. */ -static void stl_offintr(struct work_struct *work) +static void stl_offintr(void *private) { - stlport_t *portp = container_of(work, stlport_t, tqueue); + stlport_t *portp; struct tty_struct *tty; unsigned int oldsigs; + portp = private; + #ifdef DEBUG printk("stl_offintr(portp=%x)\n", (int) portp); #endif @@ -2154,7 +2156,7 @@ static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp) portp->baud_base = STL_BAUDBASE; portp->close_delay = STL_CLOSEDELAY; portp->closing_wait = 30 * HZ; - INIT_WORK(&portp->tqueue, stl_offintr); + INIT_WORK(&portp->tqueue, stl_offintr, portp); init_waitqueue_head(&portp->open_wait); init_waitqueue_head(&portp->close_wait); portp->stats.brd = portp->brdnr; 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/i2c/chips/m41t00.c b/trunk/drivers/i2c/chips/m41t00.c index 420377c86422..2dd0a34d9472 100644 --- a/trunk/drivers/i2c/chips/m41t00.c +++ b/trunk/drivers/i2c/chips/m41t00.c @@ -215,15 +215,8 @@ m41t00_set(void *arg) } static ulong new_time; -/* well, isn't this API just _lovely_? */ -static void -m41t00_barf(struct work_struct *unusable) -{ - m41t00_set(&new_time); -} - static struct workqueue_struct *m41t00_wq; -static DECLARE_WORK(m41t00_work, m41t00_barf); +static DECLARE_WORK(m41t00_work, m41t00_set, &new_time); int m41t00_set_rtc_time(ulong nowtime) 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/hysdn/boardergo.c b/trunk/drivers/isdn/hysdn/boardergo.c index a1206498a1cf..82e42a80dc4b 100644 --- a/trunk/drivers/isdn/hysdn/boardergo.c +++ b/trunk/drivers/isdn/hysdn/boardergo.c @@ -71,9 +71,8 @@ ergo_interrupt(int intno, void *dev_id) /* may be queued from everywhere (interrupts included). */ /******************************************************************************/ static void -ergo_irq_bh(struct work_struct *ugli_api) +ergo_irq_bh(hysdn_card * card) { - hysdn_card * card = container_of(ugli_api, hysdn_card, irq_queue); tErgDpram *dpr; int again; unsigned long flags; @@ -443,7 +442,7 @@ ergo_inithardware(hysdn_card * card) card->writebootseq = ergo_writebootseq; card->waitpofready = ergo_waitpofready; card->set_errlog_state = ergo_set_errlog_state; - INIT_WORK(&card->irq_queue, ergo_irq_bh); + INIT_WORK(&card->irq_queue, (void *) (void *) ergo_irq_bh, card); card->hysdn_lock = SPIN_LOCK_UNLOCKED; return (0); 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/adb.c b/trunk/drivers/macintosh/adb.c index d43ea81d6df9..be0bd34ff6f9 100644 --- a/trunk/drivers/macintosh/adb.c +++ b/trunk/drivers/macintosh/adb.c @@ -267,12 +267,12 @@ adb_probe_task(void *x) } static void -__adb_probe_task(struct work_struct *bullshit) +__adb_probe_task(void *data) { adb_probe_task_pid = kernel_thread(adb_probe_task, NULL, SIGCHLD | CLONE_KERNEL); } -static DECLARE_WORK(adb_reset_work, __adb_probe_task); +static DECLARE_WORK(adb_reset_work, __adb_probe_task, NULL); int adb_reset_bus(void) 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/3c501.c b/trunk/drivers/net/3c501.c index 06e33786078d..11d170afa9c3 100644 --- a/trunk/drivers/net/3c501.c +++ b/trunk/drivers/net/3c501.c @@ -922,7 +922,7 @@ int __init init_module(void) * and then free up the resources we took when the card was found. */ -void __exit cleanup_module(void) +void cleanup_module(void) { struct net_device *dev = dev_3c501; unregister_netdev(dev); diff --git a/trunk/drivers/net/3c503.c b/trunk/drivers/net/3c503.c index 7e34c4f07b70..a34b2206132d 100644 --- a/trunk/drivers/net/3c503.c +++ b/trunk/drivers/net/3c503.c @@ -726,7 +726,7 @@ static void cleanup_card(struct net_device *dev) iounmap(ei_status.mem); } -void __exit +void cleanup_module(void) { int this_dev; diff --git a/trunk/drivers/net/3c505.c b/trunk/drivers/net/3c505.c index 702bfb2a5e99..458cb9cbe915 100644 --- a/trunk/drivers/net/3c505.c +++ b/trunk/drivers/net/3c505.c @@ -1670,7 +1670,7 @@ int __init init_module(void) return 0; } -void __exit cleanup_module(void) +void cleanup_module(void) { int this_dev; diff --git a/trunk/drivers/net/3c507.c b/trunk/drivers/net/3c507.c index 54e1d5aebed3..aa43563610ae 100644 --- a/trunk/drivers/net/3c507.c +++ b/trunk/drivers/net/3c507.c @@ -940,7 +940,7 @@ int __init init_module(void) return IS_ERR(dev_3c507) ? PTR_ERR(dev_3c507) : 0; } -void __exit +void cleanup_module(void) { struct net_device *dev = dev_3c507; diff --git a/trunk/drivers/net/3c523.c b/trunk/drivers/net/3c523.c index 17d61eb0a7e5..91849469b4f4 100644 --- a/trunk/drivers/net/3c523.c +++ b/trunk/drivers/net/3c523.c @@ -1302,7 +1302,7 @@ int __init init_module(void) } else return 0; } -void __exit cleanup_module(void) +void cleanup_module(void) { int this_dev; for (this_dev=0; this_devlock); 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/ac3200.c b/trunk/drivers/net/ac3200.c index c01f87f5bed7..0dca8bb9d2c7 100644 --- a/trunk/drivers/net/ac3200.c +++ b/trunk/drivers/net/ac3200.c @@ -405,7 +405,7 @@ static void cleanup_card(struct net_device *dev) iounmap(ei_status.mem); } -void __exit +void cleanup_module(void) { int this_dev; diff --git a/trunk/drivers/net/apne.c b/trunk/drivers/net/apne.c index d4e408169073..9164d8cd670e 100644 --- a/trunk/drivers/net/apne.c +++ b/trunk/drivers/net/apne.c @@ -568,7 +568,7 @@ static irqreturn_t apne_interrupt(int irq, void *dev_id) #ifdef MODULE static struct net_device *apne_dev; -int __init init_module(void) +int init_module(void) { apne_dev = apne_probe(-1); if (IS_ERR(apne_dev)) @@ -576,7 +576,7 @@ int __init init_module(void) return 0; } -void __exit cleanup_module(void) +void cleanup_module(void) { unregister_netdev(apne_dev); diff --git a/trunk/drivers/net/appletalk/cops.c b/trunk/drivers/net/appletalk/cops.c index dba5e5165452..cc1a27ed197f 100644 --- a/trunk/drivers/net/appletalk/cops.c +++ b/trunk/drivers/net/appletalk/cops.c @@ -1041,7 +1041,7 @@ int __init init_module(void) return 0; } -void __exit cleanup_module(void) +void cleanup_module(void) { unregister_netdev(cops_dev); cleanup_card(cops_dev); diff --git a/trunk/drivers/net/arm/at91_ether.c b/trunk/drivers/net/arm/at91_ether.c index fada15d959de..b54b857e357e 100644 --- a/trunk/drivers/net/arm/at91_ether.c +++ b/trunk/drivers/net/arm/at91_ether.c @@ -41,6 +41,9 @@ #define DRV_NAME "at91_ether" #define DRV_VERSION "1.0" +static struct net_device *at91_dev; + +static struct timer_list check_timer; #define LINK_POLL_INTERVAL (HZ) /* ..................................................................... */ @@ -143,7 +146,7 @@ static void read_phy(unsigned char phy_addr, unsigned char address, unsigned int */ static void update_linkspeed(struct net_device *dev, int silent) { - struct at91_private *lp = netdev_priv(dev); + struct at91_private *lp = (struct at91_private *) dev->priv; unsigned int bmsr, bmcr, lpa, mac_cfg; unsigned int speed, duplex; @@ -196,7 +199,7 @@ static void update_linkspeed(struct net_device *dev, int silent) static irqreturn_t at91ether_phy_interrupt(int irq, void *dev_id) { struct net_device *dev = (struct net_device *) dev_id; - struct at91_private *lp = netdev_priv(dev); + struct at91_private *lp = (struct at91_private *) dev->priv; unsigned int phy; /* @@ -239,7 +242,7 @@ static irqreturn_t at91ether_phy_interrupt(int irq, void *dev_id) */ static void enable_phyirq(struct net_device *dev) { - struct at91_private *lp = netdev_priv(dev); + struct at91_private *lp = (struct at91_private *) dev->priv; unsigned int dsintr, irq_number; int status; @@ -249,7 +252,8 @@ static void enable_phyirq(struct net_device *dev) * PHY doesn't have an IRQ pin (RTL8201, DP83847, AC101L), * or board does not have it connected. */ - mod_timer(&lp->check_timer, jiffies + LINK_POLL_INTERVAL); + check_timer.expires = jiffies + LINK_POLL_INTERVAL; + add_timer(&check_timer); return; } @@ -290,13 +294,13 @@ static void enable_phyirq(struct net_device *dev) */ static void disable_phyirq(struct net_device *dev) { - struct at91_private *lp = netdev_priv(dev); + struct at91_private *lp = (struct at91_private *) dev->priv; unsigned int dsintr; unsigned int irq_number; irq_number = lp->board_data.phy_irq_pin; if (!irq_number) { - del_timer_sync(&lp->check_timer); + del_timer_sync(&check_timer); return; } @@ -336,7 +340,7 @@ static void disable_phyirq(struct net_device *dev) #if 0 static void reset_phy(struct net_device *dev) { - struct at91_private *lp = netdev_priv(dev); + struct at91_private *lp = (struct at91_private *) dev->priv; unsigned int bmcr; spin_lock_irq(&lp->lock); @@ -358,13 +362,13 @@ static void reset_phy(struct net_device *dev) static void at91ether_check_link(unsigned long dev_id) { struct net_device *dev = (struct net_device *) dev_id; - struct at91_private *lp = netdev_priv(dev); enable_mdi(); update_linkspeed(dev, 1); disable_mdi(); - mod_timer(&lp->check_timer, jiffies + LINK_POLL_INTERVAL); + check_timer.expires = jiffies + LINK_POLL_INTERVAL; + add_timer(&check_timer); } /* ......................... ADDRESS MANAGEMENT ........................ */ @@ -586,7 +590,7 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val static int at91ether_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { - struct at91_private *lp = netdev_priv(dev); + struct at91_private *lp = (struct at91_private *) dev->priv; int ret; spin_lock_irq(&lp->lock); @@ -607,7 +611,7 @@ static int at91ether_get_settings(struct net_device *dev, struct ethtool_cmd *cm static int at91ether_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { - struct at91_private *lp = netdev_priv(dev); + struct at91_private *lp = (struct at91_private *) dev->priv; int ret; spin_lock_irq(&lp->lock); @@ -623,7 +627,7 @@ static int at91ether_set_settings(struct net_device *dev, struct ethtool_cmd *cm static int at91ether_nwayreset(struct net_device *dev) { - struct at91_private *lp = netdev_priv(dev); + struct at91_private *lp = (struct at91_private *) dev->priv; int ret; spin_lock_irq(&lp->lock); @@ -654,7 +658,7 @@ static const struct ethtool_ops at91ether_ethtool_ops = { static int at91ether_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - struct at91_private *lp = netdev_priv(dev); + struct at91_private *lp = (struct at91_private *) dev->priv; int res; if (!netif_running(dev)) @@ -676,7 +680,7 @@ static int at91ether_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) */ static void at91ether_start(struct net_device *dev) { - struct at91_private *lp = netdev_priv(dev); + struct at91_private *lp = (struct at91_private *) dev->priv; struct recv_desc_bufs *dlist, *dlist_phys; int i; unsigned long ctl; @@ -708,7 +712,7 @@ static void at91ether_start(struct net_device *dev) */ static int at91ether_open(struct net_device *dev) { - struct at91_private *lp = netdev_priv(dev); + struct at91_private *lp = (struct at91_private *) dev->priv; unsigned long ctl; if (!is_valid_ether_addr(dev->dev_addr)) @@ -748,7 +752,7 @@ static int at91ether_open(struct net_device *dev) */ static int at91ether_close(struct net_device *dev) { - struct at91_private *lp = netdev_priv(dev); + struct at91_private *lp = (struct at91_private *) dev->priv; unsigned long ctl; /* Disable Receiver and Transmitter */ @@ -775,7 +779,7 @@ static int at91ether_close(struct net_device *dev) */ static int at91ether_tx(struct sk_buff *skb, struct net_device *dev) { - struct at91_private *lp = netdev_priv(dev); + struct at91_private *lp = (struct at91_private *) dev->priv; if (at91_emac_read(AT91_EMAC_TSR) & AT91_EMAC_TSR_BNQ) { netif_stop_queue(dev); @@ -807,7 +811,7 @@ static int at91ether_tx(struct sk_buff *skb, struct net_device *dev) */ static struct net_device_stats *at91ether_stats(struct net_device *dev) { - struct at91_private *lp = netdev_priv(dev); + struct at91_private *lp = (struct at91_private *) dev->priv; int ale, lenerr, seqe, lcol, ecol; if (netif_running(dev)) { @@ -843,7 +847,7 @@ static struct net_device_stats *at91ether_stats(struct net_device *dev) */ static void at91ether_rx(struct net_device *dev) { - struct at91_private *lp = netdev_priv(dev); + struct at91_private *lp = (struct at91_private *) dev->priv; struct recv_desc_bufs *dlist; unsigned char *p_recv; struct sk_buff *skb; @@ -853,13 +857,14 @@ static void at91ether_rx(struct net_device *dev) while (dlist->descriptors[lp->rxBuffIndex].addr & EMAC_DESC_DONE) { p_recv = dlist->recv_buf[lp->rxBuffIndex]; pktlen = dlist->descriptors[lp->rxBuffIndex].size & 0x7ff; /* Length of frame including FCS */ - skb = dev_alloc_skb(pktlen + 2); + skb = alloc_skb(pktlen + 2, GFP_ATOMIC); if (skb != NULL) { skb_reserve(skb, 2); memcpy(skb_put(skb, pktlen), p_recv, pktlen); skb->dev = dev; skb->protocol = eth_type_trans(skb, dev); + skb->len = pktlen; dev->last_rx = jiffies; lp->stats.rx_bytes += pktlen; netif_rx(skb); @@ -886,7 +891,7 @@ static void at91ether_rx(struct net_device *dev) static irqreturn_t at91ether_interrupt(int irq, void *dev_id) { struct net_device *dev = (struct net_device *) dev_id; - struct at91_private *lp = netdev_priv(dev); + struct at91_private *lp = (struct at91_private *) dev->priv; unsigned long intstatus, ctl; /* MAC Interrupt Status register indicates what interrupts are pending. @@ -922,17 +927,6 @@ static irqreturn_t at91ether_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -#ifdef CONFIG_NET_POLL_CONTROLLER -static void at91ether_poll_controller(struct net_device *dev) -{ - unsigned long flags; - - local_irq_save(flags); - at91ether_interrupt(dev->irq, dev); - local_irq_restore(flags); -} -#endif - /* * Initialize the ethernet interface */ @@ -945,6 +939,9 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add unsigned int val; int res; + if (at91_dev) /* already initialized */ + return 0; + dev = alloc_etherdev(sizeof(struct at91_private)); if (!dev) return -ENOMEM; @@ -960,7 +957,7 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add } /* Allocate memory for DMA Receive descriptors */ - lp = netdev_priv(dev); + lp = (struct at91_private *)dev->priv; lp->dlist = (struct recv_desc_bufs *) dma_alloc_coherent(NULL, sizeof(struct recv_desc_bufs), (dma_addr_t *) &lp->dlist_phys, GFP_KERNEL); if (lp->dlist == NULL) { free_irq(dev->irq, dev); @@ -982,9 +979,6 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add dev->set_mac_address = set_mac_address; dev->ethtool_ops = &at91ether_ethtool_ops; dev->do_ioctl = at91ether_ioctl; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = at91ether_poll_controller; -#endif SET_NETDEV_DEV(dev, &pdev->dev); @@ -1030,6 +1024,7 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add dma_free_coherent(NULL, sizeof(struct recv_desc_bufs), lp->dlist, (dma_addr_t)lp->dlist_phys); return res; } + at91_dev = dev; /* Determine current link speed */ spin_lock_irq(&lp->lock); @@ -1041,9 +1036,9 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add /* If board has no PHY IRQ, use a timer to poll the PHY */ if (!lp->board_data.phy_irq_pin) { - init_timer(&lp->check_timer); - lp->check_timer.data = (unsigned long)dev; - lp->check_timer.function = at91ether_check_link; + init_timer(&check_timer); + check_timer.data = (unsigned long)dev; + check_timer.function = at91ether_check_link; } /* Display ethernet banner */ @@ -1120,16 +1115,15 @@ static int __init at91ether_probe(struct platform_device *pdev) static int __devexit at91ether_remove(struct platform_device *pdev) { - struct net_device *dev = platform_get_drvdata(pdev); - struct at91_private *lp = netdev_priv(dev); + struct at91_private *lp = (struct at91_private *) at91_dev->priv; - unregister_netdev(dev); - free_irq(dev->irq, dev); + unregister_netdev(at91_dev); + free_irq(at91_dev->irq, at91_dev); dma_free_coherent(NULL, sizeof(struct recv_desc_bufs), lp->dlist, (dma_addr_t)lp->dlist_phys); clk_put(lp->ether_clk); - platform_set_drvdata(pdev, NULL); - free_netdev(dev); + free_netdev(at91_dev); + at91_dev = NULL; return 0; } @@ -1137,8 +1131,8 @@ static int __devexit at91ether_remove(struct platform_device *pdev) static int at91ether_suspend(struct platform_device *pdev, pm_message_t mesg) { + struct at91_private *lp = (struct at91_private *) at91_dev->priv; struct net_device *net_dev = platform_get_drvdata(pdev); - struct at91_private *lp = netdev_priv(net_dev); int phy_irq = lp->board_data.phy_irq_pin; if (netif_running(net_dev)) { @@ -1155,8 +1149,8 @@ static int at91ether_suspend(struct platform_device *pdev, pm_message_t mesg) static int at91ether_resume(struct platform_device *pdev) { + struct at91_private *lp = (struct at91_private *) at91_dev->priv; struct net_device *net_dev = platform_get_drvdata(pdev); - struct at91_private *lp = netdev_priv(net_dev); int phy_irq = lp->board_data.phy_irq_pin; if (netif_running(net_dev)) { diff --git a/trunk/drivers/net/arm/at91_ether.h b/trunk/drivers/net/arm/at91_ether.h index b6b665de2ea0..d1e72e02be3a 100644 --- a/trunk/drivers/net/arm/at91_ether.h +++ b/trunk/drivers/net/arm/at91_ether.h @@ -87,7 +87,6 @@ struct at91_private spinlock_t lock; /* lock for MDI interface */ short phy_media; /* media interface type */ unsigned short phy_address; /* 5-bit MDI address of PHY (0..31) */ - struct timer_list check_timer; /* Poll link status */ /* Transmit */ struct sk_buff *skb; /* holds skb until xmit interrupt completes */ diff --git a/trunk/drivers/net/arm/ether1.c b/trunk/drivers/net/arm/ether1.c index d6da3ce9ad79..f3478a30e778 100644 --- a/trunk/drivers/net/arm/ether1.c +++ b/trunk/drivers/net/arm/ether1.c @@ -254,7 +254,7 @@ ether1_readbuffer (struct net_device *dev, void *data, unsigned int start, unsig } while (thislen); } -static int __devinit +static int __init ether1_ramtest(struct net_device *dev, unsigned char byte) { unsigned char *buffer = kmalloc (BUFFER_SIZE, GFP_KERNEL); @@ -308,7 +308,7 @@ ether1_reset (struct net_device *dev) return BUS_16; } -static int __devinit +static int __init ether1_init_2(struct net_device *dev) { int i; @@ -986,7 +986,7 @@ ether1_setmulticastlist (struct net_device *dev) /* ------------------------------------------------------------------------- */ -static void __devinit ether1_banner(void) +static void __init ether1_banner(void) { static unsigned int version_printed = 0; diff --git a/trunk/drivers/net/arm/ether3.c b/trunk/drivers/net/arm/ether3.c index 4fc234785d56..84686c8a5bc2 100644 --- a/trunk/drivers/net/arm/ether3.c +++ b/trunk/drivers/net/arm/ether3.c @@ -198,7 +198,7 @@ static inline void ether3_ledon(struct net_device *dev) * Read the ethernet address string from the on board rom. * This is an ascii string!!! */ -static int __devinit +static int __init ether3_addr(char *addr, struct expansion_card *ec) { struct in_chunk_dir cd; @@ -223,7 +223,7 @@ ether3_addr(char *addr, struct expansion_card *ec) /* --------------------------------------------------------------------------- */ -static int __devinit +static int __init ether3_ramtest(struct net_device *dev, unsigned char byte) { unsigned char *buffer = kmalloc(RX_END, GFP_KERNEL); @@ -272,7 +272,7 @@ ether3_ramtest(struct net_device *dev, unsigned char byte) /* ------------------------------------------------------------------------------- */ -static int __devinit ether3_init_2(struct net_device *dev) +static int __init ether3_init_2(struct net_device *dev) { int i; @@ -765,7 +765,7 @@ static void ether3_tx(struct net_device *dev) } } -static void __devinit ether3_banner(void) +static void __init ether3_banner(void) { static unsigned version_printed = 0; diff --git a/trunk/drivers/net/at1700.c b/trunk/drivers/net/at1700.c index 56ae8babd919..8620a5b470f5 100644 --- a/trunk/drivers/net/at1700.c +++ b/trunk/drivers/net/at1700.c @@ -908,7 +908,7 @@ int __init init_module(void) return 0; } -void __exit +void cleanup_module(void) { unregister_netdev(dev_at1700); diff --git a/trunk/drivers/net/atarilance.c b/trunk/drivers/net/atarilance.c index 7e37ac86a69a..d79489e46249 100644 --- a/trunk/drivers/net/atarilance.c +++ b/trunk/drivers/net/atarilance.c @@ -1179,7 +1179,7 @@ static int lance_set_mac_address( struct net_device *dev, void *addr ) #ifdef MODULE static struct net_device *atarilance_dev; -int __init init_module(void) +int init_module(void) { atarilance_dev = atarilance_probe(-1); if (IS_ERR(atarilance_dev)) @@ -1187,7 +1187,7 @@ int __init init_module(void) return 0; } -void __exit cleanup_module(void) +void cleanup_module(void) { unregister_netdev(atarilance_dev); free_irq(atarilance_dev->irq, atarilance_dev); 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/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c index 6482aed4bb7c..488d8ed9e740 100644 --- a/trunk/drivers/net/bonding/bond_main.c +++ b/trunk/drivers/net/bonding/bond_main.c @@ -3684,7 +3684,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd mii->val_out = 0; read_lock_bh(&bond->lock); read_lock(&bond->curr_slave_lock); - if (netif_carrier_ok(bond->dev)) { + if (bond->curr_active_slave) { mii->val_out = BMSR_LSTATUS; } read_unlock(&bond->curr_slave_lock); 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/cs89x0.c b/trunk/drivers/net/cs89x0.c index 4612f71a7106..dec70c2b374a 100644 --- a/trunk/drivers/net/cs89x0.c +++ b/trunk/drivers/net/cs89x0.c @@ -1974,7 +1974,7 @@ int __init init_module(void) return ret; } -void __exit +void cleanup_module(void) { unregister_netdev(dev_cs89x0); diff --git a/trunk/drivers/net/declance.c b/trunk/drivers/net/declance.c index 4ae0fed7122e..00e2a8a134d7 100644 --- a/trunk/drivers/net/declance.c +++ b/trunk/drivers/net/declance.c @@ -40,10 +40,6 @@ * * v0.009: Module support fixes, multiple interfaces support, various * bits. macro - * - * v0.010: Fixes for the PMAD mapping of the LANCE buffer and for the - * PMAX requirement to only use halfword accesses to the - * buffer. macro */ #include @@ -58,7 +54,6 @@ #include #include #include -#include #include #include @@ -72,7 +67,7 @@ #include static char version[] __devinitdata = -"declance.c: v0.010 by Linux MIPS DECstation task force\n"; +"declance.c: v0.009 by Linux MIPS DECstation task force\n"; MODULE_AUTHOR("Linux MIPS DECstation task force"); MODULE_DESCRIPTION("DEC LANCE (DECstation onboard, PMAD-xx) driver"); @@ -115,25 +110,24 @@ MODULE_LICENSE("GPL"); #define LE_C3_BCON 0x1 /* Byte control */ /* Receive message descriptor 1 */ -#define LE_R1_OWN 0x8000 /* Who owns the entry */ -#define LE_R1_ERR 0x4000 /* Error: if FRA, OFL, CRC or BUF is set */ -#define LE_R1_FRA 0x2000 /* FRA: Frame error */ -#define LE_R1_OFL 0x1000 /* OFL: Frame overflow */ -#define LE_R1_CRC 0x0800 /* CRC error */ -#define LE_R1_BUF 0x0400 /* BUF: Buffer error */ -#define LE_R1_SOP 0x0200 /* Start of packet */ -#define LE_R1_EOP 0x0100 /* End of packet */ -#define LE_R1_POK 0x0300 /* Packet is complete: SOP + EOP */ - -/* Transmit message descriptor 1 */ -#define LE_T1_OWN 0x8000 /* Lance owns the packet */ -#define LE_T1_ERR 0x4000 /* Error summary */ -#define LE_T1_EMORE 0x1000 /* Error: more than one retry needed */ -#define LE_T1_EONE 0x0800 /* Error: one retry needed */ -#define LE_T1_EDEF 0x0400 /* Error: deferred */ -#define LE_T1_SOP 0x0200 /* Start of packet */ -#define LE_T1_EOP 0x0100 /* End of packet */ -#define LE_T1_POK 0x0300 /* Packet is complete: SOP + EOP */ +#define LE_R1_OWN 0x80 /* Who owns the entry */ +#define LE_R1_ERR 0x40 /* Error: if FRA, OFL, CRC or BUF is set */ +#define LE_R1_FRA 0x20 /* FRA: Frame error */ +#define LE_R1_OFL 0x10 /* OFL: Frame overflow */ +#define LE_R1_CRC 0x08 /* CRC error */ +#define LE_R1_BUF 0x04 /* BUF: Buffer error */ +#define LE_R1_SOP 0x02 /* Start of packet */ +#define LE_R1_EOP 0x01 /* End of packet */ +#define LE_R1_POK 0x03 /* Packet is complete: SOP + EOP */ + +#define LE_T1_OWN 0x80 /* Lance owns the packet */ +#define LE_T1_ERR 0x40 /* Error summary */ +#define LE_T1_EMORE 0x10 /* Error: more than one retry needed */ +#define LE_T1_EONE 0x08 /* Error: one retry needed */ +#define LE_T1_EDEF 0x04 /* Error: deferred */ +#define LE_T1_SOP 0x02 /* Start of packet */ +#define LE_T1_EOP 0x01 /* End of packet */ +#define LE_T1_POK 0x03 /* Packet is complete: SOP + EOP */ #define LE_T3_BUF 0x8000 /* Buffer error */ #define LE_T3_UFL 0x4000 /* Error underflow */ @@ -162,57 +156,69 @@ MODULE_LICENSE("GPL"); #undef TEST_HITS #define ZERO 0 -/* - * The DS2100/3100 have a linear 64 kB buffer which supports halfword - * accesses only. Each halfword of the buffer is word-aligned in the - * CPU address space. - * - * The PMAD-AA has a 128 kB buffer on-board. +/* The DS2000/3000 have a linear 64 KB buffer. + + * The PMAD-AA has 128 kb buffer on-board. * - * The IOASIC LANCE devices use a shared memory region. This region - * as seen from the CPU is (max) 128 kB long and has to be on an 128 kB - * boundary. The LANCE sees this as a 64 kB long continuous memory - * region. + * The IOASIC LANCE devices use a shared memory region. This region as seen + * from the CPU is (max) 128 KB long and has to be on an 128 KB boundary. + * The LANCE sees this as a 64 KB long continuous memory region. * - * The LANCE's DMA address is used as an index in this buffer and DMA - * takes place in bursts of eight 16-bit words which are packed into - * four 32-bit words by the IOASIC. This leads to a strange padding: - * 16 bytes of valid data followed by a 16 byte gap :-(. + * The LANCE's DMA address is used as an index in this buffer and DMA takes + * place in bursts of eight 16-Bit words which are packed into four 32-Bit words + * by the IOASIC. This leads to a strange padding: 16 bytes of valid data followed + * by a 16 byte gap :-(. */ struct lance_rx_desc { unsigned short rmd0; /* low address of packet */ - unsigned short rmd1; /* high address of packet - and descriptor bits */ + short gap0; + unsigned char rmd1_hadr; /* high address of packet */ + unsigned char rmd1_bits; /* descriptor bits */ + short gap1; short length; /* 2s complement (negative!) of buffer length */ + short gap2; unsigned short mblength; /* actual number of bytes received */ + short gap3; }; struct lance_tx_desc { unsigned short tmd0; /* low address of packet */ - unsigned short tmd1; /* high address of packet - and descriptor bits */ + short gap0; + unsigned char tmd1_hadr; /* high address of packet */ + unsigned char tmd1_bits; /* descriptor bits */ + short gap1; short length; /* 2s complement (negative!) of buffer length */ + short gap2; unsigned short misc; + short gap3; }; /* First part of the LANCE initialization block, described in databook. */ struct lance_init_block { unsigned short mode; /* pre-set mode (reg. 15) */ + short gap0; - unsigned short phys_addr[3]; /* physical ethernet address */ - unsigned short filter[4]; /* multicast filter */ + unsigned char phys_addr[12]; /* physical ethernet address + only 0, 1, 4, 5, 8, 9 are valid + 2, 3, 6, 7, 10, 11 are gaps */ + unsigned short filter[8]; /* multicast filter + only 0, 2, 4, 6 are valid + 1, 3, 5, 7 are gaps */ /* Receive and transmit ring base, along with extra bits. */ unsigned short rx_ptr; /* receive descriptor addr */ + short gap1; unsigned short rx_len; /* receive len and high addr */ + short gap2; unsigned short tx_ptr; /* transmit descriptor addr */ + short gap3; unsigned short tx_len; /* transmit len and high addr */ - - short gap[4]; + short gap4; + short gap5[8]; /* The buffer descriptors */ struct lance_rx_desc brx_ring[RX_RING_SIZE]; @@ -220,28 +226,15 @@ struct lance_init_block { }; #define BUF_OFFSET_CPU sizeof(struct lance_init_block) -#define BUF_OFFSET_LNC sizeof(struct lance_init_block) - -#define shift_off(off, type) \ - (type == ASIC_LANCE || type == PMAX_LANCE ? off << 1 : off) - -#define lib_off(rt, type) \ - shift_off(offsetof(struct lance_init_block, rt), type) - -#define lib_ptr(ib, rt, type) \ - ((volatile u16 *)((u8 *)(ib) + lib_off(rt, type))) - -#define rds_off(rt, type) \ - shift_off(offsetof(struct lance_rx_desc, rt), type) +#define BUF_OFFSET_LNC (sizeof(struct lance_init_block)>>1) -#define rds_ptr(rd, rt, type) \ - ((volatile u16 *)((u8 *)(rd) + rds_off(rt, type))) +#define libdesc_offset(rt, elem) \ +((__u32)(((unsigned long)(&(((struct lance_init_block *)0)->rt[elem]))))) -#define tds_off(rt, type) \ - shift_off(offsetof(struct lance_tx_desc, rt), type) - -#define tds_ptr(td, rt, type) \ - ((volatile u16 *)((u8 *)(td) + tds_off(rt, type))) +/* + * This works *only* for the ring descriptors + */ +#define LANCE_ADDR(x) (CPHYSADDR(x) >> 1) struct lance_private { struct net_device *next; @@ -249,6 +242,7 @@ struct lance_private { int slot; int dma_irq; volatile struct lance_regs *ll; + volatile struct lance_init_block *init_block; spinlock_t lock; @@ -266,8 +260,8 @@ struct lance_private { char *tx_buf_ptr_cpu[TX_RING_SIZE]; /* Pointers to the ring buffers as seen from the LANCE */ - uint rx_buf_ptr_lnc[RX_RING_SIZE]; - uint tx_buf_ptr_lnc[TX_RING_SIZE]; + char *rx_buf_ptr_lnc[RX_RING_SIZE]; + char *tx_buf_ptr_lnc[TX_RING_SIZE]; }; #define TX_BUFFS_AVAIL ((lp->tx_old<=lp->tx_new)?\ @@ -300,7 +294,7 @@ static inline void writereg(volatile unsigned short *regptr, short value) static void load_csrs(struct lance_private *lp) { volatile struct lance_regs *ll = lp->ll; - uint leptr; + int leptr; /* The address space as seen from the LANCE * begins at address 0. HK @@ -322,14 +316,12 @@ static void load_csrs(struct lance_private *lp) * Our specialized copy routines * */ -static void cp_to_buf(const int type, void *to, const void *from, int len) +void cp_to_buf(const int type, void *to, const void *from, int len) { unsigned short *tp, *fp, clen; unsigned char *rtp, *rfp; - if (type == PMAD_LANCE) { - memcpy(to, from, len); - } else if (type == PMAX_LANCE) { + if (type == PMAX_LANCE) { clen = len >> 1; tp = (unsigned short *) to; fp = (unsigned short *) from; @@ -378,14 +370,12 @@ static void cp_to_buf(const int type, void *to, const void *from, int len) iob(); } -static void cp_from_buf(const int type, void *to, const void *from, int len) +void cp_from_buf(const int type, void *to, const void *from, int len) { unsigned short *tp, *fp, clen; unsigned char *rtp, *rfp; - if (type == PMAD_LANCE) { - memcpy(to, from, len); - } else if (type == PMAX_LANCE) { + if (type == PMAX_LANCE) { clen = len >> 1; tp = (unsigned short *) to; fp = (unsigned short *) from; @@ -441,10 +431,12 @@ static void cp_from_buf(const int type, void *to, const void *from, int len) static void lance_init_ring(struct net_device *dev) { struct lance_private *lp = netdev_priv(dev); - volatile u16 *ib = (volatile u16 *)dev->mem_start; - uint leptr; + volatile struct lance_init_block *ib; + int leptr; int i; + ib = (struct lance_init_block *) (dev->mem_start); + /* Lock out other processes while setting up hardware */ netif_stop_queue(dev); lp->rx_new = lp->tx_new = 0; @@ -453,64 +445,55 @@ static void lance_init_ring(struct net_device *dev) /* Copy the ethernet address to the lance init block. * XXX bit 0 of the physical address registers has to be zero */ - *lib_ptr(ib, phys_addr[0], lp->type) = (dev->dev_addr[1] << 8) | - dev->dev_addr[0]; - *lib_ptr(ib, phys_addr[1], lp->type) = (dev->dev_addr[3] << 8) | - dev->dev_addr[2]; - *lib_ptr(ib, phys_addr[2], lp->type) = (dev->dev_addr[5] << 8) | - dev->dev_addr[4]; + ib->phys_addr[0] = dev->dev_addr[0]; + ib->phys_addr[1] = dev->dev_addr[1]; + ib->phys_addr[4] = dev->dev_addr[2]; + ib->phys_addr[5] = dev->dev_addr[3]; + ib->phys_addr[8] = dev->dev_addr[4]; + ib->phys_addr[9] = dev->dev_addr[5]; /* Setup the initialization block */ /* Setup rx descriptor pointer */ - leptr = offsetof(struct lance_init_block, brx_ring); - *lib_ptr(ib, rx_len, lp->type) = (LANCE_LOG_RX_BUFFERS << 13) | - (leptr >> 16); - *lib_ptr(ib, rx_ptr, lp->type) = leptr; + leptr = LANCE_ADDR(libdesc_offset(brx_ring, 0)); + ib->rx_len = (LANCE_LOG_RX_BUFFERS << 13) | (leptr >> 16); + ib->rx_ptr = leptr; if (ZERO) - printk("RX ptr: %8.8x(%8.8x)\n", - leptr, lib_off(brx_ring, lp->type)); + printk("RX ptr: %8.8x(%8.8x)\n", leptr, libdesc_offset(brx_ring, 0)); /* Setup tx descriptor pointer */ - leptr = offsetof(struct lance_init_block, btx_ring); - *lib_ptr(ib, tx_len, lp->type) = (LANCE_LOG_TX_BUFFERS << 13) | - (leptr >> 16); - *lib_ptr(ib, tx_ptr, lp->type) = leptr; + leptr = LANCE_ADDR(libdesc_offset(btx_ring, 0)); + ib->tx_len = (LANCE_LOG_TX_BUFFERS << 13) | (leptr >> 16); + ib->tx_ptr = leptr; if (ZERO) - printk("TX ptr: %8.8x(%8.8x)\n", - leptr, lib_off(btx_ring, lp->type)); + printk("TX ptr: %8.8x(%8.8x)\n", leptr, libdesc_offset(btx_ring, 0)); if (ZERO) printk("TX rings:\n"); /* Setup the Tx ring entries */ for (i = 0; i < TX_RING_SIZE; i++) { - leptr = lp->tx_buf_ptr_lnc[i]; - *lib_ptr(ib, btx_ring[i].tmd0, lp->type) = leptr; - *lib_ptr(ib, btx_ring[i].tmd1, lp->type) = (leptr >> 16) & - 0xff; - *lib_ptr(ib, btx_ring[i].length, lp->type) = 0xf000; - /* The ones required by tmd2 */ - *lib_ptr(ib, btx_ring[i].misc, lp->type) = 0; + leptr = (int) lp->tx_buf_ptr_lnc[i]; + ib->btx_ring[i].tmd0 = leptr; + ib->btx_ring[i].tmd1_hadr = leptr >> 16; + ib->btx_ring[i].tmd1_bits = 0; + ib->btx_ring[i].length = 0xf000; /* The ones required by tmd2 */ + ib->btx_ring[i].misc = 0; if (i < 3 && ZERO) - printk("%d: 0x%8.8x(0x%8.8x)\n", - i, leptr, (uint)lp->tx_buf_ptr_cpu[i]); + printk("%d: 0x%8.8x(0x%8.8x)\n", i, leptr, (int) lp->tx_buf_ptr_cpu[i]); } /* Setup the Rx ring entries */ if (ZERO) printk("RX rings:\n"); for (i = 0; i < RX_RING_SIZE; i++) { - leptr = lp->rx_buf_ptr_lnc[i]; - *lib_ptr(ib, brx_ring[i].rmd0, lp->type) = leptr; - *lib_ptr(ib, brx_ring[i].rmd1, lp->type) = ((leptr >> 16) & - 0xff) | - LE_R1_OWN; - *lib_ptr(ib, brx_ring[i].length, lp->type) = -RX_BUFF_SIZE | - 0xf000; - *lib_ptr(ib, brx_ring[i].mblength, lp->type) = 0; + leptr = (int) lp->rx_buf_ptr_lnc[i]; + ib->brx_ring[i].rmd0 = leptr; + ib->brx_ring[i].rmd1_hadr = leptr >> 16; + ib->brx_ring[i].rmd1_bits = LE_R1_OWN; + ib->brx_ring[i].length = -RX_BUFF_SIZE | 0xf000; + ib->brx_ring[i].mblength = 0; if (i < 3 && ZERO) - printk("%d: 0x%8.8x(0x%8.8x)\n", - i, leptr, (uint)lp->rx_buf_ptr_cpu[i]); + printk("%d: 0x%8.8x(0x%8.8x)\n", i, leptr, (int) lp->rx_buf_ptr_cpu[i]); } iob(); } @@ -528,13 +511,11 @@ static int init_restart_lance(struct lance_private *lp) udelay(10); } if ((i == 100) || (ll->rdp & LE_C0_ERR)) { - printk("LANCE unopened after %d ticks, csr0=%4.4x.\n", - i, ll->rdp); + printk("LANCE unopened after %d ticks, csr0=%4.4x.\n", i, ll->rdp); return -1; } if ((ll->rdp & LE_C0_ERR)) { - printk("LANCE unopened after %d ticks, csr0=%4.4x.\n", - i, ll->rdp); + printk("LANCE unopened after %d ticks, csr0=%4.4x.\n", i, ll->rdp); return -1; } writereg(&ll->rdp, LE_C0_IDON); @@ -547,11 +528,12 @@ static int init_restart_lance(struct lance_private *lp) static int lance_rx(struct net_device *dev) { struct lance_private *lp = netdev_priv(dev); - volatile u16 *ib = (volatile u16 *)dev->mem_start; - volatile u16 *rd; - unsigned short bits; - int entry, len; - struct sk_buff *skb; + volatile struct lance_init_block *ib; + volatile struct lance_rx_desc *rd = 0; + unsigned char bits; + int len = 0; + struct sk_buff *skb = 0; + ib = (struct lance_init_block *) (dev->mem_start); #ifdef TEST_HITS { @@ -560,22 +542,19 @@ static int lance_rx(struct net_device *dev) printk("["); for (i = 0; i < RX_RING_SIZE; i++) { if (i == lp->rx_new) - printk("%s", *lib_ptr(ib, brx_ring[i].rmd1, - lp->type) & + printk("%s", ib->brx_ring[i].rmd1_bits & LE_R1_OWN ? "_" : "X"); else - printk("%s", *lib_ptr(ib, brx_ring[i].rmd1, - lp->type) & + printk("%s", ib->brx_ring[i].rmd1_bits & LE_R1_OWN ? "." : "1"); } printk("]"); } #endif - for (rd = lib_ptr(ib, brx_ring[lp->rx_new], lp->type); - !((bits = *rds_ptr(rd, rmd1, lp->type)) & LE_R1_OWN); - rd = lib_ptr(ib, brx_ring[lp->rx_new], lp->type)) { - entry = lp->rx_new; + for (rd = &ib->brx_ring[lp->rx_new]; + !((bits = rd->rmd1_bits) & LE_R1_OWN); + rd = &ib->brx_ring[lp->rx_new]) { /* We got an incomplete frame? */ if ((bits & LE_R1_POK) != LE_R1_POK) { @@ -596,18 +575,16 @@ static int lance_rx(struct net_device *dev) if (bits & LE_R1_EOP) lp->stats.rx_errors++; } else { - len = (*rds_ptr(rd, mblength, lp->type) & 0xfff) - 4; + len = (rd->mblength & 0xfff) - 4; skb = dev_alloc_skb(len + 2); if (skb == 0) { printk("%s: Memory squeeze, deferring packet.\n", dev->name); lp->stats.rx_dropped++; - *rds_ptr(rd, mblength, lp->type) = 0; - *rds_ptr(rd, rmd1, lp->type) = - ((lp->rx_buf_ptr_lnc[entry] >> 16) & - 0xff) | LE_R1_OWN; - lp->rx_new = (entry + 1) & RX_RING_MOD_MASK; + rd->mblength = 0; + rd->rmd1_bits = LE_R1_OWN; + lp->rx_new = (lp->rx_new + 1) & RX_RING_MOD_MASK; return 0; } lp->stats.rx_bytes += len; @@ -617,7 +594,8 @@ static int lance_rx(struct net_device *dev) skb_put(skb, len); /* make room */ cp_from_buf(lp->type, skb->data, - (char *)lp->rx_buf_ptr_cpu[entry], len); + (char *)lp->rx_buf_ptr_cpu[lp->rx_new], + len); skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); @@ -626,11 +604,10 @@ static int lance_rx(struct net_device *dev) } /* Return the packet to the pool */ - *rds_ptr(rd, mblength, lp->type) = 0; - *rds_ptr(rd, length, lp->type) = -RX_BUFF_SIZE | 0xf000; - *rds_ptr(rd, rmd1, lp->type) = - ((lp->rx_buf_ptr_lnc[entry] >> 16) & 0xff) | LE_R1_OWN; - lp->rx_new = (entry + 1) & RX_RING_MOD_MASK; + rd->mblength = 0; + rd->length = -RX_BUFF_SIZE | 0xf000; + rd->rmd1_bits = LE_R1_OWN; + lp->rx_new = (lp->rx_new + 1) & RX_RING_MOD_MASK; } return 0; } @@ -638,24 +615,24 @@ static int lance_rx(struct net_device *dev) static void lance_tx(struct net_device *dev) { struct lance_private *lp = netdev_priv(dev); - volatile u16 *ib = (volatile u16 *)dev->mem_start; + volatile struct lance_init_block *ib; volatile struct lance_regs *ll = lp->ll; - volatile u16 *td; + volatile struct lance_tx_desc *td; int i, j; int status; - + ib = (struct lance_init_block *) (dev->mem_start); j = lp->tx_old; spin_lock(&lp->lock); for (i = j; i != lp->tx_new; i = j) { - td = lib_ptr(ib, btx_ring[i], lp->type); + td = &ib->btx_ring[i]; /* If we hit a packet not owned by us, stop */ - if (*tds_ptr(td, tmd1, lp->type) & LE_T1_OWN) + if (td->tmd1_bits & LE_T1_OWN) break; - if (*tds_ptr(td, tmd1, lp->type) & LE_T1_ERR) { - status = *tds_ptr(td, misc, lp->type); + if (td->tmd1_bits & LE_T1_ERR) { + status = td->misc; lp->stats.tx_errors++; if (status & LE_T3_RTY) @@ -690,19 +667,18 @@ static void lance_tx(struct net_device *dev) init_restart_lance(lp); goto out; } - } else if ((*tds_ptr(td, tmd1, lp->type) & LE_T1_POK) == - LE_T1_POK) { + } else if ((td->tmd1_bits & LE_T1_POK) == LE_T1_POK) { /* * So we don't count the packet more than once. */ - *tds_ptr(td, tmd1, lp->type) &= ~(LE_T1_POK); + td->tmd1_bits &= ~(LE_T1_POK); /* One collision before packet was sent. */ - if (*tds_ptr(td, tmd1, lp->type) & LE_T1_EONE) + if (td->tmd1_bits & LE_T1_EONE) lp->stats.collisions++; /* More than one collision, be optimistic. */ - if (*tds_ptr(td, tmd1, lp->type) & LE_T1_EMORE) + if (td->tmd1_bits & LE_T1_EMORE) lp->stats.collisions += 2; lp->stats.tx_packets++; @@ -776,7 +752,7 @@ struct net_device *last_dev = 0; static int lance_open(struct net_device *dev) { - volatile u16 *ib = (volatile u16 *)dev->mem_start; + volatile struct lance_init_block *ib = (struct lance_init_block *) (dev->mem_start); struct lance_private *lp = netdev_priv(dev); volatile struct lance_regs *ll = lp->ll; int status = 0; @@ -793,11 +769,11 @@ static int lance_open(struct net_device *dev) * * BTW it is common bug in all lance drivers! --ANK */ - *lib_ptr(ib, mode, lp->type) = 0; - *lib_ptr(ib, filter[0], lp->type) = 0; - *lib_ptr(ib, filter[1], lp->type) = 0; - *lib_ptr(ib, filter[2], lp->type) = 0; - *lib_ptr(ib, filter[3], lp->type) = 0; + ib->mode = 0; + ib->filter [0] = 0; + ib->filter [2] = 0; + ib->filter [4] = 0; + ib->filter [6] = 0; lance_init_ring(dev); load_csrs(lp); @@ -898,10 +874,12 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct lance_private *lp = netdev_priv(dev); volatile struct lance_regs *ll = lp->ll; - volatile u16 *ib = (volatile u16 *)dev->mem_start; - int entry, len; + volatile struct lance_init_block *ib = (struct lance_init_block *) (dev->mem_start); + int entry, skblen, len; - len = skb->len; + skblen = skb->len; + + len = skblen; if (len < ETH_ZLEN) { if (skb_padto(skb, ETH_ZLEN)) @@ -911,17 +889,23 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) lp->stats.tx_bytes += len; - entry = lp->tx_new; - *lib_ptr(ib, btx_ring[entry].length, lp->type) = (-len); - *lib_ptr(ib, btx_ring[entry].misc, lp->type) = 0; + entry = lp->tx_new & TX_RING_MOD_MASK; + ib->btx_ring[entry].length = (-len); + ib->btx_ring[entry].misc = 0; + + cp_to_buf(lp->type, (char *)lp->tx_buf_ptr_cpu[entry], skb->data, + skblen); - cp_to_buf(lp->type, (char *)lp->tx_buf_ptr_cpu[entry], skb->data, len); + /* Clear the slack of the packet, do I need this? */ + /* For a firewall it's a good idea - AC */ +/* + if (len != skblen) + memset ((char *) &ib->tx_buf [entry][skblen], 0, (len - skblen) << 1); + */ /* Now, give the packet to the lance */ - *lib_ptr(ib, btx_ring[entry].tmd1, lp->type) = - ((lp->tx_buf_ptr_lnc[entry] >> 16) & 0xff) | - (LE_T1_POK | LE_T1_OWN); - lp->tx_new = (entry + 1) & TX_RING_MOD_MASK; + ib->btx_ring[entry].tmd1_bits = (LE_T1_POK | LE_T1_OWN); + lp->tx_new = (lp->tx_new + 1) & TX_RING_MOD_MASK; if (TX_BUFFS_AVAIL <= 0) netif_stop_queue(dev); @@ -946,8 +930,8 @@ static struct net_device_stats *lance_get_stats(struct net_device *dev) static void lance_load_multicast(struct net_device *dev) { - struct lance_private *lp = netdev_priv(dev); - volatile u16 *ib = (volatile u16 *)dev->mem_start; + volatile struct lance_init_block *ib = (struct lance_init_block *) (dev->mem_start); + volatile u16 *mcast_table = (u16 *) & ib->filter; struct dev_mc_list *dmi = dev->mc_list; char *addrs; int i; @@ -955,17 +939,17 @@ static void lance_load_multicast(struct net_device *dev) /* set all multicast bits */ if (dev->flags & IFF_ALLMULTI) { - *lib_ptr(ib, filter[0], lp->type) = 0xffff; - *lib_ptr(ib, filter[1], lp->type) = 0xffff; - *lib_ptr(ib, filter[2], lp->type) = 0xffff; - *lib_ptr(ib, filter[3], lp->type) = 0xffff; + ib->filter[0] = 0xffff; + ib->filter[2] = 0xffff; + ib->filter[4] = 0xffff; + ib->filter[6] = 0xffff; return; } /* clear the multicast filter */ - *lib_ptr(ib, filter[0], lp->type) = 0; - *lib_ptr(ib, filter[1], lp->type) = 0; - *lib_ptr(ib, filter[2], lp->type) = 0; - *lib_ptr(ib, filter[3], lp->type) = 0; + ib->filter[0] = 0; + ib->filter[2] = 0; + ib->filter[4] = 0; + ib->filter[6] = 0; /* Add addresses */ for (i = 0; i < dev->mc_count; i++) { @@ -978,7 +962,7 @@ static void lance_load_multicast(struct net_device *dev) crc = ether_crc_le(ETH_ALEN, addrs); crc = crc >> 26; - *lib_ptr(ib, filter[crc >> 4], lp->type) |= 1 << (crc & 0xf); + mcast_table[2 * (crc >> 4)] |= 1 << (crc & 0xf); } return; } @@ -986,9 +970,11 @@ static void lance_load_multicast(struct net_device *dev) static void lance_set_multicast(struct net_device *dev) { struct lance_private *lp = netdev_priv(dev); - volatile u16 *ib = (volatile u16 *)dev->mem_start; + volatile struct lance_init_block *ib; volatile struct lance_regs *ll = lp->ll; + ib = (struct lance_init_block *) (dev->mem_start); + if (!netif_running(dev)) return; @@ -1006,9 +992,9 @@ static void lance_set_multicast(struct net_device *dev) lance_init_ring(dev); if (dev->flags & IFF_PROMISC) { - *lib_ptr(ib, mode, lp->type) |= LE_MO_PROM; + ib->mode |= LE_MO_PROM; } else { - *lib_ptr(ib, mode, lp->type) &= ~LE_MO_PROM; + ib->mode &= ~LE_MO_PROM; lance_load_multicast(dev); } load_csrs(lp); @@ -1065,6 +1051,7 @@ static int __init dec_lance_init(const int type, const int slot) lp->type = type; lp->slot = slot; switch (type) { +#ifdef CONFIG_TC case ASIC_LANCE: dev->base_addr = CKSEG1ADDR(dec_kn_slot_base + IOASIC_LANCE); @@ -1086,20 +1073,20 @@ static int __init dec_lance_init(const int type, const int slot) */ for (i = 0; i < RX_RING_SIZE; i++) { lp->rx_buf_ptr_cpu[i] = - (char *)(dev->mem_start + 2 * BUF_OFFSET_CPU + + (char *)(dev->mem_start + BUF_OFFSET_CPU + 2 * i * RX_BUFF_SIZE); lp->rx_buf_ptr_lnc[i] = - (BUF_OFFSET_LNC + i * RX_BUFF_SIZE); + (char *)(BUF_OFFSET_LNC + i * RX_BUFF_SIZE); } for (i = 0; i < TX_RING_SIZE; i++) { lp->tx_buf_ptr_cpu[i] = - (char *)(dev->mem_start + 2 * BUF_OFFSET_CPU + + (char *)(dev->mem_start + BUF_OFFSET_CPU + 2 * RX_RING_SIZE * RX_BUFF_SIZE + 2 * i * TX_BUFF_SIZE); lp->tx_buf_ptr_lnc[i] = - (BUF_OFFSET_LNC + - RX_RING_SIZE * RX_BUFF_SIZE + - i * TX_BUFF_SIZE); + (char *)(BUF_OFFSET_LNC + + RX_RING_SIZE * RX_BUFF_SIZE + + i * TX_BUFF_SIZE); } /* Setup I/O ASIC LANCE DMA. */ @@ -1108,12 +1095,11 @@ static int __init dec_lance_init(const int type, const int slot) CPHYSADDR(dev->mem_start) << 3); break; -#ifdef CONFIG_TC + case PMAD_LANCE: claim_tc_card(slot); dev->mem_start = CKSEG1ADDR(get_tc_base_addr(slot)); - dev->mem_end = dev->mem_start + 0x100000; dev->base_addr = dev->mem_start + 0x100000; dev->irq = get_tc_irq_nr(slot); esar_base = dev->mem_start + 0x1c0002; @@ -1124,7 +1110,7 @@ static int __init dec_lance_init(const int type, const int slot) (char *)(dev->mem_start + BUF_OFFSET_CPU + i * RX_BUFF_SIZE); lp->rx_buf_ptr_lnc[i] = - (BUF_OFFSET_LNC + i * RX_BUFF_SIZE); + (char *)(BUF_OFFSET_LNC + i * RX_BUFF_SIZE); } for (i = 0; i < TX_RING_SIZE; i++) { lp->tx_buf_ptr_cpu[i] = @@ -1132,18 +1118,18 @@ static int __init dec_lance_init(const int type, const int slot) RX_RING_SIZE * RX_BUFF_SIZE + i * TX_BUFF_SIZE); lp->tx_buf_ptr_lnc[i] = - (BUF_OFFSET_LNC + - RX_RING_SIZE * RX_BUFF_SIZE + - i * TX_BUFF_SIZE); + (char *)(BUF_OFFSET_LNC + + RX_RING_SIZE * RX_BUFF_SIZE + + i * TX_BUFF_SIZE); } break; #endif + case PMAX_LANCE: dev->irq = dec_interrupt[DEC_IRQ_LANCE]; dev->base_addr = CKSEG1ADDR(KN01_SLOT_BASE + KN01_LANCE); dev->mem_start = CKSEG1ADDR(KN01_SLOT_BASE + KN01_LANCE_MEM); - dev->mem_end = dev->mem_start + KN01_SLOT_SIZE; esar_base = CKSEG1ADDR(KN01_SLOT_BASE + KN01_ESAR + 1); lp->dma_irq = -1; @@ -1152,20 +1138,20 @@ static int __init dec_lance_init(const int type, const int slot) */ for (i = 0; i < RX_RING_SIZE; i++) { lp->rx_buf_ptr_cpu[i] = - (char *)(dev->mem_start + 2 * BUF_OFFSET_CPU + + (char *)(dev->mem_start + BUF_OFFSET_CPU + 2 * i * RX_BUFF_SIZE); lp->rx_buf_ptr_lnc[i] = - (BUF_OFFSET_LNC + i * RX_BUFF_SIZE); + (char *)(BUF_OFFSET_LNC + i * RX_BUFF_SIZE); } for (i = 0; i < TX_RING_SIZE; i++) { lp->tx_buf_ptr_cpu[i] = - (char *)(dev->mem_start + 2 * BUF_OFFSET_CPU + + (char *)(dev->mem_start + BUF_OFFSET_CPU + 2 * RX_RING_SIZE * RX_BUFF_SIZE + 2 * i * TX_BUFF_SIZE); lp->tx_buf_ptr_lnc[i] = - (BUF_OFFSET_LNC + - RX_RING_SIZE * RX_BUFF_SIZE + - i * TX_BUFF_SIZE); + (char *)(BUF_OFFSET_LNC + + RX_RING_SIZE * RX_BUFF_SIZE + + i * TX_BUFF_SIZE); } break; @@ -1293,8 +1279,10 @@ static int __init dec_lance_probe(void) /* Then handle onboard devices. */ if (dec_interrupt[DEC_IRQ_LANCE] >= 0) { if (dec_interrupt[DEC_IRQ_LANCE_MERR] >= 0) { +#ifdef CONFIG_TC if (dec_lance_init(ASIC_LANCE, -1) >= 0) count++; +#endif } else if (!TURBOCHANNEL) { if (dec_lance_init(PMAX_LANCE, -1) >= 0) count++; 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/e2100.c b/trunk/drivers/net/e2100.c index c62d9c6363c6..d39e8480ca56 100644 --- a/trunk/drivers/net/e2100.c +++ b/trunk/drivers/net/e2100.c @@ -463,7 +463,7 @@ static void cleanup_card(struct net_device *dev) release_region(dev->base_addr, E21_IO_EXTENT); } -void __exit +void cleanup_module(void) { int this_dev; diff --git a/trunk/drivers/net/eepro.c b/trunk/drivers/net/eepro.c index b4463094c93a..a4eb0dc99ecf 100644 --- a/trunk/drivers/net/eepro.c +++ b/trunk/drivers/net/eepro.c @@ -1827,7 +1827,7 @@ int __init init_module(void) return n_eepro ? 0 : -ENODEV; } -void __exit +void cleanup_module(void) { int i; diff --git a/trunk/drivers/net/eexpress.c b/trunk/drivers/net/eexpress.c index 4a50fcb5ad6b..e14be020e562 100644 --- a/trunk/drivers/net/eexpress.c +++ b/trunk/drivers/net/eexpress.c @@ -1719,7 +1719,7 @@ int __init init_module(void) return -ENXIO; } -void __exit cleanup_module(void) +void cleanup_module(void) { int this_dev; 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/es3210.c b/trunk/drivers/net/es3210.c index 2d2ea94a00bb..fd7b32a24ea4 100644 --- a/trunk/drivers/net/es3210.c +++ b/trunk/drivers/net/es3210.c @@ -455,7 +455,7 @@ static void cleanup_card(struct net_device *dev) iounmap(ei_status.mem); } -void __exit +void cleanup_module(void) { int this_dev; diff --git a/trunk/drivers/net/eth16i.c b/trunk/drivers/net/eth16i.c index 93283e386f3a..b7b8bc2a6307 100644 --- a/trunk/drivers/net/eth16i.c +++ b/trunk/drivers/net/eth16i.c @@ -1475,7 +1475,7 @@ int __init init_module(void) return -ENXIO; } -void __exit cleanup_module(void) +void cleanup_module(void) { int this_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/hamradio/dmascc.c b/trunk/drivers/net/hamradio/dmascc.c index e6e721aff6f6..0f8b9afd55b4 100644 --- a/trunk/drivers/net/hamradio/dmascc.c +++ b/trunk/drivers/net/hamradio/dmascc.c @@ -252,7 +252,7 @@ static inline void z8530_isr(struct scc_info *info); static irqreturn_t scc_isr(int irq, void *dev_id); static void rx_isr(struct scc_priv *priv); static void special_condition(struct scc_priv *priv, int rc); -static void rx_bh(struct work_struct *); +static void rx_bh(void *arg); static void tx_isr(struct scc_priv *priv); static void es_isr(struct scc_priv *priv); static void tm_isr(struct scc_priv *priv); @@ -579,7 +579,7 @@ static int __init setup_adapter(int card_base, int type, int n) priv->param.clocks = TCTRxCP | RCRTxCP; priv->param.persist = 256; priv->param.dma = -1; - INIT_WORK(&priv->rx_work, rx_bh); + INIT_WORK(&priv->rx_work, rx_bh, priv); dev->priv = priv; sprintf(dev->name, "dmascc%i", 2 * n + i); dev->base_addr = card_base; @@ -1272,9 +1272,9 @@ static void special_condition(struct scc_priv *priv, int rc) } -static void rx_bh(struct work_struct *ugli_api) +static void rx_bh(void *arg) { - struct scc_priv *priv = container_of(ugli_api, struct scc_priv, rx_work); + struct scc_priv *priv = arg; int i = priv->rx_tail; int cb; unsigned long flags; diff --git a/trunk/drivers/net/hp-plus.c b/trunk/drivers/net/hp-plus.c index 99a36cc3f8df..6abcfd2a4b28 100644 --- a/trunk/drivers/net/hp-plus.c +++ b/trunk/drivers/net/hp-plus.c @@ -482,7 +482,7 @@ static void cleanup_card(struct net_device *dev) release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT); } -void __exit +void cleanup_module(void) { int this_dev; diff --git a/trunk/drivers/net/hp.c b/trunk/drivers/net/hp.c index 635b13c2e2aa..29470970aa27 100644 --- a/trunk/drivers/net/hp.c +++ b/trunk/drivers/net/hp.c @@ -444,7 +444,7 @@ static void cleanup_card(struct net_device *dev) release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT); } -void __exit +void cleanup_module(void) { int this_dev; 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/lance.c b/trunk/drivers/net/lance.c index a3843320dbe1..4256c13c73c2 100644 --- a/trunk/drivers/net/lance.c +++ b/trunk/drivers/net/lance.c @@ -368,7 +368,7 @@ static void cleanup_card(struct net_device *dev) kfree(lp); } -void __exit cleanup_module(void) +void cleanup_module(void) { int this_dev; diff --git a/trunk/drivers/net/lne390.c b/trunk/drivers/net/lne390.c index 0a08d0c4e7b4..5795ee116205 100644 --- a/trunk/drivers/net/lne390.c +++ b/trunk/drivers/net/lne390.c @@ -440,7 +440,7 @@ static void cleanup_card(struct net_device *dev) iounmap(ei_status.mem); } -void __exit cleanup_module(void) +void cleanup_module(void) { int this_dev; diff --git a/trunk/drivers/net/mv643xx_eth.c b/trunk/drivers/net/mv643xx_eth.c index c41ae4286eea..9997081c6dae 100644 --- a/trunk/drivers/net/mv643xx_eth.c +++ b/trunk/drivers/net/mv643xx_eth.c @@ -277,11 +277,9 @@ static void mv643xx_eth_tx_timeout(struct net_device *dev) * * Actual routine to reset the adapter when a timeout on Tx has occurred */ -static void mv643xx_eth_tx_timeout_task(struct work_struct *ugly) +static void mv643xx_eth_tx_timeout_task(struct net_device *dev) { - struct mv643xx_private *mp = container_of(ugly, struct mv643xx_private, - tx_timeout_task); - struct net_device *dev = mp->mii.dev; /* yuck */ + struct mv643xx_private *mp = netdev_priv(dev); if (!netif_running(dev)) return; @@ -1100,7 +1098,7 @@ static void eth_tx_fill_frag_descs(struct mv643xx_private *mp, ETH_TX_ENABLE_INTERRUPT; mp->tx_skb[tx_index] = skb; } else - mp->tx_skb[tx_index] = NULL; + mp->tx_skb[tx_index] = 0; desc = &mp->p_tx_desc_area[tx_index]; desc->l4i_chk = 0; @@ -1136,7 +1134,7 @@ static void eth_tx_submit_descs_for_skb(struct mv643xx_private *mp, eth_tx_fill_frag_descs(mp, skb); length = skb_headlen(skb); - mp->tx_skb[tx_index] = NULL; + mp->tx_skb[tx_index] = 0; } else { cmd_sts |= ETH_ZERO_PADDING | ETH_TX_LAST_DESC | @@ -1362,7 +1360,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev) #endif /* Configure the timeout task */ - INIT_WORK(&mp->tx_timeout_task, mv643xx_eth_tx_timeout_task); + INIT_WORK(&mp->tx_timeout_task, + (void (*)(void *))mv643xx_eth_tx_timeout_task, dev); spin_lock_init(&mp->lock); diff --git a/trunk/drivers/net/mvme147.c b/trunk/drivers/net/mvme147.c index e246d00bba6d..56a82d8ee8f5 100644 --- a/trunk/drivers/net/mvme147.c +++ b/trunk/drivers/net/mvme147.c @@ -184,7 +184,7 @@ static int m147lance_close(struct net_device *dev) MODULE_LICENSE("GPL"); static struct net_device *dev_mvme147_lance; -int __init init_module(void) +int init_module(void) { dev_mvme147_lance = mvme147lance_probe(-1); if (IS_ERR(dev_mvme147_lance)) @@ -192,7 +192,7 @@ int __init init_module(void) return 0; } -void __exit cleanup_module(void) +void cleanup_module(void) { struct m147lance_private *lp = dev_mvme147_lance->priv; unregister_netdev(dev_mvme147_lance); diff --git a/trunk/drivers/net/myri10ge/myri10ge.c b/trunk/drivers/net/myri10ge/myri10ge.c index 81f127a78afa..36350e6db1c1 100644 --- a/trunk/drivers/net/myri10ge/myri10ge.c +++ b/trunk/drivers/net/myri10ge/myri10ge.c @@ -89,7 +89,7 @@ MODULE_LICENSE("Dual BSD/GPL"); #define MYRI10GE_EEPROM_STRINGS_SIZE 256 #define MYRI10GE_MAX_SEND_DESC_TSO ((65536 / 2048) * 2) -#define MYRI10GE_NO_CONFIRM_DATA htonl(0xffffffff) +#define MYRI10GE_NO_CONFIRM_DATA 0xffffffff #define MYRI10GE_NO_RESPONSE_RESULT 0xffffffff struct myri10ge_rx_buffer_state { @@ -156,8 +156,8 @@ struct myri10ge_priv { int sram_size; unsigned long board_span; unsigned long iomem_base; - __be32 __iomem *irq_claim; - __be32 __iomem *irq_deassert; + u32 __iomem *irq_claim; + u32 __iomem *irq_deassert; char *mac_addr_string; struct mcp_cmd_response *cmd; dma_addr_t cmd_bus; @@ -165,10 +165,10 @@ struct myri10ge_priv { dma_addr_t fw_stats_bus; struct pci_dev *pdev; int msi_enabled; - __be32 link_state; + unsigned int link_state; unsigned int rdma_tags_available; int intr_coal_delay; - __be32 __iomem *intr_coal_delay_ptr; + u32 __iomem *intr_coal_delay_ptr; int mtrr; int wake_queue; int stop_queue; @@ -273,11 +273,6 @@ MODULE_PARM_DESC(myri10ge_debug, "Debug level (0=none,...,16=all)"); #define myri10ge_pio_copy(to,from,size) __iowrite64_copy(to,from,size/8) -static inline void put_be32(__be32 val, __be32 __iomem *p) -{ - __raw_writel((__force __u32)val, (__force void __iomem *)p); -} - static int myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd, struct myri10ge_cmd *data, int atomic) @@ -301,7 +296,7 @@ myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd, buf->response_addr.low = htonl(dma_low); buf->response_addr.high = htonl(dma_high); - response->result = htonl(MYRI10GE_NO_RESPONSE_RESULT); + response->result = MYRI10GE_NO_RESPONSE_RESULT; mb(); myri10ge_pio_copy(cmd_addr, buf, sizeof(*buf)); @@ -316,14 +311,14 @@ myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd, * (1ms will be enough for those commands) */ for (sleep_total = 0; sleep_total < 1000 - && response->result == htonl(MYRI10GE_NO_RESPONSE_RESULT); + && response->result == MYRI10GE_NO_RESPONSE_RESULT; sleep_total += 10) udelay(10); } else { /* use msleep for most command */ for (sleep_total = 0; sleep_total < 15 - && response->result == htonl(MYRI10GE_NO_RESPONSE_RESULT); + && response->result == MYRI10GE_NO_RESPONSE_RESULT; sleep_total++) msleep(1); } @@ -398,7 +393,7 @@ static int myri10ge_read_mac_addr(struct myri10ge_priv *mgp) static void myri10ge_dummy_rdma(struct myri10ge_priv *mgp, int enable) { char __iomem *submit; - __be32 buf[16]; + u32 buf[16]; u32 dma_low, dma_high; int i; @@ -415,7 +410,7 @@ static void myri10ge_dummy_rdma(struct myri10ge_priv *mgp, int enable) buf[0] = htonl(dma_high); /* confirm addr MSW */ buf[1] = htonl(dma_low); /* confirm addr LSW */ - buf[2] = MYRI10GE_NO_CONFIRM_DATA; /* confirm data */ + buf[2] = htonl(MYRI10GE_NO_CONFIRM_DATA); /* confirm data */ buf[3] = htonl(dma_high); /* dummy addr MSW */ buf[4] = htonl(dma_low); /* dummy addr LSW */ buf[5] = htonl(enable); /* enable? */ @@ -484,7 +479,7 @@ static int myri10ge_load_hotplug_firmware(struct myri10ge_priv *mgp, u32 * size) } /* check id */ - hdr_offset = ntohl(*(__be32 *) (fw->data + MCP_HEADER_PTR_OFFSET)); + hdr_offset = ntohl(*(u32 *) (fw->data + MCP_HEADER_PTR_OFFSET)); if ((hdr_offset & 3) || hdr_offset + sizeof(*hdr) > fw->size) { dev_err(dev, "Bad firmware file\n"); status = -EINVAL; @@ -555,7 +550,7 @@ static int myri10ge_adopt_running_firmware(struct myri10ge_priv *mgp) static int myri10ge_load_firmware(struct myri10ge_priv *mgp) { char __iomem *submit; - __be32 buf[16]; + u32 buf[16]; u32 dma_low, dma_high, size; int status, i; @@ -605,7 +600,7 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp) buf[0] = htonl(dma_high); /* confirm addr MSW */ buf[1] = htonl(dma_low); /* confirm addr LSW */ - buf[2] = MYRI10GE_NO_CONFIRM_DATA; /* confirm data */ + buf[2] = htonl(MYRI10GE_NO_CONFIRM_DATA); /* confirm data */ /* FIX: All newest firmware should un-protect the bottom of * the sram before handoff. However, the very first interfaces @@ -710,21 +705,21 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_ACK_OFFSET, &cmd, 0); - mgp->irq_claim = (__iomem __be32 *) (mgp->sram + cmd.data0); + mgp->irq_claim = (__iomem u32 *) (mgp->sram + cmd.data0); if (!mgp->msi_enabled) { status |= myri10ge_send_cmd (mgp, MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET, &cmd, 0); - mgp->irq_deassert = (__iomem __be32 *) (mgp->sram + cmd.data0); + mgp->irq_deassert = (__iomem u32 *) (mgp->sram + cmd.data0); } status |= myri10ge_send_cmd (mgp, MXGEFW_CMD_GET_INTR_COAL_DELAY_OFFSET, &cmd, 0); - mgp->intr_coal_delay_ptr = (__iomem __be32 *) (mgp->sram + cmd.data0); + mgp->intr_coal_delay_ptr = (__iomem u32 *) (mgp->sram + cmd.data0); if (status != 0) { dev_err(&mgp->pdev->dev, "failed set interrupt parameters\n"); return status; } - put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr); + __raw_writel(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr); /* Run a small DMA test. * The magic multipliers to the length tell the firmware @@ -791,16 +786,14 @@ static inline void myri10ge_submit_8rx(struct mcp_kreq_ether_recv __iomem * dst, struct mcp_kreq_ether_recv *src) { - __be32 low; + u32 low; low = src->addr_low; - src->addr_low = htonl(DMA_32BIT_MASK); - myri10ge_pio_copy(dst, src, 4 * sizeof(*src)); - mb(); - myri10ge_pio_copy(dst + 4, src + 4, 4 * sizeof(*src)); + src->addr_low = DMA_32BIT_MASK; + myri10ge_pio_copy(dst, src, 8 * sizeof(*src)); mb(); src->addr_low = low; - put_be32(low, &dst->addr_low); + __raw_writel(low, &dst->addr_low); mb(); } @@ -946,11 +939,11 @@ myri10ge_getbuf(struct myri10ge_rx_buf *rx, struct myri10ge_priv *mgp, return retval; } -static inline void myri10ge_vlan_ip_csum(struct sk_buff *skb, __wsum hw_csum) +static inline void myri10ge_vlan_ip_csum(struct sk_buff *skb, u16 hw_csum) { struct vlan_hdr *vh = (struct vlan_hdr *)(skb->data); - if ((skb->protocol == htons(ETH_P_8021Q)) && + if ((skb->protocol == ntohs(ETH_P_8021Q)) && (vh->h_vlan_encapsulated_proto == htons(ETH_P_IP) || vh->h_vlan_encapsulated_proto == htons(ETH_P_IPV6))) { skb->csum = hw_csum; @@ -960,7 +953,7 @@ static inline void myri10ge_vlan_ip_csum(struct sk_buff *skb, __wsum hw_csum) static inline unsigned long myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx, - int bytes, int len, __wsum csum) + int bytes, int len, int csum) { dma_addr_t bus; struct sk_buff *skb; @@ -993,12 +986,12 @@ myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx, skb->protocol = eth_type_trans(skb, mgp->dev); if (mgp->csum_flag) { - if ((skb->protocol == htons(ETH_P_IP)) || - (skb->protocol == htons(ETH_P_IPV6))) { - skb->csum = csum; + if ((skb->protocol == ntohs(ETH_P_IP)) || + (skb->protocol == ntohs(ETH_P_IPV6))) { + skb->csum = ntohs((u16) csum); skb->ip_summed = CHECKSUM_COMPLETE; } else - myri10ge_vlan_ip_csum(skb, csum); + myri10ge_vlan_ip_csum(skb, ntohs((u16) csum)); } netif_receive_skb(skb); @@ -1067,12 +1060,12 @@ static inline void myri10ge_clean_rx_done(struct myri10ge_priv *mgp, int *limit) int idx = rx_done->idx; int cnt = rx_done->cnt; u16 length; - __wsum checksum; + u16 checksum; while (rx_done->entry[idx].length != 0 && *limit != 0) { length = ntohs(rx_done->entry[idx].length); rx_done->entry[idx].length = 0; - checksum = csum_unfold(rx_done->entry[idx].checksum); + checksum = ntohs(rx_done->entry[idx].checksum); if (length <= mgp->small_bytes) rx_ok = myri10ge_rx_done(mgp, &mgp->rx_small, mgp->small_bytes, @@ -1149,7 +1142,7 @@ static int myri10ge_poll(struct net_device *netdev, int *budget) if (rx_done->entry[rx_done->idx].length == 0 || !netif_running(netdev)) { netif_rx_complete(netdev); - put_be32(htonl(3), mgp->irq_claim); + __raw_writel(htonl(3), mgp->irq_claim); return 0; } return 1; @@ -1173,7 +1166,7 @@ static irqreturn_t myri10ge_intr(int irq, void *arg) netif_rx_schedule(mgp->dev); if (!mgp->msi_enabled) { - put_be32(0, mgp->irq_deassert); + __raw_writel(0, mgp->irq_deassert); if (!myri10ge_deassert_wait) stats->valid = 0; mb(); @@ -1202,7 +1195,7 @@ static irqreturn_t myri10ge_intr(int irq, void *arg) myri10ge_check_statblock(mgp); - put_be32(htonl(3), mgp->irq_claim + 1); + __raw_writel(htonl(3), mgp->irq_claim + 1); return (IRQ_HANDLED); } @@ -1240,7 +1233,7 @@ myri10ge_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coal) struct myri10ge_priv *mgp = netdev_priv(netdev); mgp->intr_coal_delay = coal->rx_coalesce_usecs; - put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr); + __raw_writel(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr); return 0; } @@ -1755,7 +1748,7 @@ static int myri10ge_open(struct net_device *dev) goto abort_with_rings; } - mgp->link_state = htonl(~0U); + mgp->link_state = -1; mgp->rdma_tags_available = 15; netif_poll_enable(mgp->dev); /* must happen prior to any irq */ @@ -1883,7 +1876,7 @@ myri10ge_submit_req(struct myri10ge_tx_buf *tx, struct mcp_kreq_ether_send *src, /* re-write the last 32-bits with the valid flags */ src->flags = last_flags; - put_be32(*((__be32 *) src + 3), (__be32 __iomem *) dst + 3); + __raw_writel(*((u32 *) src + 3), (u32 __iomem *) dst + 3); tx->req += cnt; mb(); } @@ -1926,8 +1919,7 @@ static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev) struct myri10ge_tx_buf *tx = &mgp->tx; struct skb_frag_struct *frag; dma_addr_t bus; - u32 low; - __be32 high_swapped; + u32 low, high_swapped; unsigned int len; int idx, last_idx, avail, frag_cnt, frag_idx, count, mss, max_segments; u16 pseudo_hdr_offset, cksum_offset; @@ -1972,6 +1964,7 @@ static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev) cksum_offset = 0; pseudo_hdr_offset = 0; } else { + pseudo_hdr_offset = htons(pseudo_hdr_offset); odd_flag = MXGEFW_FLAGS_ALIGN_ODD; flags |= MXGEFW_FLAGS_CKSUM; } @@ -1993,7 +1986,7 @@ static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev) /* for TSO, pseudo_hdr_offset holds mss. * The firmware figures out where to put * the checksum by parsing the header. */ - pseudo_hdr_offset = mss; + pseudo_hdr_offset = htons(mss); } else #endif /*NETIF_F_TSO */ /* Mark small packets, and pad out tiny packets */ @@ -2093,7 +2086,7 @@ static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev) #endif /* NETIF_F_TSO */ req->addr_high = high_swapped; req->addr_low = htonl(low); - req->pseudo_hdr_offset = htons(pseudo_hdr_offset); + req->pseudo_hdr_offset = pseudo_hdr_offset; req->pad = 0; /* complete solid 16-byte block; does this matter? */ req->rdma_count = 1; req->length = htons(seglen); @@ -2206,7 +2199,6 @@ static void myri10ge_set_multicast_list(struct net_device *dev) struct myri10ge_cmd cmd; struct myri10ge_priv *mgp; struct dev_mc_list *mc_list; - __be32 data[2] = {0, 0}; int err; mgp = netdev_priv(dev); @@ -2245,9 +2237,10 @@ static void myri10ge_set_multicast_list(struct net_device *dev) /* Walk the multicast list, and add each address */ for (mc_list = dev->mc_list; mc_list != NULL; mc_list = mc_list->next) { - memcpy(data, &mc_list->dmi_addr, 6); - cmd.data0 = ntohl(data[0]); - cmd.data1 = ntohl(data[1]); + memcpy(&cmd.data0, &mc_list->dmi_addr, 4); + memcpy(&cmd.data1, ((char *)&mc_list->dmi_addr) + 4, 2); + cmd.data0 = htonl(cmd.data0); + cmd.data1 = htonl(cmd.data1); err = myri10ge_send_cmd(mgp, MXGEFW_JOIN_MULTICAST_GROUP, &cmd, 1); @@ -2622,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; @@ -2895,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/myri10ge/myri10ge_mcp.h b/trunk/drivers/net/myri10ge/myri10ge_mcp.h index 29463b301a84..9519ae7cd5ec 100644 --- a/trunk/drivers/net/myri10ge/myri10ge_mcp.h +++ b/trunk/drivers/net/myri10ge/myri10ge_mcp.h @@ -6,23 +6,23 @@ /* 8 Bytes */ struct mcp_dma_addr { - __be32 high; - __be32 low; + u32 high; + u32 low; }; /* 4 Bytes */ struct mcp_slot { - __sum16 checksum; - __be16 length; + u16 checksum; + u16 length; }; /* 64 Bytes */ struct mcp_cmd { - __be32 cmd; - __be32 data0; /* will be low portion if data > 32 bits */ + u32 cmd; + u32 data0; /* will be low portion if data > 32 bits */ /* 8 */ - __be32 data1; /* will be high portion if data > 32 bits */ - __be32 data2; /* currently unused.. */ + u32 data1; /* will be high portion if data > 32 bits */ + u32 data2; /* currently unused.. */ /* 16 */ struct mcp_dma_addr response_addr; /* 24 */ @@ -31,8 +31,8 @@ struct mcp_cmd { /* 8 Bytes */ struct mcp_cmd_response { - __be32 data; - __be32 result; + u32 data; + u32 result; }; /* @@ -73,10 +73,10 @@ union mcp_pso_or_cumlen { /* 16 Bytes */ struct mcp_kreq_ether_send { - __be32 addr_high; - __be32 addr_low; - __be16 pseudo_hdr_offset; - __be16 length; + u32 addr_high; + u32 addr_low; + u16 pseudo_hdr_offset; + u16 length; u8 pad; u8 rdma_count; u8 cksum_offset; /* where to start computing cksum */ @@ -85,8 +85,8 @@ struct mcp_kreq_ether_send { /* 8 Bytes */ struct mcp_kreq_ether_recv { - __be32 addr_high; - __be32 addr_low; + u32 addr_high; + u32 addr_low; }; /* Commands */ @@ -219,19 +219,19 @@ enum myri10ge_mcp_cmd_status { struct mcp_irq_data { /* add new counters at the beginning */ - __be32 future_use[5]; - __be32 dropped_multicast_filtered; + u32 future_use[5]; + u32 dropped_multicast_filtered; /* 40 Bytes */ - __be32 send_done_count; - - __be32 link_up; - __be32 dropped_link_overflow; - __be32 dropped_link_error_or_filtered; - __be32 dropped_runt; - __be32 dropped_overrun; - __be32 dropped_no_small_buffer; - __be32 dropped_no_big_buffer; - __be32 rdma_tags_available; + u32 send_done_count; + + u32 link_up; + u32 dropped_link_overflow; + u32 dropped_link_error_or_filtered; + u32 dropped_runt; + u32 dropped_overrun; + u32 dropped_no_small_buffer; + u32 dropped_no_big_buffer; + u32 rdma_tags_available; u8 tx_stopped; u8 link_down; diff --git a/trunk/drivers/net/myri10ge/myri10ge_mcp_gen_header.h b/trunk/drivers/net/myri10ge/myri10ge_mcp_gen_header.h index 16a810dd6d51..487f7792fd46 100644 --- a/trunk/drivers/net/myri10ge/myri10ge_mcp_gen_header.h +++ b/trunk/drivers/net/myri10ge/myri10ge_mcp_gen_header.h @@ -36,7 +36,7 @@ struct mcp_gen_header { /* the first 4 fields are filled at compile time */ unsigned header_length; - __be32 mcp_type; + unsigned mcp_type; char version[128]; unsigned mcp_globals; /* pointer to mcp-type specific structure */ diff --git a/trunk/drivers/net/ne.c b/trunk/drivers/net/ne.c index a5c4199e2754..787aa4221528 100644 --- a/trunk/drivers/net/ne.c +++ b/trunk/drivers/net/ne.c @@ -867,7 +867,7 @@ static void cleanup_card(struct net_device *dev) release_region(dev->base_addr, NE_IO_EXTENT); } -void __exit cleanup_module(void) +void cleanup_module(void) { int this_dev; diff --git a/trunk/drivers/net/ne2.c b/trunk/drivers/net/ne2.c index 089b5bb702fc..5fccfea66d87 100644 --- a/trunk/drivers/net/ne2.c +++ b/trunk/drivers/net/ne2.c @@ -813,7 +813,7 @@ static void cleanup_card(struct net_device *dev) release_region(dev->base_addr, NE_IO_EXTENT); } -void __exit cleanup_module(void) +void cleanup_module(void) { int this_dev; diff --git a/trunk/drivers/net/netxen/netxen_nic.h b/trunk/drivers/net/netxen/netxen_nic.h index b5410bee5f21..d925053fe597 100644 --- a/trunk/drivers/net/netxen/netxen_nic.h +++ b/trunk/drivers/net/netxen/netxen_nic.h @@ -1,25 +1,25 @@ /* * Copyright (C) 2003 - 2006 NetXen, Inc. * All rights reserved. - * + * * 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. - * + * * The full GNU General Public License is included in this distribution * in the file called LICENSE. - * + * * Contact Information: * info@netxen.com * NetXen, @@ -63,68 +63,40 @@ #include "netxen_nic_hw.h" -#define NETXEN_NIC_BUILD_NO "1" -#define _NETXEN_NIC_LINUX_MAJOR 3 +#define NETXEN_NIC_BUILD_NO "5" +#define _NETXEN_NIC_LINUX_MAJOR 2 #define _NETXEN_NIC_LINUX_MINOR 3 -#define _NETXEN_NIC_LINUX_SUBVERSION 2 -#define NETXEN_NIC_LINUX_VERSIONID "3.3.2" "-" NETXEN_NIC_BUILD_NO -#define NETXEN_NIC_FW_VERSIONID "3.3.2" +#define _NETXEN_NIC_LINUX_SUBVERSION 59 +#define NETXEN_NIC_LINUX_VERSIONID "2.3.59" "-" NETXEN_NIC_BUILD_NO +#define NETXEN_NIC_FW_VERSIONID "2.3.59" #define RCV_DESC_RINGSIZE \ (sizeof(struct rcv_desc) * adapter->max_rx_desc_count) #define STATUS_DESC_RINGSIZE \ (sizeof(struct status_desc)* adapter->max_rx_desc_count) -#define LRO_DESC_RINGSIZE \ - (sizeof(rcvDesc_t) * adapter->max_lro_rx_desc_count) #define TX_RINGSIZE \ (sizeof(struct netxen_cmd_buffer) * adapter->max_tx_desc_count) #define RCV_BUFFSIZE \ (sizeof(struct netxen_rx_buffer) * rcv_desc->max_rx_desc_count) #define find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a))) -#define NETXEN_NETDEV_STATUS 0x1 -#define NETXEN_RCV_PRODUCER_OFFSET 0 -#define NETXEN_RCV_PEG_DB_ID 2 -#define NETXEN_HOST_DUMMY_DMA_SIZE 1024 +#define NETXEN_NETDEV_STATUS 0x1 #define ADDR_IN_WINDOW1(off) \ ((off > NETXEN_CRB_PCIX_HOST2) && (off < NETXEN_CRB_MAX)) ? 1 : 0 -/* - * In netxen_nic_down(), we must wait for any pending callback requests into - * netxen_watchdog_task() to complete; eg otherwise the watchdog_timer could be - * reenabled right after it is deleted in netxen_nic_down(). FLUSH_SCHEDULED_WORK() - * does this synchronization. - * - * Normally, schedule_work()/flush_scheduled_work() could have worked, but - * netxen_nic_close() is invoked with kernel rtnl lock held. netif_carrier_off() - * call in netxen_nic_close() triggers a schedule_work(&linkwatch_work), and a - * subsequent call to flush_scheduled_work() in netxen_nic_down() would cause - * linkwatch_event() to be executed which also attempts to acquire the rtnl - * lock thus causing a deadlock. - */ - -#define SCHEDULE_WORK(tp) queue_work(netxen_workq, tp) -#define FLUSH_SCHEDULED_WORK() flush_workqueue(netxen_workq) -extern struct workqueue_struct *netxen_workq; /* * normalize a 64MB crb address to 32MB PCI window * To use NETXEN_CRB_NORMALIZE, window _must_ be set to 1 */ -#define NETXEN_CRB_NORMAL(reg) \ - ((reg) - NETXEN_CRB_PCIX_HOST2 + NETXEN_CRB_PCIX_HOST) +#define NETXEN_CRB_NORMAL(reg) \ + (reg) - NETXEN_CRB_PCIX_HOST2 + NETXEN_CRB_PCIX_HOST #define NETXEN_CRB_NORMALIZE(adapter, reg) \ pci_base_offset(adapter, NETXEN_CRB_NORMAL(reg)) -#define DB_NORMALIZE(adapter, off) \ - (adapter->ahw.db_base + (off)) - -#define NX_P2_C0 0x24 -#define NX_P2_C1 0x25 - #define FIRST_PAGE_GROUP_START 0 -#define FIRST_PAGE_GROUP_END 0x100000 +#define FIRST_PAGE_GROUP_END 0x400000 #define SECOND_PAGE_GROUP_START 0x4000000 #define SECOND_PAGE_GROUP_END 0x66BC000 @@ -136,13 +108,11 @@ extern struct workqueue_struct *netxen_workq; #define SECOND_PAGE_GROUP_SIZE SECOND_PAGE_GROUP_END - SECOND_PAGE_GROUP_START #define THIRD_PAGE_GROUP_SIZE THIRD_PAGE_GROUP_END - THIRD_PAGE_GROUP_START -#define MAX_RX_BUFFER_LENGTH 1760 +#define MAX_RX_BUFFER_LENGTH 2000 #define MAX_RX_JUMBO_BUFFER_LENGTH 9046 -#define MAX_RX_LRO_BUFFER_LENGTH ((48*1024)-512) -#define RX_DMA_MAP_LEN (MAX_RX_BUFFER_LENGTH - 2) +#define RX_DMA_MAP_LEN (MAX_RX_BUFFER_LENGTH - NET_IP_ALIGN) #define RX_JUMBO_DMA_MAP_LEN \ - (MAX_RX_JUMBO_BUFFER_LENGTH - 2) -#define RX_LRO_DMA_MAP_LEN (MAX_RX_LRO_BUFFER_LENGTH - 2) + (MAX_RX_JUMBO_BUFFER_LENGTH - NET_IP_ALIGN) #define NETXEN_ROM_ROUNDUP 0x80000000ULL /* @@ -181,38 +151,30 @@ enum { /* Host writes the following to notify that it has done the init-handshake */ #define PHAN_INITIALIZE_ACK 0xf00f -#define NUM_RCV_DESC_RINGS 3 /* No of Rcv Descriptor contexts */ +#define NUM_RCV_DESC_RINGS 2 /* No of Rcv Descriptor contexts */ /* descriptor types */ #define RCV_DESC_NORMAL 0x01 #define RCV_DESC_JUMBO 0x02 -#define RCV_DESC_LRO 0x04 #define RCV_DESC_NORMAL_CTXID 0 #define RCV_DESC_JUMBO_CTXID 1 -#define RCV_DESC_LRO_CTXID 2 #define RCV_DESC_TYPE(ID) \ - ((ID == RCV_DESC_JUMBO_CTXID) \ - ? RCV_DESC_JUMBO \ - : ((ID == RCV_DESC_LRO_CTXID) \ - ? RCV_DESC_LRO : \ - (RCV_DESC_NORMAL))) + ((ID == RCV_DESC_JUMBO_CTXID) ? RCV_DESC_JUMBO : RCV_DESC_NORMAL) #define MAX_CMD_DESCRIPTORS 1024 #define MAX_RCV_DESCRIPTORS 32768 -#define MAX_JUMBO_RCV_DESCRIPTORS 4096 -#define MAX_LRO_RCV_DESCRIPTORS 2048 +#define MAX_JUMBO_RCV_DESCRIPTORS 1024 #define MAX_RCVSTATUS_DESCRIPTORS MAX_RCV_DESCRIPTORS #define MAX_JUMBO_RCV_DESC MAX_JUMBO_RCV_DESCRIPTORS #define MAX_RCV_DESC MAX_RCV_DESCRIPTORS #define MAX_RCVSTATUS_DESC MAX_RCV_DESCRIPTORS +#define NUM_RCV_DESC (MAX_RCV_DESC + MAX_JUMBO_RCV_DESCRIPTORS) #define MAX_EPG_DESCRIPTORS (MAX_CMD_DESCRIPTORS * 8) -#define NUM_RCV_DESC (MAX_RCV_DESC + MAX_JUMBO_RCV_DESCRIPTORS + \ - MAX_LRO_RCV_DESCRIPTORS) + #define MIN_TX_COUNT 4096 #define MIN_RX_COUNT 4096 -#define NETXEN_CTX_SIGNATURE 0xdee0 -#define NETXEN_RCV_PRODUCER(ringid) (ringid) + #define MAX_FRAME_SIZE 0x10000 /* 64K MAX size for LSO */ #define PHAN_PEG_RCV_INITIALIZED 0xff01 @@ -224,67 +186,6 @@ enum { #define get_index_range(index,length,count) \ (((index) + (count)) & ((length) - 1)) -#define MPORT_SINGLE_FUNCTION_MODE 0x1111 - -extern unsigned long long netxen_dma_mask; - -/* - * NetXen host-peg signal message structure - * - * Bit 0-1 : peg_id => 0x2 for tx and 01 for rx - * Bit 2 : priv_id => must be 1 - * Bit 3-17 : count => for doorbell - * Bit 18-27 : ctx_id => Context id - * Bit 28-31 : opcode - */ - -typedef u32 netxen_ctx_msg; - -#define _netxen_set_bits(config_word, start, bits, val) {\ - unsigned long long mask = (((1ULL << (bits)) - 1) << (start)); \ - unsigned long long value = (val); \ - (config_word) &= ~mask; \ - (config_word) |= (((value) << (start)) & mask); \ -} - -#define netxen_set_msg_peg_id(config_word, val) \ - _netxen_set_bits(config_word, 0, 2, val) -#define netxen_set_msg_privid(config_word) \ - set_bit(2, (unsigned long*)&config_word) -#define netxen_set_msg_count(config_word, val) \ - _netxen_set_bits(config_word, 3, 15, val) -#define netxen_set_msg_ctxid(config_word, val) \ - _netxen_set_bits(config_word, 18, 10, val) -#define netxen_set_msg_opcode(config_word, val) \ - _netxen_set_bits(config_word, 28, 4, val) - -struct netxen_rcv_context { - u32 rcv_ring_addr_lo; - u32 rcv_ring_addr_hi; - u32 rcv_ring_size; - u32 rsrvd; -}; - -struct netxen_ring_ctx { - - /* one command ring */ - u64 cmd_consumer_offset; - u32 cmd_ring_addr_lo; - u32 cmd_ring_addr_hi; - u32 cmd_ring_size; - u32 rsrvd; - - /* three receive rings */ - struct netxen_rcv_context rcv_ctx[3]; - - /* one status ring */ - u32 sts_ring_addr_lo; - u32 sts_ring_addr_hi; - u32 sts_ring_size; - - u32 ctx_id; -} __attribute__ ((aligned(64))); - /* * Following data structures describe the descriptors that will be used. * Added fileds of tcpHdrSize and ipHdrSize, The driver needs to do it only when @@ -302,32 +203,22 @@ struct netxen_ring_ctx { #define FLAGS_IPSEC_SA_DELETE 0x08 #define FLAGS_VLAN_TAGGED 0x10 -#define netxen_set_cmd_desc_port(cmd_desc, var) \ - ((cmd_desc)->port_ctxid |= ((var) & 0x0F)) +#define CMD_DESC_TOTAL_LENGTH(cmd_desc) \ + ((cmd_desc)->length_tcp_hdr & 0x00FFFFFF) +#define CMD_DESC_TCP_HDR_OFFSET(cmd_desc) \ + (((cmd_desc)->length_tcp_hdr >> 24) & 0x0FF) +#define CMD_DESC_PORT(cmd_desc) ((cmd_desc)->port_ctxid & 0x0F) +#define CMD_DESC_CTX_ID(cmd_desc) (((cmd_desc)->port_ctxid >> 4) & 0x0F) -#define netxen_set_cmd_desc_flags(cmd_desc, val) \ - _netxen_set_bits((cmd_desc)->flags_opcode, 0, 7, val) -#define netxen_set_cmd_desc_opcode(cmd_desc, val) \ - _netxen_set_bits((cmd_desc)->flags_opcode, 7, 6, val) - -#define netxen_set_cmd_desc_num_of_buff(cmd_desc, val) \ - _netxen_set_bits((cmd_desc)->num_of_buffers_total_length, 0, 8, val); -#define netxen_set_cmd_desc_totallength(cmd_desc, val) \ - _netxen_set_bits((cmd_desc)->num_of_buffers_total_length, 8, 24, val); - -#define netxen_get_cmd_desc_opcode(cmd_desc) \ - (((cmd_desc)->flags_opcode >> 7) & 0x003F) -#define netxen_get_cmd_desc_totallength(cmd_desc) \ - (((cmd_desc)->num_of_buffers_total_length >> 8) & 0x0FFFFFF) +#define CMD_DESC_TOTAL_LENGTH_WRT(cmd_desc, var) \ + ((cmd_desc)->length_tcp_hdr |= ((var) & 0x00FFFFFF)) +#define CMD_DESC_TCP_HDR_OFFSET_WRT(cmd_desc, var) \ + ((cmd_desc)->length_tcp_hdr |= (((var) << 24) & 0xFF000000)) +#define CMD_DESC_PORT_WRT(cmd_desc, var) \ + ((cmd_desc)->port_ctxid |= ((var) & 0x0F)) struct cmd_desc_type0 { - u8 tcp_hdr_offset; /* For LSO only */ - u8 ip_hdr_offset; /* For LSO only */ - /* Bit pattern: 0-6 flags, 7-12 opcode, 13-15 unused */ - u16 flags_opcode; - /* Bit pattern: 0-7 total number of segments, - 8-31 Total size of the packet */ - u32 num_of_buffers_total_length; + u64 netxen_next; /* for fragments handled by Phantom */ union { struct { u32 addr_low_part2; @@ -336,6 +227,13 @@ struct cmd_desc_type0 { u64 addr_buffer2; }; + /* Bit pattern: 0-23 total length, 24-32 tcp header offset */ + u32 length_tcp_hdr; + u8 ip_hdr_offset; /* For LSO only */ + u8 num_of_buffers; /* total number of segments */ + u8 flags; /* as defined above */ + u8 opcode; + u16 reference_handle; /* changed to u16 to add mss */ u16 mss; /* passed by NDIS_PACKET for LSO */ /* Bit pattern 0-3 port, 0-3 ctx id */ @@ -350,6 +248,7 @@ struct cmd_desc_type0 { }; u64 addr_buffer3; }; + union { struct { u32 addr_low_part1; @@ -371,8 +270,6 @@ struct cmd_desc_type0 { u64 addr_buffer4; }; - u64 unused; - } __attribute__ ((aligned(64))); /* Note: sizeof(rcv_desc) should always be a mutliple of 2 */ @@ -399,49 +296,22 @@ struct rcv_desc { #define NETXEN_PROT_UNKNOWN (0) /* Note: sizeof(status_desc) should always be a mutliple of 2 */ - -#define netxen_get_sts_desc_lro_cnt(status_desc) \ - ((status_desc)->lro & 0x7F) -#define netxen_get_sts_desc_lro_last_frag(status_desc) \ - (((status_desc)->lro & 0x80) >> 7) - -#define netxen_get_sts_port(status_desc) \ - ((status_desc)->status_desc_data & 0x0F) -#define netxen_get_sts_status(status_desc) \ - (((status_desc)->status_desc_data >> 4) & 0x0F) -#define netxen_get_sts_type(status_desc) \ - (((status_desc)->status_desc_data >> 8) & 0x0F) -#define netxen_get_sts_totallength(status_desc) \ - (((status_desc)->status_desc_data >> 12) & 0xFFFF) -#define netxen_get_sts_refhandle(status_desc) \ - (((status_desc)->status_desc_data >> 28) & 0xFFFF) -#define netxen_get_sts_prot(status_desc) \ - (((status_desc)->status_desc_data >> 44) & 0x0F) -#define netxen_get_sts_owner(status_desc) \ - (((status_desc)->status_desc_data >> 56) & 0x03) -#define netxen_get_sts_opcode(status_desc) \ - (((status_desc)->status_desc_data >> 58) & 0x03F) - -#define netxen_clear_sts_owner(status_desc) \ - ((status_desc)->status_desc_data &= \ - ~(((unsigned long long)3) << 56 )) -#define netxen_set_sts_owner(status_desc, val) \ - ((status_desc)->status_desc_data |= \ - (((unsigned long long)((val) & 0x3)) << 56 )) +#define STATUS_DESC_PORT(status_desc) \ + ((status_desc)->port_status_type_op & 0x0F) +#define STATUS_DESC_STATUS(status_desc) \ + (((status_desc)->port_status_type_op >> 4) & 0x0F) +#define STATUS_DESC_TYPE(status_desc) \ + (((status_desc)->port_status_type_op >> 8) & 0x0F) +#define STATUS_DESC_OPCODE(status_desc) \ + (((status_desc)->port_status_type_op >> 12) & 0x0F) struct status_desc { - /* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-27 total_length - 28-43 reference_handle, 44-47 protocol, 48-52 unused - 53-55 desc_cnt, 56-57 owner, 58-63 opcode - */ - u64 status_desc_data; - u32 hash_value; - u8 hash_type; - u8 msg_type; - u8 unused; - /* Bit pattern: 0-6 lro_count indicates frag sequence, - 7 last_frag indicates last frag */ - u8 lro; + /* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-15 opcode */ + u16 port_status_type_op; + u16 total_length; /* NIC mode */ + u16 reference_handle; /* handle for the associated packet */ + /* Bit pattern: 0-1 owner, 2-5 protocol */ + u16 owner; /* Owner of the descriptor */ } __attribute__ ((aligned(8))); enum { @@ -689,12 +559,11 @@ typedef enum { #define PRIMARY_START (BOOTLD_START) #define FLASH_CRBINIT_SIZE (0x4000) #define FLASH_BRDCFG_SIZE (sizeof(struct netxen_board_info)) -#define FLASH_USER_SIZE (sizeof(struct netxen_user_info)/sizeof(u32)) +#define FLASH_USER_SIZE (sizeof(netxen_user_info)/sizeof(u32)) #define FLASH_SECONDARY_SIZE (USER_START-SECONDARY_START) #define NUM_PRIMARY_SECTORS (0x20) #define NUM_CONFIG_SECTORS (1) -#define PFX "NetXen: " -extern char netxen_nic_driver_name[]; +#define PFX "netxen: " /* Note: Make sure to not call this before adapter->port is valid */ #if !defined(NETXEN_DEBUG) @@ -703,7 +572,7 @@ extern char netxen_nic_driver_name[]; #else #define DPRINTK(klevel, fmt, args...) do { \ printk(KERN_##klevel PFX "%s: %s: " fmt, __FUNCTION__,\ - (adapter != NULL && \ + (adapter != NULL && adapter->port != NULL && \ adapter->port[0] != NULL && \ adapter->port[0]->netdev != NULL) ? \ adapter->port[0]->netdev->name : NULL, \ @@ -740,6 +609,7 @@ struct netxen_cmd_buffer { u8 frag_count; unsigned long time_stamp; u32 state; + u32 no_of_descriptors; }; /* In rx_buffer, we do not need multiple fragments as is a single buffer */ @@ -748,9 +618,6 @@ struct netxen_rx_buffer { u64 dma; u16 ref_handle; u16 state; - u32 lro_expected_frags; - u32 lro_current_frags; - u32 lro_length; }; /* Board types */ @@ -766,8 +633,6 @@ struct netxen_hardware_context { void __iomem *pci_base0; void __iomem *pci_base1; void __iomem *pci_base2; - void __iomem *db_base; - unsigned long db_len; u8 revision_id; u16 board_type; @@ -777,13 +642,14 @@ struct netxen_hardware_context { u32 qg_linksup; /* Address of cmd ring in Phantom */ struct cmd_desc_type0 *cmd_desc_head; + char *pauseaddr; struct pci_dev *cmd_desc_pdev; dma_addr_t cmd_desc_phys_addr; + dma_addr_t pause_physaddr; + struct pci_dev *pause_pdev; struct netxen_adapter *adapter; }; -#define RCV_RING_LRO RCV_DESC_LRO - #define MINIMUM_ETHERNET_FRAME_SIZE 64 /* With FCS */ #define ETHERNET_FCS_SIZE 4 @@ -836,13 +702,8 @@ struct netxen_recv_context { }; #define NETXEN_NIC_MSI_ENABLED 0x02 -#define NETXEN_DMA_MASK 0xfffffffe -#define NETXEN_DB_MAPSIZE_BYTES 0x1000 -struct netxen_dummy_dma { - void *addr; - dma_addr_t phys_addr; -}; +struct netxen_drvops; struct netxen_adapter { struct netxen_hardware_context ahw; @@ -853,19 +714,17 @@ 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; u32 cmd_producer; - u32 *cmd_consumer; + u32 cmd_consumer; u32 last_cmd_consumer; u32 max_tx_desc_count; u32 max_rx_desc_count; u32 max_jumbo_rx_desc_count; - u32 max_lro_rx_desc_count; /* Num of instances active on cmd buffer ring */ u32 proc_cmd_buf_counter; @@ -887,27 +746,8 @@ struct netxen_adapter { struct netxen_recv_context recv_ctx[MAX_RCV_CTX]; int is_up; - int number; - struct netxen_dummy_dma dummy_dma; - - /* Context interface shared between card and host */ - struct netxen_ring_ctx *ctx_desc; - struct pci_dev *ctx_desc_pdev; - dma_addr_t ctx_desc_phys_addr; - int (*enable_phy_interrupts) (struct netxen_adapter *, int); - int (*disable_phy_interrupts) (struct netxen_adapter *, int); - void (*handle_phy_intr) (struct netxen_adapter *); - int (*macaddr_set) (struct netxen_port *, netxen_ethernet_macaddr_t); - int (*set_mtu) (struct netxen_port *, int); - int (*set_promisc) (struct netxen_adapter *, int, - netxen_niu_prom_mode_t); - int (*unset_promisc) (struct netxen_adapter *, int, - netxen_niu_prom_mode_t); - int (*phy_read) (struct netxen_adapter *, long phy, long reg, u32 *); - int (*phy_write) (struct netxen_adapter *, long phy, long reg, u32 val); - int (*init_port) (struct netxen_adapter *, int); - void (*init_niu) (struct netxen_adapter *); - int (*stop_port) (struct netxen_adapter *, int); + int work_done; + struct netxen_drvops *ops; }; /* netxen_adapter structure */ /* Max number of xmit producer threads that can run simultaneously */ @@ -989,6 +829,25 @@ static inline void __iomem *pci_base(struct netxen_adapter *adapter, return NULL; } +struct netxen_drvops { + int (*enable_phy_interrupts) (struct netxen_adapter *, int); + int (*disable_phy_interrupts) (struct netxen_adapter *, int); + void (*handle_phy_intr) (struct netxen_adapter *); + int (*macaddr_set) (struct netxen_port *, netxen_ethernet_macaddr_t); + int (*set_mtu) (struct netxen_port *, int); + int (*set_promisc) (struct netxen_adapter *, int, + netxen_niu_prom_mode_t); + int (*unset_promisc) (struct netxen_adapter *, int, + netxen_niu_prom_mode_t); + int (*phy_read) (struct netxen_adapter *, long phy, long reg, u32 *); + int (*phy_write) (struct netxen_adapter *, long phy, long reg, u32 val); + int (*init_port) (struct netxen_adapter *, int); + void (*init_niu) (struct netxen_adapter *); + int (*stop_port) (struct netxen_adapter *, int); +}; + +extern char netxen_nic_driver_name[]; + int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter, int port); int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter, @@ -1027,20 +886,10 @@ int netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data, int len); int netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data, int len); -int netxen_nic_hw_read_ioctl(struct netxen_adapter *adapter, u64 off, - void *data, int len); -int netxen_nic_hw_write_ioctl(struct netxen_adapter *adapter, u64 off, - void *data, int len); -int netxen_nic_pci_mem_write_ioctl(struct netxen_adapter *adapter, - u64 off, void *data, int size); -int netxen_nic_pci_mem_read_ioctl(struct netxen_adapter *adapter, - u64 off, void *data, int size); void netxen_crb_writelit_adapter(struct netxen_adapter *adapter, unsigned long off, int data); /* Functions from netxen_nic_init.c */ -void netxen_free_adapter_offload(struct netxen_adapter *adapter); -int netxen_initialize_adapter_offload(struct netxen_adapter *adapter); void netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); void netxen_load_firmware(struct netxen_adapter *adapter); int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); @@ -1072,12 +921,10 @@ 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_post_rx_buffers_nodb(struct netxen_adapter *adapter, u32 ctx, - u32 ringid); -int netxen_process_cmd_ring(unsigned long data); +void netxen_process_cmd_ring(unsigned long data); u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max); void netxen_nic_set_multi(struct net_device *netdev); int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu); @@ -1171,6 +1018,7 @@ static inline void get_brd_name_by_type(u32 type, char *name) int netxen_is_flash_supported(struct netxen_adapter *adapter); int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[]); + extern void netxen_change_ringparam(struct netxen_adapter *adapter); extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp); diff --git a/trunk/drivers/net/netxen/netxen_nic_ethtool.c b/trunk/drivers/net/netxen/netxen_nic_ethtool.c index 2ab4885cc950..9a914aeba5bc 100644 --- a/trunk/drivers/net/netxen/netxen_nic_ethtool.c +++ b/trunk/drivers/net/netxen/netxen_nic_ethtool.c @@ -1,25 +1,25 @@ /* * Copyright (C) 2003 - 2006 NetXen, Inc. * All rights reserved. - * + * * 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. - * + * * The full GNU General Public License is included in this distribution * in the file called LICENSE. - * + * * Contact Information: * info@netxen.com * NetXen, @@ -118,7 +118,7 @@ netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) u32 fw_minor = 0; u32 fw_build = 0; - strncpy(drvinfo->driver, netxen_nic_driver_name, 32); + strncpy(drvinfo->driver, "netxen_nic", 32); strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32); fw_major = readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_FW_VERSION_MAJOR)); @@ -210,6 +210,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) printk(KERN_ERR "netxen-nic: Unsupported board model %d\n", (netxen_brdtype_t) boardinfo->board_type); return -EIO; + } return 0; @@ -225,18 +226,18 @@ netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) /* read which mode */ if (adapter->ahw.board_type == NETXEN_NIC_GBE) { /* autonegotiation */ - if (adapter->phy_write - && adapter->phy_write(adapter, port->portnum, - NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, - (__le32) ecmd->autoneg) != 0) + if (adapter->ops->phy_write + && adapter->ops->phy_write(adapter, port->portnum, + NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, + (__le32) ecmd->autoneg) != 0) return -EIO; else port->link_autoneg = ecmd->autoneg; - if (adapter->phy_read - && adapter->phy_read(adapter, port->portnum, - NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, - &status) != 0) + if (adapter->ops->phy_read + && adapter->ops->phy_read(adapter, port->portnum, + NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, + &status) != 0) return -EIO; /* speed */ @@ -256,10 +257,10 @@ netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) netxen_clear_phy_duplex(status); if (ecmd->duplex == DUPLEX_FULL) netxen_set_phy_duplex(status); - if (adapter->phy_write - && adapter->phy_write(adapter, port->portnum, - NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, - *((int *)&status)) != 0) + if (adapter->ops->phy_write + && adapter->ops->phy_write(adapter, port->portnum, + NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, + *((int *)&status)) != 0) return -EIO; else { port->link_speed = ecmd->speed; @@ -421,10 +422,10 @@ static u32 netxen_nic_get_link(struct net_device *dev) /* read which mode */ if (adapter->ahw.board_type == NETXEN_NIC_GBE) { - if (adapter->phy_read - && adapter->phy_read(adapter, port->portnum, - NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, - &status) != 0) + if (adapter->ops->phy_read + && adapter->ops->phy_read(adapter, port->portnum, + NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, + &status) != 0) return -EIO; else return (netxen_get_phy_link(status)); @@ -459,22 +460,20 @@ netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring) { struct netxen_port *port = netdev_priv(dev); struct netxen_adapter *adapter = port->adapter; - int i; + int i, j; ring->rx_pending = 0; - ring->rx_jumbo_pending = 0; for (i = 0; i < MAX_RCV_CTX; ++i) { - ring->rx_pending += adapter->recv_ctx[i]. - rcv_desc[RCV_DESC_NORMAL_CTXID].rcv_pending; - ring->rx_jumbo_pending += adapter->recv_ctx[i]. - rcv_desc[RCV_DESC_JUMBO_CTXID].rcv_pending; + for (j = 0; j < NUM_RCV_DESC_RINGS; j++) + ring->rx_pending += + adapter->recv_ctx[i].rcv_desc[j].rcv_pending; } ring->rx_max_pending = adapter->max_rx_desc_count; ring->tx_max_pending = adapter->max_tx_desc_count; - ring->rx_jumbo_max_pending = adapter->max_jumbo_rx_desc_count; ring->rx_mini_max_pending = 0; ring->rx_mini_pending = 0; + ring->rx_jumbo_max_pending = 0; ring->rx_jumbo_pending = 0; } @@ -527,10 +526,10 @@ netxen_nic_set_pauseparam(struct net_device *dev, *(u32 *) (&val)); /* set autoneg */ autoneg = pause->autoneg; - if (adapter->phy_write - && adapter->phy_write(adapter, port->portnum, - NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, - (__le32) autoneg) != 0) + if (adapter->ops->phy_write + && adapter->ops->phy_write(adapter, port->portnum, + NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, + (__le32) autoneg) != 0) return -EIO; else { port->link_autoneg = pause->autoneg; diff --git a/trunk/drivers/net/netxen/netxen_nic_hdr.h b/trunk/drivers/net/netxen/netxen_nic_hdr.h index fe8b675f9e72..72c6ec4ee2a0 100644 --- a/trunk/drivers/net/netxen/netxen_nic_hdr.h +++ b/trunk/drivers/net/netxen/netxen_nic_hdr.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2003 - 2006 NetXen, Inc. * All rights reserved. - * + * * 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 @@ -16,10 +16,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. - * + * * The full GNU General Public License is included in this distribution * in the file called LICENSE. - * + * * Contact Information: * info@netxen.com * NetXen, diff --git a/trunk/drivers/net/netxen/netxen_nic_hw.c b/trunk/drivers/net/netxen/netxen_nic_hw.c index 9147b6048dfb..105c24f0ad4c 100644 --- a/trunk/drivers/net/netxen/netxen_nic_hw.c +++ b/trunk/drivers/net/netxen/netxen_nic_hw.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2003 - 2006 NetXen, Inc. * All rights reserved. - * + * * 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 @@ -16,10 +16,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. - * + * * The full GNU General Public License is included in this distribution * in the file called LICENSE. - * + * * Contact Information: * info@netxen.com * NetXen, @@ -42,7 +42,7 @@ #define NETXEN_FLASH_BASE (BOOTLD_START) #define NETXEN_PHANTOM_MEM_BASE (NETXEN_FLASH_BASE) -#define NETXEN_MAX_MTU 8000 + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE +#define NETXEN_MAX_MTU 8000 #define NETXEN_MIN_MTU 64 #define NETXEN_ETH_FCS_SIZE 4 #define NETXEN_ENET_HEADER_SIZE 14 @@ -81,8 +81,8 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p) DPRINTK(INFO, "valid ether addr\n"); memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); - if (adapter->macaddr_set) - adapter->macaddr_set(port, addr->sa_data); + if (adapter->ops->macaddr_set) + adapter->ops->macaddr_set(port, addr->sa_data); return 0; } @@ -99,17 +99,17 @@ void netxen_nic_set_multi(struct net_device *netdev) mc_ptr = netdev->mc_list; if (netdev->flags & IFF_PROMISC) { - if (adapter->set_promisc) - adapter->set_promisc(adapter, - port->portnum, - NETXEN_NIU_PROMISC_MODE); + if (adapter->ops->set_promisc) + adapter->ops->set_promisc(adapter, + port->portnum, + NETXEN_NIU_PROMISC_MODE); } else { - if (adapter->unset_promisc && + if (adapter->ops->unset_promisc && adapter->ahw.boardcfg.board_type != NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) - adapter->unset_promisc(adapter, - port->portnum, - NETXEN_NIU_NON_PROMISC_MODE); + adapter->ops->unset_promisc(adapter, + port->portnum, + NETXEN_NIU_NON_PROMISC_MODE); } if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { netxen_nic_mcr_set_mode_select(netxen_mac_addr_cntl_data, 0x03); @@ -160,8 +160,8 @@ int netxen_nic_change_mtu(struct net_device *netdev, int mtu) return -EINVAL; } - if (adapter->set_mtu) - adapter->set_mtu(port, mtu); + if (adapter->ops->set_mtu) + adapter->ops->set_mtu(port, mtu); netdev->mtu = mtu; return 0; @@ -176,18 +176,22 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) struct netxen_hardware_context *hw = &adapter->ahw; u32 state = 0; void *addr; + void *pause_addr; int loops = 0, err = 0; int ctx, ring; u32 card_cmdring = 0; + struct netxen_rcv_desc_crb *rcv_desc_crb = NULL; struct netxen_recv_context *recv_ctx; struct netxen_rcv_desc_ctx *rcv_desc; - DPRINTK(INFO, "crb_base: %lx %x", NETXEN_PCI_CRBSPACE, + DPRINTK(INFO, "crb_base: %lx %lx", NETXEN_PCI_CRBSPACE, PCI_OFFSET_SECOND_RANGE(adapter, NETXEN_PCI_CRBSPACE)); - DPRINTK(INFO, "cam base: %lx %x", NETXEN_CRB_CAM, + DPRINTK(INFO, "cam base: %lx %lx", NETXEN_CRB_CAM, pci_base_offset(adapter, NETXEN_CRB_CAM)); - DPRINTK(INFO, "cam RAM: %lx %x", NETXEN_CAM_RAM_BASE, + DPRINTK(INFO, "cam RAM: %lx %lx", NETXEN_CAM_RAM_BASE, pci_base_offset(adapter, NETXEN_CAM_RAM_BASE)); + DPRINTK(INFO, "NIC base:%lx %lx\n", NIC_CRB_BASE_PORT1, + pci_base_offset(adapter, NIC_CRB_BASE_PORT1)); /* Window 1 call */ card_cmdring = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_CMDRING)); @@ -222,42 +226,33 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) DPRINTK(INFO, "Recieve Peg ready too. starting stuff\n"); addr = netxen_alloc(adapter->ahw.pdev, - sizeof(struct netxen_ring_ctx) + - sizeof(uint32_t), - (dma_addr_t *) & adapter->ctx_desc_phys_addr, - &adapter->ctx_desc_pdev); + sizeof(struct cmd_desc_type0) * + adapter->max_tx_desc_count, + &hw->cmd_desc_phys_addr, &hw->cmd_desc_pdev); - printk("ctx_desc_phys_addr: 0x%llx\n", - (u64) adapter->ctx_desc_phys_addr); if (addr == NULL) { DPRINTK(ERR, "bad return from pci_alloc_consistent\n"); - err = -ENOMEM; - return err; + return -ENOMEM; } - memset(addr, 0, sizeof(struct netxen_ring_ctx)); - adapter->ctx_desc = (struct netxen_ring_ctx *)addr; - adapter->ctx_desc->cmd_consumer_offset = adapter->ctx_desc_phys_addr - + sizeof(struct netxen_ring_ctx); - adapter->cmd_consumer = (uint32_t *) (((char *)addr) + - sizeof(struct netxen_ring_ctx)); - - addr = pci_alloc_consistent(adapter->ahw.pdev, - sizeof(struct cmd_desc_type0) * - adapter->max_tx_desc_count, - (dma_addr_t *) & hw->cmd_desc_phys_addr); - printk("cmd_desc_phys_addr: 0x%llx\n", (u64) hw->cmd_desc_phys_addr); - if (addr == NULL) { - DPRINTK(ERR, "bad return from pci_alloc_consistent\n"); - netxen_free_hw_resources(adapter); + pause_addr = netxen_alloc(adapter->ahw.pdev, 512, + (dma_addr_t *) & hw->pause_physaddr, + &hw->pause_pdev); + if (pause_addr == NULL) { + DPRINTK(1, ERR, "bad return from pci_alloc_consistent\n"); return -ENOMEM; } - adapter->ctx_desc->cmd_ring_addr_lo = - hw->cmd_desc_phys_addr & 0xffffffffUL; - adapter->ctx_desc->cmd_ring_addr_hi = - ((u64) hw->cmd_desc_phys_addr >> 32); - adapter->ctx_desc->cmd_ring_size = adapter->max_tx_desc_count; + hw->pauseaddr = (char *)pause_addr; + { + u64 *ptr = (u64 *) pause_addr; + *ptr++ = NETXEN_NIC_ZERO_PAUSE_ADDR; + *ptr++ = NETXEN_NIC_ZERO_PAUSE_ADDR; + *ptr++ = NETXEN_NIC_UNIT_PAUSE_ADDR; + *ptr++ = NETXEN_NIC_ZERO_PAUSE_ADDR; + *ptr++ = NETXEN_NIC_EPG_PAUSE_ADDR1; + *ptr++ = NETXEN_NIC_EPG_PAUSE_ADDR2; + } hw->cmd_desc_head = (struct cmd_desc_type0 *)addr; @@ -278,12 +273,6 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) return err; } rcv_desc->desc_head = (struct rcv_desc *)addr; - adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr_lo = - rcv_desc->phys_addr & 0xffffffffUL; - adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr_hi = - ((u64) rcv_desc->phys_addr >> 32); - adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size = - rcv_desc->max_rx_desc_count; } addr = netxen_alloc(adapter->ahw.pdev, STATUS_DESC_RINGSIZE, @@ -297,21 +286,47 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) return err; } recv_ctx->rcv_status_desc_head = (struct status_desc *)addr; - adapter->ctx_desc->sts_ring_addr_lo = - recv_ctx->rcv_status_desc_phys_addr & 0xffffffffUL; - adapter->ctx_desc->sts_ring_addr_hi = - ((u64) recv_ctx->rcv_status_desc_phys_addr >> 32); - adapter->ctx_desc->sts_ring_size = adapter->max_rx_desc_count; + for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { + rcv_desc = &recv_ctx->rcv_desc[ring]; + rcv_desc_crb = + &recv_crb_registers[ctx].rcv_desc_crb[ring]; + DPRINTK(INFO, "ring #%d crb global ring reg 0x%x\n", + ring, rcv_desc_crb->crb_globalrcv_ring); + /* Window = 1 */ + writel(lower32(rcv_desc->phys_addr), + NETXEN_CRB_NORMALIZE(adapter, + rcv_desc_crb-> + crb_globalrcv_ring)); + DPRINTK(INFO, "GLOBAL_RCV_RING ctx %d, addr 0x%x" + " val 0x%llx," + " virt %p\n", ctx, + rcv_desc_crb->crb_globalrcv_ring, + (unsigned long long)rcv_desc->phys_addr, + +rcv_desc->desc_head); + } + /* Window = 1 */ + writel(lower32(recv_ctx->rcv_status_desc_phys_addr), + NETXEN_CRB_NORMALIZE(adapter, + recv_crb_registers[ctx]. + crb_rcvstatus_ring)); + DPRINTK(INFO, "RCVSTATUS_RING, ctx %d, addr 0x%x," + " val 0x%x,virt%p\n", + ctx, + recv_crb_registers[ctx].crb_rcvstatus_ring, + (unsigned long long)recv_ctx->rcv_status_desc_phys_addr, + recv_ctx->rcv_status_desc_head); } /* Window = 1 */ - - writel(lower32(adapter->ctx_desc_phys_addr), - NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_LO)); - writel(upper32(adapter->ctx_desc_phys_addr), - NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_HI)); - writel(NETXEN_CTX_SIGNATURE, - NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_SIGNATURE_REG)); + writel(lower32(hw->pause_physaddr), + NETXEN_CRB_NORMALIZE(adapter, CRB_PAUSE_ADDR_LO)); + writel(upper32(hw->pause_physaddr), + NETXEN_CRB_NORMALIZE(adapter, CRB_PAUSE_ADDR_HI)); + + writel(lower32(hw->cmd_desc_phys_addr), + NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO)); + writel(upper32(hw->cmd_desc_phys_addr), + NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_HI)); return err; } @@ -321,15 +336,6 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter) struct netxen_rcv_desc_ctx *rcv_desc; int ctx, ring; - if (adapter->ctx_desc != NULL) { - pci_free_consistent(adapter->ctx_desc_pdev, - sizeof(struct netxen_ring_ctx) + - sizeof(uint32_t), - adapter->ctx_desc, - adapter->ctx_desc_phys_addr); - adapter->ctx_desc = NULL; - } - if (adapter->ahw.cmd_desc_head != NULL) { pci_free_consistent(adapter->ahw.cmd_desc_pdev, sizeof(struct cmd_desc_type0) * @@ -338,9 +344,11 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter) adapter->ahw.cmd_desc_phys_addr); adapter->ahw.cmd_desc_head = NULL; } - /* Special handling: there are 2 ports on this board */ - if (adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) { - adapter->ahw.max_ports = 2; + if (adapter->ahw.pauseaddr != NULL) { + pci_free_consistent(adapter->ahw.pause_pdev, 512, + adapter->ahw.pauseaddr, + adapter->ahw.pause_physaddr); + adapter->ahw.pauseaddr = NULL; } for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { @@ -375,22 +383,19 @@ void netxen_tso_check(struct netxen_adapter *adapter, desc->total_hdr_length = sizeof(struct ethhdr) + ((skb->nh.iph)->ihl * sizeof(u32)) + ((skb->h.th)->doff * sizeof(u32)); - netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO); + desc->opcode = TX_TCP_LSO; } else if (skb->ip_summed == CHECKSUM_COMPLETE) { if (skb->nh.iph->protocol == IPPROTO_TCP) { - netxen_set_cmd_desc_opcode(desc, TX_TCP_PKT); + desc->opcode = TX_TCP_PKT; } else if (skb->nh.iph->protocol == IPPROTO_UDP) { - netxen_set_cmd_desc_opcode(desc, TX_UDP_PKT); + desc->opcode = TX_UDP_PKT; } else { return; } } adapter->stats.xmitcsummed++; - desc->tcp_hdr_offset = skb->h.raw - skb->data; - netxen_set_cmd_desc_totallength(desc, - cpu_to_le32 - (netxen_get_cmd_desc_totallength - (desc))); + CMD_DESC_TCP_HDR_OFFSET_WRT(desc, skb->h.raw - skb->data); + desc->length_tcp_hdr = cpu_to_le32(desc->length_tcp_hdr); desc->ip_hdr_offset = skb->nh.raw - skb->data; } @@ -643,7 +648,7 @@ void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val) addr = NETXEN_CRB_NORMALIZE(adapter, off); DPRINTK(INFO, "writing to base %lx offset %llx addr %p data %x\n", - pci_base(adapter, off), off, addr, val); + pci_base(adapter, off), off, addr); writel(val, addr); } @@ -655,7 +660,7 @@ int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off) addr = NETXEN_CRB_NORMALIZE(adapter, off); DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n", - pci_base(adapter, off), off, addr); + adapter->ahw.pci_base, off, addr); val = readl(addr); writel(val, addr); @@ -843,8 +848,8 @@ void netxen_nic_stop_all_ports(struct netxen_adapter *adapter) for (port_nr = 0; port_nr < adapter->ahw.max_ports; port_nr++) { port = adapter->port[port_nr]; - if (adapter->stop_port) - adapter->stop_port(adapter, port->portnum); + if (adapter->ops->stop_port) + adapter->ops->stop_port(adapter, port->portnum); } } @@ -868,13 +873,13 @@ void netxen_nic_set_link_parameters(struct netxen_port *port) { struct netxen_adapter *adapter = port->adapter; __le32 status; - __le32 autoneg; + u16 autoneg; __le32 mode; netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, &mode); if (netxen_get_niu_enable_ge(mode)) { /* Gb 10/100/1000 Mbps mode */ - if (adapter->phy_read - && adapter-> + if (adapter->ops->phy_read + && adapter->ops-> phy_read(adapter, port->portnum, NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, &status) == 0) { @@ -904,11 +909,11 @@ void netxen_nic_set_link_parameters(struct netxen_port *port) port->link_duplex = -1; break; } - if (adapter->phy_read - && adapter-> + if (adapter->ops->phy_read + && adapter->ops-> phy_read(adapter, port->portnum, NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, - &autoneg) != 0) + (__le32 *) & autoneg) != 0) port->link_autoneg = autoneg; } else goto link_down; @@ -1003,291 +1008,3 @@ int netxen_crb_read_val(struct netxen_adapter *adapter, unsigned long off) netxen_nic_hw_read_wx(adapter, off, &data, 4); return data; } - -int netxen_nic_hw_write_ioctl(struct netxen_adapter *adapter, u64 off, - void *data, int len) -{ - void *addr; - u64 offset = off; - u8 *mem_ptr = NULL; - unsigned long mem_base; - unsigned long mem_page; - - if (ADDR_IN_WINDOW1(off)) { - addr = NETXEN_CRB_NORMALIZE(adapter, off); - if (!addr) { - mem_base = pci_resource_start(adapter->ahw.pdev, 0); - offset = NETXEN_CRB_NORMAL(off); - mem_page = offset & PAGE_MASK; - if (mem_page != ((offset + len - 1) & PAGE_MASK)) - mem_ptr = - ioremap(mem_base + mem_page, PAGE_SIZE * 2); - else - mem_ptr = - ioremap(mem_base + mem_page, PAGE_SIZE); - if (mem_ptr == 0UL) { - return 1; - } - addr = mem_ptr; - addr += offset & (PAGE_SIZE - 1); - } - } else { - addr = pci_base_offset(adapter, off); - if (!addr) { - mem_base = pci_resource_start(adapter->ahw.pdev, 0); - mem_page = off & PAGE_MASK; - if (mem_page != ((off + len - 1) & PAGE_MASK)) - mem_ptr = - ioremap(mem_base + mem_page, PAGE_SIZE * 2); - else - mem_ptr = - ioremap(mem_base + mem_page, PAGE_SIZE); - if (mem_ptr == 0UL) { - return 1; - } - addr = mem_ptr; - addr += off & (PAGE_SIZE - 1); - } - netxen_nic_pci_change_crbwindow(adapter, 0); - } - switch (len) { - case 1: - writeb(*(u8 *) data, addr); - break; - case 2: - writew(*(u16 *) data, addr); - break; - case 4: - writel(*(u32 *) data, addr); - break; - case 8: - writeq(*(u64 *) data, addr); - break; - default: - DPRINTK(INFO, - "writing data %lx to offset %llx, num words=%d\n", - *(unsigned long *)data, off, (len >> 3)); - - netxen_nic_hw_block_write64((u64 __iomem *) data, addr, - (len >> 3)); - break; - } - - if (!ADDR_IN_WINDOW1(off)) - netxen_nic_pci_change_crbwindow(adapter, 1); - if (mem_ptr) - iounmap(mem_ptr); - return 0; -} - -int netxen_nic_hw_read_ioctl(struct netxen_adapter *adapter, u64 off, - void *data, int len) -{ - void *addr; - u64 offset; - u8 *mem_ptr = NULL; - unsigned long mem_base; - unsigned long mem_page; - - if (ADDR_IN_WINDOW1(off)) { - addr = NETXEN_CRB_NORMALIZE(adapter, off); - if (!addr) { - mem_base = pci_resource_start(adapter->ahw.pdev, 0); - offset = NETXEN_CRB_NORMAL(off); - mem_page = offset & PAGE_MASK; - if (mem_page != ((offset + len - 1) & PAGE_MASK)) - mem_ptr = - ioremap(mem_base + mem_page, PAGE_SIZE * 2); - else - mem_ptr = - ioremap(mem_base + mem_page, PAGE_SIZE); - if (mem_ptr == 0UL) { - *(u8 *) data = 0; - return 1; - } - addr = mem_ptr; - addr += offset & (PAGE_SIZE - 1); - } - } else { - addr = pci_base_offset(adapter, off); - if (!addr) { - mem_base = pci_resource_start(adapter->ahw.pdev, 0); - mem_page = off & PAGE_MASK; - if (mem_page != ((off + len - 1) & PAGE_MASK)) - mem_ptr = - ioremap(mem_base + mem_page, PAGE_SIZE * 2); - else - mem_ptr = - ioremap(mem_base + mem_page, PAGE_SIZE); - if (mem_ptr == 0UL) - return 1; - addr = mem_ptr; - addr += off & (PAGE_SIZE - 1); - } - netxen_nic_pci_change_crbwindow(adapter, 0); - } - switch (len) { - case 1: - *(u8 *) data = readb(addr); - break; - case 2: - *(u16 *) data = readw(addr); - break; - case 4: - *(u32 *) data = readl(addr); - break; - case 8: - *(u64 *) data = readq(addr); - break; - default: - netxen_nic_hw_block_read64((u64 __iomem *) data, addr, - (len >> 3)); - break; - } - if (!ADDR_IN_WINDOW1(off)) - netxen_nic_pci_change_crbwindow(adapter, 1); - if (mem_ptr) - iounmap(mem_ptr); - return 0; -} - -int netxen_nic_pci_mem_write_ioctl(struct netxen_adapter *adapter, u64 off, - void *data, int size) -{ - void *addr; - int ret = 0; - u8 *mem_ptr = NULL; - unsigned long mem_base; - unsigned long mem_page; - - if (data == NULL || off > (128 * 1024 * 1024)) { - printk(KERN_ERR "%s: data: %p off:%llx\n", - netxen_nic_driver_name, data, off); - return 1; - } - off = netxen_nic_pci_set_window(adapter, off); - /* Corner case : Malicious user tried to break the driver by reading - last few bytes in ranges and tries to read further addresses. - */ - if (!pci_base(adapter, off + size - 1) && pci_base(adapter, off)) { - printk(KERN_ERR "%s: Invalid access to memory address range" - " 0x%llx - 0x%llx\n", netxen_nic_driver_name, off, - off + size); - return 1; - } - addr = pci_base_offset(adapter, off); - DPRINTK(INFO, "writing data %llx to offset %llx\n", - *(unsigned long long *)data, off); - if (!addr) { - mem_base = pci_resource_start(adapter->ahw.pdev, 0); - mem_page = off & PAGE_MASK; - /* Map two pages whenever user tries to access addresses in two - consecutive pages. - */ - if (mem_page != ((off + size - 1) & PAGE_MASK)) - mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2); - else - mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE); - if (mem_ptr == 0UL) { - return 1; - } - addr = mem_ptr; - addr += off & (PAGE_SIZE - 1); - } - switch (size) { - case 1: - writeb(*(u8 *) data, addr); - break; - case 2: - writew(*(u16 *) data, addr); - break; - case 4: - writel(*(u32 *) data, addr); - break; - case 8: - writeq(*(u64 *) data, addr); - break; - default: - DPRINTK(INFO, - "writing data %lx to offset %llx, num words=%d\n", - *(unsigned long *)data, off, (size >> 3)); - - netxen_nic_hw_block_write64((u64 __iomem *) data, addr, - (size >> 3)); - break; - } - - if (mem_ptr) - iounmap(mem_ptr); - DPRINTK(INFO, "wrote %llx\n", *(unsigned long long *)data); - - return ret; -} - -int netxen_nic_pci_mem_read_ioctl(struct netxen_adapter *adapter, - u64 off, void *data, int size) -{ - void *addr; - int ret = 0; - u8 *mem_ptr = NULL; - unsigned long mem_base; - unsigned long mem_page; - - if (data == NULL || off > (128 * 1024 * 1024)) { - printk(KERN_ERR "%s: data: %p off:%llx\n", - netxen_nic_driver_name, data, off); - return 1; - } - off = netxen_nic_pci_set_window(adapter, off); - /* Corner case : Malicious user tried to break the driver by reading - last few bytes in ranges and tries to read further addresses. - */ - if (!pci_base(adapter, off + size - 1) && pci_base(adapter, off)) { - printk(KERN_ERR "%s: Invalid access to memory address range" - " 0x%llx - 0x%llx\n", netxen_nic_driver_name, off, - off + size); - return 1; - } - addr = pci_base_offset(adapter, off); - if (!addr) { - mem_base = pci_resource_start(adapter->ahw.pdev, 0); - mem_page = off & PAGE_MASK; - /* Map two pages whenever user tries to access addresses in two - consecutive pages. - */ - if (mem_page != ((off + size - 1) & PAGE_MASK)) - mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2); - else - mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE); - if (mem_ptr == 0UL) { - *(u8 *) data = 0; - return 1; - } - addr = mem_ptr; - addr += off & (PAGE_SIZE - 1); - } - switch (size) { - case 1: - *(u8 *) data = readb(addr); - break; - case 2: - *(u16 *) data = readw(addr); - break; - case 4: - *(u32 *) data = readl(addr); - break; - case 8: - *(u64 *) data = readq(addr); - break; - default: - netxen_nic_hw_block_read64((u64 __iomem *) data, addr, - (size >> 3)); - break; - } - - if (mem_ptr) - iounmap(mem_ptr); - DPRINTK(INFO, "read %llx\n", *(unsigned long long *)data); - - return ret; -} diff --git a/trunk/drivers/net/netxen/netxen_nic_hw.h b/trunk/drivers/net/netxen/netxen_nic_hw.h index 0685633a9c1e..201a636b7ab8 100644 --- a/trunk/drivers/net/netxen/netxen_nic_hw.h +++ b/trunk/drivers/net/netxen/netxen_nic_hw.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2003 - 2006 NetXen, Inc. * All rights reserved. - * + * * 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 @@ -16,10 +16,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. - * + * * The full GNU General Public License is included in this distribution * in the file called LICENSE. - * + * * Contact Information: * info@netxen.com * NetXen, @@ -83,8 +83,8 @@ struct netxen_adapter; #define NETXEN_PCI_MAPSIZE_BYTES (NETXEN_PCI_MAPSIZE << 20) #define NETXEN_NIC_LOCKED_READ_REG(X, Y) \ - addr = pci_base_offset(adapter, X); \ - *(u32 *)Y = readl((void __iomem*) addr); + addr = pci_base_offset(adapter, (X)); \ + *(u32 *)Y = readl(addr); struct netxen_port; void netxen_nic_set_link_parameters(struct netxen_port *port); diff --git a/trunk/drivers/net/netxen/netxen_nic_init.c b/trunk/drivers/net/netxen/netxen_nic_init.c index 290145ec08e7..0dca029bc3e5 100644 --- a/trunk/drivers/net/netxen/netxen_nic_init.c +++ b/trunk/drivers/net/netxen/netxen_nic_init.c @@ -1,25 +1,25 @@ /* * Copyright (C) 2003 - 2006 NetXen, Inc. * All rights reserved. - * + * * 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. - * + * * The full GNU General Public License is included in this distribution * in the file called LICENSE. - * + * * Contact Information: * info@netxen.com * NetXen, @@ -137,8 +137,6 @@ int netxen_init_firmware(struct netxen_adapter *adapter) return err; } /* Window 1 call */ - writel(MPORT_SINGLE_FUNCTION_MODE, - NETXEN_CRB_NORMALIZE(adapter, CRB_MPORT_MODE)); writel(PHAN_INITIALIZE_ACK, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); @@ -186,12 +184,15 @@ void netxen_initialize_adapter_sw(struct netxen_adapter *adapter) for (i = 0; i < num_rx_bufs; i++) { rx_buf->ref_handle = i; rx_buf->state = NETXEN_BUFFER_FREE; + DPRINTK(INFO, "Rx buf:ctx%d i(%d) rx_buf:" "%p\n", ctxid, i, rx_buf); rx_buf++; } } } + DPRINTK(INFO, "initialized buffers for %s and %s\n", + "adapter->free_cmd_buf_list", "adapter->free_rxbuf"); } void netxen_initialize_adapter_hw(struct netxen_adapter *adapter) @@ -211,36 +212,37 @@ void netxen_initialize_adapter_hw(struct netxen_adapter *adapter) void netxen_initialize_adapter_ops(struct netxen_adapter *adapter) { + struct netxen_drvops *ops = adapter->ops; switch (adapter->ahw.board_type) { case NETXEN_NIC_GBE: - adapter->enable_phy_interrupts = + ops->enable_phy_interrupts = netxen_niu_gbe_enable_phy_interrupts; - adapter->disable_phy_interrupts = + ops->disable_phy_interrupts = netxen_niu_gbe_disable_phy_interrupts; - adapter->handle_phy_intr = netxen_nic_gbe_handle_phy_intr; - adapter->macaddr_set = netxen_niu_macaddr_set; - adapter->set_mtu = netxen_nic_set_mtu_gb; - adapter->set_promisc = netxen_niu_set_promiscuous_mode; - adapter->unset_promisc = netxen_niu_set_promiscuous_mode; - adapter->phy_read = netxen_niu_gbe_phy_read; - adapter->phy_write = netxen_niu_gbe_phy_write; - adapter->init_port = netxen_niu_gbe_init_port; - adapter->init_niu = netxen_nic_init_niu_gb; - adapter->stop_port = netxen_niu_disable_gbe_port; + ops->handle_phy_intr = netxen_nic_gbe_handle_phy_intr; + ops->macaddr_set = netxen_niu_macaddr_set; + ops->set_mtu = netxen_nic_set_mtu_gb; + ops->set_promisc = netxen_niu_set_promiscuous_mode; + ops->unset_promisc = netxen_niu_set_promiscuous_mode; + ops->phy_read = netxen_niu_gbe_phy_read; + ops->phy_write = netxen_niu_gbe_phy_write; + ops->init_port = netxen_niu_gbe_init_port; + ops->init_niu = netxen_nic_init_niu_gb; + ops->stop_port = netxen_niu_disable_gbe_port; break; case NETXEN_NIC_XGBE: - adapter->enable_phy_interrupts = + ops->enable_phy_interrupts = netxen_niu_xgbe_enable_phy_interrupts; - adapter->disable_phy_interrupts = + ops->disable_phy_interrupts = netxen_niu_xgbe_disable_phy_interrupts; - adapter->handle_phy_intr = netxen_nic_xgbe_handle_phy_intr; - adapter->macaddr_set = netxen_niu_xg_macaddr_set; - adapter->set_mtu = netxen_nic_set_mtu_xgb; - adapter->init_port = netxen_niu_xg_init_port; - adapter->set_promisc = netxen_niu_xg_set_promiscuous_mode; - adapter->unset_promisc = netxen_niu_xg_set_promiscuous_mode; - adapter->stop_port = netxen_niu_disable_xg_port; + ops->handle_phy_intr = netxen_nic_xgbe_handle_phy_intr; + ops->macaddr_set = netxen_niu_xg_macaddr_set; + ops->set_mtu = netxen_nic_set_mtu_xgb; + ops->init_port = netxen_niu_xg_init_port; + ops->set_promisc = netxen_niu_xg_set_promiscuous_mode; + ops->unset_promisc = netxen_niu_xg_set_promiscuous_mode; + ops->stop_port = netxen_niu_disable_xg_port; break; default: @@ -381,8 +383,8 @@ int netxen_rom_wip_poll(struct netxen_adapter *adapter) return 0; } -static inline int do_rom_fast_write(struct netxen_adapter *adapter, int addr, - int data) +static inline int do_rom_fast_write(struct netxen_adapter *adapter, + int addr, int data) { if (netxen_rom_wren(adapter)) { return -1; @@ -620,43 +622,6 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) return 0; } -int netxen_initialize_adapter_offload(struct netxen_adapter *adapter) -{ - uint64_t addr; - uint32_t hi; - uint32_t lo; - - adapter->dummy_dma.addr = - pci_alloc_consistent(adapter->ahw.pdev, - NETXEN_HOST_DUMMY_DMA_SIZE, - &adapter->dummy_dma.phys_addr); - if (adapter->dummy_dma.addr == NULL) { - printk("%s: ERROR: Could not allocate dummy DMA memory\n", - __FUNCTION__); - return -ENOMEM; - } - - addr = (uint64_t) adapter->dummy_dma.phys_addr; - hi = (addr >> 32) & 0xffffffff; - lo = addr & 0xffffffff; - - writel(hi, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI)); - writel(lo, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO)); - - return 0; -} - -void netxen_free_adapter_offload(struct netxen_adapter *adapter) -{ - if (adapter->dummy_dma.addr) { - pci_free_consistent(adapter->ahw.pdev, - NETXEN_HOST_DUMMY_DMA_SIZE, - adapter->dummy_dma.addr, - adapter->dummy_dma.phys_addr); - adapter->dummy_dma.addr = NULL; - } -} - void netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) { u32 val = 0; @@ -691,8 +656,7 @@ int netxen_nic_rx_has_work(struct netxen_adapter *adapter) desc_head = recv_ctx->rcv_status_desc_head; desc = &desc_head[consumer]; - if (((le16_to_cpu(netxen_get_sts_owner(desc))) - & STATUS_OWNER_HOST)) + if (((le16_to_cpu(desc->owner)) & STATUS_OWNER_HOST)) return 1; } @@ -746,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; @@ -771,8 +734,8 @@ void netxen_watchdog_task(struct work_struct *work) netif_wake_queue(netdev); } - if (adapter->handle_phy_intr) - adapter->handle_phy_intr(adapter); + if (adapter->ops->handle_phy_intr) + adapter->ops->handle_phy_intr(adapter); mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); } @@ -785,19 +748,19 @@ void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, struct status_desc *desc) { - struct netxen_port *port = adapter->port[netxen_get_sts_port(desc)]; + struct netxen_port *port = adapter->port[STATUS_DESC_PORT(desc)]; struct pci_dev *pdev = port->pdev; struct net_device *netdev = port->netdev; - int index = le16_to_cpu(netxen_get_sts_refhandle(desc)); + int index = le16_to_cpu(desc->reference_handle); struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]); struct netxen_rx_buffer *buffer; struct sk_buff *skb; - u32 length = le16_to_cpu(netxen_get_sts_totallength(desc)); + u32 length = le16_to_cpu(desc->total_length); u32 desc_ctx; struct netxen_rcv_desc_ctx *rcv_desc; int ret; - desc_ctx = netxen_get_sts_type(desc); + desc_ctx = STATUS_DESC_TYPE(desc); if (unlikely(desc_ctx >= NUM_RCV_DESC_RINGS)) { printk("%s: %s Bad Rcv descriptor ring\n", netxen_nic_driver_name, netdev->name); @@ -805,49 +768,20 @@ netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, } rcv_desc = &recv_ctx->rcv_desc[desc_ctx]; - if (unlikely(index > rcv_desc->max_rx_desc_count)) { - DPRINTK(ERR, "Got a buffer index:%x Max is %x\n", - index, rcv_desc->max_rx_desc_count); - return; - } buffer = &rcv_desc->rx_buf_arr[index]; - if (desc_ctx == RCV_DESC_LRO_CTXID) { - buffer->lro_current_frags++; - if (netxen_get_sts_desc_lro_last_frag(desc)) { - buffer->lro_expected_frags = - netxen_get_sts_desc_lro_cnt(desc); - buffer->lro_length = length; - } - if (buffer->lro_current_frags != buffer->lro_expected_frags) { - if (buffer->lro_expected_frags != 0) { - printk("LRO: (refhandle:%x) recv frag." - "wait for last. flags: %x expected:%d" - "have:%d\n", index, - netxen_get_sts_desc_lro_last_frag(desc), - buffer->lro_expected_frags, - buffer->lro_current_frags); - } - return; - } - } pci_unmap_single(pdev, buffer->dma, rcv_desc->dma_size, PCI_DMA_FROMDEVICE); skb = (struct sk_buff *)buffer->skb; - if (likely(netxen_get_sts_status(desc) == STATUS_CKSUM_OK)) { + if (likely(STATUS_DESC_STATUS(desc) == STATUS_CKSUM_OK)) { port->stats.csummed++; skb->ip_summed = CHECKSUM_UNNECESSARY; - } + } else + skb->ip_summed = CHECKSUM_NONE; skb->dev = netdev; - if (desc_ctx == RCV_DESC_LRO_CTXID) { - /* True length was only available on the last pkt */ - skb_put(skb, buffer->lro_length); - } else { - skb_put(skb, length); - } - + skb_put(skb, length); skb->protocol = eth_type_trans(skb, netdev); ret = netif_receive_skb(skb); @@ -893,8 +827,6 @@ netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, adapter->stats.post_called++; buffer->skb = NULL; buffer->state = NETXEN_BUFFER_FREE; - buffer->lro_current_frags = 0; - buffer->lro_expected_frags = 0; port->stats.no_rcv++; port->stats.rxbytes += length; @@ -907,7 +839,6 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) struct status_desc *desc_head = recv_ctx->rcv_status_desc_head; struct status_desc *desc; /* used to read status desc here */ u32 consumer = recv_ctx->status_rx_consumer; - u32 producer = 0; int count = 0, ring; DPRINTK(INFO, "procesing receive\n"); @@ -919,22 +850,18 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) */ while (count < max) { desc = &desc_head[consumer]; - if (! - (le16_to_cpu(netxen_get_sts_owner(desc)) & - STATUS_OWNER_HOST)) { - DPRINTK(ERR, "desc %p ownedby %x\n", desc, - netxen_get_sts_owner(desc)); + if (!((le16_to_cpu(desc->owner)) & STATUS_OWNER_HOST)) { + DPRINTK(ERR, "desc %p ownedby %x\n", desc, desc->owner); break; } netxen_process_rcv(adapter, ctxid, desc); - netxen_clear_sts_owner(desc); - netxen_set_sts_owner(desc, STATUS_OWNER_PHANTOM); + desc->owner = STATUS_OWNER_PHANTOM; consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1); count++; } if (count) { for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { - netxen_post_rx_buffers_nodb(adapter, ctxid, ring); + netxen_post_rx_buffers(adapter, ctxid, ring); } } @@ -942,7 +869,6 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) if (count) { adapter->stats.process_rcv++; recv_ctx->status_rx_consumer = consumer; - recv_ctx->status_rx_producer = producer; /* Window = 1 */ writel(consumer, @@ -955,13 +881,12 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) } /* Process Command status ring */ -int netxen_process_cmd_ring(unsigned long data) +void netxen_process_cmd_ring(unsigned long data) { u32 last_consumer; u32 consumer; struct netxen_adapter *adapter = (struct netxen_adapter *)data; - int count1 = 0; - int count2 = 0; + int count = 0; struct netxen_cmd_buffer *buffer; struct netxen_port *port; /* port #1 */ struct netxen_port *nport; @@ -970,7 +895,6 @@ int netxen_process_cmd_ring(unsigned long data) u32 i; struct sk_buff *skb = NULL; int p; - int done; spin_lock(&adapter->tx_lock); last_consumer = adapter->last_cmd_consumer; @@ -980,13 +904,14 @@ int netxen_process_cmd_ring(unsigned long data) * number as part of the descriptor. This way we will be able to get * the netdev which is associated with that device. */ + consumer = + readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_CONSUMER_OFFSET)); - consumer = *(adapter->cmd_consumer); if (last_consumer == consumer) { /* Ring is empty */ DPRINTK(INFO, "last_consumer %d == consumer %d\n", last_consumer, consumer); spin_unlock(&adapter->tx_lock); - return 1; + return; } adapter->proc_cmd_buf_counter++; @@ -997,7 +922,7 @@ int netxen_process_cmd_ring(unsigned long data) */ spin_unlock(&adapter->tx_lock); - while ((last_consumer != consumer) && (count1 < MAX_STATUS_HANDLE)) { + while ((last_consumer != consumer) && (count < MAX_STATUS_HANDLE)) { buffer = &adapter->cmd_buf_arr[last_consumer]; port = adapter->port[buffer->port]; pdev = port->pdev; @@ -1023,25 +948,24 @@ int netxen_process_cmd_ring(unsigned long data) && netif_carrier_ok(port->netdev)) && ((jiffies - port->netdev->trans_start) > port->netdev->watchdog_timeo)) { - SCHEDULE_WORK(port->adapter->tx_timeout_task - + port->portnum); + schedule_work(&port->adapter->tx_timeout_task); } last_consumer = get_next_index(last_consumer, adapter->max_tx_desc_count); - count1++; + count++; } - adapter->stats.noxmitdone += count1; + adapter->stats.noxmitdone += count; - count2 = 0; + count = 0; spin_lock(&adapter->tx_lock); if ((--adapter->proc_cmd_buf_counter) == 0) { adapter->last_cmd_consumer = last_consumer; while ((adapter->last_cmd_consumer != consumer) - && (count2 < MAX_STATUS_HANDLE)) { + && (count < MAX_STATUS_HANDLE)) { buffer = &adapter->cmd_buf_arr[adapter->last_cmd_consumer]; - count2++; + count++; if (buffer->skb) break; else @@ -1050,7 +974,7 @@ int netxen_process_cmd_ring(unsigned long data) adapter->max_tx_desc_count); } } - if (count1 || count2) { + if (count) { for (p = 0; p < adapter->ahw.max_ports; p++) { nport = adapter->port[p]; if (netif_queue_stopped(nport->netdev) @@ -1060,30 +984,10 @@ int netxen_process_cmd_ring(unsigned long data) } } } - /* - * If everything is freed up to consumer then check if the ring is full - * If the ring is full then check if more needs to be freed and - * schedule the call back again. - * - * This happens when there are 2 CPUs. One could be freeing and the - * other filling it. If the ring is full when we get out of here and - * the card has already interrupted the host then the host can miss the - * interrupt. - * - * There is still a possible race condition and the host could miss an - * interrupt. The card has to take care of this. - */ - if (adapter->last_cmd_consumer == consumer && - (((adapter->cmd_producer + 1) % - adapter->max_tx_desc_count) == adapter->last_cmd_consumer)) { - consumer = *(adapter->cmd_consumer); - } - done = (adapter->last_cmd_consumer == consumer); spin_unlock(&adapter->tx_lock); DPRINTK(INFO, "last consumer is %d in %s\n", last_consumer, __FUNCTION__); - return (done); } /* @@ -1095,105 +999,8 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) struct sk_buff *skb; struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]); struct netxen_rcv_desc_ctx *rcv_desc = NULL; - uint producer; - struct rcv_desc *pdesc; - struct netxen_rx_buffer *buffer; - int count = 0; - int index = 0; - netxen_ctx_msg msg = 0; - dma_addr_t dma; - - adapter->stats.post_called++; - rcv_desc = &recv_ctx->rcv_desc[ringid]; - - producer = rcv_desc->producer; - index = rcv_desc->begin_alloc; - buffer = &rcv_desc->rx_buf_arr[index]; - /* We can start writing rx descriptors into the phantom memory. */ - while (buffer->state == NETXEN_BUFFER_FREE) { - skb = dev_alloc_skb(rcv_desc->skb_size); - if (unlikely(!skb)) { - /* - * TODO - * We need to schedule the posting of buffers to the pegs. - */ - rcv_desc->begin_alloc = index; - DPRINTK(ERR, "netxen_post_rx_buffers: " - " allocated only %d buffers\n", count); - break; - } - - count++; /* now there should be no failure */ - pdesc = &rcv_desc->desc_head[producer]; - -#if defined(XGB_DEBUG) - *(unsigned long *)(skb->head) = 0xc0debabe; - if (skb_is_nonlinear(skb)) { - printk("Allocated SKB @%p is nonlinear\n"); - } -#endif - skb_reserve(skb, 2); - /* This will be setup when we receive the - * buffer after it has been filled FSL TBD TBD - * skb->dev = netdev; - */ - dma = pci_map_single(pdev, skb->data, rcv_desc->dma_size, - PCI_DMA_FROMDEVICE); - pdesc->addr_buffer = dma; - buffer->skb = skb; - buffer->state = NETXEN_BUFFER_BUSY; - buffer->dma = dma; - /* make a rcv descriptor */ - pdesc->reference_handle = buffer->ref_handle; - pdesc->buffer_length = rcv_desc->dma_size; - DPRINTK(INFO, "done writing descripter\n"); - producer = - get_next_index(producer, rcv_desc->max_rx_desc_count); - index = get_next_index(index, rcv_desc->max_rx_desc_count); - buffer = &rcv_desc->rx_buf_arr[index]; - } - /* if we did allocate buffers, then write the count to Phantom */ - if (count) { - rcv_desc->begin_alloc = index; - rcv_desc->rcv_pending += count; - adapter->stats.lastposted = count; - adapter->stats.posted += count; - rcv_desc->producer = producer; - if (rcv_desc->rcv_free >= 32) { - rcv_desc->rcv_free = 0; - /* Window = 1 */ - writel((producer - 1) & - (rcv_desc->max_rx_desc_count - 1), - NETXEN_CRB_NORMALIZE(adapter, - recv_crb_registers[0]. - rcv_desc_crb[ringid]. - crb_rcv_producer_offset)); - /* - * Write a doorbell msg to tell phanmon of change in - * receive ring producer - */ - netxen_set_msg_peg_id(msg, NETXEN_RCV_PEG_DB_ID); - netxen_set_msg_privid(msg); - netxen_set_msg_count(msg, - ((producer - - 1) & (rcv_desc-> - max_rx_desc_count - 1))); - netxen_set_msg_ctxid(msg, 0); - netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid)); - writel(msg, - DB_NORMALIZE(adapter, - NETXEN_RCV_PRODUCER_OFFSET)); - } - } -} - -void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ctx, - uint32_t ringid) -{ - struct pci_dev *pdev = adapter->ahw.pdev; - struct sk_buff *skb; - struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]); - struct netxen_rcv_desc_ctx *rcv_desc = NULL; + struct netxen_recv_crb *crbarea = &recv_crb_registers[ctx]; + struct netxen_rcv_desc_crb *rcv_desc_crb = NULL; u32 producer; struct rcv_desc *pdesc; struct netxen_rx_buffer *buffer; @@ -1202,6 +1009,7 @@ void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ctx, adapter->stats.post_called++; rcv_desc = &recv_ctx->rcv_desc[ringid]; + rcv_desc_crb = &crbarea->rcv_desc_crb[ringid]; producer = rcv_desc->producer; index = rcv_desc->begin_alloc; @@ -1214,13 +1022,13 @@ void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ctx, * We need to schedule the posting of buffers to the pegs. */ rcv_desc->begin_alloc = index; - DPRINTK(ERR, "netxen_post_rx_buffers_nodb: " + DPRINTK(ERR, "netxen_post_rx_buffers: " " allocated only %d buffers\n", count); break; } count++; /* now there should be no failure */ pdesc = &rcv_desc->desc_head[producer]; - skb_reserve(skb, 2); + skb_reserve(skb, NET_IP_ALIGN); /* * This will be setup when we receive the * buffer after it has been filled @@ -1231,7 +1039,6 @@ void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ctx, buffer->dma = pci_map_single(pdev, skb->data, rcv_desc->dma_size, PCI_DMA_FROMDEVICE); - /* make a rcv descriptor */ pdesc->reference_handle = le16_to_cpu(buffer->ref_handle); pdesc->buffer_length = le16_to_cpu(rcv_desc->dma_size); @@ -1256,8 +1063,7 @@ void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ctx, writel((producer - 1) & (rcv_desc->max_rx_desc_count - 1), NETXEN_CRB_NORMALIZE(adapter, - recv_crb_registers[0]. - rcv_desc_crb[ringid]. + rcv_desc_crb-> crb_rcv_producer_offset)); wmb(); } @@ -1390,8 +1196,8 @@ netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data, switch (data.cmd) { case netxen_nic_cmd_pci_read: - if ((retval = netxen_nic_hw_read_ioctl(adapter, data.off, - &(data.u), data.size))) + if ((retval = netxen_nic_hw_read_wx(adapter, data.off, + &(data.u), data.size))) goto error_out; if (copy_to_user ((void __user *)&(up_data->u), &(data.u), data.size)) { @@ -1404,35 +1210,8 @@ netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data, break; case netxen_nic_cmd_pci_write: - if ((retval = netxen_nic_hw_write_ioctl(adapter, data.off, - &(data.u), data.size))) - goto error_out; - data.rv = 0; - break; - - case netxen_nic_cmd_pci_mem_read: - if (netxen_nic_pci_mem_read_ioctl(adapter, data.off, &(data.u), - data.size)) { - DPRINTK(ERR, "Failed to read the data.\n"); - retval = -EFAULT; - goto error_out; - } - if (copy_to_user - ((void __user *)&(up_data->u), &(data.u), data.size)) { - DPRINTK(ERR, "bad copy to userland: %d\n", - (int)sizeof(data)); - retval = -EFAULT; - goto error_out; - } - data.rv = 0; - break; - - case netxen_nic_cmd_pci_mem_write: - if ((retval = netxen_nic_pci_mem_write_ioctl(adapter, data.off, - &(data.u), - data.size))) - goto error_out; - data.rv = 0; + data.rv = netxen_nic_hw_write_wx(adapter, data.off, &(data.u), + data.size); break; case netxen_nic_cmd_pci_config_read: @@ -1517,7 +1296,7 @@ netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data, retval = -EOPNOTSUPP; goto error_out; } - put_user(data.rv, (&(up_data->rv))); + put_user(data.rv, (u16 __user *) (&(up_data->rv))); DPRINTK(INFO, "done ioctl for %p well.\n", adapter); error_out: diff --git a/trunk/drivers/net/netxen/netxen_nic_ioctl.h b/trunk/drivers/net/netxen/netxen_nic_ioctl.h index 1221fa527552..23e53adbf123 100644 --- a/trunk/drivers/net/netxen/netxen_nic_ioctl.h +++ b/trunk/drivers/net/netxen/netxen_nic_ioctl.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2003 - 2006 NetXen, Inc. * All rights reserved. - * + * * 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 @@ -16,10 +16,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. - * + * * The full GNU General Public License is included in this distribution * in the file called LICENSE. - * + * * Contact Information: * info@netxen.com * NetXen, @@ -36,7 +36,7 @@ #define NETXEN_NIC_CMD (NETXEN_CMD_START + 1) #define NETXEN_NIC_NAME (NETXEN_CMD_START + 2) #define NETXEN_NIC_NAME_LEN 16 -#define NETXEN_NIC_NAME_RSP "NETXEN-UNM" +#define NETXEN_NIC_NAME_RSP "NETXEN" typedef enum { netxen_nic_cmd_none = 0, diff --git a/trunk/drivers/net/netxen/netxen_nic_isr.c b/trunk/drivers/net/netxen/netxen_nic_isr.c index 1b45f50fa6aa..ae180fee8008 100644 --- a/trunk/drivers/net/netxen/netxen_nic_isr.c +++ b/trunk/drivers/net/netxen/netxen_nic_isr.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2003 - 2006 NetXen, Inc. * All rights reserved. - * + * * 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 @@ -16,10 +16,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. - * + * * The full GNU General Public License is included in this distribution * in the file called LICENSE. - * + * * Contact Information: * info@netxen.com * NetXen, @@ -68,7 +68,8 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 portno, u32 link) { - struct net_device *netdev = (adapter->port[portno])->netdev; + struct netxen_port *pport = adapter->port[portno]; + struct net_device *netdev = pport->netdev; if (link) netif_carrier_on(netdev); @@ -83,41 +84,46 @@ void netxen_handle_port_int(struct netxen_adapter *adapter, u32 portno, struct netxen_port *port; /* This should clear the interrupt source */ - if (adapter->phy_read) - adapter->phy_read(adapter, portno, - NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS, - &int_src); + if (adapter->ops->phy_read) + adapter->ops->phy_read(adapter, portno, + NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS, + &int_src); if (int_src == 0) { DPRINTK(INFO, "No phy interrupts for port #%d\n", portno); return; } - if (adapter->disable_phy_interrupts) - adapter->disable_phy_interrupts(adapter, portno); + if (adapter->ops->disable_phy_interrupts) + adapter->ops->disable_phy_interrupts(adapter, portno); port = adapter->port[portno]; if (netxen_get_phy_int_jabber(int_src)) - DPRINTK(INFO, "Jabber interrupt \n"); + DPRINTK(INFO, "NetXen: %s Jabber interrupt \n", + port->netdev->name); if (netxen_get_phy_int_polarity_changed(int_src)) - DPRINTK(INFO, "POLARITY CHANGED int \n"); + DPRINTK(INFO, "NetXen: %s POLARITY CHANGED int \n", + port->netdev->name); if (netxen_get_phy_int_energy_detect(int_src)) - DPRINTK(INFO, "ENERGY DETECT INT \n"); + DPRINTK(INFO, "NetXen: %s ENERGY DETECT INT \n", + port->netdev->name); if (netxen_get_phy_int_downshift(int_src)) - DPRINTK(INFO, "DOWNSHIFT INT \n"); + DPRINTK(INFO, "NetXen: %s DOWNSHIFT INT \n", + port->netdev->name); /* write it down later.. */ if ((netxen_get_phy_int_speed_changed(int_src)) || (netxen_get_phy_int_link_status_changed(int_src))) { __le32 status; - DPRINTK(INFO, "SPEED CHANGED OR LINK STATUS CHANGED \n"); + DPRINTK(INFO, "NetXen: %s SPEED CHANGED OR" + " LINK STATUS CHANGED \n", port->netdev->name); - if (adapter->phy_read - && adapter->phy_read(adapter, portno, - NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, - &status) == 0) { + if (adapter->ops->phy_read + && adapter->ops->phy_read(adapter, portno, + NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, + &status) == 0) { if (netxen_get_phy_int_link_status_changed(int_src)) { if (netxen_get_phy_link(status)) { netxen_niu_gbe_init_port(adapter, @@ -137,8 +143,8 @@ void netxen_handle_port_int(struct netxen_adapter *adapter, u32 portno, } } } - if (adapter->enable_phy_interrupts) - adapter->enable_phy_interrupts(adapter, portno); + if (adapter->ops->enable_phy_interrupts) + adapter->ops->enable_phy_interrupts(adapter, portno); } void netxen_nic_isr_other(struct netxen_adapter *adapter) @@ -153,7 +159,8 @@ void netxen_nic_isr_other(struct netxen_adapter *adapter) qg_linksup = adapter->ahw.qg_linksup; adapter->ahw.qg_linksup = val; - DPRINTK(INFO, "link update 0x%08x\n", val); + DPRINTK(1, INFO, "%s: link update 0x%08x\n", netxen_nic_driver_name, + val); for (portno = 0; portno < NETXEN_NIU_MAX_GBE_PORTS; portno++) { linkup = val & 1; if (linkup != (qg_linksup & 1)) { diff --git a/trunk/drivers/net/netxen/netxen_nic_main.c b/trunk/drivers/net/netxen/netxen_nic_main.c index 913e8147114f..1cb662d5bd76 100644 --- a/trunk/drivers/net/netxen/netxen_nic_main.c +++ b/trunk/drivers/net/netxen/netxen_nic_main.c @@ -1,25 +1,25 @@ /* * Copyright (C) 2003 - 2006 NetXen, Inc. * All rights reserved. - * + * * 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. - * + * * The full GNU General Public License is included in this distribution * in the file called LICENSE. - * + * * Contact Information: * info@netxen.com * NetXen, @@ -32,7 +32,6 @@ */ #include -#include #include "netxen_nic_hw.h" #include "netxen_nic.h" @@ -49,21 +48,14 @@ MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID); -char netxen_nic_driver_name[] = "netxen-nic"; +char netxen_nic_driver_name[] = "netxen"; static char netxen_nic_driver_string[] = "NetXen Network Driver version " NETXEN_NIC_LINUX_VERSIONID; -struct netxen_adapter *g_adapter = NULL; - #define NETXEN_NETDEV_WEIGHT 120 #define NETXEN_ADAPTER_UP_MAGIC 777 #define NETXEN_NIC_PEG_TUNE 0 -u8 nx_p2_id = NX_P2_C0; - -#define DMA_32BIT_MASK 0x00000000ffffffffULL -#define DMA_35BIT_MASK 0x00000007ffffffffULL - /* Local functions to NetXen NIC driver */ static int __devinit netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent); @@ -72,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, @@ -95,9 +87,6 @@ static struct pci_device_id netxen_pci_tbl[] __devinitdata = { MODULE_DEVICE_TABLE(pci, netxen_pci_tbl); -struct workqueue_struct *netxen_workq; -static void netxen_watchdog(unsigned long); - /* * netxen_nic_probe() * @@ -116,28 +105,20 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct net_device *netdev = NULL; struct netxen_adapter *adapter = NULL; struct netxen_port *port = NULL; - void __iomem *mem_ptr0 = NULL; - void __iomem *mem_ptr1 = NULL; - void __iomem *mem_ptr2 = NULL; + u8 *mem_ptr0 = NULL; + u8 *mem_ptr1 = NULL; + u8 *mem_ptr2 = NULL; - u8 *db_ptr = NULL; - unsigned long mem_base, mem_len, db_base, db_len; + unsigned long mem_base, mem_len; int pci_using_dac, i, err; int ring; struct netxen_recv_context *recv_ctx = NULL; struct netxen_rcv_desc_ctx *rcv_desc = NULL; struct netxen_cmd_buffer *cmd_buf_arr = NULL; u64 mac_addr[FLASH_NUM_PORTS + 1]; - int valid_mac = 0; - static int netxen_cards_found = 0; + int valid_mac; printk(KERN_INFO "%s \n", netxen_nic_driver_string); - /* In current scheme, we use only PCI function 0 */ - if (PCI_FUNC(pdev->devfn) != 0) { - DPRINTK(ERR, "NetXen function %d will not be enabled.\n", - PCI_FUNC(pdev->devfn)); - return -ENODEV; - } if ((err = pci_enable_device(pdev))) return err; if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { @@ -149,12 +130,10 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_disable_pdev; pci_set_master(pdev); - pci_read_config_byte(pdev, PCI_REVISION_ID, &nx_p2_id); - if (nx_p2_id == NX_P2_C1 && - (pci_set_dma_mask(pdev, DMA_35BIT_MASK) == 0) && - (pci_set_consistent_dma_mask(pdev, DMA_35BIT_MASK) == 0)) { + if ((pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) && + (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) == 0)) pci_using_dac = 1; - } else { + else { if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) || (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))) goto err_out_free_res; @@ -174,34 +153,21 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ioremap(mem_base + THIRD_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE); if ((mem_ptr0 == 0UL) || (mem_ptr1 == 0UL) || (mem_ptr2 == 0UL)) { - DPRINTK(ERR, + DPRINTK(1, ERR, "Cannot remap adapter memory aborting.:" "0 -> %p, 1 -> %p, 2 -> %p\n", mem_ptr0, mem_ptr1, mem_ptr2); err = -EIO; - goto err_out_iounmap; - } - db_base = pci_resource_start(pdev, 4); /* doorbell is on bar 4 */ - db_len = pci_resource_len(pdev, 4); - - if (db_len == 0) { - printk(KERN_ERR "%s: doorbell is disabled\n", - netxen_nic_driver_name); - err = -EIO; - goto err_out_iounmap; - } - DPRINTK(INFO, "doorbell ioremap from %lx a size of %lx\n", db_base, - db_len); - - db_ptr = ioremap(db_base, NETXEN_DB_MAPSIZE_BYTES); - if (db_ptr == 0UL) { - printk(KERN_ERR "%s: Failed to allocate doorbell map.", - netxen_nic_driver_name); - err = -EIO; - goto err_out_iounmap; + if (mem_ptr0) + iounmap(mem_ptr0); + if (mem_ptr1) + iounmap(mem_ptr1); + if (mem_ptr2) + iounmap(mem_ptr2); + + goto err_out_free_res; } - DPRINTK(INFO, "doorbell ioremaped at %p\n", db_ptr); /* * Allocate a adapter structure which will manage all the initialization @@ -217,24 +183,17 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netxen_nic_driver_name, (int)sizeof(struct netxen_adapter)); err = -ENOMEM; - goto err_out_dbunmap; + goto err_out_iounmap; } - if (netxen_cards_found == 0) { - g_adapter = adapter; - } adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS; adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS; adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS; - adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS; pci_set_drvdata(pdev, adapter); cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE); if (cmd_buf_arr == NULL) { - printk(KERN_ERR - "%s: Could not allocate cmd_buf_arr memory:%d\n", - netxen_nic_driver_name, (int)TX_RINGSIZE); err = -ENOMEM; goto err_out_free_adapter; } @@ -261,23 +220,11 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) rcv_desc->skb_size = MAX_RX_JUMBO_BUFFER_LENGTH; break; - case RCV_RING_LRO: - rcv_desc->max_rx_desc_count = - adapter->max_lro_rx_desc_count; - rcv_desc->flags = RCV_DESC_LRO; - rcv_desc->dma_size = RX_LRO_DMA_MAP_LEN; - rcv_desc->skb_size = MAX_RX_LRO_BUFFER_LENGTH; - break; - } rcv_desc->rx_buf_arr = (struct netxen_rx_buffer *) vmalloc(RCV_BUFFSIZE); if (rcv_desc->rx_buf_arr == NULL) { - printk(KERN_ERR "%s: Could not allocate" - "rcv_desc->rx_buf_arr memory:%d\n", - netxen_nic_driver_name, - (int)RCV_BUFFSIZE); err = -ENOMEM; goto err_out_free_rx_buffer; } @@ -286,21 +233,30 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } + adapter->ops = kzalloc(sizeof(struct netxen_drvops), GFP_KERNEL); + if (adapter->ops == NULL) { + printk(KERN_ERR + "%s: Could not allocate memory for adapter->ops:%d\n", + netxen_nic_driver_name, + (int)sizeof(struct netxen_adapter)); + err = -ENOMEM; + goto err_out_free_rx_buffer; + } + adapter->cmd_buf_arr = cmd_buf_arr; adapter->ahw.pci_base0 = mem_ptr0; adapter->ahw.pci_base1 = mem_ptr1; adapter->ahw.pci_base2 = mem_ptr2; - adapter->ahw.db_base = db_ptr; - adapter->ahw.db_len = db_len; spin_lock_init(&adapter->tx_lock); spin_lock_init(&adapter->lock); - netxen_initialize_adapter_sw(adapter); /* initialize the buffers in adapter */ #ifdef CONFIG_IA64 netxen_pinit_from_rom(adapter, 0); udelay(500); netxen_load_firmware(adapter); #endif + /* initialize the buffers in adapter */ + netxen_initialize_adapter_sw(adapter); /* * Set the CRB window to invalid. If any register in window 0 is * accessed it should set the window to 0 and then reset it to 1. @@ -318,10 +274,11 @@ 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; - adapter->ahw.revision_id = nx_p2_id; + pci_read_config_byte(pdev, PCI_REVISION_ID, &adapter->ahw.revision_id); if (pci_enable_msi(pdev)) { adapter->flags &= ~NETXEN_NIC_MSI_ENABLED; @@ -343,12 +300,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_CONSUMER_OFFSET)); writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO)); - /* do this before waking up pegs so that we have valid dummy dma addr */ - err = netxen_initialize_adapter_offload(adapter); - if (err) { - goto err_out_free_dev; - } - /* Unlock the HW, prompting the boot sequence */ writel(1, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE)); @@ -357,7 +308,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); /* initialize the all the ports */ - adapter->active_ports = 0; for (i = 0; i < adapter->ahw.max_ports; i++) { netdev = alloc_etherdev(sizeof(struct netxen_port)); @@ -423,13 +373,14 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->dev_addr[4], netdev->dev_addr[5]); } else { - if (adapter->macaddr_set) - adapter->macaddr_set(port, - netdev->dev_addr); + if (adapter->ops->macaddr_set) + adapter->ops->macaddr_set(port, + netdev-> + 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); @@ -441,6 +392,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_free_dev; } adapter->port_count++; + adapter->active_ports = 0; adapter->port[i] = port; } @@ -461,7 +413,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) break; } - adapter->number = netxen_cards_found; adapter->driver_mismatch = 0; return 0; @@ -476,8 +427,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) free_netdev(port->netdev); } } - - netxen_free_adapter_offload(adapter); + kfree(adapter->ops); err_out_free_rx_buffer: for (i = 0; i < MAX_RCV_CTX; ++i) { @@ -490,23 +440,19 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } } } + vfree(cmd_buf_arr); + kfree(adapter->port); + err_out_free_adapter: pci_set_drvdata(pdev, NULL); kfree(adapter); - err_out_dbunmap: - if (db_ptr) - iounmap(db_ptr); - err_out_iounmap: - if (mem_ptr0) - iounmap(mem_ptr0); - if (mem_ptr1) - iounmap(mem_ptr1); - if (mem_ptr2) - iounmap(mem_ptr2); + iounmap(mem_ptr0); + iounmap(mem_ptr1); + iounmap(mem_ptr2); err_out_free_res: pci_release_regions(pdev); @@ -531,8 +477,12 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) netxen_nic_stop_all_ports(adapter); /* leave the hw in the same state as reboot */ + netxen_pinit_from_rom(adapter, 0); + udelay(500); netxen_load_firmware(adapter); - netxen_free_adapter_offload(adapter); + + if ((adapter->flags & NETXEN_NIC_MSI_ENABLED)) + netxen_nic_disable_int(adapter); udelay(500); /* Delay for a while to drain the DMA engines */ for (i = 0; i < adapter->port_count; i++) { @@ -549,7 +499,6 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) netxen_free_hw_resources(adapter); - iounmap(adapter->ahw.db_base); iounmap(adapter->ahw.pci_base0); iounmap(adapter->ahw.pci_base1); iounmap(adapter->ahw.pci_base2); @@ -576,6 +525,7 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) } vfree(adapter->cmd_buf_arr); + kfree(adapter->ops); kfree(adapter); } @@ -597,8 +547,6 @@ static int netxen_nic_open(struct net_device *netdev) return -EIO; } netxen_nic_flash_print(adapter); - if (adapter->init_niu) - adapter->init_niu(adapter); /* setup all the resources for the Phantom... */ /* this include the descriptors for rcv, tx, and status */ @@ -609,31 +557,32 @@ static int netxen_nic_open(struct net_device *netdev) err); return err; } - if (adapter->init_port - && adapter->init_port(adapter, port->portnum) != 0) { + if (adapter->ops->init_port + && adapter->ops->init_port(adapter, port->portnum) != 0) { printk(KERN_ERR "%s: Failed to initialize port %d\n", netxen_nic_driver_name, port->portnum); netxen_free_hw_resources(adapter); return -EIO; } + if (adapter->ops->init_niu) + adapter->ops->init_niu(adapter); for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) netxen_post_rx_buffers(adapter, ctx, ring); } - adapter->irq = adapter->ahw.pdev->irq; + adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; + } + adapter->active_ports++; + if (adapter->active_ports == 1) { err = request_irq(adapter->ahw.pdev->irq, &netxen_intr, SA_SHIRQ | SA_SAMPLE_RANDOM, netdev->name, adapter); if (err) { printk(KERN_ERR "request_irq failed with: %d\n", err); - netxen_free_hw_resources(adapter); + adapter->active_ports--; return err; } - - adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; - } - adapter->active_ports++; - if (adapter->active_ports == 1) { + adapter->irq = adapter->ahw.pdev->irq; if (!adapter->driver_mismatch) mod_timer(&adapter->watchdog_timer, jiffies); @@ -642,14 +591,11 @@ static int netxen_nic_open(struct net_device *netdev) /* Done here again so that even if phantom sw overwrote it, * we set it */ - if (adapter->macaddr_set) - adapter->macaddr_set(port, netdev->dev_addr); + if (adapter->ops->macaddr_set) + adapter->ops->macaddr_set(port, netdev->dev_addr); netxen_nic_set_link_parameters(port); netxen_nic_set_multi(netdev); - if (adapter->set_mtu) - adapter->set_mtu(port, netdev->mtu); - if (!adapter->driver_mismatch) netif_start_queue(netdev); @@ -702,7 +648,6 @@ static int netxen_nic_close(struct net_device *netdev) } cmd_buff++; } - FLUSH_SCHEDULED_WORK(); del_timer_sync(&adapter->watchdog_timer); } @@ -723,6 +668,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) struct cmd_desc_type0 *hwdesc; int k; struct netxen_cmd_buffer *pbuf = NULL; + unsigned int tries = 0; static int dropped_packet = 0; int frag_count; u32 local_producer = 0; @@ -784,7 +730,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if (((skb->nh.iph)->ihl * sizeof(u32)) + ((skb->h.th)->doff * sizeof(u32)) + sizeof(struct ethhdr) > - (sizeof(struct cmd_desc_type0) - 2)) { + (sizeof(struct cmd_desc_type0) - NET_IP_ALIGN)) { no_of_desc++; } } @@ -795,17 +741,27 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if ((k + no_of_desc) >= ((last_cmd_consumer <= k) ? last_cmd_consumer + max_tx_desc_count : last_cmd_consumer)) { - port->stats.nocmddescriptor++; - DPRINTK(ERR, "No command descriptors available," - " producer = %d, consumer = %d count=%llu," - " dropping packet\n", producer, - adapter->last_cmd_consumer, - port->stats.nocmddescriptor); - - netif_stop_queue(netdev); - port->flags |= NETXEN_NETDEV_STATUS; spin_unlock_bh(&adapter->tx_lock); - return NETDEV_TX_BUSY; + if (tries == 0) { + local_bh_disable(); + netxen_process_cmd_ring((unsigned long)adapter); + local_bh_enable(); + ++tries; + goto retry_getting_window; + } else { + port->stats.nocmddescriptor++; + DPRINTK(ERR, "No command descriptors available," + " producer = %d, consumer = %d count=%llu," + " dropping packet\n", producer, + adapter->last_cmd_consumer, + port->stats.nocmddescriptor); + + spin_lock_bh(&adapter->tx_lock); + netif_stop_queue(netdev); + port->flags |= NETXEN_NETDEV_STATUS; + spin_unlock_bh(&adapter->tx_lock); + return NETDEV_TX_BUSY; + } } k = get_index_range(k, max_tx_desc_count, no_of_desc); adapter->cmd_producer = k; @@ -827,6 +783,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) pbuf->mss = 0; hwdesc->mss = 0; } + pbuf->no_of_descriptors = no_of_desc; pbuf->total_length = skb->len; pbuf->skb = skb; pbuf->cmd = TX_ETHER_PKT; @@ -836,11 +793,11 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) buffrag->dma = pci_map_single(port->pdev, skb->data, first_seg_len, PCI_DMA_TODEVICE); buffrag->length = first_seg_len; - netxen_set_cmd_desc_totallength(hwdesc, skb->len); - netxen_set_cmd_desc_num_of_buff(hwdesc, frag_count); - netxen_set_cmd_desc_opcode(hwdesc, TX_ETHER_PKT); + CMD_DESC_TOTAL_LENGTH_WRT(hwdesc, skb->len); + hwdesc->num_of_buffers = frag_count; + hwdesc->opcode = TX_ETHER_PKT; - netxen_set_cmd_desc_port(hwdesc, port->portnum); + CMD_DESC_PORT_WRT(hwdesc, port->portnum); hwdesc->buffer1_length = cpu_to_le16(first_seg_len); hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma); @@ -899,12 +856,12 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) /* For LSO, we need to copy the MAC/IP/TCP headers into * the descriptor ring */ - if (netxen_get_cmd_desc_opcode(&hw->cmd_desc_head[saved_producer]) - == TX_TCP_LSO) { + if (hw->cmd_desc_head[saved_producer].opcode == TX_TCP_LSO) { int hdr_len, first_hdr_len, more_hdr; hdr_len = hw->cmd_desc_head[saved_producer].total_hdr_length; - if (hdr_len > (sizeof(struct cmd_desc_type0) - 2)) { - first_hdr_len = sizeof(struct cmd_desc_type0) - 2; + if (hdr_len > (sizeof(struct cmd_desc_type0) - NET_IP_ALIGN)) { + first_hdr_len = + sizeof(struct cmd_desc_type0) - NET_IP_ALIGN; more_hdr = 1; } else { first_hdr_len = hdr_len; @@ -914,7 +871,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) hwdesc = &hw->cmd_desc_head[producer]; /* copy the first 64 bytes */ - memcpy(((void *)hwdesc) + 2, + memcpy(((void *)hwdesc) + NET_IP_ALIGN, (void *)(skb->data), first_hdr_len); producer = get_next_index(producer, max_tx_desc_count); @@ -930,7 +887,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) } spin_lock_bh(&adapter->tx_lock); port->stats.txbytes += - netxen_get_cmd_desc_totallength(&hw->cmd_desc_head[saved_producer]); + CMD_DESC_TOTAL_LENGTH(&hw->cmd_desc_head[saved_producer]); /* Code to update the adapter considering how many producer threads are currently working */ if ((--adapter->num_threads) == 0) { @@ -940,6 +897,20 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_PRODUCER_OFFSET)); wmb(); adapter->total_threads = 0; + } else { + u32 crb_producer = 0; + crb_producer = + readl(NETXEN_CRB_NORMALIZE + (adapter, CRB_CMD_PRODUCER_OFFSET)); + if (crb_producer == local_producer) { + crb_producer = get_index_range(crb_producer, + max_tx_desc_count, + no_of_desc); + writel(crb_producer, + NETXEN_CRB_NORMALIZE(adapter, + CRB_CMD_PRODUCER_OFFSET)); + wmb(); + } } port->stats.xmitfinished++; @@ -956,36 +927,29 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) static void netxen_watchdog(unsigned long v) { struct netxen_adapter *adapter = (struct netxen_adapter *)v; - if (adapter != g_adapter) { - printk("%s: ***BUG*** adapter[%p] != g_adapter[%p]\n", - __FUNCTION__, adapter, g_adapter); - return; - } - - SCHEDULE_WORK(&adapter->watchdog_task); + schedule_work(&adapter->watchdog_task); } static void netxen_tx_timeout(struct net_device *netdev) { struct netxen_port *port = (struct netxen_port *)netdev_priv(netdev); + struct netxen_adapter *adapter = port->adapter; - SCHEDULE_WORK(port->adapter->tx_timeout_task + port->portnum); + 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); } @@ -1002,11 +966,6 @@ netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev) if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { int count = 0; u32 mask; - mask = readl(pci_base_offset(adapter, ISR_INT_VECTOR)); - if ((mask & 0x80) == 0) { - /* not our interrupt */ - return ret; - } netxen_nic_disable_int(adapter); /* Window = 0 or 1 */ do { @@ -1066,10 +1025,7 @@ irqreturn_t netxen_intr(int irq, void *data) netdev = port->netdev; /* process our status queue (for all 4 ports) */ - if (netif_running(netdev)) { - netxen_handle_int(adapter, netdev); - break; - } + netxen_handle_int(adapter, netdev); } return IRQ_HANDLED; @@ -1083,12 +1039,11 @@ static int netxen_nic_poll(struct net_device *netdev, int *budget) int done = 1; int ctx; int this_work_done; - int work_done = 0; DPRINTK(INFO, "polling for %d descriptors\n", *budget); port->stats.polled++; - work_done = 0; + adapter->work_done = 0; for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { /* * Fairness issue. This will give undue weight to the @@ -1105,20 +1060,20 @@ static int netxen_nic_poll(struct net_device *netdev, int *budget) this_work_done = netxen_process_rcv_ring(adapter, ctx, work_to_do / MAX_RCV_CTX); - work_done += this_work_done; + adapter->work_done += this_work_done; } - netdev->quota -= work_done; - *budget -= work_done; + netdev->quota -= adapter->work_done; + *budget -= adapter->work_done; - if (work_done >= work_to_do && netxen_nic_rx_has_work(adapter) != 0) + if (adapter->work_done >= work_to_do + && netxen_nic_rx_has_work(adapter) != 0) done = 0; - if (netxen_process_cmd_ring((unsigned long)adapter) == 0) - done = 0; + netxen_process_cmd_ring((unsigned long)adapter); DPRINTK(INFO, "new work_done: %d work_to_do: %d\n", - work_done, work_to_do); + adapter->work_done, work_to_do); if (done) { netif_rx_complete(netdev); netxen_nic_enable_int(adapter); @@ -1161,9 +1116,8 @@ netxen_nic_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) if (ifr->ifr_data) { sprintf(dev_name, "%s-%d", NETXEN_NIC_NAME_RSP, port->portnum); - nr_bytes = - copy_to_user((char __user *)ifr->ifr_data, dev_name, - NETXEN_NIC_NAME_LEN); + nr_bytes = copy_to_user((char *)ifr->ifr_data, dev_name, + NETXEN_NIC_NAME_LEN); if (nr_bytes) err = -EIO; @@ -1190,9 +1144,6 @@ static struct pci_driver netxen_driver = { static int __init netxen_init_module(void) { - if ((netxen_workq = create_singlethread_workqueue("netxen")) == 0) - return -ENOMEM; - return pci_module_init(&netxen_driver); } @@ -1203,7 +1154,7 @@ static void __exit netxen_exit_module(void) /* * Wait for some time to allow the dma to drain, if any. */ - destroy_workqueue(netxen_workq); + mdelay(5); pci_unregister_driver(&netxen_driver); } diff --git a/trunk/drivers/net/netxen/netxen_nic_niu.c b/trunk/drivers/net/netxen/netxen_nic_niu.c index 4987dc765d99..7950a04532e6 100644 --- a/trunk/drivers/net/netxen/netxen_nic_niu.c +++ b/trunk/drivers/net/netxen/netxen_nic_niu.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2003 - 2006 NetXen, Inc. * All rights reserved. - * + * * 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 @@ -16,10 +16,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. - * + * * The full GNU General Public License is included in this distribution * in the file called LICENSE. - * + * * Contact Information: * info@netxen.com * NetXen, @@ -40,15 +40,13 @@ static long phy_lock_timeout = 100000000; -static inline int phy_lock(struct netxen_adapter *adapter) +static inline int phy_lock(void) { int i; int done = 0, timeout = 0; while (!done) { - done = - readl(pci_base_offset - (adapter, NETXEN_PCIE_REG(PCIE_SEM3_LOCK))); + done = readl((void __iomem *)NETXEN_PCIE_REG(PCIE_SEM3_LOCK)); if (done == 1) break; if (timeout >= phy_lock_timeout) { @@ -63,15 +61,13 @@ static inline int phy_lock(struct netxen_adapter *adapter) } } - writel(PHY_LOCK_DRIVER, - NETXEN_CRB_NORMALIZE(adapter, NETXEN_PHY_LOCK_ID)); + writel(NETXEN_PHY_LOCK_ID, (void __iomem *)PHY_LOCK_DRIVER); return 0; } -static inline int phy_unlock(struct netxen_adapter *adapter) +static inline int phy_unlock(void) { - readl(pci_base_offset(adapter, NETXEN_PCIE_REG(PCIE_SEM3_UNLOCK))); - + readl((void __iomem *)NETXEN_PCIE_REG(PCIE_SEM3_UNLOCK)); return 0; } @@ -99,7 +95,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, __le32 status; __le32 mac_cfg0; - if (phy_lock(adapter) != 0) { + if (phy_lock() != 0) { return -1; } @@ -166,7 +162,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, NETXEN_NIU_GB_MAC_CONFIG_0(0), &mac_cfg0, 4)) return -EIO; - phy_unlock(adapter); + phy_unlock(); return result; } @@ -403,8 +399,8 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port) { int result = 0; __le32 status; - if (adapter->disable_phy_interrupts) - adapter->disable_phy_interrupts(adapter, port); + if (adapter->ops->disable_phy_interrupts) + adapter->ops->disable_phy_interrupts(adapter, port); mdelay(2); if (0 == @@ -616,7 +612,7 @@ int netxen_niu_macaddr_set(struct netxen_port *port, __le32 temp = 0; struct netxen_adapter *adapter = port->adapter; int phy = port->portnum; - unsigned char mac_addr[6]; + unsigned char mac_addr[MAX_ADDR_LEN]; int i; for (i = 0; i < 10; i++) { @@ -635,7 +631,7 @@ int netxen_niu_macaddr_set(struct netxen_port *port, netxen_niu_macaddr_get(adapter, phy, (netxen_ethernet_macaddr_t *) mac_addr); - if (memcmp(mac_addr, addr, 6) == 0) + if (memcmp(mac_addr, addr, MAX_ADDR_LEN == 0)) break; } diff --git a/trunk/drivers/net/netxen/netxen_nic_phan_reg.h b/trunk/drivers/net/netxen/netxen_nic_phan_reg.h index 7879f855af0b..8181d436783f 100644 --- a/trunk/drivers/net/netxen/netxen_nic_phan_reg.h +++ b/trunk/drivers/net/netxen/netxen_nic_phan_reg.h @@ -33,74 +33,15 @@ /* * CRB Registers or queue message done only at initialization time. */ -#define NIC_CRB_BASE NETXEN_CAM_RAM(0x200) -#define NETXEN_NIC_REG(X) (NIC_CRB_BASE+(X)) -#define CRB_PHAN_CNTRL_LO_OFFSET NETXEN_NIC_REG(0x00) -#define CRB_PHAN_CNTRL_HI_OFFSET NETXEN_NIC_REG(0x04) -#define CRB_CMD_PRODUCER_OFFSET NETXEN_NIC_REG(0x08) -#define CRB_CMD_CONSUMER_OFFSET NETXEN_NIC_REG(0x0c) -#define CRB_PAUSE_ADDR_LO NETXEN_NIC_REG(0x10) /* C0 EPG BUG */ -#define CRB_PAUSE_ADDR_HI NETXEN_NIC_REG(0x14) -#define CRB_HOST_CMD_ADDR_HI NETXEN_NIC_REG(0x18) /* host add:cmd ring */ -#define CRB_HOST_CMD_ADDR_LO NETXEN_NIC_REG(0x1c) -#define CRB_CMD_INTR_LOOP NETXEN_NIC_REG(0x20) /* 4 regs for perf */ -#define CRB_CMD_DMA_LOOP NETXEN_NIC_REG(0x24) -#define CRB_RCV_INTR_LOOP NETXEN_NIC_REG(0x28) -#define CRB_RCV_DMA_LOOP NETXEN_NIC_REG(0x2c) -#define CRB_ENABLE_TX_INTR NETXEN_NIC_REG(0x30) /* phantom init status */ -#define CRB_MMAP_ADDR_3 NETXEN_NIC_REG(0x34) -#define CRB_CMDPEG_CMDRING NETXEN_NIC_REG(0x38) -#define CRB_HOST_DUMMY_BUF_ADDR_HI NETXEN_NIC_REG(0x3c) -#define CRB_HOST_DUMMY_BUF_ADDR_LO NETXEN_NIC_REG(0x40) -#define CRB_MMAP_ADDR_0 NETXEN_NIC_REG(0x44) -#define CRB_MMAP_ADDR_1 NETXEN_NIC_REG(0x48) -#define CRB_MMAP_ADDR_2 NETXEN_NIC_REG(0x4c) -#define CRB_CMDPEG_STATE NETXEN_NIC_REG(0x50) -#define CRB_MMAP_SIZE_0 NETXEN_NIC_REG(0x54) -#define CRB_MMAP_SIZE_1 NETXEN_NIC_REG(0x58) -#define CRB_MMAP_SIZE_2 NETXEN_NIC_REG(0x5c) -#define CRB_MMAP_SIZE_3 NETXEN_NIC_REG(0x60) -#define CRB_GLOBAL_INT_COAL NETXEN_NIC_REG(0x64) /* interrupt coalescing */ -#define CRB_INT_COAL_MODE NETXEN_NIC_REG(0x68) -#define CRB_MAX_RCV_BUFS NETXEN_NIC_REG(0x6c) -#define CRB_TX_INT_THRESHOLD NETXEN_NIC_REG(0x70) -#define CRB_RX_PKT_TIMER NETXEN_NIC_REG(0x74) -#define CRB_TX_PKT_TIMER NETXEN_NIC_REG(0x78) -#define CRB_RX_PKT_CNT NETXEN_NIC_REG(0x7c) -#define CRB_RX_TMR_CNT NETXEN_NIC_REG(0x80) -#define CRB_RX_LRO_TIMER NETXEN_NIC_REG(0x84) -#define CRB_RX_LRO_MID_TIMER NETXEN_NIC_REG(0x88) -#define CRB_DMA_MAX_RCV_BUFS NETXEN_NIC_REG(0x8c) -#define CRB_MAX_DMA_ENTRIES NETXEN_NIC_REG(0x90) -#define CRB_XG_STATE NETXEN_NIC_REG(0x94) /* XG Link status */ -#define CRB_AGENT_GO NETXEN_NIC_REG(0x98) /* NIC pkt gen agent */ -#define CRB_AGENT_TX_SIZE NETXEN_NIC_REG(0x9c) -#define CRB_AGENT_TX_TYPE NETXEN_NIC_REG(0xa0) -#define CRB_AGENT_TX_ADDR NETXEN_NIC_REG(0xa4) -#define CRB_AGENT_TX_MSS NETXEN_NIC_REG(0xa8) -#define CRB_TX_STATE NETXEN_NIC_REG(0xac) /* Debug -performance */ -#define CRB_TX_COUNT NETXEN_NIC_REG(0xb0) -#define CRB_RX_STATE NETXEN_NIC_REG(0xb4) -#define CRB_RX_PERF_DEBUG_1 NETXEN_NIC_REG(0xb8) -#define CRB_RX_LRO_CONTROL NETXEN_NIC_REG(0xbc) /* LRO On/OFF */ -#define CRB_RX_LRO_START_NUM NETXEN_NIC_REG(0xc0) -#define CRB_MPORT_MODE NETXEN_NIC_REG(0xc4) /* Multiport Mode */ -#define CRB_CMD_RING_SIZE NETXEN_NIC_REG(0xc8) -#define CRB_INT_VECTOR NETXEN_NIC_REG(0xd4) -#define CRB_CTX_RESET NETXEN_NIC_REG(0xd8) -#define CRB_HOST_STS_PROD NETXEN_NIC_REG(0xdc) -#define CRB_HOST_STS_CONS NETXEN_NIC_REG(0xe0) -#define CRB_PEG_CMD_PROD NETXEN_NIC_REG(0xe4) -#define CRB_PEG_CMD_CONS NETXEN_NIC_REG(0xe8) -#define CRB_HOST_BUFFER_PROD NETXEN_NIC_REG(0xec) -#define CRB_HOST_BUFFER_CONS NETXEN_NIC_REG(0xf0) -#define CRB_JUMBO_BUFFER_PROD NETXEN_NIC_REG(0xf4) -#define CRB_JUMBO_BUFFER_CONS NETXEN_NIC_REG(0xf8) +/* + * The following 2 are the base adresses for the CRB registers and their + * offsets will be added to get addresses for the index addresses. + */ +#define NIC_CRB_BASE_PORT1 NETXEN_CAM_RAM(0x200) +#define NIC_CRB_BASE_PORT2 NETXEN_CAM_RAM(0x250) -#define CRB_CMD_PRODUCER_OFFSET_1 NETXEN_NIC_REG(0x1ac) -#define CRB_CMD_CONSUMER_OFFSET_1 NETXEN_NIC_REG(0x1b0) -#define CRB_TEMP_STATE NETXEN_NIC_REG(0x1b4) +#define NETXEN_NIC_REG(X) (NIC_CRB_BASE_PORT1+(X)) /* * CrbPortPhanCntrHi/Lo is used to pass the address of HostPhantomIndex address @@ -110,20 +51,74 @@ * on the Phantom. */ -#define nx_get_temp_val(x) ((x) >> 16) -#define nx_get_temp_state(x) ((x) & 0xffff) -#define nx_encode_temp(val, state) (((val) << 16) | (state)) +#define CRB_PHAN_CNTRL_LO_OFFSET NETXEN_NIC_REG(0x00) +#define CRB_PHAN_CNTRL_HI_OFFSET NETXEN_NIC_REG(0x04) + +/* point to the indexes */ +#define CRB_CMD_PRODUCER_OFFSET NETXEN_NIC_REG(0x08) +#define CRB_CMD_CONSUMER_OFFSET NETXEN_NIC_REG(0x0c) + +#define CRB_PAUSE_ADDR_LO NETXEN_NIC_REG(0x10) +#define CRB_PAUSE_ADDR_HI NETXEN_NIC_REG(0x14) + +/* address of command descriptors in the host memory */ +#define CRB_HOST_CMD_ADDR_HI NETXEN_NIC_REG(0x30) +#define CRB_HOST_CMD_ADDR_LO NETXEN_NIC_REG(0x34) + +/* The following 4 CRB registers are for doing performance coal */ +#define CRB_CMD_INTR_LOOP NETXEN_NIC_REG(0x38) +#define CRB_CMD_DMA_LOOP NETXEN_NIC_REG(0x3c) +#define CRB_RCV_INTR_LOOP NETXEN_NIC_REG(0x40) +#define CRB_RCV_DMA_LOOP NETXEN_NIC_REG(0x44) + +/* Needed by the host to find out the state of Phantom's initialization */ +#define CRB_ENABLE_TX_INTR NETXEN_NIC_REG(0x4c) +#define CRB_CMDPEG_STATE NETXEN_NIC_REG(0x50) +#define CRB_CMDPEG_CMDRING NETXEN_NIC_REG(0x54) + +/* Interrupt coalescing parameters */ +#define CRB_GLOBAL_INT_COAL NETXEN_NIC_REG(0x80) +#define CRB_INT_COAL_MODE NETXEN_NIC_REG(0x84) +#define CRB_MAX_RCV_BUFS NETXEN_NIC_REG(0x88) +#define CRB_TX_INT_THRESHOLD NETXEN_NIC_REG(0x8c) +#define CRB_RX_PKT_TIMER NETXEN_NIC_REG(0x90) +#define CRB_TX_PKT_TIMER NETXEN_NIC_REG(0x94) +#define CRB_RX_PKT_CNT NETXEN_NIC_REG(0x98) +#define CRB_RX_TMR_CNT NETXEN_NIC_REG(0x9c) +#define CRB_INT_THRESH NETXEN_NIC_REG(0xa4) + +/* Register for communicating XG link status */ +#define CRB_XG_STATE NETXEN_NIC_REG(0xa0) + +/* Register for communicating card temperature */ +/* Upper 16 bits are temperature value. Lower 16 bits are the state */ +#define CRB_TEMP_STATE NETXEN_NIC_REG(0xa8) +#define nx_get_temp_val(x) ((x) >> 16) +#define nx_get_temp_state(x) ((x) & 0xffff) +#define nx_encode_temp(val, state) (((val) << 16) | (state)) + +/* Debug registers for controlling NIC pkt gen agent */ +#define CRB_AGENT_GO NETXEN_NIC_REG(0xb0) +#define CRB_AGENT_TX_SIZE NETXEN_NIC_REG(0xb4) +#define CRB_AGENT_TX_TYPE NETXEN_NIC_REG(0xb8) +#define CRB_AGENT_TX_ADDR NETXEN_NIC_REG(0xbc) +#define CRB_AGENT_TX_MSS NETXEN_NIC_REG(0xc0) + +/* Debug registers for observing NIC performance */ +#define CRB_TX_STATE NETXEN_NIC_REG(0xd0) +#define CRB_TX_COUNT NETXEN_NIC_REG(0xd4) +#define CRB_RX_STATE NETXEN_NIC_REG(0xd8) /* CRB registers per Rcv Descriptor ring */ struct netxen_rcv_desc_crb { u32 crb_rcv_producer_offset __attribute__ ((aligned(512))); u32 crb_rcv_consumer_offset; u32 crb_globalrcv_ring; - u32 crb_rcv_ring_size; }; /* - * CRB registers used by the receive peg logic. + * CRB registers used by the receive peg logic. One instance of these + * needs to be instantiated per instance of the receive peg. */ struct netxen_recv_crb { @@ -132,7 +127,6 @@ struct netxen_recv_crb { u32 crb_rcv_status_producer; u32 crb_rcv_status_consumer; u32 crb_rcvpeg_state; - u32 crb_status_ring_size; }; #if defined(DEFINE_GLOBAL_RECV_CRB) @@ -145,48 +139,30 @@ struct netxen_recv_crb recv_crb_registers[] = { { { /* crb_rcv_producer_offset: */ - NETXEN_NIC_REG(0x100), + NETXEN_NIC_REG(0x18), /* crb_rcv_consumer_offset: */ - NETXEN_NIC_REG(0x104), + NETXEN_NIC_REG(0x1c), /* crb_gloablrcv_ring: */ - NETXEN_NIC_REG(0x108), - /* crb_rcv_ring_size */ - NETXEN_NIC_REG(0x10c), - + NETXEN_NIC_REG(0x20), }, /* Jumbo frames */ { /* crb_rcv_producer_offset: */ - NETXEN_NIC_REG(0x110), - /* crb_rcv_consumer_offset: */ - NETXEN_NIC_REG(0x114), - /* crb_gloablrcv_ring: */ - NETXEN_NIC_REG(0x118), - /* crb_rcv_ring_size */ - NETXEN_NIC_REG(0x11c), - }, - /* LRO */ - { - /* crb_rcv_producer_offset: */ - NETXEN_NIC_REG(0x120), + NETXEN_NIC_REG(0x100), /* crb_rcv_consumer_offset: */ - NETXEN_NIC_REG(0x124), + NETXEN_NIC_REG(0x104), /* crb_gloablrcv_ring: */ - NETXEN_NIC_REG(0x128), - /* crb_rcv_ring_size */ - NETXEN_NIC_REG(0x12c), + NETXEN_NIC_REG(0x108), } }, /* crb_rcvstatus_ring: */ - NETXEN_NIC_REG(0x130), + NETXEN_NIC_REG(0x24), /* crb_rcv_status_producer: */ - NETXEN_NIC_REG(0x134), + NETXEN_NIC_REG(0x28), /* crb_rcv_status_consumer: */ - NETXEN_NIC_REG(0x138), + NETXEN_NIC_REG(0x2c), /* crb_rcvpeg_state: */ - NETXEN_NIC_REG(0x13c), - /* crb_status_ring_size */ - NETXEN_NIC_REG(0x140), + NETXEN_NIC_REG(0x48), }, /* @@ -197,66 +173,34 @@ struct netxen_recv_crb recv_crb_registers[] = { { { /* crb_rcv_producer_offset: */ - NETXEN_NIC_REG(0x144), + NETXEN_NIC_REG(0x80), /* crb_rcv_consumer_offset: */ - NETXEN_NIC_REG(0x148), + NETXEN_NIC_REG(0x84), /* crb_globalrcv_ring: */ - NETXEN_NIC_REG(0x14c), - /* crb_rcv_ring_size */ - NETXEN_NIC_REG(0x150), - + NETXEN_NIC_REG(0x88), }, /* Jumbo frames */ { /* crb_rcv_producer_offset: */ - NETXEN_NIC_REG(0x154), - /* crb_rcv_consumer_offset: */ - NETXEN_NIC_REG(0x158), - /* crb_globalrcv_ring: */ - NETXEN_NIC_REG(0x15c), - /* crb_rcv_ring_size */ - NETXEN_NIC_REG(0x160), - }, - /* LRO */ - { - /* crb_rcv_producer_offset: */ - NETXEN_NIC_REG(0x164), + NETXEN_NIC_REG(0x10C), /* crb_rcv_consumer_offset: */ - NETXEN_NIC_REG(0x168), + NETXEN_NIC_REG(0x110), /* crb_globalrcv_ring: */ - NETXEN_NIC_REG(0x16c), - /* crb_rcv_ring_size */ - NETXEN_NIC_REG(0x170), + NETXEN_NIC_REG(0x114), } - }, /* crb_rcvstatus_ring: */ - NETXEN_NIC_REG(0x174), + NETXEN_NIC_REG(0x8c), /* crb_rcv_status_producer: */ - NETXEN_NIC_REG(0x178), + NETXEN_NIC_REG(0x90), /* crb_rcv_status_consumer: */ - NETXEN_NIC_REG(0x17c), + NETXEN_NIC_REG(0x94), /* crb_rcvpeg_state: */ - NETXEN_NIC_REG(0x180), - /* crb_status_ring_size */ - NETXEN_NIC_REG(0x184), - + NETXEN_NIC_REG(0x98), }, }; - -u64 ctx_addr_sig_regs[][3] = { - {NETXEN_NIC_REG(0x188), NETXEN_NIC_REG(0x18c), NETXEN_NIC_REG(0x1c0)}, - {NETXEN_NIC_REG(0x190), NETXEN_NIC_REG(0x194), NETXEN_NIC_REG(0x1c4)}, - {NETXEN_NIC_REG(0x198), NETXEN_NIC_REG(0x19c), NETXEN_NIC_REG(0x1c8)}, - {NETXEN_NIC_REG(0x1a0), NETXEN_NIC_REG(0x1a4), NETXEN_NIC_REG(0x1cc)} -}; - #else extern struct netxen_recv_crb recv_crb_registers[]; -extern u64 ctx_addr_sig_regs[][3]; -#define CRB_CTX_ADDR_REG_LO (ctx_addr_sig_regs[0][0]) -#define CRB_CTX_ADDR_REG_HI (ctx_addr_sig_regs[0][2]) -#define CRB_CTX_SIGNATURE_REG (ctx_addr_sig_regs[0][1]) #endif /* DEFINE_GLOBAL_RECEIVE_CRB */ /* diff --git a/trunk/drivers/net/ni52.c b/trunk/drivers/net/ni52.c index 196993a29b09..26e42f6e9fb1 100644 --- a/trunk/drivers/net/ni52.c +++ b/trunk/drivers/net/ni52.c @@ -1335,7 +1335,7 @@ int __init init_module(void) return 0; } -void __exit cleanup_module(void) +void cleanup_module(void) { unregister_netdev(dev_ni52); release_region(dev_ni52->base_addr, NI52_TOTAL_SIZE); diff --git a/trunk/drivers/net/ni65.c b/trunk/drivers/net/ni65.c index 1578f4d98498..340ad0d5388a 100644 --- a/trunk/drivers/net/ni65.c +++ b/trunk/drivers/net/ni65.c @@ -1259,7 +1259,7 @@ int __init init_module(void) return IS_ERR(dev_ni65) ? PTR_ERR(dev_ni65) : 0; } -void __exit cleanup_module(void) +void cleanup_module(void) { unregister_netdev(dev_ni65); cleanup_card(dev_ni65); diff --git a/trunk/drivers/net/ns83820.c b/trunk/drivers/net/ns83820.c index 568daeb3e9d8..b0127c71a5b6 100644 --- a/trunk/drivers/net/ns83820.c +++ b/trunk/drivers/net/ns83820.c @@ -414,10 +414,10 @@ struct rx_info { struct sk_buff *skbs[NR_RX_DESC]; - __le32 *next_rx_desc; + u32 *next_rx_desc; u16 next_rx, next_empty; - __le32 *descs; + u32 *descs; dma_addr_t phy_descs; }; @@ -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; @@ -460,7 +459,7 @@ struct ns83820 { struct sk_buff *tx_skbs[NR_TX_DESC]; char pad[16] __attribute__((aligned(16))); - __le32 *tx_descs; + u32 *tx_descs; dma_addr_t tx_phy_descs; struct timer_list tx_watchdog; @@ -534,7 +533,7 @@ static void ns83820_vlan_rx_kill_vid(struct net_device *ndev, unsigned short vid * conditions, still route realtime traffic with as low jitter as * possible. */ -static inline void build_rx_desc(struct ns83820 *dev, __le32 *desc, dma_addr_t link, dma_addr_t buf, u32 cmdsts, u32 extsts) +static inline void build_rx_desc(struct ns83820 *dev, u32 *desc, dma_addr_t link, dma_addr_t buf, u32 cmdsts, u32 extsts) { desc_addr_set(desc + DESC_LINK, link); desc_addr_set(desc + DESC_BUFPTR, buf); @@ -548,7 +547,7 @@ static inline int ns83820_add_rx_skb(struct ns83820 *dev, struct sk_buff *skb) { unsigned next_empty; u32 cmdsts; - __le32 *sg; + u32 *sg; dma_addr_t buf; next_empty = dev->rx_info.next_empty; @@ -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) @@ -875,8 +874,7 @@ static void fastcall rx_irq(struct net_device *ndev) struct rx_info *info = &dev->rx_info; unsigned next_rx; int rx_rc, len; - u32 cmdsts; - __le32 *desc; + u32 cmdsts, *desc; unsigned long flags; int nr = 0; @@ -1012,8 +1010,7 @@ static inline void kick_tx(struct ns83820 *dev) static void do_tx_done(struct net_device *ndev) { struct ns83820 *dev = PRIV(ndev); - u32 cmdsts, tx_done_idx; - __le32 *desc; + u32 cmdsts, tx_done_idx, *desc; dprintk("do_tx_done(%p)\n", ndev); tx_done_idx = dev->tx_done_idx; @@ -1080,7 +1077,7 @@ static void ns83820_cleanup_tx(struct ns83820 *dev) struct sk_buff *skb = dev->tx_skbs[i]; dev->tx_skbs[i] = NULL; if (skb) { - __le32 *desc = dev->tx_descs + (i * DESC_SIZE); + u32 *desc = dev->tx_descs + (i * DESC_SIZE); pci_unmap_single(dev->pci_dev, desc_addr_get(desc + DESC_BUFPTR), le32_to_cpu(desc[DESC_CMDSTS]) & CMDSTS_LEN_MASK, @@ -1110,7 +1107,7 @@ static int ns83820_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) skb_frag_t *frag; int stopped = 0; int do_intr = 0; - volatile __le32 *first_desc; + volatile u32 *first_desc; dprintk("ns83820_hard_start_xmit\n"); @@ -1183,7 +1180,7 @@ static int ns83820_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) first_desc = dev->tx_descs + (free_idx * DESC_SIZE); for (;;) { - volatile __le32 *desc = dev->tx_descs + (free_idx * DESC_SIZE); + volatile u32 *desc = dev->tx_descs + (free_idx * DESC_SIZE); dprintk("frag[%3u]: %4u @ 0x%08Lx\n", free_idx, len, (unsigned long long)buf); @@ -1458,8 +1455,7 @@ static int ns83820_stop(struct net_device *ndev) static void ns83820_tx_timeout(struct net_device *ndev) { struct ns83820 *dev = PRIV(ndev); - u32 tx_done_idx; - __le32 *desc; + u32 tx_done_idx, *desc; unsigned long flags; spin_lock_irqsave(&dev->tx_lock, flags); @@ -1845,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; @@ -1858,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/seeq8005.c b/trunk/drivers/net/seeq8005.c index 0d6c95c7aedf..d9d0a3a3c558 100644 --- a/trunk/drivers/net/seeq8005.c +++ b/trunk/drivers/net/seeq8005.c @@ -750,7 +750,7 @@ int __init init_module(void) return 0; } -void __exit cleanup_module(void) +void cleanup_module(void) { unregister_netdev(dev_seeq); release_region(dev_seeq->base_addr, SEEQ8005_IO_EXTENT); 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/sk98lin/skgesirq.c b/trunk/drivers/net/sk98lin/skgesirq.c index 3e7aa49afd00..ab66d80a4455 100644 --- a/trunk/drivers/net/sk98lin/skgesirq.c +++ b/trunk/drivers/net/sk98lin/skgesirq.c @@ -1319,7 +1319,7 @@ SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &Isrc); #ifdef xDEBUG - if ((Isrc & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) == + if ((Isrc & ~(PHY_B_IS_HCT | PHY_B_IS_LCT) == (PHY_B_IS_SCR_S_ER | PHY_B_IS_RRS_CHANGE | PHY_B_IS_LRS_CHANGE)) { SK_U32 Stat1, Stat2, Stat3; 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 f6223c533c01..537c0aaa1db8 100644 --- a/trunk/drivers/net/skge.h +++ b/trunk/drivers/net/skge.h @@ -389,10 +389,10 @@ enum { /* Packet Arbiter Registers */ /* B3_PA_CTRL 16 bit Packet Arbiter Ctrl Register */ enum { - PA_CLR_TO_TX2 = 1<<13,/* Clear IRQ Packet Timeout TX2 */ - PA_CLR_TO_TX1 = 1<<12,/* Clear IRQ Packet Timeout TX1 */ - PA_CLR_TO_RX2 = 1<<11,/* Clear IRQ Packet Timeout RX2 */ - PA_CLR_TO_RX1 = 1<<10,/* Clear IRQ Packet Timeout RX1 */ + PA_CLR_TO_TX2 = 1<<13, /* Clear IRQ Packet Timeout TX2 */ + PA_CLR_TO_TX1 = 1<<12, /* Clear IRQ Packet Timeout TX1 */ + PA_CLR_TO_RX2 = 1<<11, /* Clear IRQ Packet Timeout RX2 */ + PA_CLR_TO_RX1 = 1<<10, /* Clear IRQ Packet Timeout RX1 */ PA_ENA_TO_TX2 = 1<<9, /* Enable Timeout Timer TX2 */ PA_DIS_TO_TX2 = 1<<8, /* Disable Timeout Timer TX2 */ PA_ENA_TO_TX1 = 1<<7, /* Enable Timeout Timer TX1 */ @@ -481,14 +481,14 @@ enum { /* RAM Buffer Register Offsets */ enum { - RB_START= 0x00,/* 32 bit RAM Buffer Start Address */ + RB_START = 0x00,/* 32 bit RAM Buffer Start Address */ RB_END = 0x04,/* 32 bit RAM Buffer End Address */ RB_WP = 0x08,/* 32 bit RAM Buffer Write Pointer */ RB_RP = 0x0c,/* 32 bit RAM Buffer Read Pointer */ - RB_RX_UTPP= 0x10,/* 32 bit Rx Upper Threshold, Pause Packet */ - RB_RX_LTPP= 0x14,/* 32 bit Rx Lower Threshold, Pause Packet */ - RB_RX_UTHP= 0x18,/* 32 bit Rx Upper Threshold, High Prio */ - RB_RX_LTHP= 0x1c,/* 32 bit Rx Lower Threshold, High Prio */ + RB_RX_UTPP = 0x10,/* 32 bit Rx Upper Threshold, Pause Packet */ + RB_RX_LTPP = 0x14,/* 32 bit Rx Lower Threshold, Pause Packet */ + RB_RX_UTHP = 0x18,/* 32 bit Rx Upper Threshold, High Prio */ + RB_RX_LTHP = 0x1c,/* 32 bit Rx Lower Threshold, High Prio */ /* 0x10 - 0x1f: reserved at Tx RAM Buffer Registers */ RB_PC = 0x20,/* 32 bit RAM Buffer Packet Counter */ RB_LEV = 0x24,/* 32 bit RAM Buffer Level Register */ @@ -532,7 +532,7 @@ enum { PHY_ADDR_MARV = 0, }; -#define RB_ADDR(offs, queue) ((u16)B16_RAM_REGS + (u16)(queue) + (offs)) +#define RB_ADDR(offs, queue) (B16_RAM_REGS + (queue) + (offs)) /* Receive MAC FIFO, Receive LED, and Link_Sync regs (GENESIS only) */ enum { @@ -578,15 +578,15 @@ enum { MFF_DIS_TIST = 1<<2, /* Disable Time Stamp Gener */ MFF_CLR_INTIST = 1<<1, /* Clear IRQ No Time Stamp */ MFF_CLR_INSTAT = 1<<0, /* Clear IRQ No Status */ - MFF_RX_CTRL_DEF = MFF_ENA_TIM_PAT, +#define MFF_RX_CTRL_DEF MFF_ENA_TIM_PAT }; /* TX_MFF_CTRL1 16 bit Transmit MAC FIFO Control Reg 1 */ enum { - MFF_CLR_PERR = 1<<15, /* Clear Parity Error IRQ */ - - MFF_ENA_PKT_REC = 1<<13, /* Enable Packet Recovery */ - MFF_DIS_PKT_REC = 1<<12, /* Disable Packet Recovery */ + MFF_CLR_PERR = 1<<15, /* Clear Parity Error IRQ */ + /* Bit 14: reserved */ + MFF_ENA_PKT_REC = 1<<13, /* Enable Packet Recovery */ + MFF_DIS_PKT_REC = 1<<12, /* Disable Packet Recovery */ MFF_ENA_W4E = 1<<7, /* Enable Wait for Empty */ MFF_DIS_W4E = 1<<6, /* Disable Wait for Empty */ @@ -595,10 +595,9 @@ enum { MFF_DIS_LOOPB = 1<<2, /* Disable Loopback */ MFF_CLR_MAC_RST = 1<<1, /* Clear XMAC Reset */ MFF_SET_MAC_RST = 1<<0, /* Set XMAC Reset */ - - MFF_TX_CTRL_DEF = MFF_ENA_PKT_REC | (u16) MFF_ENA_TIM_PAT | MFF_ENA_FLUSH, }; +#define MFF_TX_CTRL_DEF (MFF_ENA_PKT_REC | MFF_ENA_TIM_PAT | MFF_ENA_FLUSH) /* RX_MFF_TST2 8 bit Receive MAC FIFO Test Register 2 */ /* TX_MFF_TST2 8 bit Transmit MAC FIFO Test Register 2 */ @@ -1305,8 +1304,8 @@ enum { /* special defines for FIBER (88E1011S only) */ enum { - PHY_M_AN_ASP_X = 1<<8, /* Asymmetric Pause */ - PHY_M_AN_PC_X = 1<<7, /* MAC Pause implemented */ + PHY_M_AN_ASP_X = 1<<8, /* Asymmetric Pause */ + PHY_M_AN_PC_X = 1<<7, /* MAC Pause implemented */ PHY_M_AN_1000X_AHD = 1<<6, /* Advertise 10000Base-X Half Duplex */ PHY_M_AN_1000X_AFD = 1<<5, /* Advertise 10000Base-X Full Duplex */ }; @@ -1321,7 +1320,7 @@ enum { /***** PHY_MARV_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/ enum { - PHY_M_1000C_TEST= 7<<13,/* Bit 15..13: Test Modes */ + PHY_M_1000C_TEST = 7<<13,/* Bit 15..13: Test Modes */ PHY_M_1000C_MSE = 1<<12, /* Manual Master/Slave Enable */ PHY_M_1000C_MSC = 1<<11, /* M/S Configuration (1=Master) */ PHY_M_1000C_MPD = 1<<10, /* Multi-Port Device */ @@ -1350,7 +1349,7 @@ enum { PHY_M_PC_EN_DET_PLUS = 3<<8, /* Energy Detect Plus (Mode 2) */ }; -#define PHY_M_PC_MDI_XMODE(x) ((((u16)(x)<<5) & PHY_M_PC_MDIX_MSK) +#define PHY_M_PC_MDI_XMODE(x) (((x)<<5) & PHY_M_PC_MDIX_MSK) enum { PHY_M_PC_MAN_MDI = 0, /* 00 = Manual MDI configuration */ @@ -1433,24 +1432,24 @@ enum { PHY_M_EC_DIS_LINK_P = 1<<12, /* Disable Link Pulses (88E1111 only) */ PHY_M_EC_M_DSC_MSK = 3<<10, /* Bit 11..10: Master Downshift Counter */ /* (88E1011 only) */ - PHY_M_EC_S_DSC_MSK = 3<<8, /* Bit 9.. 8: Slave Downshift Counter */ + PHY_M_EC_S_DSC_MSK = 3<<8,/* Bit 9.. 8: Slave Downshift Counter */ /* (88E1011 only) */ - PHY_M_EC_M_DSC_MSK2 = 7<<9, /* Bit 11.. 9: Master Downshift Counter */ + PHY_M_EC_M_DSC_MSK2 = 7<<9,/* Bit 11.. 9: Master Downshift Counter */ /* (88E1111 only) */ - PHY_M_EC_DOWN_S_ENA = 1<<8, /* Downshift Enable (88E1111 only) */ + PHY_M_EC_DOWN_S_ENA = 1<<8, /* Downshift Enable (88E1111 only) */ /* !!! Errata in spec. (1 = disable) */ - PHY_M_EC_RX_TIM_CT = 1<<7, /* RGMII Rx Timing Control*/ - PHY_M_EC_MAC_S_MSK = 7<<4, /* Bit 6.. 4: Def. MAC interface speed */ - PHY_M_EC_FIB_AN_ENA = 1<<3, /* Fiber Auto-Neg. Enable (88E1011S only) */ - PHY_M_EC_DTE_D_ENA = 1<<2, /* DTE Detect Enable (88E1111 only) */ - PHY_M_EC_TX_TIM_CT = 1<<1, /* RGMII Tx Timing Control */ - PHY_M_EC_TRANS_DIS = 1<<0, /* Transmitter Disable (88E1111 only) */}; - -#define PHY_M_EC_M_DSC(x) ((u16)(x)<<10) /* 00=1x; 01=2x; 10=3x; 11=4x */ -#define PHY_M_EC_S_DSC(x) ((u16)(x)<<8) /* 00=dis; 01=1x; 10=2x; 11=3x */ -#define PHY_M_EC_MAC_S(x) ((u16)(x)<<4) /* 01X=0; 110=2.5; 111=25 (MHz) */ - -#define PHY_M_EC_M_DSC_2(x) ((u16)(x)<<9) /* 000=1x; 001=2x; 010=3x; 011=4x */ + PHY_M_EC_RX_TIM_CT = 1<<7, /* RGMII Rx Timing Control*/ + PHY_M_EC_MAC_S_MSK = 7<<4,/* Bit 6.. 4: Def. MAC interface speed */ + PHY_M_EC_FIB_AN_ENA = 1<<3, /* Fiber Auto-Neg. Enable (88E1011S only) */ + PHY_M_EC_DTE_D_ENA = 1<<2, /* DTE Detect Enable (88E1111 only) */ + PHY_M_EC_TX_TIM_CT = 1<<1, /* RGMII Tx Timing Control */ + PHY_M_EC_TRANS_DIS = 1<<0, /* Transmitter Disable (88E1111 only) */}; + +#define PHY_M_EC_M_DSC(x) ((x)<<10) /* 00=1x; 01=2x; 10=3x; 11=4x */ +#define PHY_M_EC_S_DSC(x) ((x)<<8) /* 00=dis; 01=1x; 10=2x; 11=3x */ +#define PHY_M_EC_MAC_S(x) ((x)<<4) /* 01X=0; 110=2.5; 111=25 (MHz) */ + +#define PHY_M_EC_M_DSC_2(x) ((x)<<9) /* 000=1x; 001=2x; 010=3x; 011=4x */ /* 100=5x; 101=6x; 110=7x; 111=8x */ enum { MAC_TX_CLK_0_MHZ = 2, @@ -1469,12 +1468,10 @@ enum { PHY_M_LEDC_LK_C_MSK = 7<<3,/* Bit 5.. 3: Link Control Mask */ /* (88E1111 only) */ }; -#define PHY_M_LED_PULS_DUR(x) (((u16)(x)<<12) & PHY_M_LEDC_PULS_MSK) -#define PHY_M_LED_BLINK_RT(x) (((u16)(x)<<8) & PHY_M_LEDC_BL_R_MSK) enum { - PHY_M_LEDC_LINK_MSK = 3<<3, /* Bit 4.. 3: Link Control Mask */ - /* (88E1011 only) */ + PHY_M_LEDC_LINK_MSK = 3<<3,/* Bit 4.. 3: Link Control Mask */ + /* (88E1011 only) */ PHY_M_LEDC_DP_CTRL = 1<<2, /* Duplex Control */ PHY_M_LEDC_DP_C_MSB = 1<<2, /* Duplex Control (MSB, 88E1111 only) */ PHY_M_LEDC_RX_CTRL = 1<<1, /* Rx Activity / Link */ @@ -1482,24 +1479,27 @@ enum { PHY_M_LEDC_TX_C_MSB = 1<<0, /* Tx Control (MSB, 88E1111 only) */ }; +#define PHY_M_LED_PULS_DUR(x) (((x)<<12) & PHY_M_LEDC_PULS_MSK) + enum { - PULS_NO_STR = 0, /* no pulse stretching */ - PULS_21MS = 1, /* 21 ms to 42 ms */ - PULS_42MS = 2, /* 42 ms to 84 ms */ - PULS_84MS = 3, /* 84 ms to 170 ms */ - PULS_170MS = 4, /* 170 ms to 340 ms */ - PULS_340MS = 5, /* 340 ms to 670 ms */ - PULS_670MS = 6, /* 670 ms to 1.3 s */ - PULS_1300MS = 7, /* 1.3 s to 2.7 s */ + PULS_NO_STR = 0,/* no pulse stretching */ + PULS_21MS = 1,/* 21 ms to 42 ms */ + PULS_42MS = 2,/* 42 ms to 84 ms */ + PULS_84MS = 3,/* 84 ms to 170 ms */ + PULS_170MS = 4,/* 170 ms to 340 ms */ + PULS_340MS = 5,/* 340 ms to 670 ms */ + PULS_670MS = 6,/* 670 ms to 1.3 s */ + PULS_1300MS = 7,/* 1.3 s to 2.7 s */ }; +#define PHY_M_LED_BLINK_RT(x) (((x)<<8) & PHY_M_LEDC_BL_R_MSK) enum { - BLINK_42MS = 0, /* 42 ms */ - BLINK_84MS = 1, /* 84 ms */ - BLINK_170MS = 2, /* 170 ms */ - BLINK_340MS = 3, /* 340 ms */ - BLINK_670MS = 4, /* 670 ms */ + BLINK_42MS = 0,/* 42 ms */ + BLINK_84MS = 1,/* 84 ms */ + BLINK_170MS = 2,/* 170 ms */ + BLINK_340MS = 3,/* 340 ms */ + BLINK_670MS = 4,/* 670 ms */ }; /***** PHY_MARV_LED_OVER 16 bit r/w Manual LED Override Reg *****/ @@ -1525,7 +1525,7 @@ enum { PHY_M_EC2_FO_IMPED = 1<<5, /* Fiber Output Impedance */ PHY_M_EC2_FO_M_CLK = 1<<4, /* Fiber Mode Clock Enable */ PHY_M_EC2_FO_BOOST = 1<<3, /* Fiber Output Boost */ - PHY_M_EC2_FO_AM_MSK = 7, /* Bit 2.. 0: Fiber Output Amplitude */ + PHY_M_EC2_FO_AM_MSK = 7,/* Bit 2.. 0: Fiber Output Amplitude */ }; /***** PHY_MARV_EXT_P_STAT 16 bit r/w Ext. PHY Specific Status *****/ @@ -1550,7 +1550,7 @@ enum { PHY_M_CABD_DIS_WAIT = 1<<15, /* Disable Waiting Period (Page 1) */ /* (88E1111 only) */ PHY_M_CABD_STAT_MSK = 3<<13, /* Bit 14..13: Status Mask */ - PHY_M_CABD_AMPL_MSK = 0x1f<<8, /* Bit 12.. 8: Amplitude Mask */ + PHY_M_CABD_AMPL_MSK = 0x1f<<8,/* Bit 12.. 8: Amplitude Mask */ /* (88E1111 only) */ PHY_M_CABD_DIST_MSK = 0xff, /* Bit 7.. 0: Distance Mask */ }; @@ -1605,9 +1605,9 @@ enum { /***** PHY_MARV_PHY_CTRL (page 3) 16 bit r/w LED Control Reg. *****/ enum { - PHY_M_LEDC_LOS_MSK = 0xf<<12, /* Bit 15..12: LOS LED Ctrl. Mask */ + PHY_M_LEDC_LOS_MSK = 0xf<<12,/* Bit 15..12: LOS LED Ctrl. Mask */ PHY_M_LEDC_INIT_MSK = 0xf<<8, /* Bit 11.. 8: INIT LED Ctrl. Mask */ - PHY_M_LEDC_STA1_MSK = 0xf<<4, /* Bit 7.. 4: STAT1 LED Ctrl. Mask */ + PHY_M_LEDC_STA1_MSK = 0xf<<4,/* Bit 7.. 4: STAT1 LED Ctrl. Mask */ PHY_M_LEDC_STA0_MSK = 0xf, /* Bit 3.. 0: STAT0 LED Ctrl. Mask */ }; @@ -1804,8 +1804,8 @@ enum { /* GM_SMI_CTRL 16 bit r/w SMI Control Register */ enum { - GM_SMI_CT_PHY_A_MSK = 0x1f<<11, /* Bit 15..11: PHY Device Address */ - GM_SMI_CT_REG_A_MSK = 0x1f<<6, /* Bit 10.. 6: PHY Register Address */ + GM_SMI_CT_PHY_A_MSK = 0x1f<<11,/* Bit 15..11: PHY Device Address */ + GM_SMI_CT_REG_A_MSK = 0x1f<<6,/* Bit 10.. 6: PHY Register Address */ GM_SMI_CT_OP_RD = 1<<5, /* Bit 5: OpCode Read (0=Write)*/ GM_SMI_CT_RD_VAL = 1<<4, /* Bit 4: Read Valid (Read completed) */ GM_SMI_CT_BUSY = 1<<3, /* Bit 3: Busy (Operation in progress) */ @@ -1875,9 +1875,9 @@ enum { /* TX_GMF_CTRL_T 32 bit Tx GMAC FIFO Control/Test */ enum { - GMF_WSP_TST_ON = 1<<18, /* Write Shadow Pointer Test On */ - GMF_WSP_TST_OFF = 1<<17, /* Write Shadow Pointer Test Off */ - GMF_WSP_STEP = 1<<16, /* Write Shadow Pointer Step/Increment */ + GMF_WSP_TST_ON = 1<<18,/* Write Shadow Pointer Test On */ + GMF_WSP_TST_OFF = 1<<17,/* Write Shadow Pointer Test Off */ + GMF_WSP_STEP = 1<<16,/* Write Shadow Pointer Step/Increment */ GMF_CLI_TX_FU = 1<<6, /* Clear IRQ Tx FIFO Underrun */ GMF_CLI_TX_FC = 1<<5, /* Clear IRQ Tx Frame Complete */ @@ -2111,18 +2111,18 @@ enum { /* XM_MMU_CMD 16 bit r/w MMU Command Register */ enum { - XM_MMU_PHY_RDY = 1<<12, /* Bit 12: PHY Read Ready */ - XM_MMU_PHY_BUSY = 1<<11, /* Bit 11: PHY Busy */ - XM_MMU_IGN_PF = 1<<10, /* Bit 10: Ignore Pause Frame */ - XM_MMU_MAC_LB = 1<<9, /* Bit 9: Enable MAC Loopback */ - XM_MMU_FRC_COL = 1<<7, /* Bit 7: Force Collision */ - XM_MMU_SIM_COL = 1<<6, /* Bit 6: Simulate Collision */ - XM_MMU_NO_PRE = 1<<5, /* Bit 5: No MDIO Preamble */ - XM_MMU_GMII_FD = 1<<4, /* Bit 4: GMII uses Full Duplex */ - XM_MMU_RAT_CTRL = 1<<3, /* Bit 3: Enable Rate Control */ - XM_MMU_GMII_LOOP= 1<<2, /* Bit 2: PHY is in Loopback Mode */ - XM_MMU_ENA_RX = 1<<1, /* Bit 1: Enable Receiver */ - XM_MMU_ENA_TX = 1<<0, /* Bit 0: Enable Transmitter */ + XM_MMU_PHY_RDY = 1<<12,/* Bit 12: PHY Read Ready */ + XM_MMU_PHY_BUSY = 1<<11,/* Bit 11: PHY Busy */ + XM_MMU_IGN_PF = 1<<10,/* Bit 10: Ignore Pause Frame */ + XM_MMU_MAC_LB = 1<<9, /* Bit 9: Enable MAC Loopback */ + XM_MMU_FRC_COL = 1<<7, /* Bit 7: Force Collision */ + XM_MMU_SIM_COL = 1<<6, /* Bit 6: Simulate Collision */ + XM_MMU_NO_PRE = 1<<5, /* Bit 5: No MDIO Preamble */ + XM_MMU_GMII_FD = 1<<4, /* Bit 4: GMII uses Full Duplex */ + XM_MMU_RAT_CTRL = 1<<3, /* Bit 3: Enable Rate Control */ + XM_MMU_GMII_LOOP= 1<<2, /* Bit 2: PHY is in Loopback Mode */ + XM_MMU_ENA_RX = 1<<1, /* Bit 1: Enable Receiver */ + XM_MMU_ENA_TX = 1<<0, /* Bit 0: Enable Transmitter */ }; @@ -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; @@ -2506,7 +2506,7 @@ static inline void skge_write8(const struct skge_hw *hw, int reg, u8 val) } /* MAC Related Registers inside the device. */ -#define SK_REG(port,reg) (((port)<<7)+(u16)(reg)) +#define SK_REG(port,reg) (((port)<<7)+(reg)) #define SK_XMAC_REG(port, reg) \ ((BASE_XMAC_1 + (port) * (BASE_XMAC_2 - BASE_XMAC_1)) | (reg) << 1) diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index fb1d2c30c1bb..842abd9396c6 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -100,32 +100,33 @@ module_param(idle_timeout, int, 0); MODULE_PARM_DESC(idle_timeout, "Watchdog timer for lost interrupts (ms)"); static const struct pci_device_id sky2_id_table[] = { - { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, /* SK-9Sxx */ - { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx */ + { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, + { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) }, /* DGE-560T */ { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4001) }, /* DGE-550SX */ { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4B02) }, /* DGE-560SX */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) }, /* 88E8021 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) }, /* 88E8022 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) }, /* 88E8061 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4343) }, /* 88E8062 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4344) }, /* 88E8021 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4345) }, /* 88E8022 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4346) }, /* 88E8061 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4347) }, /* 88E8062 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4350) }, /* 88E8035 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4351) }, /* 88E8036 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) }, /* 88E8038 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) }, /* 88E8039 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4356) }, /* 88EC033 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) }, /* 88E8052 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, /* 88E8050 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) }, /* 88E8053 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) }, /* 88E8055 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) }, /* 88E8056 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) }, /* 88EC036 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) }, /* 88EC032 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */ + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4343) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4344) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4345) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4346) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4347) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4350) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4351) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4365) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) }, { 0 } }; @@ -521,7 +522,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */ ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL; /* turn off the Rx LED (LED_RX) */ - ledover &= ~PHY_M_LED_MO_RX; + ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); } if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev == CHIP_REV_YU_EC_A1) { @@ -544,7 +545,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) { /* turn on 100 Mbps LED (LED_LINK100) */ - ledover |= PHY_M_LED_MO_100; + ledover |= PHY_M_LED_MO_100(MO_LED_ON); } if (ledover) @@ -696,15 +697,10 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) } -/* Assign Ram Buffer allocation to queue */ -static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 space) +/* Assign Ram Buffer allocation in units of 64bit (8 bytes) */ +static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 end) { - u32 end; - - /* convert from K bytes to qwords used for hw register */ - start *= 1024/8; - space *= 1024/8; - end = start + space - 1; + pr_debug(PFX "q %d %#x %#x\n", q, start, end); sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR); sky2_write32(hw, RB_ADDR(q, RB_START), start); @@ -713,6 +709,7 @@ static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 space) sky2_write32(hw, RB_ADDR(q, RB_RP), start); if (q == Q_R1 || q == Q_R2) { + u32 space = end - start + 1; u32 tp = space - space/4; /* On receive queue's set the thresholds @@ -1062,16 +1059,11 @@ static int sky2_rx_start(struct sky2_port *sky2) sky2->rx_put = sky2->rx_next = 0; sky2_qset(hw, rxq); - /* On PCI express lowering the watermark gives better performance */ - if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP)) - sky2_write32(hw, Q_ADDR(rxq, Q_WM), BMU_WM_PEX); - - /* These chips have no ram buffer? - * MAC Rx RAM Read is controlled by hardware */ if (hw->chip_id == CHIP_ID_YUKON_EC_U && - (hw->chip_rev == CHIP_REV_YU_EC_U_A1 - || hw->chip_rev == CHIP_REV_YU_EC_U_B0)) + (hw->chip_rev == CHIP_REV_YU_EC_U_A1 || hw->chip_rev == CHIP_REV_YU_EC_U_B0)) { + /* MAC Rx RAM Read is controlled by hardware */ sky2_write32(hw, Q_ADDR(rxq, Q_F), F_M_RX_RAM_DIS); + } sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1); @@ -1147,7 +1139,7 @@ static int sky2_up(struct net_device *dev) struct sky2_port *sky2 = netdev_priv(dev); struct sky2_hw *hw = sky2->hw; unsigned port = sky2->port; - u32 ramsize, imask; + u32 ramsize, rxspace, imask; int cap, err = -ENOMEM; struct net_device *otherdev = hw->dev[sky2->port^1]; @@ -1200,25 +1192,20 @@ static int sky2_up(struct net_device *dev) sky2_mac_init(hw, port); - /* Register is number of 4K blocks on internal RAM buffer. */ - ramsize = sky2_read8(hw, B2_E_0) * 4; - printk(KERN_INFO PFX "%s: ram buffer %dK\n", dev->name, ramsize); - - if (ramsize > 0) { - u32 rxspace; + /* Determine available ram buffer space in qwords. */ + ramsize = sky2_read8(hw, B2_E_0) * 4096/8; - if (ramsize < 16) - rxspace = ramsize / 2; - else - rxspace = 8 + (2*(ramsize - 16))/3; + if (ramsize > 6*1024/8) + rxspace = ramsize - (ramsize + 2) / 3; + else + rxspace = ramsize / 2; - sky2_ramset(hw, rxqaddr[port], 0, rxspace); - sky2_ramset(hw, txqaddr[port], rxspace, ramsize - rxspace); + sky2_ramset(hw, rxqaddr[port], 0, rxspace-1); + sky2_ramset(hw, txqaddr[port], rxspace, ramsize-1); - /* Make sure SyncQ is disabled */ - sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL), - RB_RST_SET); - } + /* Make sure SyncQ is disabled */ + sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL), + RB_RST_SET); sky2_qset(hw, txqaddr[port]); @@ -2930,8 +2917,18 @@ static void sky2_led(struct sky2_hw *hw, unsigned port, int on) default: gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); - gm_phy_write(hw, port, PHY_MARV_LED_OVER, - on ? PHY_M_LED_ALL : 0); + gm_phy_write(hw, port, PHY_MARV_LED_OVER, + on ? PHY_M_LED_MO_DUP(MO_LED_ON) | + PHY_M_LED_MO_10(MO_LED_ON) | + PHY_M_LED_MO_100(MO_LED_ON) | + PHY_M_LED_MO_1000(MO_LED_ON) | + PHY_M_LED_MO_RX(MO_LED_ON) + : PHY_M_LED_MO_DUP(MO_LED_OFF) | + PHY_M_LED_MO_10(MO_LED_OFF) | + PHY_M_LED_MO_100(MO_LED_OFF) | + PHY_M_LED_MO_1000(MO_LED_OFF) | + PHY_M_LED_MO_RX(MO_LED_OFF)); + } } diff --git a/trunk/drivers/net/sky2.h b/trunk/drivers/net/sky2.h index 6ed1d47dbbd3..7760545edbf2 100644 --- a/trunk/drivers/net/sky2.h +++ b/trunk/drivers/net/sky2.h @@ -608,7 +608,7 @@ enum { PHY_ADDR_MARV = 0, }; -#define RB_ADDR(offs, queue) ((u16) B16_RAM_REGS + (queue) + (offs)) +#define RB_ADDR(offs, queue) (B16_RAM_REGS + (queue) + (offs)) enum { @@ -680,7 +680,6 @@ enum { BMU_FIFO_ENA | BMU_OP_ON, BMU_WM_DEFAULT = 0x600, - BMU_WM_PEX = 0x80, }; /* Tx BMU Control / Status Registers (Yukon-2) */ @@ -1061,7 +1060,7 @@ enum { PHY_M_PC_EN_DET_PLUS = 3<<8, /* Energy Detect Plus (Mode 2) */ }; -#define PHY_M_PC_MDI_XMODE(x) (((u16)(x)<<5) & PHY_M_PC_MDIX_MSK) +#define PHY_M_PC_MDI_XMODE(x) (((x)<<5) & PHY_M_PC_MDIX_MSK) enum { PHY_M_PC_MAN_MDI = 0, /* 00 = Manual MDI configuration */ @@ -1157,13 +1156,13 @@ enum { PHY_M_EC_TX_TIM_CT = 1<<1, /* RGMII Tx Timing Control */ PHY_M_EC_TRANS_DIS = 1<<0, /* Transmitter Disable (88E1111 only) */}; -#define PHY_M_EC_M_DSC(x) ((u16)(x)<<10 & PHY_M_EC_M_DSC_MSK) +#define PHY_M_EC_M_DSC(x) ((x)<<10 & PHY_M_EC_M_DSC_MSK) /* 00=1x; 01=2x; 10=3x; 11=4x */ -#define PHY_M_EC_S_DSC(x) ((u16)(x)<<8 & PHY_M_EC_S_DSC_MSK) +#define PHY_M_EC_S_DSC(x) ((x)<<8 & PHY_M_EC_S_DSC_MSK) /* 00=dis; 01=1x; 10=2x; 11=3x */ -#define PHY_M_EC_DSC_2(x) ((u16)(x)<<9 & PHY_M_EC_M_DSC_MSK2) +#define PHY_M_EC_DSC_2(x) ((x)<<9 & PHY_M_EC_M_DSC_MSK2) /* 000=1x; 001=2x; 010=3x; 011=4x */ -#define PHY_M_EC_MAC_S(x) ((u16)(x)<<4 & PHY_M_EC_MAC_S_MSK) +#define PHY_M_EC_MAC_S(x) ((x)<<4 & PHY_M_EC_MAC_S_MSK) /* 01X=0; 110=2.5; 111=25 (MHz) */ /* for Yukon-2 Gigabit Ethernet PHY (88E1112 only) */ @@ -1174,7 +1173,7 @@ enum { }; /* !!! Errata in spec. (1 = disable) */ -#define PHY_M_PC_DSC(x) (((u16)(x)<<12) & PHY_M_PC_DSC_MSK) +#define PHY_M_PC_DSC(x) (((x)<<12) & PHY_M_PC_DSC_MSK) /* 100=5x; 101=6x; 110=7x; 111=8x */ enum { MAC_TX_CLK_0_MHZ = 2, @@ -1204,7 +1203,7 @@ enum { PHY_M_LEDC_TX_C_MSB = 1<<0, /* Tx Control (MSB, 88E1111 only) */ }; -#define PHY_M_LED_PULS_DUR(x) (((u16)(x)<<12) & PHY_M_LEDC_PULS_MSK) +#define PHY_M_LED_PULS_DUR(x) (((x)<<12) & PHY_M_LEDC_PULS_MSK) /***** PHY_MARV_PHY_STAT (page 3)16 bit r/w Polarity Control Reg. *****/ enum { @@ -1234,7 +1233,7 @@ enum { PULS_1300MS = 7,/* 1.3 s to 2.7 s */ }; -#define PHY_M_LED_BLINK_RT(x) (((u16)(x)<<8) & PHY_M_LEDC_BL_R_MSK) +#define PHY_M_LED_BLINK_RT(x) (((x)<<8) & PHY_M_LEDC_BL_R_MSK) enum { BLINK_42MS = 0,/* 42 ms */ @@ -1244,18 +1243,21 @@ enum { BLINK_670MS = 4,/* 670 ms */ }; -/**** PHY_MARV_LED_OVER 16 bit r/w LED control */ -enum { - PHY_M_LED_MO_DUP = 3<<10,/* Bit 11..10: Duplex */ - PHY_M_LED_MO_10 = 3<<8, /* Bit 9.. 8: Link 10 */ - PHY_M_LED_MO_100 = 3<<6, /* Bit 7.. 6: Link 100 */ - PHY_M_LED_MO_1000 = 3<<4, /* Bit 5.. 4: Link 1000 */ - PHY_M_LED_MO_RX = 3<<2, /* Bit 3.. 2: Rx */ - PHY_M_LED_MO_TX = 3<<0, /* Bit 1.. 0: Tx */ +/***** PHY_MARV_LED_OVER 16 bit r/w Manual LED Override Reg *****/ +#define PHY_M_LED_MO_SGMII(x) ((x)<<14) /* Bit 15..14: SGMII AN Timer */ + /* Bit 13..12: reserved */ +#define PHY_M_LED_MO_DUP(x) ((x)<<10) /* Bit 11..10: Duplex */ +#define PHY_M_LED_MO_10(x) ((x)<<8) /* Bit 9.. 8: Link 10 */ +#define PHY_M_LED_MO_100(x) ((x)<<6) /* Bit 7.. 6: Link 100 */ +#define PHY_M_LED_MO_1000(x) ((x)<<4) /* Bit 5.. 4: Link 1000 */ +#define PHY_M_LED_MO_RX(x) ((x)<<2) /* Bit 3.. 2: Rx */ +#define PHY_M_LED_MO_TX(x) ((x)<<0) /* Bit 1.. 0: Tx */ - PHY_M_LED_ALL = PHY_M_LED_MO_DUP | PHY_M_LED_MO_10 - | PHY_M_LED_MO_100 | PHY_M_LED_MO_1000 - | PHY_M_LED_MO_RX, +enum { + MO_LED_NORM = 0, + MO_LED_BLINK = 1, + MO_LED_OFF = 2, + MO_LED_ON = 3, }; /***** PHY_MARV_EXT_CTRL_2 16 bit r/w Ext. PHY Specific Ctrl 2 *****/ @@ -1292,9 +1294,9 @@ enum { PHY_M_FELP_LED0_MSK = 0xf, /* Bit 3.. 0: LED0 Mask (SPEED) */ }; -#define PHY_M_FELP_LED2_CTRL(x) (((u16)(x)<<8) & PHY_M_FELP_LED2_MSK) -#define PHY_M_FELP_LED1_CTRL(x) (((u16)(x)<<4) & PHY_M_FELP_LED1_MSK) -#define PHY_M_FELP_LED0_CTRL(x) (((u16)(x)<<0) & PHY_M_FELP_LED0_MSK) +#define PHY_M_FELP_LED2_CTRL(x) (((x)<<8) & PHY_M_FELP_LED2_MSK) +#define PHY_M_FELP_LED1_CTRL(x) (((x)<<4) & PHY_M_FELP_LED1_MSK) +#define PHY_M_FELP_LED0_CTRL(x) (((x)<<0) & PHY_M_FELP_LED0_MSK) enum { LED_PAR_CTRL_COLX = 0x00, @@ -1550,8 +1552,8 @@ enum { GM_SMI_CT_BUSY = 1<<3, /* Bit 3: Busy (Operation in progress) */ }; -#define GM_SMI_CT_PHY_AD(x) (((u16)(x)<<11) & GM_SMI_CT_PHY_A_MSK) -#define GM_SMI_CT_REG_AD(x) (((u16)(x)<<6) & GM_SMI_CT_REG_A_MSK) +#define GM_SMI_CT_PHY_AD(x) (((x)<<11) & GM_SMI_CT_PHY_A_MSK) +#define GM_SMI_CT_REG_AD(x) (((x)<<6) & GM_SMI_CT_REG_A_MSK) /* GM_PHY_ADDR 16 bit r/w GPHY Address Register */ enum { diff --git a/trunk/drivers/net/smc-ultra.c b/trunk/drivers/net/smc-ultra.c index d70bc9795346..889ef0d7c374 100644 --- a/trunk/drivers/net/smc-ultra.c +++ b/trunk/drivers/net/smc-ultra.c @@ -593,7 +593,7 @@ static void cleanup_card(struct net_device *dev) iounmap(ei_status.mem); } -void __exit +void cleanup_module(void) { int this_dev; diff --git a/trunk/drivers/net/smc-ultra32.c b/trunk/drivers/net/smc-ultra32.c index 2c5319c62fa5..e10755ec5def 100644 --- a/trunk/drivers/net/smc-ultra32.c +++ b/trunk/drivers/net/smc-ultra32.c @@ -437,7 +437,7 @@ int __init init_module(void) return -ENXIO; } -void __exit cleanup_module(void) +void cleanup_module(void) { int this_dev; diff --git a/trunk/drivers/net/smc9194.c b/trunk/drivers/net/smc9194.c index bd6e84506c29..c0d13d650913 100644 --- a/trunk/drivers/net/smc9194.c +++ b/trunk/drivers/net/smc9194.c @@ -1616,7 +1616,7 @@ int __init init_module(void) return 0; } -void __exit cleanup_module(void) +void cleanup_module(void) { unregister_netdev(devSMC9194); free_irq(devSMC9194->irq, devSMC9194); 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/smc91x.h b/trunk/drivers/net/smc91x.h index 9367c574477a..a8640169fc77 100644 --- a/trunk/drivers/net/smc91x.h +++ b/trunk/drivers/net/smc91x.h @@ -238,7 +238,7 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) #define SMC_CAN_USE_16BIT 1 #define SMC_CAN_USE_32BIT 0 -#define SMC_inb(a, r) inb(((u32)a) + (r)) +#define SMC_inb(a, r) inb((u32)a) + (r)) #define SMC_inw(a, r) inw(((u32)a) + (r)) #define SMC_outb(v, a, r) outb(v, ((u32)a) + (r)) #define SMC_outw(v, a, r) outw(v, ((u32)a) + (r)) @@ -434,24 +434,6 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r, #define SMC_IRQ_FLAGS (0) -#elif defined(CONFIG_ARCH_VERSATILE) - -#define SMC_CAN_USE_8BIT 1 -#define SMC_CAN_USE_16BIT 1 -#define SMC_CAN_USE_32BIT 1 -#define SMC_NOWAIT 1 - -#define SMC_inb(a, r) readb((a) + (r)) -#define SMC_inw(a, r) readw((a) + (r)) -#define SMC_inl(a, r) readl((a) + (r)) -#define SMC_outb(v, a, r) writeb(v, (a) + (r)) -#define SMC_outw(v, a, r) writew(v, (a) + (r)) -#define SMC_outl(v, a, r) writel(v, (a) + (r)) -#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) -#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) - -#define SMC_IRQ_FLAGS (0) - #else #define SMC_CAN_USE_8BIT 1 @@ -1234,7 +1216,7 @@ static const char * chip_ids[ 16 ] = { if (SMC_CAN_USE_32BIT) { \ void *__ptr = (p); \ int __len = (l); \ - void __iomem *__ioaddr = ioaddr; \ + void *__ioaddr = ioaddr; \ if (__len >= 2 && (unsigned long)__ptr & 2) { \ __len -= 2; \ SMC_outw(*(u16 *)__ptr, ioaddr, DATA_REG); \ @@ -1258,7 +1240,7 @@ static const char * chip_ids[ 16 ] = { if (SMC_CAN_USE_32BIT) { \ void *__ptr = (p); \ int __len = (l); \ - void __iomem *__ioaddr = ioaddr; \ + void *__ioaddr = ioaddr; \ if ((unsigned long)__ptr & 2) { \ /* \ * We want 32bit alignment here. \ 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/sun3lance.c b/trunk/drivers/net/sun3lance.c index c62e85d89f41..47a1c09d19ac 100644 --- a/trunk/drivers/net/sun3lance.c +++ b/trunk/drivers/net/sun3lance.c @@ -945,7 +945,7 @@ static void set_multicast_list( struct net_device *dev ) static struct net_device *sun3lance_dev; -int __init init_module(void) +int init_module(void) { sun3lance_dev = sun3lance_probe(-1); if (IS_ERR(sun3lance_dev)) @@ -953,7 +953,7 @@ int __init init_module(void) return 0; } -void __exit cleanup_module(void) +void cleanup_module(void) { unregister_netdev(sun3lance_dev); #ifdef CONFIG_SUN3 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/tokenring/smctr.c b/trunk/drivers/net/tokenring/smctr.c index cec282a6f62d..46dabdb12071 100644 --- a/trunk/drivers/net/tokenring/smctr.c +++ b/trunk/drivers/net/tokenring/smctr.c @@ -5706,7 +5706,7 @@ int __init init_module(void) return found ? 0 : -ENODEV; } -void __exit cleanup_module(void) +void cleanup_module(void) { int i; 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/wd.c b/trunk/drivers/net/wd.c index 7f38012b9c92..41f1d6778849 100644 --- a/trunk/drivers/net/wd.c +++ b/trunk/drivers/net/wd.c @@ -538,7 +538,7 @@ static void cleanup_card(struct net_device *dev) iounmap(ei_status.mem); } -void __exit +void cleanup_module(void) { int this_dev; 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..d7a86b188a99 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); } @@ -1062,10 +1059,8 @@ int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length) memcpy(skb_put(skb, length), buffer, length); r = ieee80211_rx(ieee, skb, &stats); - if (!r) { - ZD_ASSERT(in_irq()); - dev_kfree_skb_irq(skb); - } + if (!r) + dev_kfree_skb_any(skb); return 0; } @@ -1185,10 +1180,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 +1203,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/s390/block/dasd.c b/trunk/drivers/s390/block/dasd.c index 2af2d9b53d18..a2cef57d7bcb 100644 --- a/trunk/drivers/s390/block/dasd.c +++ b/trunk/drivers/s390/block/dasd.c @@ -54,7 +54,7 @@ static void dasd_flush_request_queue(struct dasd_device *); static void dasd_int_handler(struct ccw_device *, unsigned long, struct irb *); static int dasd_flush_ccw_queue(struct dasd_device *, int); static void dasd_tasklet(struct dasd_device *); -static void do_kick_device(struct work_struct *); +static void do_kick_device(void *data); /* * SECTION: Operations on the device structure. @@ -100,7 +100,7 @@ dasd_alloc_device(void) (unsigned long) device); INIT_LIST_HEAD(&device->ccw_queue); init_timer(&device->timer); - INIT_WORK(&device->kick_work, do_kick_device); + INIT_WORK(&device->kick_work, do_kick_device, device); device->state = DASD_STATE_NEW; device->target = DASD_STATE_NEW; @@ -407,9 +407,11 @@ dasd_change_state(struct dasd_device *device) * event daemon. */ static void -do_kick_device(struct work_struct *work) +do_kick_device(void *data) { - struct dasd_device *device = container_of(work, struct dasd_device, kick_work); + struct dasd_device *device; + + device = (struct dasd_device *) data; dasd_change_state(device); dasd_schedule_bh(device); dasd_put_device(device); diff --git a/trunk/drivers/s390/cio/css.c b/trunk/drivers/s390/cio/css.c index 26cf2f5ae2e7..ad7f7e1c0163 100644 --- a/trunk/drivers/s390/cio/css.c +++ b/trunk/drivers/s390/cio/css.c @@ -334,7 +334,7 @@ static LIST_HEAD(slow_subchannels_head); static DEFINE_SPINLOCK(slow_subchannel_lock); static void -css_trigger_slow_path(struct work_struct *unused) +css_trigger_slow_path(void) { CIO_TRACE_EVENT(4, "slowpath"); @@ -359,7 +359,8 @@ css_trigger_slow_path(struct work_struct *unused) spin_unlock_irq(&slow_subchannel_lock); } -DECLARE_WORK(slow_path_work, css_trigger_slow_path); +typedef void (*workfunc)(void *); +DECLARE_WORK(slow_path_work, (workfunc)css_trigger_slow_path, NULL); struct workqueue_struct *slow_path_wq; /* Reprobe subchannel if unregistered. */ @@ -396,7 +397,7 @@ static int reprobe_subchannel(struct subchannel_id schid, void *data) } /* Work function used to reprobe all unregistered subchannels. */ -static void reprobe_all(struct work_struct *unused) +static void reprobe_all(void *data) { int ret; @@ -412,7 +413,7 @@ static void reprobe_all(struct work_struct *unused) need_reprobe); } -DECLARE_WORK(css_reprobe_work, reprobe_all); +DECLARE_WORK(css_reprobe_work, reprobe_all, NULL); /* Schedule reprobing of all unregistered subchannels. */ void css_schedule_reprobe(void) diff --git a/trunk/drivers/s390/crypto/ap_bus.c b/trunk/drivers/s390/crypto/ap_bus.c index e4dc947e74e9..6a54334ffe09 100644 --- a/trunk/drivers/s390/crypto/ap_bus.c +++ b/trunk/drivers/s390/crypto/ap_bus.c @@ -37,7 +37,7 @@ #include "ap_bus.h" /* Some prototypes. */ -static void ap_scan_bus(struct work_struct *); +static void ap_scan_bus(void *); static void ap_poll_all(unsigned long); static void ap_poll_timeout(unsigned long); static int ap_poll_thread_start(void); @@ -71,7 +71,7 @@ static struct device *ap_root_device = NULL; static struct workqueue_struct *ap_work_queue; static struct timer_list ap_config_timer; static int ap_config_time = AP_CONFIG_TIME; -static DECLARE_WORK(ap_config_work, ap_scan_bus); +static DECLARE_WORK(ap_config_work, ap_scan_bus, NULL); /** * Tasklet & timer for AP request polling. @@ -732,7 +732,7 @@ static void ap_device_release(struct device *dev) kfree(ap_dev); } -static void ap_scan_bus(struct work_struct *unused) +static void ap_scan_bus(void *data) { struct ap_device *ap_dev; struct device *dev; diff --git a/trunk/drivers/s390/net/lcs.c b/trunk/drivers/s390/net/lcs.c index e5665b6743a1..08d4e47070bd 100644 --- a/trunk/drivers/s390/net/lcs.c +++ b/trunk/drivers/s390/net/lcs.c @@ -67,7 +67,7 @@ static char debug_buffer[255]; * Some prototypes. */ static void lcs_tasklet(unsigned long); -static void lcs_start_kernel_thread(struct work_struct *); +static void lcs_start_kernel_thread(struct lcs_card *card); static void lcs_get_frames_cb(struct lcs_channel *, struct lcs_buffer *); static int lcs_send_delipm(struct lcs_card *, struct lcs_ipm_list *); static int lcs_recovery(void *ptr); @@ -1724,9 +1724,8 @@ lcs_stopcard(struct lcs_card *card) * Kernel Thread helper functions for LGW initiated commands */ static void -lcs_start_kernel_thread(struct work_struct *work) +lcs_start_kernel_thread(struct lcs_card *card) { - struct lcs_card *card = container_of(work, struct lcs_card, kernel_thread_starter); LCS_DBF_TEXT(5, trace, "krnthrd"); if (lcs_do_start_thread(card, LCS_RECOVERY_THREAD)) kernel_thread(lcs_recovery, (void *) card, SIGCHLD); @@ -2054,7 +2053,8 @@ lcs_probe_device(struct ccwgroup_device *ccwgdev) ccwgdev->cdev[0]->handler = lcs_irq; ccwgdev->cdev[1]->handler = lcs_irq; card->gdev = ccwgdev; - INIT_WORK(&card->kernel_thread_starter, lcs_start_kernel_thread); + INIT_WORK(&card->kernel_thread_starter, + (void *) lcs_start_kernel_thread, card); card->thread_start_mask = 0; card->thread_allowed_mask = 0; card->thread_running_mask = 0; diff --git a/trunk/drivers/s390/net/qeth_main.c b/trunk/drivers/s390/net/qeth_main.c index 2bde4f1fb9c2..7fdc5272c446 100644 --- a/trunk/drivers/s390/net/qeth_main.c +++ b/trunk/drivers/s390/net/qeth_main.c @@ -1039,9 +1039,8 @@ qeth_do_start_thread(struct qeth_card *card, unsigned long thread) } static void -qeth_start_kernel_thread(struct work_struct *work) +qeth_start_kernel_thread(struct qeth_card *card) { - struct qeth_card *card = container_of(work, struct qeth_card, kernel_thread_starter); QETH_DBF_TEXT(trace , 2, "strthrd"); if (card->read.state != CH_STATE_UP && @@ -1104,7 +1103,8 @@ qeth_setup_card(struct qeth_card *card) card->thread_start_mask = 0; card->thread_allowed_mask = 0; card->thread_running_mask = 0; - INIT_WORK(&card->kernel_thread_starter, qeth_start_kernel_thread); + INIT_WORK(&card->kernel_thread_starter, + (void *)qeth_start_kernel_thread,card); INIT_LIST_HEAD(&card->ip_list); card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_KERNEL); if (!card->ip_tbd_list) { 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 e28260f05d6b..000000000000 --- a/trunk/drivers/scsi/ibmvscsi/ibmvstgt.c +++ /dev/null @@ -1,960 +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; - struct srp_target *target; -}; - -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(struct work_struct *work) -{ - struct vio_port *vport = container_of(work, struct vio_port, crq_work); - struct srp_target *target = vport->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; - vport->target = target; - 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); - - 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/oktagon_esp.c b/trunk/drivers/scsi/oktagon_esp.c index c116a6ae3c54..dd67a68c5c23 100644 --- a/trunk/drivers/scsi/oktagon_esp.c +++ b/trunk/drivers/scsi/oktagon_esp.c @@ -72,12 +72,12 @@ static void dma_advance_sg(Scsi_Cmnd *); static int oktagon_notify_reboot(struct notifier_block *this, unsigned long code, void *x); #ifdef USE_BOTTOM_HALF -static void dma_commit(struct work_struct *unused); +static void dma_commit(void *opaque); long oktag_to_io(long *paddr, long *addr, long len); long oktag_from_io(long *addr, long *paddr, long len); -static DECLARE_WORK(tq_fake_dma, dma_commit); +static DECLARE_WORK(tq_fake_dma, dma_commit, NULL); #define DMA_MAXTRANSFER 0x8000 @@ -266,7 +266,7 @@ oktagon_notify_reboot(struct notifier_block *this, unsigned long code, void *x) */ -static void dma_commit(struct work_struct *unused) +static void dma_commit(void *opaque) { long wait,len2,pos; struct NCR_ESP *esp; 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.c b/trunk/drivers/serial/sh-sci.c index 3b5f19ec2126..cfcc3caf49d8 100644 --- a/trunk/drivers/serial/sh-sci.c +++ b/trunk/drivers/serial/sh-sci.c @@ -775,7 +775,7 @@ static int sci_notifier(struct notifier_block *self, * * Clean this up later.. */ - clk = clk_get(NULL, "module_clk"); + clk = clk_get("module_clk"); port->uartclk = clk_get_rate(clk) * 16; clk_put(clk); } @@ -960,7 +960,7 @@ static void sci_set_termios(struct uart_port *port, struct termios *termios, default: { #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) - struct clk *clk = clk_get(NULL, "module_clk"); + struct clk *clk = clk_get("module_clk"); t = SCBRR_VALUE(baud, clk_get_rate(clk)); clk_put(clk); #else @@ -1128,7 +1128,7 @@ static void __init sci_init_ports(void) * XXX: We should use a proper SCI/SCIF clock */ { - struct clk *clk = clk_get(NULL, "module_clk"); + struct clk *clk = clk_get("module_clk"); sci_ports[i].port.uartclk = clk_get_rate(clk) * 16; clk_put(clk); } diff --git a/trunk/drivers/serial/sh-sci.h b/trunk/drivers/serial/sh-sci.h index e4557cc4f74b..7ee992146ae9 100644 --- a/trunk/drivers/serial/sh-sci.h +++ b/trunk/drivers/serial/sh-sci.h @@ -133,20 +133,6 @@ # 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 @@ -379,7 +365,6 @@ SCIx_FNS(SCxSR, 0x08, 8, 0x10, 8, 0x08, 16, 0x10, 16, 0x04, 8) SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8, 0x05, 8) SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16) #if defined(CONFIG_CPU_SUBTYPE_SH7760) || defined(CONFIG_CPU_SUBTYPE_SH7780) -SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16) SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16) SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16) SCIF_FNS(SCSPTR, 0, 0, 0x24, 16) @@ -559,28 +544,6 @@ 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-i386/atomic.h b/trunk/include/asm-i386/atomic.h index a6c024e2506f..51a166242522 100644 --- a/trunk/include/asm-i386/atomic.h +++ b/trunk/include/asm-i386/atomic.h @@ -14,7 +14,7 @@ * on us. We need to use _exactly_ the address the user gave us, * not some alias that contains the same information. */ -typedef struct { int counter; } atomic_t; +typedef struct { volatile int counter; } atomic_t; #define ATOMIC_INIT(i) { (i) } diff --git a/trunk/include/asm-i386/spinlock_types.h b/trunk/include/asm-i386/spinlock_types.h index 4da9345c1500..59efe849f351 100644 --- a/trunk/include/asm-i386/spinlock_types.h +++ b/trunk/include/asm-i386/spinlock_types.h @@ -6,13 +6,13 @@ #endif typedef struct { - unsigned int slock; + volatile unsigned int slock; } raw_spinlock_t; #define __RAW_SPIN_LOCK_UNLOCKED { 1 } typedef struct { - unsigned int lock; + volatile unsigned int lock; } raw_rwlock_t; #define __RAW_RW_LOCK_UNLOCKED { RW_LOCK_BIAS } 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/asm-mips/i8259.h b/trunk/include/asm-mips/i8259.h index 4df8d8b118c0..0214abe3f0af 100644 --- a/trunk/include/asm-mips/i8259.h +++ b/trunk/include/asm-mips/i8259.h @@ -19,31 +19,10 @@ #include -/* i8259A PIC registers */ -#define PIC_MASTER_CMD 0x20 -#define PIC_MASTER_IMR 0x21 -#define PIC_MASTER_ISR PIC_MASTER_CMD -#define PIC_MASTER_POLL PIC_MASTER_ISR -#define PIC_MASTER_OCW3 PIC_MASTER_ISR -#define PIC_SLAVE_CMD 0xa0 -#define PIC_SLAVE_IMR 0xa1 - -/* i8259A PIC related value */ -#define PIC_CASCADE_IR 2 -#define MASTER_ICW4_DEFAULT 0x01 -#define SLAVE_ICW4_DEFAULT 0x01 -#define PIC_ICW4_AEOI 2 - extern spinlock_t i8259A_lock; -extern void init_8259A(int auto_eoi); -extern void enable_8259A_irq(unsigned int irq); -extern void disable_8259A_irq(unsigned int irq); - extern void init_i8259_irqs(void); -#define I8259A_IRQ_BASE 0 - /* * Do the traditional i8259 interrupt polling thing. This is for the few * cases where no better interrupt acknowledge method is available and we @@ -56,15 +35,15 @@ static inline int i8259_irq(void) spin_lock(&i8259A_lock); /* Perform an interrupt acknowledge cycle on controller 1. */ - outb(0x0C, PIC_MASTER_CMD); /* prepare for poll */ - irq = inb(PIC_MASTER_CMD) & 7; - if (irq == PIC_CASCADE_IR) { + outb(0x0C, 0x20); /* prepare for poll */ + irq = inb(0x20) & 7; + if (irq == 2) { /* * Interrupt is cascaded so perform interrupt * acknowledge on controller 2. */ - outb(0x0C, PIC_SLAVE_CMD); /* prepare for poll */ - irq = (inb(PIC_SLAVE_CMD) & 7) + 8; + outb(0x0C, 0xA0); /* prepare for poll */ + irq = (inb(0xA0) & 7) + 8; } if (unlikely(irq == 7)) { @@ -75,14 +54,14 @@ static inline int i8259_irq(void) * significant bit is not set then there is no valid * interrupt. */ - outb(0x0B, PIC_MASTER_ISR); /* ISR register */ - if(~inb(PIC_MASTER_ISR) & 0x80) + outb(0x0B, 0x20); /* ISR register */ + if(~inb(0x20) & 0x80) irq = -1; } spin_unlock(&i8259A_lock); - return likely(irq >= 0) ? irq + I8259A_IRQ_BASE : irq; + return irq; } #endif /* _ASM_I8259_H */ diff --git a/trunk/include/asm-mips/pgtable-32.h b/trunk/include/asm-mips/pgtable-32.h index 2fbd47eba32d..d20f2e9b28be 100644 --- a/trunk/include/asm-mips/pgtable-32.h +++ b/trunk/include/asm-mips/pgtable-32.h @@ -156,9 +156,9 @@ pfn_pte(unsigned long pfn, pgprot_t prot) #define __pte_offset(address) \ (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) #define pte_offset(dir, address) \ - ((pte_t *) pmd_page_vaddr(*(dir)) + __pte_offset(address)) -#define pte_offset_kernel(dir, address) \ - ((pte_t *) pmd_page_vaddr(*(dir)) + __pte_offset(address)) + ((pte_t *) (pmd_page_vaddr(*dir)) + __pte_offset(address)) +#define pte_offset_kernel(dir, address) \ + ((pte_t *) pmd_page_vaddr(*(dir)) + __pte_offset(address)) #define pte_offset_map(dir, address) \ ((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address)) diff --git a/trunk/include/asm-mips/pgtable-64.h b/trunk/include/asm-mips/pgtable-64.h index a5b18710b6a4..b9b1e86493ee 100644 --- a/trunk/include/asm-mips/pgtable-64.h +++ b/trunk/include/asm-mips/pgtable-64.h @@ -212,9 +212,9 @@ static inline pmd_t *pmd_offset(pud_t * pud, unsigned long address) #define __pte_offset(address) \ (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) #define pte_offset(dir, address) \ - ((pte_t *) pmd_page_vaddr(*(dir)) + __pte_offset(address)) + ((pte_t *) (pmd_page_vaddr(*dir)) + __pte_offset(address)) #define pte_offset_kernel(dir, address) \ - ((pte_t *) pmd_page_vaddr(*(dir)) + __pte_offset(address)) + ((pte_t *) pmd_page_vaddr(*(dir)) + __pte_offset(address)) #define pte_offset_map(dir, address) \ ((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address)) #define pte_offset_map_nested(dir, address) \ diff --git a/trunk/include/asm-sh/atomic.h b/trunk/include/asm-sh/atomic.h index 28305c3cbddf..8bdc1ba56f73 100644 --- a/trunk/include/asm-sh/atomic.h +++ b/trunk/include/asm-sh/atomic.h @@ -28,11 +28,11 @@ static inline void atomic_add(int i, atomic_t *v) unsigned long tmp; __asm__ __volatile__ ( -"1: movli.l @%2, %0 ! atomic_add \n" -" add %1, %0 \n" -" movco.l %0, @%2 \n" +"1: movli.l @%3, %0 ! atomic_add \n" +" add %2, %0 \n" +" movco.l %0, @%3 \n" " bf 1b \n" - : "=&z" (tmp) + : "=&z" (tmp), "=r" (&v->counter) : "r" (i), "r" (&v->counter) : "t"); #else @@ -50,11 +50,11 @@ static inline void atomic_sub(int i, atomic_t *v) unsigned long tmp; __asm__ __volatile__ ( -"1: movli.l @%2, %0 ! atomic_sub \n" -" sub %1, %0 \n" -" movco.l %0, @%2 \n" +"1: movli.l @%3, %0 ! atomic_sub \n" +" sub %2, %0 \n" +" movco.l %0, @%3 \n" " bf 1b \n" - : "=&z" (tmp) + : "=&z" (tmp), "=r" (&v->counter) : "r" (i), "r" (&v->counter) : "t"); #else @@ -80,12 +80,12 @@ static inline int atomic_add_return(int i, atomic_t *v) #ifdef CONFIG_CPU_SH4A __asm__ __volatile__ ( -"1: movli.l @%2, %0 ! atomic_add_return \n" -" add %1, %0 \n" -" movco.l %0, @%2 \n" +"1: movli.l @%3, %0 ! atomic_add_return \n" +" add %2, %0 \n" +" movco.l %0, @%3 \n" " bf 1b \n" " synco \n" - : "=&z" (temp) + : "=&z" (temp), "=r" (&v->counter) : "r" (i), "r" (&v->counter) : "t"); #else @@ -109,12 +109,12 @@ static inline int atomic_sub_return(int i, atomic_t *v) #ifdef CONFIG_CPU_SH4A __asm__ __volatile__ ( -"1: movli.l @%2, %0 ! atomic_sub_return \n" -" sub %1, %0 \n" -" movco.l %0, @%2 \n" +"1: movli.l @%3, %0 ! atomic_sub_return \n" +" sub %2, %0 \n" +" movco.l %0, @%3 \n" " bf 1b \n" " synco \n" - : "=&z" (temp) + : "=&z" (temp), "=r" (&v->counter) : "r" (i), "r" (&v->counter) : "t"); #else @@ -186,11 +186,11 @@ static inline void atomic_clear_mask(unsigned int mask, atomic_t *v) unsigned long tmp; __asm__ __volatile__ ( -"1: movli.l @%2, %0 ! atomic_clear_mask \n" -" and %1, %0 \n" -" movco.l %0, @%2 \n" +"1: movli.l @%3, %0 ! atomic_clear_mask \n" +" and %2, %0 \n" +" movco.l %0, @%3 \n" " bf 1b \n" - : "=&z" (tmp) + : "=&z" (tmp), "=r" (&v->counter) : "r" (~mask), "r" (&v->counter) : "t"); #else @@ -208,11 +208,11 @@ static inline void atomic_set_mask(unsigned int mask, atomic_t *v) unsigned long tmp; __asm__ __volatile__ ( -"1: movli.l @%2, %0 ! atomic_set_mask \n" -" or %1, %0 \n" -" movco.l %0, @%2 \n" +"1: movli.l @%3, %0 ! atomic_set_mask \n" +" or %2, %0 \n" +" movco.l %0, @%3 \n" " bf 1b \n" - : "=&z" (tmp) + : "=&z" (tmp), "=r" (&v->counter) : "r" (mask), "r" (&v->counter) : "t"); #else diff --git a/trunk/include/asm-sh/bugs.h b/trunk/include/asm-sh/bugs.h index 795047da5e17..beeea40f549e 100644 --- a/trunk/include/asm-sh/bugs.h +++ b/trunk/include/asm-sh/bugs.h @@ -23,20 +23,16 @@ static void __init check_bugs(void) cpu_data->loops_per_jiffy = loops_per_jiffy; switch (cpu_data->type) { - case CPU_SH7604 ... CPU_SH7619: + case CPU_SH7604: *p++ = '2'; break; - case CPU_SH7206: - *p++ = '2'; - *p++ = 'a'; - break; case CPU_SH7705 ... CPU_SH7300: *p++ = '3'; break; case CPU_SH7750 ... CPU_SH4_501: *p++ = '4'; break; - case CPU_SH7770 ... CPU_SH7785: + case CPU_SH7770 ... CPU_SH7781: *p++ = '4'; *p++ = 'a'; break; diff --git a/trunk/include/asm-sh/clock.h b/trunk/include/asm-sh/clock.h index 1df92807f8c5..fdfb75b30f0d 100644 --- a/trunk/include/asm-sh/clock.h +++ b/trunk/include/asm-sh/clock.h @@ -4,7 +4,6 @@ #include #include #include -#include struct clk; @@ -19,7 +18,7 @@ struct clk_ops { struct clk { struct list_head node; const char *name; - int id; + struct module *owner; struct clk *parent; @@ -41,13 +40,22 @@ void arch_init_clk_ops(struct clk_ops **, int type); int clk_init(void); int __clk_enable(struct clk *); +int clk_enable(struct clk *); + void __clk_disable(struct clk *); +void clk_disable(struct clk *); +int clk_set_rate(struct clk *, unsigned long rate); +unsigned long clk_get_rate(struct clk *); void clk_recalc_rate(struct clk *); +struct clk *clk_get(const char *id); +void clk_put(struct clk *); + int clk_register(struct clk *); void clk_unregister(struct clk *); int show_clocks(struct seq_file *m); #endif /* __ASM_SH_CLOCK_H */ + diff --git a/trunk/include/asm-sh/cpu-sh2/cache.h b/trunk/include/asm-sh/cpu-sh2/cache.h index 20b9796842dc..cd96402e8562 100644 --- a/trunk/include/asm-sh/cpu-sh2/cache.h +++ b/trunk/include/asm-sh/cpu-sh2/cache.h @@ -12,7 +12,6 @@ #define L1_CACHE_SHIFT 4 -#if defined(CONFIG_CPU_SUBTYPE_SH7604) #define CCR 0xfffffe92 /* Address of Cache Control Register */ #define CCR_CACHE_CE 0x01 /* Cache enable */ @@ -28,26 +27,5 @@ #define CCR_CACHE_ORA CCR_CACHE_TW #define CCR_CACHE_WT 0x00 /* SH-2 is _always_ write-through */ -#elif defined(CONFIG_CPU_SUBTYPE_SH7619) -#define CCR1 0xffffffec -#define CCR CCR1 - -#define CCR_CACHE_CE 0x01 /* Cache enable */ -#define CCR_CACHE_WT 0x06 /* CCR[bit1=1,bit2=1] */ - /* 0x00000000-0x7fffffff: Write-through */ - /* 0x80000000-0x9fffffff: Write-back */ - /* 0xc0000000-0xdfffffff: Write-through */ -#define CCR_CACHE_CB 0x00 /* CCR[bit1=0,bit2=0] */ - /* 0x00000000-0x7fffffff: Write-back */ - /* 0x80000000-0x9fffffff: Write-through */ - /* 0xc0000000-0xdfffffff: Write-back */ -#define CCR_CACHE_CF 0x08 /* Cache invalidate */ - -#define CACHE_OC_ADDRESS_ARRAY 0xf0000000 -#define CACHE_OC_DATA_ARRAY 0xf1000000 - -#define CCR_CACHE_ENABLE CCR_CACHE_CE -#define CCR_CACHE_INVALIDATE CCR_CACHE_CF -#endif #endif /* __ASM_CPU_SH2_CACHE_H */ diff --git a/trunk/include/asm-sh/cpu-sh2/freq.h b/trunk/include/asm-sh/cpu-sh2/freq.h deleted file mode 100644 index 31de475da70b..000000000000 --- a/trunk/include/asm-sh/cpu-sh2/freq.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * include/asm-sh/cpu-sh2/freq.h - * - * 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. - */ -#ifndef __ASM_CPU_SH2_FREQ_H -#define __ASM_CPU_SH2_FREQ_H - -#if defined(CONFIG_CPU_SUBTYPE_SH7619) -#define FREQCR 0xf815ff80 -#endif - -#endif /* __ASM_CPU_SH2_FREQ_H */ - diff --git a/trunk/include/asm-sh/cpu-sh2/mmu_context.h b/trunk/include/asm-sh/cpu-sh2/mmu_context.h deleted file mode 100644 index beeb299e01ec..000000000000 --- a/trunk/include/asm-sh/cpu-sh2/mmu_context.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * include/asm-sh/cpu-sh2/mmu_context.h - * - * Copyright (C) 2003 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. - */ -#ifndef __ASM_CPU_SH2_MMU_CONTEXT_H -#define __ASM_CPU_SH2_MMU_CONTEXT_H - -/* No MMU */ - -#endif /* __ASM_CPU_SH2_MMU_CONTEXT_H */ - diff --git a/trunk/include/asm-sh/cpu-sh2/timer.h b/trunk/include/asm-sh/cpu-sh2/timer.h deleted file mode 100644 index a39c241e8195..000000000000 --- a/trunk/include/asm-sh/cpu-sh2/timer.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_CPU_SH2_TIMER_H -#define __ASM_CPU_SH2_TIMER_H - -/* Nothing needed yet */ - -#endif /* __ASM_CPU_SH2_TIMER_H */ diff --git a/trunk/include/asm-sh/cpu-sh2a/addrspace.h b/trunk/include/asm-sh/cpu-sh2a/addrspace.h deleted file mode 100644 index 3d2e9aa21522..000000000000 --- a/trunk/include/asm-sh/cpu-sh2a/addrspace.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-sh/cpu-sh2a/cache.h b/trunk/include/asm-sh/cpu-sh2a/cache.h deleted file mode 100644 index 3e4b9e480982..000000000000 --- a/trunk/include/asm-sh/cpu-sh2a/cache.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * include/asm-sh/cpu-sh2a/cache.h - * - * Copyright (C) 2004 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. - */ -#ifndef __ASM_CPU_SH2A_CACHE_H -#define __ASM_CPU_SH2A_CACHE_H - -#define L1_CACHE_SHIFT 4 - -#define CCR1 0xfffc1000 -#define CCR2 0xfffc1004 - -/* CCR1 behaves more like the traditional CCR */ -#define CCR CCR1 - -/* - * Most of the SH-2A CCR1 definitions resemble the SH-4 ones. All others not - * listed here are reserved. - */ -#define CCR_CACHE_CB 0x0000 /* Hack */ -#define CCR_CACHE_OCE 0x0001 -#define CCR_CACHE_WT 0x0002 -#define CCR_CACHE_OCI 0x0008 /* OCF */ -#define CCR_CACHE_ICE 0x0100 -#define CCR_CACHE_ICI 0x0800 /* ICF */ - -#define CACHE_IC_ADDRESS_ARRAY 0xf0000000 -#define CACHE_OC_ADDRESS_ARRAY 0xf0800000 - -#define CCR_CACHE_ENABLE (CCR_CACHE_OCE | CCR_CACHE_ICE) -#define CCR_CACHE_INVALIDATE (CCR_CACHE_OCI | CCR_CACHE_ICI) - -#endif /* __ASM_CPU_SH2A_CACHE_H */ - diff --git a/trunk/include/asm-sh/cpu-sh2a/cacheflush.h b/trunk/include/asm-sh/cpu-sh2a/cacheflush.h deleted file mode 100644 index fa3186c73350..000000000000 --- a/trunk/include/asm-sh/cpu-sh2a/cacheflush.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-sh/cpu-sh2a/dma.h b/trunk/include/asm-sh/cpu-sh2a/dma.h deleted file mode 100644 index 0d5ad85c1de8..000000000000 --- a/trunk/include/asm-sh/cpu-sh2a/dma.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-sh/cpu-sh2a/freq.h b/trunk/include/asm-sh/cpu-sh2a/freq.h deleted file mode 100644 index e518fff6d10f..000000000000 --- a/trunk/include/asm-sh/cpu-sh2a/freq.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * include/asm-sh/cpu-sh2a/freq.h - * - * 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. - */ -#ifndef __ASM_CPU_SH2A_FREQ_H -#define __ASM_CPU_SH2A_FREQ_H - -#if defined(CONFIG_CPU_SUBTYPE_SH7206) -#define FREQCR 0xfffe0010 -#endif - -#endif /* __ASM_CPU_SH2A_FREQ_H */ - diff --git a/trunk/include/asm-sh/cpu-sh2a/mmu_context.h b/trunk/include/asm-sh/cpu-sh2a/mmu_context.h deleted file mode 100644 index cd2387f7db9e..000000000000 --- a/trunk/include/asm-sh/cpu-sh2a/mmu_context.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-sh/cpu-sh2a/timer.h b/trunk/include/asm-sh/cpu-sh2a/timer.h deleted file mode 100644 index fee504adf11e..000000000000 --- a/trunk/include/asm-sh/cpu-sh2a/timer.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-sh/cpu-sh2a/ubc.h b/trunk/include/asm-sh/cpu-sh2a/ubc.h deleted file mode 100644 index cf28062b96a2..000000000000 --- a/trunk/include/asm-sh/cpu-sh2a/ubc.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-sh/cpu-sh2a/watchdog.h b/trunk/include/asm-sh/cpu-sh2a/watchdog.h deleted file mode 100644 index c1b3e2488478..000000000000 --- a/trunk/include/asm-sh/cpu-sh2a/watchdog.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-sh/dma.h b/trunk/include/asm-sh/dma.h index faf3051cd429..d9daa028689f 100644 --- a/trunk/include/asm-sh/dma.h +++ b/trunk/include/asm-sh/dma.h @@ -14,7 +14,9 @@ #include #include #include +#include #include +#include /* The maximum address that we can perform a DMA transfer to on this platform */ /* Don't define MAX_DMA_ADDRESS; it's useless on the SuperH and any @@ -44,21 +46,16 @@ * DMAC (dma_info) flags */ enum { - DMAC_CHANNELS_CONFIGURED = 0x01, - DMAC_CHANNELS_TEI_CAPABLE = 0x02, /* Transfer end interrupt */ + DMAC_CHANNELS_CONFIGURED = 0x00, + DMAC_CHANNELS_TEI_CAPABLE = 0x01, }; /* * DMA channel capabilities / flags */ enum { - DMA_CONFIGURED = 0x01, - - /* - * Transfer end interrupt, inherited from DMAC. - * wait_queue used in dma_wait_for_completion. - */ - DMA_TEI_CAPABLE = 0x02, + DMA_TEI_CAPABLE = 0x01, + DMA_CONFIGURED = 0x02, }; extern spinlock_t dma_spin_lock; @@ -71,31 +68,28 @@ struct dma_ops { int (*get_residue)(struct dma_channel *chan); int (*xfer)(struct dma_channel *chan); - int (*configure)(struct dma_channel *chan, unsigned long flags); - int (*extend)(struct dma_channel *chan, unsigned long op, void *param); + void (*configure)(struct dma_channel *chan, unsigned long flags); }; struct dma_channel { - char dev_id[16]; /* unique name per DMAC of channel */ + char dev_id[16]; - unsigned int chan; /* DMAC channel number */ + unsigned int chan; /* Physical channel number */ unsigned int vchan; /* Virtual channel number */ - unsigned int mode; unsigned int count; unsigned long sar; unsigned long dar; - const char **caps; - unsigned long flags; atomic_t busy; + struct semaphore sem; wait_queue_head_t wait_queue; struct sys_device dev; - void *priv_data; + char *name; }; struct dma_info { @@ -109,12 +103,6 @@ struct dma_info { struct dma_channel *channels; struct list_head list; - int first_channel_nr; -}; - -struct dma_chan_caps { - int ch_num; - const char **caplist; }; #define to_dma_channel(channel) container_of(channel, struct dma_channel, dev) @@ -133,8 +121,6 @@ extern int dma_xfer(unsigned int chan, unsigned long from, #define dma_read_page(chan, from, to) \ dma_read(chan, from, to, PAGE_SIZE) -extern int request_dma_bycap(const char **dmac, const char **caps, - const char *dev_id); extern int request_dma(unsigned int chan, const char *dev_id); extern void free_dma(unsigned int chan); extern int get_dma_residue(unsigned int chan); @@ -145,10 +131,6 @@ extern void dma_configure_channel(unsigned int chan, unsigned long flags); extern int register_dmac(struct dma_info *info); extern void unregister_dmac(struct dma_info *info); -extern struct dma_info *get_dma_info_by_name(const char *dmac_name); - -extern int dma_extend(unsigned int chan, unsigned long op, void *param); -extern int register_chan_caps(const char *dmac, struct dma_chan_caps *capslist); #ifdef CONFIG_SYSFS /* arch/sh/drivers/dma/dma-sysfs.c */ diff --git a/trunk/include/asm-sh/elf.h b/trunk/include/asm-sh/elf.h index 43ca244564b1..fc050fd7645e 100644 --- a/trunk/include/asm-sh/elf.h +++ b/trunk/include/asm-sh/elf.h @@ -74,7 +74,7 @@ typedef struct user_fpu_struct elf_fpregset_t; #define ELF_ARCH EM_SH #define USE_ELF_CORE_DUMP -#define ELF_EXEC_PAGESIZE PAGE_SIZE +#define ELF_EXEC_PAGESIZE 4096 /* This is the location that an ET_DYN program is loaded if exec'ed. Typical use of this is to invoke "./ld.so someprog" to test out a new version of diff --git a/trunk/include/asm-sh/entry-macros.S b/trunk/include/asm-sh/entry-macros.S deleted file mode 100644 index 500030eae7aa..000000000000 --- a/trunk/include/asm-sh/entry-macros.S +++ /dev/null @@ -1,33 +0,0 @@ -! entry.S macro define - - .macro cli - stc sr, r0 - or #0xf0, r0 - ldc r0, sr - .endm - - .macro sti - mov #0xf0, r11 - extu.b r11, r11 - not r11, r11 - stc sr, r10 - and r11, r10 -#ifdef CONFIG_HAS_SR_RB - stc k_g_imask, r11 - or r11, r10 -#endif - ldc r10, sr - .endm - - .macro get_current_thread_info, ti, tmp -#ifdef CONFIG_HAS_SR_RB - stc r7_bank, \ti -#else - mov #((THREAD_SIZE - 1) >> 10) ^ 0xff, \tmp - shll8 \tmp - shll2 \tmp - mov r15, \ti - and \tmp, \ti -#endif - .endm - diff --git a/trunk/include/asm-sh/irq-sh73180.h b/trunk/include/asm-sh/irq-sh73180.h new file mode 100644 index 000000000000..b28af9a69d72 --- /dev/null +++ b/trunk/include/asm-sh/irq-sh73180.h @@ -0,0 +1,314 @@ +#ifndef __ASM_SH_IRQ_SH73180_H +#define __ASM_SH_IRQ_SH73180_H + +/* + * linux/include/asm-sh/irq-sh73180.h + * + * Copyright (C) 2004 Takashi SHUDO + */ + +#undef INTC_IPRA +#undef INTC_IPRB +#undef INTC_IPRC +#undef INTC_IPRD + +#undef DMTE0_IRQ +#undef DMTE1_IRQ +#undef DMTE2_IRQ +#undef DMTE3_IRQ +#undef DMTE4_IRQ +#undef DMTE5_IRQ +#undef DMTE6_IRQ +#undef DMTE7_IRQ +#undef DMAE_IRQ +#undef DMA_IPR_ADDR +#undef DMA_IPR_POS +#undef DMA_PRIORITY + +#undef INTC_IMCR0 +#undef INTC_IMCR1 +#undef INTC_IMCR2 +#undef INTC_IMCR3 +#undef INTC_IMCR4 +#undef INTC_IMCR5 +#undef INTC_IMCR6 +#undef INTC_IMCR7 +#undef INTC_IMCR8 +#undef INTC_IMCR9 +#undef INTC_IMCR10 + + +#define INTC_IPRA 0xA4080000UL +#define INTC_IPRB 0xA4080004UL +#define INTC_IPRC 0xA4080008UL +#define INTC_IPRD 0xA408000CUL +#define INTC_IPRE 0xA4080010UL +#define INTC_IPRF 0xA4080014UL +#define INTC_IPRG 0xA4080018UL +#define INTC_IPRH 0xA408001CUL +#define INTC_IPRI 0xA4080020UL +#define INTC_IPRJ 0xA4080024UL +#define INTC_IPRK 0xA4080028UL + +#define INTC_IMR0 0xA4080080UL +#define INTC_IMR1 0xA4080084UL +#define INTC_IMR2 0xA4080088UL +#define INTC_IMR3 0xA408008CUL +#define INTC_IMR4 0xA4080090UL +#define INTC_IMR5 0xA4080094UL +#define INTC_IMR6 0xA4080098UL +#define INTC_IMR7 0xA408009CUL +#define INTC_IMR8 0xA40800A0UL +#define INTC_IMR9 0xA40800A4UL +#define INTC_IMR10 0xA40800A8UL +#define INTC_IMR11 0xA40800ACUL + +#define INTC_IMCR0 0xA40800C0UL +#define INTC_IMCR1 0xA40800C4UL +#define INTC_IMCR2 0xA40800C8UL +#define INTC_IMCR3 0xA40800CCUL +#define INTC_IMCR4 0xA40800D0UL +#define INTC_IMCR5 0xA40800D4UL +#define INTC_IMCR6 0xA40800D8UL +#define INTC_IMCR7 0xA40800DCUL +#define INTC_IMCR8 0xA40800E0UL +#define INTC_IMCR9 0xA40800E4UL +#define INTC_IMCR10 0xA40800E8UL +#define INTC_IMCR11 0xA40800ECUL + +#define INTC_ICR0 0xA4140000UL +#define INTC_ICR1 0xA414001CUL + +#define INTMSK0 0xa4140044 +#define INTMSKCLR0 0xa4140064 +#define INTC_INTPRI0 0xa4140010 + +/* + NOTE: + + *_IRQ = (INTEVT2 - 0x200)/0x20 +*/ + +/* TMU0 */ +#define TMU0_IRQ 16 +#define TMU0_IPR_ADDR INTC_IPRA +#define TMU0_IPR_POS 3 +#define TMU0_PRIORITY 2 + +#define TIMER_IRQ 16 +#define TIMER_IPR_ADDR INTC_IPRA +#define TIMER_IPR_POS 3 +#define TIMER_PRIORITY 2 + +/* TMU1 */ +#define TMU1_IRQ 17 +#define TMU1_IPR_ADDR INTC_IPRA +#define TMU1_IPR_POS 2 +#define TMU1_PRIORITY 2 + +/* TMU2 */ +#define TMU2_IRQ 18 +#define TMU2_IPR_ADDR INTC_IPRA +#define TMU2_IPR_POS 1 +#define TMU2_PRIORITY 2 + +/* LCDC */ +#define LCDC_IRQ 28 +#define LCDC_IPR_ADDR INTC_IPRB +#define LCDC_IPR_POS 2 +#define LCDC_PRIORITY 2 + +/* VIO (Video I/O) */ +#define CEU_IRQ 52 +#define BEU_IRQ 53 +#define VEU_IRQ 54 +#define VOU_IRQ 55 +#define VIO_IPR_ADDR INTC_IPRE +#define VIO_IPR_POS 2 +#define VIO_PRIORITY 2 + +/* MFI (Multi Functional Interface) */ +#define MFI_IRQ 56 +#define MFI_IPR_ADDR INTC_IPRE +#define MFI_IPR_POS 1 +#define MFI_PRIORITY 2 + +/* VPU (Video Processing Unit) */ +#define VPU_IRQ 60 +#define VPU_IPR_ADDR INTC_IPRE +#define VPU_IPR_POS 0 +#define VPU_PRIORITY 2 + +/* 3DG */ +#define TDG_IRQ 63 +#define TDG_IPR_ADDR INTC_IPRJ +#define TDG_IPR_POS 2 +#define TDG_PRIORITY 2 + +/* DMAC(1) */ +#define DMTE0_IRQ 48 +#define DMTE1_IRQ 49 +#define DMTE2_IRQ 50 +#define DMTE3_IRQ 51 +#define DMA1_IPR_ADDR INTC_IPRE +#define DMA1_IPR_POS 3 +#define DMA1_PRIORITY 7 + +/* DMAC(2) */ +#define DMTE4_IRQ 76 +#define DMTE5_IRQ 77 +#define DMA2_IPR_ADDR INTC_IPRF +#define DMA2_IPR_POS 2 +#define DMA2_PRIORITY 7 + +/* SCIF0 */ +#define SCIF_ERI_IRQ 80 +#define SCIF_RXI_IRQ 81 +#define SCIF_BRI_IRQ 82 +#define SCIF_TXI_IRQ 83 +#define SCIF_IPR_ADDR INTC_IPRG +#define SCIF_IPR_POS 3 +#define SCIF_PRIORITY 3 + +/* SIOF0 */ +#define SIOF0_IRQ 84 +#define SIOF0_IPR_ADDR INTC_IPRH +#define SIOF0_IPR_POS 3 +#define SIOF0_PRIORITY 3 + +/* FLCTL (Flash Memory Controller) */ +#define FLSTE_IRQ 92 +#define FLTEND_IRQ 93 +#define FLTRQ0_IRQ 94 +#define FLTRQ1_IRQ 95 +#define FLCTL_IPR_ADDR INTC_IPRH +#define FLCTL_IPR_POS 1 +#define FLCTL_PRIORITY 3 + +/* IIC(0) (IIC Bus Interface) */ +#define IIC0_ALI_IRQ 96 +#define IIC0_TACKI_IRQ 97 +#define IIC0_WAITI_IRQ 98 +#define IIC0_DTEI_IRQ 99 +#define IIC0_IPR_ADDR INTC_IPRH +#define IIC0_IPR_POS 0 +#define IIC0_PRIORITY 3 + +/* IIC(1) (IIC Bus Interface) */ +#define IIC1_ALI_IRQ 44 +#define IIC1_TACKI_IRQ 45 +#define IIC1_WAITI_IRQ 46 +#define IIC1_DTEI_IRQ 47 +#define IIC1_IPR_ADDR INTC_IPRG +#define IIC1_IPR_POS 0 +#define IIC1_PRIORITY 3 + +/* SIO0 */ +#define SIO0_IRQ 88 +#define SIO0_IPR_ADDR INTC_IPRI +#define SIO0_IPR_POS 3 +#define SIO0_PRIORITY 3 + +/* SDHI */ +#define SDHI_SDHII0_IRQ 100 +#define SDHI_SDHII1_IRQ 101 +#define SDHI_SDHII2_IRQ 102 +#define SDHI_SDHII3_IRQ 103 +#define SDHI_IPR_ADDR INTC_IPRK +#define SDHI_IPR_POS 0 +#define SDHI_PRIORITY 3 + +/* SIU (Sound Interface Unit) */ +#define SIU_IRQ 108 +#define SIU_IPR_ADDR INTC_IPRJ +#define SIU_IPR_POS 1 +#define SIU_PRIORITY 3 + +#define PORT_PACR 0xA4050100UL +#define PORT_PBCR 0xA4050102UL +#define PORT_PCCR 0xA4050104UL +#define PORT_PDCR 0xA4050106UL +#define PORT_PECR 0xA4050108UL +#define PORT_PFCR 0xA405010AUL +#define PORT_PGCR 0xA405010CUL +#define PORT_PHCR 0xA405010EUL +#define PORT_PJCR 0xA4050110UL +#define PORT_PKCR 0xA4050112UL +#define PORT_PLCR 0xA4050114UL +#define PORT_SCPCR 0xA4050116UL +#define PORT_PMCR 0xA4050118UL +#define PORT_PNCR 0xA405011AUL +#define PORT_PQCR 0xA405011CUL +#define PORT_PRCR 0xA405011EUL +#define PORT_PTCR 0xA405014CUL +#define PORT_PUCR 0xA405014EUL +#define PORT_PVCR 0xA4050150UL + +#define PORT_PSELA 0xA4050140UL +#define PORT_PSELB 0xA4050142UL +#define PORT_PSELC 0xA4050144UL +#define PORT_PSELE 0xA4050158UL + +#define PORT_HIZCRA 0xA4050146UL +#define PORT_HIZCRB 0xA4050148UL +#define PORT_DRVCR 0xA405014AUL + +#define PORT_PADR 0xA4050120UL +#define PORT_PBDR 0xA4050122UL +#define PORT_PCDR 0xA4050124UL +#define PORT_PDDR 0xA4050126UL +#define PORT_PEDR 0xA4050128UL +#define PORT_PFDR 0xA405012AUL +#define PORT_PGDR 0xA405012CUL +#define PORT_PHDR 0xA405012EUL +#define PORT_PJDR 0xA4050130UL +#define PORT_PKDR 0xA4050132UL +#define PORT_PLDR 0xA4050134UL +#define PORT_SCPDR 0xA4050136UL +#define PORT_PMDR 0xA4050138UL +#define PORT_PNDR 0xA405013AUL +#define PORT_PQDR 0xA405013CUL +#define PORT_PRDR 0xA405013EUL +#define PORT_PTDR 0xA405016CUL +#define PORT_PUDR 0xA405016EUL +#define PORT_PVDR 0xA4050170UL + +#define IRQ0_IRQ 32 +#define IRQ1_IRQ 33 +#define IRQ2_IRQ 34 +#define IRQ3_IRQ 35 +#define IRQ4_IRQ 36 +#define IRQ5_IRQ 37 +#define IRQ6_IRQ 38 +#define IRQ7_IRQ 39 + +#define INTPRI00 0xA4140010UL + +#define IRQ0_IPR_ADDR INTPRI00 +#define IRQ1_IPR_ADDR INTPRI00 +#define IRQ2_IPR_ADDR INTPRI00 +#define IRQ3_IPR_ADDR INTPRI00 +#define IRQ4_IPR_ADDR INTPRI00 +#define IRQ5_IPR_ADDR INTPRI00 +#define IRQ6_IPR_ADDR INTPRI00 +#define IRQ7_IPR_ADDR INTPRI00 + +#define IRQ0_IPR_POS 7 +#define IRQ1_IPR_POS 6 +#define IRQ2_IPR_POS 5 +#define IRQ3_IPR_POS 4 +#define IRQ4_IPR_POS 3 +#define IRQ5_IPR_POS 2 +#define IRQ6_IPR_POS 1 +#define IRQ7_IPR_POS 0 + +#define IRQ0_PRIORITY 1 +#define IRQ1_PRIORITY 1 +#define IRQ2_PRIORITY 1 +#define IRQ3_PRIORITY 1 +#define IRQ4_PRIORITY 1 +#define IRQ5_PRIORITY 1 +#define IRQ6_PRIORITY 1 +#define IRQ7_PRIORITY 1 + +#endif /* __ASM_SH_IRQ_SH73180_H */ diff --git a/trunk/include/asm-sh/irq-sh7343.h b/trunk/include/asm-sh/irq-sh7343.h new file mode 100644 index 000000000000..5d15419b53b0 --- /dev/null +++ b/trunk/include/asm-sh/irq-sh7343.h @@ -0,0 +1,317 @@ +#ifndef __ASM_SH_IRQ_SH7343_H +#define __ASM_SH_IRQ_SH7343_H + +/* + * linux/include/asm-sh/irq-sh7343.h + * + * Copyright (C) 2006 Kenati Technologies Inc. + * Andre Mccurdy + * Ranjit Deshpande + */ + +#undef INTC_IPRA +#undef INTC_IPRB +#undef INTC_IPRC +#undef INTC_IPRD + +#undef DMTE0_IRQ +#undef DMTE1_IRQ +#undef DMTE2_IRQ +#undef DMTE3_IRQ +#undef DMTE4_IRQ +#undef DMTE5_IRQ +#undef DMTE6_IRQ +#undef DMTE7_IRQ +#undef DMAE_IRQ +#undef DMA_IPR_ADDR +#undef DMA_IPR_POS +#undef DMA_PRIORITY + +#undef INTC_IMCR0 +#undef INTC_IMCR1 +#undef INTC_IMCR2 +#undef INTC_IMCR3 +#undef INTC_IMCR4 +#undef INTC_IMCR5 +#undef INTC_IMCR6 +#undef INTC_IMCR7 +#undef INTC_IMCR8 +#undef INTC_IMCR9 +#undef INTC_IMCR10 + + +#define INTC_IPRA 0xA4080000UL +#define INTC_IPRB 0xA4080004UL +#define INTC_IPRC 0xA4080008UL +#define INTC_IPRD 0xA408000CUL +#define INTC_IPRE 0xA4080010UL +#define INTC_IPRF 0xA4080014UL +#define INTC_IPRG 0xA4080018UL +#define INTC_IPRH 0xA408001CUL +#define INTC_IPRI 0xA4080020UL +#define INTC_IPRJ 0xA4080024UL +#define INTC_IPRK 0xA4080028UL +#define INTC_IPRL 0xA408002CUL + +#define INTC_IMR0 0xA4080080UL +#define INTC_IMR1 0xA4080084UL +#define INTC_IMR2 0xA4080088UL +#define INTC_IMR3 0xA408008CUL +#define INTC_IMR4 0xA4080090UL +#define INTC_IMR5 0xA4080094UL +#define INTC_IMR6 0xA4080098UL +#define INTC_IMR7 0xA408009CUL +#define INTC_IMR8 0xA40800A0UL +#define INTC_IMR9 0xA40800A4UL +#define INTC_IMR10 0xA40800A8UL +#define INTC_IMR11 0xA40800ACUL + +#define INTC_IMCR0 0xA40800C0UL +#define INTC_IMCR1 0xA40800C4UL +#define INTC_IMCR2 0xA40800C8UL +#define INTC_IMCR3 0xA40800CCUL +#define INTC_IMCR4 0xA40800D0UL +#define INTC_IMCR5 0xA40800D4UL +#define INTC_IMCR6 0xA40800D8UL +#define INTC_IMCR7 0xA40800DCUL +#define INTC_IMCR8 0xA40800E0UL +#define INTC_IMCR9 0xA40800E4UL +#define INTC_IMCR10 0xA40800E8UL +#define INTC_IMCR11 0xA40800ECUL + +#define INTC_ICR0 0xA4140000UL +#define INTC_ICR1 0xA414001CUL + +#define INTMSK0 0xa4140044 +#define INTMSKCLR0 0xa4140064 +#define INTC_INTPRI0 0xa4140010 + +/* + NOTE: + + *_IRQ = (INTEVT2 - 0x200)/0x20 +*/ + +/* TMU0 */ +#define TMU0_IRQ 16 +#define TMU0_IPR_ADDR INTC_IPRA +#define TMU0_IPR_POS 3 +#define TMU0_PRIORITY 2 + +#define TIMER_IRQ 16 +#define TIMER_IPR_ADDR INTC_IPRA +#define TIMER_IPR_POS 3 +#define TIMER_PRIORITY 2 + +/* TMU1 */ +#define TMU1_IRQ 17 +#define TMU1_IPR_ADDR INTC_IPRA +#define TMU1_IPR_POS 2 +#define TMU1_PRIORITY 2 + +/* TMU2 */ +#define TMU2_IRQ 18 +#define TMU2_IPR_ADDR INTC_IPRA +#define TMU2_IPR_POS 1 +#define TMU2_PRIORITY 2 + +/* LCDC */ +#define LCDC_IRQ 28 +#define LCDC_IPR_ADDR INTC_IPRB +#define LCDC_IPR_POS 2 +#define LCDC_PRIORITY 2 + +/* VIO (Video I/O) */ +#define CEU_IRQ 52 +#define BEU_IRQ 53 +#define VEU_IRQ 54 +#define VOU_IRQ 55 +#define VIO_IPR_ADDR INTC_IPRE +#define VIO_IPR_POS 2 +#define VIO_PRIORITY 2 + +/* MFI (Multi Functional Interface) */ +#define MFI_IRQ 56 +#define MFI_IPR_ADDR INTC_IPRE +#define MFI_IPR_POS 1 +#define MFI_PRIORITY 2 + +/* VPU (Video Processing Unit) */ +#define VPU_IRQ 60 +#define VPU_IPR_ADDR INTC_IPRE +#define VPU_IPR_POS 0 +#define VPU_PRIORITY 2 + +/* 3DG */ +#define TDG_IRQ 63 +#define TDG_IPR_ADDR INTC_IPRJ +#define TDG_IPR_POS 2 +#define TDG_PRIORITY 2 + +/* DMAC(1) */ +#define DMTE0_IRQ 48 +#define DMTE1_IRQ 49 +#define DMTE2_IRQ 50 +#define DMTE3_IRQ 51 +#define DMA1_IPR_ADDR INTC_IPRE +#define DMA1_IPR_POS 3 +#define DMA1_PRIORITY 7 + +/* DMAC(2) */ +#define DMTE4_IRQ 76 +#define DMTE5_IRQ 77 +#define DMA2_IPR_ADDR INTC_IPRF +#define DMA2_IPR_POS 2 +#define DMA2_PRIORITY 7 + +/* SCIF0 */ +#define SCIF_ERI_IRQ 80 +#define SCIF_RXI_IRQ 81 +#define SCIF_BRI_IRQ 82 +#define SCIF_TXI_IRQ 83 +#define SCIF_IPR_ADDR INTC_IPRG +#define SCIF_IPR_POS 3 +#define SCIF_PRIORITY 3 + +/* SIOF0 */ +#define SIOF0_IRQ 84 +#define SIOF0_IPR_ADDR INTC_IPRH +#define SIOF0_IPR_POS 3 +#define SIOF0_PRIORITY 3 + +/* FLCTL (Flash Memory Controller) */ +#define FLSTE_IRQ 92 +#define FLTEND_IRQ 93 +#define FLTRQ0_IRQ 94 +#define FLTRQ1_IRQ 95 +#define FLCTL_IPR_ADDR INTC_IPRH +#define FLCTL_IPR_POS 1 +#define FLCTL_PRIORITY 3 + +/* IIC(0) (IIC Bus Interface) */ +#define IIC0_ALI_IRQ 96 +#define IIC0_TACKI_IRQ 97 +#define IIC0_WAITI_IRQ 98 +#define IIC0_DTEI_IRQ 99 +#define IIC0_IPR_ADDR INTC_IPRH +#define IIC0_IPR_POS 0 +#define IIC0_PRIORITY 3 + +/* IIC(1) (IIC Bus Interface) */ +#define IIC1_ALI_IRQ 44 +#define IIC1_TACKI_IRQ 45 +#define IIC1_WAITI_IRQ 46 +#define IIC1_DTEI_IRQ 47 +#define IIC1_IPR_ADDR INTC_IPRI +#define IIC1_IPR_POS 0 +#define IIC1_PRIORITY 3 + +/* SIO0 */ +#define SIO0_IRQ 88 +#define SIO0_IPR_ADDR INTC_IPRI +#define SIO0_IPR_POS 3 +#define SIO0_PRIORITY 3 + +/* SDHI */ +#define SDHI_SDHII0_IRQ 100 +#define SDHI_SDHII1_IRQ 101 +#define SDHI_SDHII2_IRQ 102 +#define SDHI_SDHII3_IRQ 103 +#define SDHI_IPR_ADDR INTC_IPRK +#define SDHI_IPR_POS 0 +#define SDHI_PRIORITY 3 + +/* SIU (Sound Interface Unit) */ +#define SIU_IRQ 108 +#define SIU_IPR_ADDR INTC_IPRJ +#define SIU_IPR_POS 1 +#define SIU_PRIORITY 3 + +#define PORT_PACR 0xA4050100UL +#define PORT_PBCR 0xA4050102UL +#define PORT_PCCR 0xA4050104UL +#define PORT_PDCR 0xA4050106UL +#define PORT_PECR 0xA4050108UL +#define PORT_PFCR 0xA405010AUL +#define PORT_PGCR 0xA405010CUL +#define PORT_PHCR 0xA405010EUL +#define PORT_PJCR 0xA4050110UL +#define PORT_PKCR 0xA4050112UL +#define PORT_PLCR 0xA4050114UL +#define PORT_SCPCR 0xA4050116UL +#define PORT_PMCR 0xA4050118UL +#define PORT_PNCR 0xA405011AUL +#define PORT_PQCR 0xA405011CUL +#define PORT_PRCR 0xA405011EUL +#define PORT_PTCR 0xA405014CUL +#define PORT_PUCR 0xA405014EUL +#define PORT_PVCR 0xA4050150UL + +#define PORT_PSELA 0xA4050140UL +#define PORT_PSELB 0xA4050142UL +#define PORT_PSELC 0xA4050144UL +#define PORT_PSELE 0xA4050158UL + +#define PORT_HIZCRA 0xA4050146UL +#define PORT_HIZCRB 0xA4050148UL +#define PORT_DRVCR 0xA405014AUL + +#define PORT_PADR 0xA4050120UL +#define PORT_PBDR 0xA4050122UL +#define PORT_PCDR 0xA4050124UL +#define PORT_PDDR 0xA4050126UL +#define PORT_PEDR 0xA4050128UL +#define PORT_PFDR 0xA405012AUL +#define PORT_PGDR 0xA405012CUL +#define PORT_PHDR 0xA405012EUL +#define PORT_PJDR 0xA4050130UL +#define PORT_PKDR 0xA4050132UL +#define PORT_PLDR 0xA4050134UL +#define PORT_SCPDR 0xA4050136UL +#define PORT_PMDR 0xA4050138UL +#define PORT_PNDR 0xA405013AUL +#define PORT_PQDR 0xA405013CUL +#define PORT_PRDR 0xA405013EUL +#define PORT_PTDR 0xA405016CUL +#define PORT_PUDR 0xA405016EUL +#define PORT_PVDR 0xA4050170UL + +#define IRQ0_IRQ 32 +#define IRQ1_IRQ 33 +#define IRQ2_IRQ 34 +#define IRQ3_IRQ 35 +#define IRQ4_IRQ 36 +#define IRQ5_IRQ 37 +#define IRQ6_IRQ 38 +#define IRQ7_IRQ 39 + +#define INTPRI00 0xA4140010UL + +#define IRQ0_IPR_ADDR INTPRI00 +#define IRQ1_IPR_ADDR INTPRI00 +#define IRQ2_IPR_ADDR INTPRI00 +#define IRQ3_IPR_ADDR INTPRI00 +#define IRQ4_IPR_ADDR INTPRI00 +#define IRQ5_IPR_ADDR INTPRI00 +#define IRQ6_IPR_ADDR INTPRI00 +#define IRQ7_IPR_ADDR INTPRI00 + +#define IRQ0_IPR_POS 7 +#define IRQ1_IPR_POS 6 +#define IRQ2_IPR_POS 5 +#define IRQ3_IPR_POS 4 +#define IRQ4_IPR_POS 3 +#define IRQ5_IPR_POS 2 +#define IRQ6_IPR_POS 1 +#define IRQ7_IPR_POS 0 + +#define IRQ0_PRIORITY 1 +#define IRQ1_PRIORITY 1 +#define IRQ2_PRIORITY 1 +#define IRQ3_PRIORITY 1 +#define IRQ4_PRIORITY 1 +#define IRQ5_PRIORITY 1 +#define IRQ6_PRIORITY 1 +#define IRQ7_PRIORITY 1 + +#endif /* __ASM_SH_IRQ_SH7343_H */ diff --git a/trunk/include/asm-sh/irq-sh7780.h b/trunk/include/asm-sh/irq-sh7780.h new file mode 100644 index 000000000000..19912ae6a7f7 --- /dev/null +++ b/trunk/include/asm-sh/irq-sh7780.h @@ -0,0 +1,311 @@ +#ifndef __ASM_SH_IRQ_SH7780_H +#define __ASM_SH_IRQ_SH7780_H + +/* + * linux/include/asm-sh/irq-sh7780.h + * + * Copyright (C) 2004 Takashi SHUDO + */ +#define INTC_BASE 0xffd00000 +#define INTC_ICR0 (INTC_BASE+0x0) +#define INTC_ICR1 (INTC_BASE+0x1c) +#define INTC_INTPRI (INTC_BASE+0x10) +#define INTC_INTREQ (INTC_BASE+0x24) +#define INTC_INTMSK0 (INTC_BASE+0x44) +#define INTC_INTMSK1 (INTC_BASE+0x48) +#define INTC_INTMSK2 (INTC_BASE+0x40080) +#define INTC_INTMSKCLR0 (INTC_BASE+0x64) +#define INTC_INTMSKCLR1 (INTC_BASE+0x68) +#define INTC_INTMSKCLR2 (INTC_BASE+0x40084) +#define INTC_NMIFCR (INTC_BASE+0xc0) +#define INTC_USERIMASK (INTC_BASE+0x30000) + +#define INTC_INT2PRI0 (INTC_BASE+0x40000) +#define INTC_INT2PRI1 (INTC_BASE+0x40004) +#define INTC_INT2PRI2 (INTC_BASE+0x40008) +#define INTC_INT2PRI3 (INTC_BASE+0x4000c) +#define INTC_INT2PRI4 (INTC_BASE+0x40010) +#define INTC_INT2PRI5 (INTC_BASE+0x40014) +#define INTC_INT2PRI6 (INTC_BASE+0x40018) +#define INTC_INT2PRI7 (INTC_BASE+0x4001c) +#define INTC_INT2A0 (INTC_BASE+0x40030) +#define INTC_INT2A1 (INTC_BASE+0x40034) +#define INTC_INT2MSKR (INTC_BASE+0x40038) +#define INTC_INT2MSKCR (INTC_BASE+0x4003c) +#define INTC_INT2B0 (INTC_BASE+0x40040) +#define INTC_INT2B1 (INTC_BASE+0x40044) +#define INTC_INT2B2 (INTC_BASE+0x40048) +#define INTC_INT2B3 (INTC_BASE+0x4004c) +#define INTC_INT2B4 (INTC_BASE+0x40050) +#define INTC_INT2B5 (INTC_BASE+0x40054) +#define INTC_INT2B6 (INTC_BASE+0x40058) +#define INTC_INT2B7 (INTC_BASE+0x4005c) +#define INTC_INT2GPIC (INTC_BASE+0x40090) +/* + NOTE: + *_IRQ = (INTEVT2 - 0x200)/0x20 +*/ +/* IRQ 0-7 line external int*/ +#define IRQ0_IRQ 2 +#define IRQ0_IPR_ADDR INTC_INTPRI +#define IRQ0_IPR_POS 7 +#define IRQ0_PRIORITY 2 + +#define IRQ1_IRQ 4 +#define IRQ1_IPR_ADDR INTC_INTPRI +#define IRQ1_IPR_POS 6 +#define IRQ1_PRIORITY 2 + +#define IRQ2_IRQ 6 +#define IRQ2_IPR_ADDR INTC_INTPRI +#define IRQ2_IPR_POS 5 +#define IRQ2_PRIORITY 2 + +#define IRQ3_IRQ 8 +#define IRQ3_IPR_ADDR INTC_INTPRI +#define IRQ3_IPR_POS 4 +#define IRQ3_PRIORITY 2 + +#define IRQ4_IRQ 10 +#define IRQ4_IPR_ADDR INTC_INTPRI +#define IRQ4_IPR_POS 3 +#define IRQ4_PRIORITY 2 + +#define IRQ5_IRQ 12 +#define IRQ5_IPR_ADDR INTC_INTPRI +#define IRQ5_IPR_POS 2 +#define IRQ5_PRIORITY 2 + +#define IRQ6_IRQ 14 +#define IRQ6_IPR_ADDR INTC_INTPRI +#define IRQ6_IPR_POS 1 +#define IRQ6_PRIORITY 2 + +#define IRQ7_IRQ 0 +#define IRQ7_IPR_ADDR INTC_INTPRI +#define IRQ7_IPR_POS 0 +#define IRQ7_PRIORITY 2 + +/* TMU */ +/* ch0 */ +#define TMU_IRQ 28 +#define TMU_IPR_ADDR INTC_INT2PRI0 +#define TMU_IPR_POS 3 +#define TMU_PRIORITY 2 + +#define TIMER_IRQ 28 +#define TIMER_IPR_ADDR INTC_INT2PRI0 +#define TIMER_IPR_POS 3 +#define TIMER_PRIORITY 2 + +/* ch 1*/ +#define TMU_CH1_IRQ 29 +#define TMU_CH1_IPR_ADDR INTC_INT2PRI0 +#define TMU_CH1_IPR_POS 2 +#define TMU_CH1_PRIORITY 2 + +#define TIMER1_IRQ 29 +#define TIMER1_IPR_ADDR INTC_INT2PRI0 +#define TIMER1_IPR_POS 2 +#define TIMER1_PRIORITY 2 + +/* ch 2*/ +#define TMU_CH2_IRQ 30 +#define TMU_CH2_IPR_ADDR INTC_INT2PRI0 +#define TMU_CH2_IPR_POS 1 +#define TMU_CH2_PRIORITY 2 +/* ch 2 Input capture */ +#define TMU_CH2IC_IRQ 31 +#define TMU_CH2IC_IPR_ADDR INTC_INT2PRI0 +#define TMU_CH2IC_IPR_POS 0 +#define TMU_CH2IC_PRIORITY 2 +/* ch 3 */ +#define TMU_CH3_IRQ 96 +#define TMU_CH3_IPR_ADDR INTC_INT2PRI1 +#define TMU_CH3_IPR_POS 3 +#define TMU_CH3_PRIORITY 2 +/* ch 4 */ +#define TMU_CH4_IRQ 97 +#define TMU_CH4_IPR_ADDR INTC_INT2PRI1 +#define TMU_CH4_IPR_POS 2 +#define TMU_CH4_PRIORITY 2 +/* ch 5*/ +#define TMU_CH5_IRQ 98 +#define TMU_CH5_IPR_ADDR INTC_INT2PRI1 +#define TMU_CH5_IPR_POS 1 +#define TMU_CH5_PRIORITY 2 + +/* SCIF0 */ +#define SCIF0_ERI_IRQ 40 +#define SCIF0_RXI_IRQ 41 +#define SCIF0_BRI_IRQ 42 +#define SCIF0_TXI_IRQ 43 +#define SCIF0_IPR_ADDR INTC_INT2PRI2 +#define SCIF0_IPR_POS 3 +#define SCIF0_PRIORITY 3 + +/* SCIF1 */ +#define SCIF1_ERI_IRQ 76 +#define SCIF1_RXI_IRQ 77 +#define SCIF1_BRI_IRQ 78 +#define SCIF1_TXI_IRQ 79 +#define SCIF1_IPR_ADDR INTC_INT2PRI2 +#define SCIF1_IPR_POS 2 +#define SCIF1_PRIORITY 3 + +#define WDT_IRQ 27 +#define WDT_IPR_ADDR INTC_INT2PRI2 +#define WDT_IPR_POS 1 +#define WDT_PRIORITY 2 + +/* DMAC(0) */ +#define DMINT0_IRQ 34 +#define DMINT1_IRQ 35 +#define DMINT2_IRQ 36 +#define DMINT3_IRQ 37 +#define DMINT4_IRQ 44 +#define DMINT5_IRQ 45 +#define DMINT6_IRQ 46 +#define DMINT7_IRQ 47 +#define DMAE_IRQ 38 +#define DMA0_IPR_ADDR INTC_INT2PRI3 +#define DMA0_IPR_POS 2 +#define DMA0_PRIORITY 7 + +/* DMAC(1) */ +#define DMINT8_IRQ 92 +#define DMINT9_IRQ 93 +#define DMINT10_IRQ 94 +#define DMINT11_IRQ 95 +#define DMA1_IPR_ADDR INTC_INT2PRI3 +#define DMA1_IPR_POS 1 +#define DMA1_PRIORITY 7 + +#define DMTE0_IRQ DMINT0_IRQ +#define DMTE4_IRQ DMINT4_IRQ +#define DMA_IPR_ADDR DMA0_IPR_ADDR +#define DMA_IPR_POS DMA0_IPR_POS +#define DMA_PRIORITY DMA0_PRIORITY + +/* CMT */ +#define CMT_IRQ 56 +#define CMT_IPR_ADDR INTC_INT2PRI4 +#define CMT_IPR_POS 3 +#define CMT_PRIORITY 0 + +/* HAC */ +#define HAC_IRQ 60 +#define HAC_IPR_ADDR INTC_INT2PRI4 +#define HAC_IPR_POS 2 +#define CMT_PRIORITY 0 + +/* PCIC(0) */ +#define PCIC0_IRQ 64 +#define PCIC0_IPR_ADDR INTC_INT2PRI4 +#define PCIC0_IPR_POS 1 +#define PCIC0_PRIORITY 2 + +/* PCIC(1) */ +#define PCIC1_IRQ 65 +#define PCIC1_IPR_ADDR INTC_INT2PRI4 +#define PCIC1_IPR_POS 0 +#define PCIC1_PRIORITY 2 + +/* PCIC(2) */ +#define PCIC2_IRQ 66 +#define PCIC2_IPR_ADDR INTC_INT2PRI5 +#define PCIC2_IPR_POS 3 +#define PCIC2_PRIORITY 2 + +/* PCIC(3) */ +#define PCIC3_IRQ 67 +#define PCIC3_IPR_ADDR INTC_INT2PRI5 +#define PCIC3_IPR_POS 2 +#define PCIC3_PRIORITY 2 + +/* PCIC(4) */ +#define PCIC4_IRQ 68 +#define PCIC4_IPR_ADDR INTC_INT2PRI5 +#define PCIC4_IPR_POS 1 +#define PCIC4_PRIORITY 2 + +/* PCIC(5) */ +#define PCICERR_IRQ 69 +#define PCICPWD3_IRQ 70 +#define PCICPWD2_IRQ 71 +#define PCICPWD1_IRQ 72 +#define PCICPWD0_IRQ 73 +#define PCIC5_IPR_ADDR INTC_INT2PRI5 +#define PCIC5_IPR_POS 0 +#define PCIC5_PRIORITY 2 + +/* SIOF */ +#define SIOF_IRQ 80 +#define SIOF_IPR_ADDR INTC_INT2PRI6 +#define SIOF_IPR_POS 3 +#define SIOF_PRIORITY 3 + +/* HSPI */ +#define HSPI_IRQ 84 +#define HSPI_IPR_ADDR INTC_INT2PRI6 +#define HSPI_IPR_POS 2 +#define HSPI_PRIORITY 3 + +/* MMCIF */ +#define MMCIF_FSTAT_IRQ 88 +#define MMCIF_TRAN_IRQ 89 +#define MMCIF_ERR_IRQ 90 +#define MMCIF_FRDY_IRQ 91 +#define MMCIF_IPR_ADDR INTC_INT2PRI6 +#define MMCIF_IPR_POS 1 +#define HSPI_PRIORITY 3 + +/* SSI */ +#define SSI_IRQ 100 +#define SSI_IPR_ADDR INTC_INT2PRI6 +#define SSI_IPR_POS 0 +#define SSI_PRIORITY 3 + +/* FLCTL */ +#define FLCTL_FLSTE_IRQ 104 +#define FLCTL_FLTEND_IRQ 105 +#define FLCTL_FLTRQ0_IRQ 106 +#define FLCTL_FLTRQ1_IRQ 107 +#define FLCTL_IPR_ADDR INTC_INT2PRI7 +#define FLCTL_IPR_POS 3 +#define FLCTL_PRIORITY 3 + +/* GPIO */ +#define GPIO0_IRQ 108 +#define GPIO1_IRQ 109 +#define GPIO2_IRQ 110 +#define GPIO3_IRQ 111 +#define GPIO_IPR_ADDR INTC_INT2PRI7 +#define GPIO_IPR_POS 2 +#define GPIO_PRIORITY 3 + +#define INTC_TMU0_MSK 0 +#define INTC_TMU3_MSK 1 +#define INTC_RTC_MSK 2 +#define INTC_SCIF0_MSK 3 +#define INTC_SCIF1_MSK 4 +#define INTC_WDT_MSK 5 +#define INTC_HUID_MSK 7 +#define INTC_DMAC0_MSK 8 +#define INTC_DMAC1_MSK 9 +#define INTC_CMT_MSK 12 +#define INTC_HAC_MSK 13 +#define INTC_PCIC0_MSK 14 +#define INTC_PCIC1_MSK 15 +#define INTC_PCIC2_MSK 16 +#define INTC_PCIC3_MSK 17 +#define INTC_PCIC4_MSK 18 +#define INTC_PCIC5_MSK 19 +#define INTC_SIOF_MSK 20 +#define INTC_HSPI_MSK 21 +#define INTC_MMCIF_MSK 22 +#define INTC_SSI_MSK 23 +#define INTC_FLCTL_MSK 24 +#define INTC_GPIO_MSK 25 + +#endif /* __ASM_SH_IRQ_SH7780_H */ diff --git a/trunk/include/asm-sh/irq.h b/trunk/include/asm-sh/irq.h index fd576088e47e..6cd3e9e2a76a 100644 --- a/trunk/include/asm-sh/irq.h +++ b/trunk/include/asm-sh/irq.h @@ -1,9 +1,233 @@ #ifndef __ASM_SH_IRQ_H #define __ASM_SH_IRQ_H +/* + * + * linux/include/asm-sh/irq.h + * + * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi + * Copyright (C) 2000 Kazumoto Kojima + * Copyright (C) 2003 Paul Mundt + * + */ + #include #include /* for pt_regs */ +#ifndef CONFIG_CPU_SUBTYPE_SH7780 + +#define INTC_DMAC0_MSK 0 + +#if defined(CONFIG_CPU_SH3) +#define INTC_IPRA 0xfffffee2UL +#define INTC_IPRB 0xfffffee4UL +#elif defined(CONFIG_CPU_SH4) +#define INTC_IPRA 0xffd00004UL +#define INTC_IPRB 0xffd00008UL +#define INTC_IPRC 0xffd0000cUL +#define INTC_IPRD 0xffd00010UL +#endif + +#define TIMER_IRQ 16 +#define TIMER_IPR_ADDR INTC_IPRA +#define TIMER_IPR_POS 3 +#define TIMER_PRIORITY 2 + +#define TIMER1_IRQ 17 +#define TIMER1_IPR_ADDR INTC_IPRA +#define TIMER1_IPR_POS 2 +#define TIMER1_PRIORITY 4 + +#define RTC_IRQ 22 +#define RTC_IPR_ADDR INTC_IPRA +#define RTC_IPR_POS 0 +#define RTC_PRIORITY TIMER_PRIORITY + +#if defined(CONFIG_CPU_SH3) +#define DMTE0_IRQ 48 +#define DMTE1_IRQ 49 +#define DMTE2_IRQ 50 +#define DMTE3_IRQ 51 +#define DMA_IPR_ADDR INTC_IPRE +#define DMA_IPR_POS 3 +#define DMA_PRIORITY 7 +#if defined(CONFIG_CPU_SUBTYPE_SH7300) +/* TMU2 */ +#define TIMER2_IRQ 18 +#define TIMER2_IPR_ADDR INTC_IPRA +#define TIMER2_IPR_POS 1 +#define TIMER2_PRIORITY 2 + +/* WDT */ +#define WDT_IRQ 27 +#define WDT_IPR_ADDR INTC_IPRB +#define WDT_IPR_POS 3 +#define WDT_PRIORITY 2 + +/* SIM (SIM Card Module) */ +#define SIM_ERI_IRQ 23 +#define SIM_RXI_IRQ 24 +#define SIM_TXI_IRQ 25 +#define SIM_TEND_IRQ 26 +#define SIM_IPR_ADDR INTC_IPRB +#define SIM_IPR_POS 1 +#define SIM_PRIORITY 2 + +/* VIO (Video I/O) */ +#define VIO_IRQ 52 +#define VIO_IPR_ADDR INTC_IPRE +#define VIO_IPR_POS 2 +#define VIO_PRIORITY 2 + +/* MFI (Multi Functional Interface) */ +#define MFI_IRQ 56 +#define MFI_IPR_ADDR INTC_IPRE +#define MFI_IPR_POS 1 +#define MFI_PRIORITY 2 + +/* VPU (Video Processing Unit) */ +#define VPU_IRQ 60 +#define VPU_IPR_ADDR INTC_IPRE +#define VPU_IPR_POS 0 +#define VPU_PRIORITY 2 + +/* KEY (Key Scan Interface) */ +#define KEY_IRQ 79 +#define KEY_IPR_ADDR INTC_IPRF +#define KEY_IPR_POS 3 +#define KEY_PRIORITY 2 + +/* CMT (Compare Match Timer) */ +#define CMT_IRQ 104 +#define CMT_IPR_ADDR INTC_IPRF +#define CMT_IPR_POS 0 +#define CMT_PRIORITY 2 + +/* DMAC(1) */ +#define DMTE0_IRQ 48 +#define DMTE1_IRQ 49 +#define DMTE2_IRQ 50 +#define DMTE3_IRQ 51 +#define DMA1_IPR_ADDR INTC_IPRE +#define DMA1_IPR_POS 3 +#define DMA1_PRIORITY 7 + +/* DMAC(2) */ +#define DMTE4_IRQ 76 +#define DMTE5_IRQ 77 +#define DMA2_IPR_ADDR INTC_IPRF +#define DMA2_IPR_POS 2 +#define DMA2_PRIORITY 7 + +/* SIOF0 */ +#define SIOF0_IRQ 84 +#define SIOF0_IPR_ADDR INTC_IPRH +#define SIOF0_IPR_POS 3 +#define SIOF0_PRIORITY 3 + +/* FLCTL (Flash Memory Controller) */ +#define FLSTE_IRQ 92 +#define FLTEND_IRQ 93 +#define FLTRQ0_IRQ 94 +#define FLTRQ1_IRQ 95 +#define FLCTL_IPR_ADDR INTC_IPRH +#define FLCTL_IPR_POS 1 +#define FLCTL_PRIORITY 3 + +/* IIC (IIC Bus Interface) */ +#define IIC_ALI_IRQ 96 +#define IIC_TACKI_IRQ 97 +#define IIC_WAITI_IRQ 98 +#define IIC_DTEI_IRQ 99 +#define IIC_IPR_ADDR INTC_IPRH +#define IIC_IPR_POS 0 +#define IIC_PRIORITY 3 + +/* SIO0 */ +#define SIO0_IRQ 88 +#define SIO0_IPR_ADDR INTC_IPRI +#define SIO0_IPR_POS 3 +#define SIO0_PRIORITY 3 + +/* SIU (Sound Interface Unit) */ +#define SIU_IRQ 108 +#define SIU_IPR_ADDR INTC_IPRJ +#define SIU_IPR_POS 1 +#define SIU_PRIORITY 3 + +#endif +#elif defined(CONFIG_CPU_SH4) +#define DMTE0_IRQ 34 +#define DMTE1_IRQ 35 +#define DMTE2_IRQ 36 +#define DMTE3_IRQ 37 +#define DMTE4_IRQ 44 /* 7751R only */ +#define DMTE5_IRQ 45 /* 7751R only */ +#define DMTE6_IRQ 46 /* 7751R only */ +#define DMTE7_IRQ 47 /* 7751R only */ +#define DMAE_IRQ 38 +#define DMA_IPR_ADDR INTC_IPRC +#define DMA_IPR_POS 2 +#define DMA_PRIORITY 7 +#endif + +#if defined (CONFIG_CPU_SUBTYPE_SH7707) || defined (CONFIG_CPU_SUBTYPE_SH7708) || \ + defined (CONFIG_CPU_SUBTYPE_SH7709) || defined (CONFIG_CPU_SUBTYPE_SH7750) || \ + defined (CONFIG_CPU_SUBTYPE_SH7751) || defined (CONFIG_CPU_SUBTYPE_SH7706) +#define SCI_ERI_IRQ 23 +#define SCI_RXI_IRQ 24 +#define SCI_TXI_IRQ 25 +#define SCI_IPR_ADDR INTC_IPRB +#define SCI_IPR_POS 1 +#define SCI_PRIORITY 3 +#endif + +#if defined(CONFIG_CPU_SUBTYPE_SH7300) +#define SCIF0_IRQ 80 +#define SCIF0_IPR_ADDR INTC_IPRG +#define SCIF0_IPR_POS 3 +#define SCIF0_PRIORITY 3 +#elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \ + defined(CONFIG_CPU_SUBTYPE_SH7706) || \ + defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) +#define SCIF_ERI_IRQ 56 +#define SCIF_RXI_IRQ 57 +#define SCIF_BRI_IRQ 58 +#define SCIF_TXI_IRQ 59 +#define SCIF_IPR_ADDR INTC_IPRE +#define SCIF_IPR_POS 1 +#define SCIF_PRIORITY 3 + +#define IRDA_ERI_IRQ 52 +#define IRDA_RXI_IRQ 53 +#define IRDA_BRI_IRQ 54 +#define IRDA_TXI_IRQ 55 +#define IRDA_IPR_ADDR INTC_IPRE +#define IRDA_IPR_POS 2 +#define IRDA_PRIORITY 3 +#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751) || \ + defined(CONFIG_CPU_SUBTYPE_ST40STB1) || defined(CONFIG_CPU_SUBTYPE_SH4_202) +#define SCIF_ERI_IRQ 40 +#define SCIF_RXI_IRQ 41 +#define SCIF_BRI_IRQ 42 +#define SCIF_TXI_IRQ 43 +#define SCIF_IPR_ADDR INTC_IPRC +#define SCIF_IPR_POS 1 +#define SCIF_PRIORITY 3 +#if defined(CONFIG_CPU_SUBTYPE_ST40STB1) +#define SCIF1_ERI_IRQ 23 +#define SCIF1_RXI_IRQ 24 +#define SCIF1_BRI_IRQ 25 +#define SCIF1_TXI_IRQ 26 +#define SCIF1_IPR_ADDR INTC_IPRB +#define SCIF1_IPR_POS 1 +#define SCIF1_PRIORITY 3 +#endif /* ST40STB1 */ + +#endif /* 775x / SH4-202 / ST40STB1 */ +#endif /* 7780 */ + /* NR_IRQS is made from three components: * 1. ONCHIP_NR_IRQS - number of IRLS + on-chip peripherial modules * 2. PINT_NR_IRQS - number of PINT interrupts @@ -41,10 +265,6 @@ # define ONCHIP_NR_IRQS 109 #elif defined(CONFIG_CPU_SUBTYPE_SH7780) # define ONCHIP_NR_IRQS 111 -#elif defined(CONFIG_CPU_SUBTYPE_SH7206) -# define ONCHIP_NR_IRQS 256 -#elif defined(CONFIG_CPU_SUBTYPE_SH7619) -# define ONCHIP_NR_IRQS 128 #elif defined(CONFIG_SH_UNKNOWN) /* Most be last */ # define ONCHIP_NR_IRQS 144 #endif @@ -92,11 +312,9 @@ /* NR_IRQS. 1+2+3 */ #define NR_IRQS (ONCHIP_NR_IRQS + PINT_NR_IRQS + OFFCHIP_NR_IRQS) -/* - * Convert back and forth between INTEVT and IRQ values. - */ -#define evt2irq(evt) (((evt) >> 5) - 16) -#define irq2evt(irq) (((irq) + 16) << 5) +extern void disable_irq(unsigned int); +extern void disable_irq_nosync(unsigned int); +extern void enable_irq(unsigned int); /* * Simple Mask Register Support @@ -109,36 +327,362 @@ extern unsigned short *irq_mask_register; */ void init_IRQ_pint(void); -/* - * The shift value is now the number of bits to shift, not the number of - * bits/4. This is to make it easier to read the value directly from the - * datasheets. The IPR address, addr, will be set from ipr_idx via the - * map_ipridx_to_addr function. - */ struct ipr_data { unsigned int irq; - int ipr_idx; /* Index for the IPR registered */ - int shift; /* Number of bits to shift the data */ - int priority; /* The priority */ unsigned int addr; /* Address of Interrupt Priority Register */ + int shift; /* Shifts of the 16-bit data */ + int priority; /* The priority */ }; /* - * Given an IPR IDX, map the value to an IPR register address. + * Function for "on chip support modules". */ -unsigned int map_ipridx_to_addr(int idx); +extern void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs); +extern void make_imask_irq(unsigned int irq); -/* - * Enable individual interrupt mode for external IPR IRQs. - */ -void ipr_irq_enable_irlm(void); +#if defined(CONFIG_CPU_SUBTYPE_SH7300) +#undef INTC_IPRA +#undef INTC_IPRB +#define INTC_IPRA 0xA414FEE2UL +#define INTC_IPRB 0xA414FEE4UL +#define INTC_IPRC 0xA4140016UL +#define INTC_IPRD 0xA4140018UL +#define INTC_IPRE 0xA414001AUL +#define INTC_IPRF 0xA4080000UL +#define INTC_IPRG 0xA4080002UL +#define INTC_IPRH 0xA4080004UL +#define INTC_IPRI 0xA4080006UL +#define INTC_IPRJ 0xA4080008UL -/* - * Function for "on chip support modules". - */ -void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs); -void make_imask_irq(unsigned int irq); -void init_IRQ_ipr(void); +#define INTC_IMR0 0xA4080040UL +#define INTC_IMR1 0xA4080042UL +#define INTC_IMR2 0xA4080044UL +#define INTC_IMR3 0xA4080046UL +#define INTC_IMR4 0xA4080048UL +#define INTC_IMR5 0xA408004AUL +#define INTC_IMR6 0xA408004CUL +#define INTC_IMR7 0xA408004EUL +#define INTC_IMR8 0xA4080050UL +#define INTC_IMR9 0xA4080052UL +#define INTC_IMR10 0xA4080054UL + +#define INTC_IMCR0 0xA4080060UL +#define INTC_IMCR1 0xA4080062UL +#define INTC_IMCR2 0xA4080064UL +#define INTC_IMCR3 0xA4080066UL +#define INTC_IMCR4 0xA4080068UL +#define INTC_IMCR5 0xA408006AUL +#define INTC_IMCR6 0xA408006CUL +#define INTC_IMCR7 0xA408006EUL +#define INTC_IMCR8 0xA4080070UL +#define INTC_IMCR9 0xA4080072UL +#define INTC_IMCR10 0xA4080074UL + +#define INTC_ICR0 0xA414FEE0UL +#define INTC_ICR1 0xA4140010UL + +#define INTC_IRR0 0xA4140004UL + +#define PORT_PACR 0xA4050100UL +#define PORT_PBCR 0xA4050102UL +#define PORT_PCCR 0xA4050104UL +#define PORT_PDCR 0xA4050106UL +#define PORT_PECR 0xA4050108UL +#define PORT_PFCR 0xA405010AUL +#define PORT_PGCR 0xA405010CUL +#define PORT_PHCR 0xA405010EUL +#define PORT_PJCR 0xA4050110UL +#define PORT_PKCR 0xA4050112UL +#define PORT_PLCR 0xA4050114UL +#define PORT_SCPCR 0xA4050116UL +#define PORT_PMCR 0xA4050118UL +#define PORT_PNCR 0xA405011AUL +#define PORT_PQCR 0xA405011CUL + +#define PORT_PSELA 0xA4050140UL +#define PORT_PSELB 0xA4050142UL +#define PORT_PSELC 0xA4050144UL + +#define PORT_HIZCRA 0xA4050146UL +#define PORT_HIZCRB 0xA4050148UL +#define PORT_DRVCR 0xA4050150UL + +#define PORT_PADR 0xA4050120UL +#define PORT_PBDR 0xA4050122UL +#define PORT_PCDR 0xA4050124UL +#define PORT_PDDR 0xA4050126UL +#define PORT_PEDR 0xA4050128UL +#define PORT_PFDR 0xA405012AUL +#define PORT_PGDR 0xA405012CUL +#define PORT_PHDR 0xA405012EUL +#define PORT_PJDR 0xA4050130UL +#define PORT_PKDR 0xA4050132UL +#define PORT_PLDR 0xA4050134UL +#define PORT_SCPDR 0xA4050136UL +#define PORT_PMDR 0xA4050138UL +#define PORT_PNDR 0xA405013AUL +#define PORT_PQDR 0xA405013CUL + +#define IRQ0_IRQ 32 +#define IRQ1_IRQ 33 +#define IRQ2_IRQ 34 +#define IRQ3_IRQ 35 +#define IRQ4_IRQ 36 +#define IRQ5_IRQ 37 + +#define IRQ0_IPR_ADDR INTC_IPRC +#define IRQ1_IPR_ADDR INTC_IPRC +#define IRQ2_IPR_ADDR INTC_IPRC +#define IRQ3_IPR_ADDR INTC_IPRC +#define IRQ4_IPR_ADDR INTC_IPRD +#define IRQ5_IPR_ADDR INTC_IPRD + +#define IRQ0_IPR_POS 0 +#define IRQ1_IPR_POS 1 +#define IRQ2_IPR_POS 2 +#define IRQ3_IPR_POS 3 +#define IRQ4_IPR_POS 0 +#define IRQ5_IPR_POS 1 + +#define IRQ0_PRIORITY 1 +#define IRQ1_PRIORITY 1 +#define IRQ2_PRIORITY 1 +#define IRQ3_PRIORITY 1 +#define IRQ4_PRIORITY 1 +#define IRQ5_PRIORITY 1 + +extern int ipr_irq_demux(int irq); +#define __irq_demux(irq) ipr_irq_demux(irq) + +#elif defined(CONFIG_CPU_SUBTYPE_SH7604) +#define INTC_IPRA 0xfffffee2UL +#define INTC_IPRB 0xfffffe60UL + +#define INTC_VCRA 0xfffffe62UL +#define INTC_VCRB 0xfffffe64UL +#define INTC_VCRC 0xfffffe66UL +#define INTC_VCRD 0xfffffe68UL + +#define INTC_VCRWDT 0xfffffee4UL +#define INTC_VCRDIV 0xffffff0cUL +#define INTC_VCRDMA0 0xffffffa0UL +#define INTC_VCRDMA1 0xffffffa8UL + +#define INTC_ICR 0xfffffee0UL +#elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \ + defined(CONFIG_CPU_SUBTYPE_SH7706) || \ + defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) || \ + defined(CONFIG_CPU_SUBTYPE_SH7710) +#define INTC_IRR0 0xa4000004UL +#define INTC_IRR1 0xa4000006UL +#define INTC_IRR2 0xa4000008UL + +#define INTC_ICR0 0xfffffee0UL +#define INTC_ICR1 0xa4000010UL +#define INTC_ICR2 0xa4000012UL +#define INTC_INTER 0xa4000014UL + +#define INTC_IPRC 0xa4000016UL +#define INTC_IPRD 0xa4000018UL +#define INTC_IPRE 0xa400001aUL +#if defined(CONFIG_CPU_SUBTYPE_SH7707) +#define INTC_IPRF 0xa400001cUL +#elif defined(CONFIG_CPU_SUBTYPE_SH7705) +#define INTC_IPRF 0xa4080000UL +#define INTC_IPRG 0xa4080002UL +#define INTC_IPRH 0xa4080004UL +#elif defined(CONFIG_CPU_SUBTYPE_SH7710) +/* Interrupt Controller Registers */ +#undef INTC_IPRA +#undef INTC_IPRB +#define INTC_IPRA 0xA414FEE2UL +#define INTC_IPRB 0xA414FEE4UL +#define INTC_IPRF 0xA4080000UL +#define INTC_IPRG 0xA4080002UL +#define INTC_IPRH 0xA4080004UL +#define INTC_IPRI 0xA4080006UL + +#undef INTC_ICR0 +#undef INTC_ICR1 +#define INTC_ICR0 0xA414FEE0UL +#define INTC_ICR1 0xA4140010UL + +#define INTC_IRR0 0xa4000004UL +#define INTC_IRR1 0xa4000006UL +#define INTC_IRR2 0xa4000008UL +#define INTC_IRR3 0xa400000AUL +#define INTC_IRR4 0xa400000CUL +#define INTC_IRR5 0xa4080020UL +#define INTC_IRR7 0xa4080024UL +#define INTC_IRR8 0xa4080026UL + +/* Interrupt numbers */ +#define TIMER2_IRQ 18 +#define TIMER2_IPR_ADDR INTC_IPRA +#define TIMER2_IPR_POS 1 +#define TIMER2_PRIORITY 2 + +/* WDT */ +#define WDT_IRQ 27 +#define WDT_IPR_ADDR INTC_IPRB +#define WDT_IPR_POS 3 +#define WDT_PRIORITY 2 + +#define SCIF0_ERI_IRQ 52 +#define SCIF0_RXI_IRQ 53 +#define SCIF0_BRI_IRQ 54 +#define SCIF0_TXI_IRQ 55 +#define SCIF0_IPR_ADDR INTC_IPRE +#define SCIF0_IPR_POS 2 +#define SCIF0_PRIORITY 3 + +#define DMTE4_IRQ 76 +#define DMTE5_IRQ 77 +#define DMA2_IPR_ADDR INTC_IPRF +#define DMA2_IPR_POS 2 +#define DMA2_PRIORITY 7 + +#define IPSEC_IRQ 79 +#define IPSEC_IPR_ADDR INTC_IPRF +#define IPSEC_IPR_POS 3 +#define IPSEC_PRIORITY 3 + +/* EDMAC */ +#define EDMAC0_IRQ 80 +#define EDMAC0_IPR_ADDR INTC_IPRG +#define EDMAC0_IPR_POS 3 +#define EDMAC0_PRIORITY 3 + +#define EDMAC1_IRQ 81 +#define EDMAC1_IPR_ADDR INTC_IPRG +#define EDMAC1_IPR_POS 2 +#define EDMAC1_PRIORITY 3 + +#define EDMAC2_IRQ 82 +#define EDMAC2_IPR_ADDR INTC_IPRG +#define EDMAC2_IPR_POS 1 +#define EDMAC2_PRIORITY 3 + +/* SIOF */ +#define SIOF0_ERI_IRQ 96 +#define SIOF0_TXI_IRQ 97 +#define SIOF0_RXI_IRQ 98 +#define SIOF0_CCI_IRQ 99 +#define SIOF0_IPR_ADDR INTC_IPRH +#define SIOF0_IPR_POS 0 +#define SIOF0_PRIORITY 7 + +#define SIOF1_ERI_IRQ 100 +#define SIOF1_TXI_IRQ 101 +#define SIOF1_RXI_IRQ 102 +#define SIOF1_CCI_IRQ 103 +#define SIOF1_IPR_ADDR INTC_IPRI +#define SIOF1_IPR_POS 1 +#define SIOF1_PRIORITY 7 +#endif /* CONFIG_CPU_SUBTYPE_SH7710 */ + +#if defined(CONFIG_CPU_SUBTYPE_SH7710) +#define PORT_PACR 0xa4050100UL +#define PORT_PBCR 0xa4050102UL +#define PORT_PCCR 0xa4050104UL +#define PORT_PETCR 0xa4050106UL +#define PORT_PADR 0xa4050120UL +#define PORT_PBDR 0xa4050122UL +#define PORT_PCDR 0xa4050124UL +#else +#define PORT_PACR 0xa4000100UL +#define PORT_PBCR 0xa4000102UL +#define PORT_PCCR 0xa4000104UL +#define PORT_PFCR 0xa400010aUL +#define PORT_PADR 0xa4000120UL +#define PORT_PBDR 0xa4000122UL +#define PORT_PCDR 0xa4000124UL +#define PORT_PFDR 0xa400012aUL +#endif + +#define IRQ0_IRQ 32 +#define IRQ1_IRQ 33 +#define IRQ2_IRQ 34 +#define IRQ3_IRQ 35 +#define IRQ4_IRQ 36 +#define IRQ5_IRQ 37 + +#define IRQ0_IPR_ADDR INTC_IPRC +#define IRQ1_IPR_ADDR INTC_IPRC +#define IRQ2_IPR_ADDR INTC_IPRC +#define IRQ3_IPR_ADDR INTC_IPRC +#define IRQ4_IPR_ADDR INTC_IPRD +#define IRQ5_IPR_ADDR INTC_IPRD + +#define IRQ0_IPR_POS 0 +#define IRQ1_IPR_POS 1 +#define IRQ2_IPR_POS 2 +#define IRQ3_IPR_POS 3 +#define IRQ4_IPR_POS 0 +#define IRQ5_IPR_POS 1 + +#define IRQ0_PRIORITY 1 +#define IRQ1_PRIORITY 1 +#define IRQ2_PRIORITY 1 +#define IRQ3_PRIORITY 1 +#define IRQ4_PRIORITY 1 +#define IRQ5_PRIORITY 1 + +#define PINT0_IRQ 40 +#define PINT8_IRQ 41 + +#define PINT0_IPR_ADDR INTC_IPRD +#define PINT8_IPR_ADDR INTC_IPRD + +#define PINT0_IPR_POS 3 +#define PINT8_IPR_POS 2 +#define PINT0_PRIORITY 2 +#define PINT8_PRIORITY 2 + +extern int ipr_irq_demux(int irq); +#define __irq_demux(irq) ipr_irq_demux(irq) +#endif /* CONFIG_CPU_SUBTYPE_SH7707 || CONFIG_CPU_SUBTYPE_SH7709 */ + +#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751) || \ + defined(CONFIG_CPU_SUBTYPE_ST40STB1) || defined(CONFIG_CPU_SUBTYPE_SH4_202) +#define INTC_ICR 0xffd00000 +#define INTC_ICR_NMIL (1<<15) +#define INTC_ICR_MAI (1<<14) +#define INTC_ICR_NMIB (1<<9) +#define INTC_ICR_NMIE (1<<8) +#define INTC_ICR_IRLM (1<<7) +#endif + +#ifdef CONFIG_CPU_SUBTYPE_SH7780 +#include +#endif + +/* SH with INTC2-style interrupts */ +#ifdef CONFIG_CPU_HAS_INTC2_IRQ +#if defined(CONFIG_CPU_SUBTYPE_ST40STB1) +#define INTC2_BASE 0xfe080000 +#define INTC2_FIRST_IRQ 64 +#define INTC2_INTREQ_OFFSET 0x20 +#define INTC2_INTMSK_OFFSET 0x40 +#define INTC2_INTMSKCLR_OFFSET 0x60 +#define NR_INTC2_IRQS 25 +#elif defined(CONFIG_CPU_SUBTYPE_SH7760) +#define INTC2_BASE 0xfe080000 +#define INTC2_FIRST_IRQ 48 /* INTEVT 0x800 */ +#define INTC2_INTREQ_OFFSET 0x20 +#define INTC2_INTMSK_OFFSET 0x40 +#define INTC2_INTMSKCLR_OFFSET 0x60 +#define NR_INTC2_IRQS 64 +#elif defined(CONFIG_CPU_SUBTYPE_SH7780) +#define INTC2_BASE 0xffd40000 +#define INTC2_FIRST_IRQ 21 +#define INTC2_INTMSK_OFFSET (0x38) +#define INTC2_INTMSKCLR_OFFSET (0x3c) +#define NR_INTC2_IRQS 60 +#endif + +#define INTC2_INTPRI_OFFSET 0x00 struct intc2_data { unsigned short irq; @@ -149,14 +693,20 @@ struct intc2_data { void make_intc2_irq(struct intc2_data *, unsigned int nr_irqs); void init_IRQ_intc2(void); +#endif + +extern int shmse_irq_demux(int irq); static inline int generic_irq_demux(int irq) { return irq; } +#ifndef __irq_demux +#define __irq_demux(irq) (irq) +#endif #define irq_canonicalize(irq) (irq) -#define irq_demux(irq) sh_mv.mv_irq_demux(irq) +#define irq_demux(irq) __irq_demux(sh_mv.mv_irq_demux(irq)) #ifdef CONFIG_4KSTACKS extern void irq_ctx_init(int cpu); @@ -167,4 +717,12 @@ extern void irq_ctx_exit(int cpu); # define irq_ctx_exit(cpu) do { } while (0) #endif +#if defined(CONFIG_CPU_SUBTYPE_SH73180) +#include +#endif + +#if defined(CONFIG_CPU_SUBTYPE_SH7343) +#include +#endif + #endif /* __ASM_SH_IRQ_H */ diff --git a/trunk/include/asm-sh/irqflags.h b/trunk/include/asm-sh/irqflags.h deleted file mode 100644 index 9dedc1b693e3..000000000000 --- a/trunk/include/asm-sh/irqflags.h +++ /dev/null @@ -1,123 +0,0 @@ -#ifndef __ASM_SH_IRQFLAGS_H -#define __ASM_SH_IRQFLAGS_H - -static inline void raw_local_irq_enable(void) -{ - unsigned long __dummy0, __dummy1; - - __asm__ __volatile__ ( - "stc sr, %0\n\t" - "and %1, %0\n\t" -#ifdef CONFIG_CPU_HAS_SR_RB - "stc r6_bank, %1\n\t" - "or %1, %0\n\t" -#endif - "ldc %0, sr\n\t" - : "=&r" (__dummy0), "=r" (__dummy1) - : "1" (~0x000000f0) - : "memory" - ); -} - -static inline void raw_local_irq_disable(void) -{ - unsigned long flags; - - __asm__ __volatile__ ( - "stc sr, %0\n\t" - "or #0xf0, %0\n\t" - "ldc %0, sr\n\t" - : "=&z" (flags) - : /* no inputs */ - : "memory" - ); -} - -static inline void set_bl_bit(void) -{ - unsigned long __dummy0, __dummy1; - - __asm__ __volatile__ ( - "stc sr, %0\n\t" - "or %2, %0\n\t" - "and %3, %0\n\t" - "ldc %0, sr\n\t" - : "=&r" (__dummy0), "=r" (__dummy1) - : "r" (0x10000000), "r" (0xffffff0f) - : "memory" - ); -} - -static inline void clear_bl_bit(void) -{ - unsigned long __dummy0, __dummy1; - - __asm__ __volatile__ ( - "stc sr, %0\n\t" - "and %2, %0\n\t" - "ldc %0, sr\n\t" - : "=&r" (__dummy0), "=r" (__dummy1) - : "1" (~0x10000000) - : "memory" - ); -} - -static inline unsigned long __raw_local_save_flags(void) -{ - unsigned long flags; - - __asm__ __volatile__ ( - "stc sr, %0\n\t" - "and #0xf0, %0\n\t" - : "=&z" (flags) - : /* no inputs */ - : "memory" - ); - - return flags; -} - -#define raw_local_save_flags(flags) \ - do { (flags) = __raw_local_save_flags(); } while (0) - -static inline int raw_irqs_disabled_flags(unsigned long flags) -{ - return (flags != 0); -} - -static inline int raw_irqs_disabled(void) -{ - unsigned long flags = __raw_local_save_flags(); - - return raw_irqs_disabled_flags(flags); -} - -static inline unsigned long __raw_local_irq_save(void) -{ - unsigned long flags, __dummy; - - __asm__ __volatile__ ( - "stc sr, %1\n\t" - "mov %1, %0\n\t" - "or #0xf0, %0\n\t" - "ldc %0, sr\n\t" - "mov %1, %0\n\t" - "and #0xf0, %0\n\t" - : "=&z" (flags), "=&r" (__dummy) - : /* no inputs */ - : "memory" - ); - - return flags; -} - -#define raw_local_irq_save(flags) \ - do { (flags) = __raw_local_irq_save(); } while (0) - -static inline void raw_local_irq_restore(unsigned long flags) -{ - if ((flags & 0xf0) != 0xf0) - raw_local_irq_enable(); -} - -#endif /* __ASM_SH_IRQFLAGS_H */ diff --git a/trunk/include/asm-sh/mmu_context.h b/trunk/include/asm-sh/mmu_context.h index 46f04e23bd45..c7088efe579a 100644 --- a/trunk/include/asm-sh/mmu_context.h +++ b/trunk/include/asm-sh/mmu_context.h @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -41,8 +42,10 @@ extern unsigned long mmu_context_cache; /* * Get MMU context if needed. */ -static inline void get_mmu_context(struct mm_struct *mm) +static __inline__ void +get_mmu_context(struct mm_struct *mm) { + extern void flush_tlb_all(void); unsigned long mc = mmu_context_cache; /* Check if we have old version of context. */ @@ -58,7 +61,6 @@ static inline void get_mmu_context(struct mm_struct *mm) * Flush all TLB and start new cycle. */ flush_tlb_all(); - /* * Fix version; Note that we avoid version #0 * to distingush NO_CONTEXT. @@ -73,10 +75,11 @@ static inline void get_mmu_context(struct mm_struct *mm) * Initialize the context related info for a new mm_struct * instance. */ -static inline int init_new_context(struct task_struct *tsk, +static __inline__ int init_new_context(struct task_struct *tsk, struct mm_struct *mm) { mm->context.id = NO_CONTEXT; + return 0; } @@ -84,12 +87,12 @@ static inline int init_new_context(struct task_struct *tsk, * Destroy context related info for an mm_struct that is about * to be put to rest. */ -static inline void destroy_context(struct mm_struct *mm) +static __inline__ void destroy_context(struct mm_struct *mm) { /* Do nothing */ } -static inline void set_asid(unsigned long asid) +static __inline__ void set_asid(unsigned long asid) { unsigned long __dummy; @@ -102,7 +105,7 @@ static inline void set_asid(unsigned long asid) "r" (0xffffff00)); } -static inline unsigned long get_asid(void) +static __inline__ unsigned long get_asid(void) { unsigned long asid; @@ -117,29 +120,24 @@ static inline unsigned long get_asid(void) * After we have set current->mm to a new value, this activates * the context for the new mm so we see the new mappings. */ -static inline void activate_context(struct mm_struct *mm) +static __inline__ void activate_context(struct mm_struct *mm) { get_mmu_context(mm); set_asid(mm->context.id & MMU_CONTEXT_ASID_MASK); } -/* MMU_TTB is used for optimizing the fault handling. */ -static inline void set_TTB(pgd_t *pgd) -{ - ctrl_outl((unsigned long)pgd, MMU_TTB); -} - -static inline pgd_t *get_TTB(void) -{ - return (pgd_t *)ctrl_inl(MMU_TTB); -} - -static inline void switch_mm(struct mm_struct *prev, - struct mm_struct *next, - struct task_struct *tsk) +/* MMU_TTB can be used for optimizing the fault handling. + (Currently not used) */ +static __inline__ void switch_mm(struct mm_struct *prev, + struct mm_struct *next, + struct task_struct *tsk) { if (likely(prev != next)) { - set_TTB(next->pgd); + unsigned long __pgdir = (unsigned long)next->pgd; + + __asm__ __volatile__("mov.l %0, %1" + : /* no output */ + : "r" (__pgdir), "m" (__m(MMU_TTB))); activate_context(next); } } @@ -149,7 +147,7 @@ static inline void switch_mm(struct mm_struct *prev, #define activate_mm(prev, next) \ switch_mm((prev),(next),NULL) -static inline void +static __inline__ void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) { } diff --git a/trunk/include/asm-sh/page.h b/trunk/include/asm-sh/page.h index 380fd62dd05a..ca8b26d90475 100644 --- a/trunk/include/asm-sh/page.h +++ b/trunk/include/asm-sh/page.h @@ -13,16 +13,9 @@ [ P4 control ] 0xE0000000 */ + /* PAGE_SHIFT determines the page size */ -#if defined(CONFIG_PAGE_SIZE_4KB) -# define PAGE_SHIFT 12 -#elif defined(CONFIG_PAGE_SIZE_8KB) -# define PAGE_SHIFT 13 -#elif defined(CONFIG_PAGE_SIZE_64KB) -# define PAGE_SHIFT 16 -#else -# error "Bogus kernel page size?" -#endif +#define PAGE_SHIFT 12 #ifdef __ASSEMBLY__ #define PAGE_SIZE (1 << PAGE_SHIFT) @@ -35,14 +28,8 @@ #if defined(CONFIG_HUGETLB_PAGE_SIZE_64K) #define HPAGE_SHIFT 16 -#elif defined(CONFIG_HUGETLB_PAGE_SIZE_256K) -#define HPAGE_SHIFT 18 #elif defined(CONFIG_HUGETLB_PAGE_SIZE_1MB) #define HPAGE_SHIFT 20 -#elif defined(CONFIG_HUGETLB_PAGE_SIZE_4MB) -#define HPAGE_SHIFT 22 -#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64MB) -#define HPAGE_SHIFT 26 #endif #ifdef CONFIG_HUGETLB_PAGE @@ -82,25 +69,15 @@ extern void __copy_user_page(void *to, void *from, void *orig_to); /* * These are used to make use of C type-checking.. */ -#ifdef CONFIG_X2TLB -typedef struct { unsigned long pte_low, pte_high; } pte_t; -typedef struct { unsigned long long pgprot; } pgprot_t; -#define pte_val(x) \ - ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) -#define __pte(x) \ - ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; }) -#else -typedef struct { unsigned long pte_low; } pte_t; -typedef struct { unsigned long pgprot; } pgprot_t; -#define pte_val(x) ((x).pte_low) -#define __pte(x) ((pte_t) { (x) } ) -#endif - +typedef struct { unsigned long pte; } pte_t; typedef struct { unsigned long pgd; } pgd_t; +typedef struct { unsigned long pgprot; } pgprot_t; +#define pte_val(x) ((x).pte) #define pgd_val(x) ((x).pgd) #define pgprot_val(x) ((x).pgprot) +#define __pte(x) ((pte_t) { (x) } ) #define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) diff --git a/trunk/include/asm-sh/pgalloc.h b/trunk/include/asm-sh/pgalloc.h index 888e4529e6fe..e841465ab4d2 100644 --- a/trunk/include/asm-sh/pgalloc.h +++ b/trunk/include/asm-sh/pgalloc.h @@ -1,16 +1,13 @@ #ifndef __ASM_SH_PGALLOC_H #define __ASM_SH_PGALLOC_H -static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, - pte_t *pte) -{ - set_pmd(pmd, __pmd((unsigned long)pte)); -} +#define pmd_populate_kernel(mm, pmd, pte) \ + set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte))) static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte) { - set_pmd(pmd, __pmd((unsigned long)page_address(pte))); + set_pmd(pmd, __pmd(_PAGE_TABLE + page_to_phys(pte))); } /* @@ -18,16 +15,7 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, */ static inline pgd_t *pgd_alloc(struct mm_struct *mm) { - pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_REPEAT); - - if (pgd) { - memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); - memcpy(pgd + USER_PTRS_PER_PGD, - swapper_pg_dir + USER_PTRS_PER_PGD, - (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); - } - - return pgd; + return (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO); } static inline void pgd_free(pgd_t *pgd) diff --git a/trunk/include/asm-sh/pgtable-2level.h b/trunk/include/asm-sh/pgtable-2level.h new file mode 100644 index 000000000000..b525db6f61c6 --- /dev/null +++ b/trunk/include/asm-sh/pgtable-2level.h @@ -0,0 +1,70 @@ +#ifndef __ASM_SH_PGTABLE_2LEVEL_H +#define __ASM_SH_PGTABLE_2LEVEL_H + +/* + * traditional two-level paging structure: + */ + +#define PGDIR_SHIFT 22 +#define PTRS_PER_PGD 1024 + +/* + * this is two-level, so we don't really have any + * PMD directory physically. + */ +#define PMD_SHIFT 22 +#define PTRS_PER_PMD 1 + +#define PTRS_PER_PTE 1024 + +#ifndef __ASSEMBLY__ +#define pte_ERROR(e) \ + printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) +#define pmd_ERROR(e) \ + printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) +#define pgd_ERROR(e) \ + printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) + +/* + * The "pgd_xxx()" functions here are trivial for a folded two-level + * setup: the pgd is never bad, and a pmd always exists (as it's folded + * into the pgd entry) + */ +static inline int pgd_none(pgd_t pgd) { return 0; } +static inline int pgd_bad(pgd_t pgd) { return 0; } +static inline int pgd_present(pgd_t pgd) { return 1; } +static inline void pgd_clear (pgd_t * pgdp) { } + +/* + * Certain architectures need to do special things when PTEs + * within a page table are directly modified. Thus, the following + * hook is made available. + */ +#define set_pte(pteptr, pteval) (*(pteptr) = pteval) +#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) + +/* + * (pmds are folded into pgds so this doesn't get actually called, + * but the define is needed for a generic inline function.) + */ +#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval) +#define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval) + +#define pgd_page_vaddr(pgd) \ +((unsigned long) __va(pgd_val(pgd) & PAGE_MASK)) + +#define pgd_page(pgd) \ + (phys_to_page(pgd_val(pgd))) + +static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) +{ + return (pmd_t *) dir; +} + +#define pte_pfn(x) ((unsigned long)(((x).pte >> PAGE_SHIFT))) +#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) +#define pfn_pmd(pfn, prot) __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) + +#endif /* !__ASSEMBLY__ */ + +#endif /* __ASM_SH_PGTABLE_2LEVEL_H */ diff --git a/trunk/include/asm-sh/pgtable.h b/trunk/include/asm-sh/pgtable.h index c84901dbd8e5..2c8682ad1012 100644 --- a/trunk/include/asm-sh/pgtable.h +++ b/trunk/include/asm-sh/pgtable.h @@ -15,10 +15,15 @@ #include #include +#define PTRS_PER_PGD 1024 + #ifndef __ASSEMBLY__ #include #include +extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; +extern void paging_init(void); + /* * ZERO_PAGE is a global shared page that is always zero: used * for zero-mapped memory areas etc.. @@ -28,28 +33,15 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; #endif /* !__ASSEMBLY__ */ -/* - * traditional two-level paging structure - */ -/* PTE bits */ -#ifdef CONFIG_X2TLB -# define PTE_MAGNITUDE 3 /* 64-bit PTEs on extended mode SH-X2 TLB */ -#else -# define PTE_MAGNITUDE 2 /* 32-bit PTEs */ -#endif -#define PTE_SHIFT PAGE_SHIFT -#define PTE_BITS (PTE_SHIFT - PTE_MAGNITUDE) - -/* PGD bits */ -#define PGDIR_SHIFT (PTE_SHIFT + PTE_BITS) -#define PGDIR_BITS (32 - PGDIR_SHIFT) -#define PGDIR_SIZE (1 << PGDIR_SHIFT) +/* traditional two-level paging structure */ +#define PGDIR_SHIFT 22 +#define PTRS_PER_PMD 1 +#define PTRS_PER_PTE 1024 +#define PMD_SIZE (1UL << PMD_SHIFT) +#define PMD_MASK (~(PMD_SIZE-1)) +#define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) -/* Entries per level */ -#define PTRS_PER_PTE (PAGE_SIZE / 4) -#define PTRS_PER_PGD (PAGE_SIZE / 4) - #define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) #define FIRST_USER_ADDRESS 0 @@ -57,7 +49,7 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; /* * First 1MB map is used by fixed purpose. - * Currently only 4-entry (16kB) is used (see arch/sh/mm/cache.c) + * Currently only 4-enty (16kB) is used (see arch/sh/mm/cache.c) */ #define VMALLOC_START (P3SEG+0x00100000) #define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE) @@ -65,8 +57,7 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; /* * Linux PTEL encoding. * - * Hardware and software bit definitions for the PTEL value (see below for - * notes on SH-X2 MMUs and 64-bit PTEs): + * Hardware and software bit definitions for the PTEL value: * * - Bits 0 and 7 are reserved on SH-3 (_PAGE_WT and _PAGE_SZ1 on SH-4). * @@ -85,57 +76,20 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; * * - Bits 31, 30, and 29 remain unused by everyone and can be used for future * software flags, although care must be taken to update _PAGE_CLEAR_FLAGS. - * - * XXX: Leave the _PAGE_FILE and _PAGE_WT overhaul for a rainy day. - * - * SH-X2 MMUs and extended PTEs - * - * SH-X2 supports an extended mode TLB with split data arrays due to the - * number of bits needed for PR and SZ (now EPR and ESZ) encodings. The PR and - * SZ bit placeholders still exist in data array 1, but are implemented as - * reserved bits, with the real logic existing in data array 2. - * - * The downside to this is that we can no longer fit everything in to a 32-bit - * PTE encoding, so a 64-bit pte_t is necessary for these parts. On the plus - * side, this gives us quite a few spare bits to play with for future usage. */ -/* Legacy and compat mode bits */ #define _PAGE_WT 0x001 /* WT-bit on SH-4, 0 on SH-3 */ #define _PAGE_HW_SHARED 0x002 /* SH-bit : shared among processes */ #define _PAGE_DIRTY 0x004 /* D-bit : page changed */ #define _PAGE_CACHABLE 0x008 /* C-bit : cachable */ -#ifndef CONFIG_X2TLB -# define _PAGE_SZ0 0x010 /* SZ0-bit : Size of page */ -# define _PAGE_RW 0x020 /* PR0-bit : write access allowed */ -# define _PAGE_USER 0x040 /* PR1-bit : user space access allowed*/ -# define _PAGE_SZ1 0x080 /* SZ1-bit : Size of page (on SH-4) */ -#endif +#define _PAGE_SZ0 0x010 /* SZ0-bit : Size of page */ +#define _PAGE_RW 0x020 /* PR0-bit : write access allowed */ +#define _PAGE_USER 0x040 /* PR1-bit : user space access allowed */ +#define _PAGE_SZ1 0x080 /* SZ1-bit : Size of page (on SH-4) */ #define _PAGE_PRESENT 0x100 /* V-bit : page is valid */ #define _PAGE_PROTNONE 0x200 /* software: if not present */ #define _PAGE_ACCESSED 0x400 /* software: page referenced */ #define _PAGE_FILE _PAGE_WT /* software: pagecache or swap? */ -/* Extended mode bits */ -#define _PAGE_EXT_ESZ0 0x0010 /* ESZ0-bit: Size of page */ -#define _PAGE_EXT_ESZ1 0x0020 /* ESZ1-bit: Size of page */ -#define _PAGE_EXT_ESZ2 0x0040 /* ESZ2-bit: Size of page */ -#define _PAGE_EXT_ESZ3 0x0080 /* ESZ3-bit: Size of page */ - -#define _PAGE_EXT_USER_EXEC 0x0100 /* EPR0-bit: User space executable */ -#define _PAGE_EXT_USER_WRITE 0x0200 /* EPR1-bit: User space writable */ -#define _PAGE_EXT_USER_READ 0x0400 /* EPR2-bit: User space readable */ - -#define _PAGE_EXT_KERN_EXEC 0x0800 /* EPR3-bit: Kernel space executable */ -#define _PAGE_EXT_KERN_WRITE 0x1000 /* EPR4-bit: Kernel space writable */ -#define _PAGE_EXT_KERN_READ 0x2000 /* EPR5-bit: Kernel space readable */ - -/* Wrapper for extended mode pgprot twiddling */ -#ifdef CONFIG_X2TLB -# define _PAGE_EXT(x) ((unsigned long long)(x) << 32) -#else -# define _PAGE_EXT(x) (0) -#endif - /* software: moves to PTEA.TC (Timing Control) */ #define _PAGE_PCC_AREA5 0x00000000 /* use BSC registers for area5 */ #define _PAGE_PCC_AREA6 0x80000000 /* use BSC registers for area6 */ @@ -160,160 +114,37 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; #define _PAGE_FLAGS_HARDWARE_MASK (0x1fffffff & ~(_PAGE_CLEAR_FLAGS)) -/* Hardware flags, page size encoding */ -#if defined(CONFIG_X2TLB) -# if defined(CONFIG_PAGE_SIZE_4KB) -# define _PAGE_FLAGS_HARD _PAGE_EXT(_PAGE_EXT_ESZ0) -# elif defined(CONFIG_PAGE_SIZE_8KB) -# define _PAGE_FLAGS_HARD _PAGE_EXT(_PAGE_EXT_ESZ1) -# elif defined(CONFIG_PAGE_SIZE_64KB) -# define _PAGE_FLAGS_HARD _PAGE_EXT(_PAGE_EXT_ESZ2) -# endif -#else -# if defined(CONFIG_PAGE_SIZE_4KB) -# define _PAGE_FLAGS_HARD _PAGE_SZ0 -# elif defined(CONFIG_PAGE_SIZE_64KB) -# define _PAGE_FLAGS_HARD _PAGE_SZ1 -# endif -#endif +/* Hardware flags: SZ0=1 (4k-byte) */ +#define _PAGE_FLAGS_HARD _PAGE_SZ0 -#if defined(CONFIG_X2TLB) -# if defined(CONFIG_HUGETLB_PAGE_SIZE_64K) -# define _PAGE_SZHUGE (_PAGE_EXT_ESZ2) -# elif defined(CONFIG_HUGETLB_PAGE_SIZE_256K) -# define _PAGE_SZHUGE (_PAGE_EXT_ESZ0 | _PAGE_EXT_ESZ2) -# elif defined(CONFIG_HUGETLB_PAGE_SIZE_1MB) -# define _PAGE_SZHUGE (_PAGE_EXT_ESZ0 | _PAGE_EXT_ESZ1 | _PAGE_EXT_ESZ2) -# elif defined(CONFIG_HUGETLB_PAGE_SIZE_4MB) -# define _PAGE_SZHUGE (_PAGE_EXT_ESZ3) -# elif defined(CONFIG_HUGETLB_PAGE_SIZE_64MB) -# define _PAGE_SZHUGE (_PAGE_EXT_ESZ2 | _PAGE_EXT_ESZ3) -# endif -#else -# if defined(CONFIG_HUGETLB_PAGE_SIZE_64K) -# define _PAGE_SZHUGE (_PAGE_SZ1) -# elif defined(CONFIG_HUGETLB_PAGE_SIZE_1MB) -# define _PAGE_SZHUGE (_PAGE_SZ0 | _PAGE_SZ1) -# endif -#endif - -/* - * Stub out _PAGE_SZHUGE if we don't have a good definition for it, - * to make pte_mkhuge() happy. - */ -#ifndef _PAGE_SZHUGE -# define _PAGE_SZHUGE (_PAGE_FLAGS_HARD) +#if defined(CONFIG_HUGETLB_PAGE_SIZE_64K) +#define _PAGE_SZHUGE (_PAGE_SZ1) +#elif defined(CONFIG_HUGETLB_PAGE_SIZE_1MB) +#define _PAGE_SZHUGE (_PAGE_SZ0 | _PAGE_SZ1) #endif -#define _PAGE_CHG_MASK \ - (PTE_MASK | _PAGE_ACCESSED | _PAGE_CACHABLE | _PAGE_DIRTY) +#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY) +#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) +#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_CACHABLE | _PAGE_DIRTY) #ifndef __ASSEMBLY__ -#if defined(CONFIG_X2TLB) /* SH-X2 TLB */ -#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_CACHABLE | \ - _PAGE_ACCESSED | _PAGE_FLAGS_HARD) - -#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \ - _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \ - _PAGE_EXT(_PAGE_EXT_USER_READ | \ - _PAGE_EXT_USER_WRITE)) - -#define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \ - _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \ - _PAGE_EXT(_PAGE_EXT_USER_EXEC | \ - _PAGE_EXT_USER_READ)) - -#define PAGE_COPY PAGE_EXECREAD - -#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \ - _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \ - _PAGE_EXT(_PAGE_EXT_USER_READ)) - -#define PAGE_WRITEONLY __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \ - _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \ - _PAGE_EXT(_PAGE_EXT_USER_WRITE)) - -#define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \ - _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \ - _PAGE_EXT(_PAGE_EXT_USER_WRITE | \ - _PAGE_EXT_USER_READ | \ - _PAGE_EXT_USER_EXEC)) - -#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_CACHABLE | \ - _PAGE_DIRTY | _PAGE_ACCESSED | \ - _PAGE_HW_SHARED | _PAGE_FLAGS_HARD | \ - _PAGE_EXT(_PAGE_EXT_KERN_READ | \ - _PAGE_EXT_KERN_WRITE | \ - _PAGE_EXT_KERN_EXEC)) - +#ifdef CONFIG_MMU +#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_CACHABLE |_PAGE_ACCESSED | _PAGE_FLAGS_HARD) +#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_CACHABLE |_PAGE_ACCESSED | _PAGE_FLAGS_HARD) +#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_CACHABLE | _PAGE_ACCESSED | _PAGE_FLAGS_HARD) +#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_CACHABLE | _PAGE_ACCESSED | _PAGE_FLAGS_HARD) +#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_CACHABLE | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_HW_SHARED | _PAGE_FLAGS_HARD) #define PAGE_KERNEL_NOCACHE \ - __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | \ - _PAGE_ACCESSED | _PAGE_HW_SHARED | \ - _PAGE_FLAGS_HARD | \ - _PAGE_EXT(_PAGE_EXT_KERN_READ | \ - _PAGE_EXT_KERN_WRITE | \ - _PAGE_EXT_KERN_EXEC)) - -#define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_CACHABLE | \ - _PAGE_DIRTY | _PAGE_ACCESSED | \ - _PAGE_HW_SHARED | _PAGE_FLAGS_HARD | \ - _PAGE_EXT(_PAGE_EXT_KERN_READ | \ - _PAGE_EXT_KERN_EXEC)) - -#define PAGE_KERNEL_PCC(slot, type) \ - __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | \ - _PAGE_ACCESSED | _PAGE_FLAGS_HARD | \ - _PAGE_EXT(_PAGE_EXT_KERN_READ | \ - _PAGE_EXT_KERN_WRITE | \ - _PAGE_EXT_KERN_EXEC) \ - (slot ? _PAGE_PCC_AREA5 : _PAGE_PCC_AREA6) | \ - (type)) - -#elif defined(CONFIG_MMU) /* SH-X TLB */ -#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_CACHABLE | \ - _PAGE_ACCESSED | _PAGE_FLAGS_HARD) - -#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \ - _PAGE_CACHABLE | _PAGE_ACCESSED | \ - _PAGE_FLAGS_HARD) - -#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_CACHABLE | \ - _PAGE_ACCESSED | _PAGE_FLAGS_HARD) - -#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_CACHABLE | \ - _PAGE_ACCESSED | _PAGE_FLAGS_HARD) - -#define PAGE_EXECREAD PAGE_READONLY -#define PAGE_RWX PAGE_SHARED -#define PAGE_WRITEONLY PAGE_SHARED - -#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_CACHABLE | \ - _PAGE_DIRTY | _PAGE_ACCESSED | \ - _PAGE_HW_SHARED | _PAGE_FLAGS_HARD) - -#define PAGE_KERNEL_NOCACHE \ - __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | \ - _PAGE_ACCESSED | _PAGE_HW_SHARED | \ - _PAGE_FLAGS_HARD) - -#define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_CACHABLE | \ - _PAGE_DIRTY | _PAGE_ACCESSED | \ - _PAGE_HW_SHARED | _PAGE_FLAGS_HARD) - + __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_HW_SHARED | _PAGE_FLAGS_HARD) +#define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_CACHABLE | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_HW_SHARED | _PAGE_FLAGS_HARD) #define PAGE_KERNEL_PCC(slot, type) \ - __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | \ - _PAGE_ACCESSED | _PAGE_FLAGS_HARD | \ - (slot ? _PAGE_PCC_AREA5 : _PAGE_PCC_AREA6) | \ - (type)) + __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_FLAGS_HARD | (slot ? _PAGE_PCC_AREA5 : _PAGE_PCC_AREA6) | (type)) #else /* no mmu */ #define PAGE_NONE __pgprot(0) #define PAGE_SHARED __pgprot(0) #define PAGE_COPY __pgprot(0) -#define PAGE_EXECREAD __pgprot(0) -#define PAGE_RWX __pgprot(0) #define PAGE_READONLY __pgprot(0) -#define PAGE_WRITEONLY __pgprot(0) #define PAGE_KERNEL __pgprot(0) #define PAGE_KERNEL_NOCACHE __pgprot(0) #define PAGE_KERNEL_RO __pgprot(0) @@ -323,32 +154,27 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; #endif /* __ASSEMBLY__ */ /* - * SH-X and lower (legacy) SuperH parts (SH-3, SH-4, some SH-4A) can't do page - * protection for execute, and considers it the same as a read. Also, write - * permission implies read permission. This is the closest we can get.. - * - * SH-X2 (SH7785) and later parts take this to the opposite end of the extreme, - * not only supporting separate execute, read, and write bits, but having - * completely separate permission bits for user and kernel space. + * As i386 and MIPS, SuperH can't do page protection for execute, and + * considers that the same as a read. Also, write permissions imply + * read permissions. This is the closest we can get.. */ - /*xwr*/ #define __P000 PAGE_NONE #define __P001 PAGE_READONLY #define __P010 PAGE_COPY #define __P011 PAGE_COPY -#define __P100 PAGE_EXECREAD -#define __P101 PAGE_EXECREAD +#define __P100 PAGE_READONLY +#define __P101 PAGE_READONLY #define __P110 PAGE_COPY #define __P111 PAGE_COPY #define __S000 PAGE_NONE #define __S001 PAGE_READONLY -#define __S010 PAGE_WRITEONLY +#define __S010 PAGE_SHARED #define __S011 PAGE_SHARED -#define __S100 PAGE_EXECREAD -#define __S101 PAGE_EXECREAD -#define __S110 PAGE_RWX -#define __S111 PAGE_RWX +#define __S100 PAGE_READONLY +#define __S101 PAGE_READONLY +#define __S110 PAGE_SHARED +#define __S111 PAGE_SHARED #ifndef __ASSEMBLY__ @@ -357,17 +183,7 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; * within a page table are directly modified. Thus, the following * hook is made available. */ -#ifdef CONFIG_X2TLB -static inline void set_pte(pte_t *ptep, pte_t pte) -{ - ptep->pte_high = pte.pte_high; - smp_wmb(); - ptep->pte_low = pte.pte_low; -} -#else #define set_pte(pteptr, pteval) (*(pteptr) = pteval) -#endif - #define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) /* @@ -376,18 +192,18 @@ static inline void set_pte(pte_t *ptep, pte_t pte) */ #define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval) -#define pte_pfn(x) ((unsigned long)(((x).pte_low >> PAGE_SHIFT))) +#define pte_pfn(x) ((unsigned long)(((x).pte >> PAGE_SHIFT))) #define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) #define pfn_pmd(pfn, prot) __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) #define pte_none(x) (!pte_val(x)) #define pte_present(x) (pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE)) -#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) +#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) #define pmd_none(x) (!pmd_val(x)) -#define pmd_present(x) (pmd_val(x)) +#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT) #define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) -#define pmd_bad(x) (pmd_val(x) & ~PAGE_MASK) +#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE) #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) #define pte_page(x) phys_to_page(pte_val(x)&PTE_PHYS_MASK) @@ -396,52 +212,28 @@ static inline void set_pte(pte_t *ptep, pte_t pte) * The following only work if pte_present() is true. * Undefined behaviour if not.. */ -#define pte_not_present(pte) (!(pte_val(pte) & _PAGE_PRESENT)) -#define pte_dirty(pte) (pte_val(pte) & _PAGE_DIRTY) -#define pte_young(pte) (pte_val(pte) & _PAGE_ACCESSED) -#define pte_file(pte) (pte_val(pte) & _PAGE_FILE) - -#ifdef CONFIG_X2TLB -#define pte_read(pte) ((pte).pte_high & _PAGE_EXT_USER_READ) -#define pte_exec(pte) ((pte).pte_high & _PAGE_EXT_USER_EXEC) -#define pte_write(pte) ((pte).pte_high & _PAGE_EXT_USER_WRITE) -#else -#define pte_read(pte) (pte_val(pte) & _PAGE_USER) -#define pte_exec(pte) (pte_val(pte) & _PAGE_USER) -#define pte_write(pte) (pte_val(pte) & _PAGE_RW) +static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; } +static inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_USER; } +static inline int pte_dirty(pte_t pte){ return pte_val(pte) & _PAGE_DIRTY; } +static inline int pte_young(pte_t pte){ return pte_val(pte) & _PAGE_ACCESSED; } +static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } +static inline int pte_write(pte_t pte){ return pte_val(pte) & _PAGE_RW; } +static inline int pte_not_present(pte_t pte){ return !(pte_val(pte) & _PAGE_PRESENT); } + +static inline pte_t pte_rdprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; } +static inline pte_t pte_exprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; } +static inline pte_t pte_mkclean(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; } +static inline pte_t pte_mkold(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; } +static inline pte_t pte_wrprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_RW)); return pte; } +static inline pte_t pte_mkread(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; } +static inline pte_t pte_mkexec(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; } +static inline pte_t pte_mkdirty(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; } +static inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; } +static inline pte_t pte_mkwrite(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; } +#ifdef CONFIG_HUGETLB_PAGE +static inline pte_t pte_mkhuge(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_SZHUGE)); return pte; } #endif -#define PTE_BIT_FUNC(h,fn,op) \ -static inline pte_t pte_##fn(pte_t pte) { pte.pte_##h op; return pte; } - -#ifdef CONFIG_X2TLB -/* - * We cheat a bit in the SH-X2 TLB case. As the permission bits are - * individually toggled (and user permissions are entirely decoupled from - * kernel permissions), we attempt to couple them a bit more sanely here. - */ -PTE_BIT_FUNC(high, rdprotect, &= ~_PAGE_EXT_USER_READ); -PTE_BIT_FUNC(high, mkread, |= _PAGE_EXT_USER_READ | _PAGE_EXT_KERN_READ); -PTE_BIT_FUNC(high, wrprotect, &= ~_PAGE_EXT_USER_WRITE); -PTE_BIT_FUNC(high, mkwrite, |= _PAGE_EXT_USER_WRITE | _PAGE_EXT_KERN_WRITE); -PTE_BIT_FUNC(high, exprotect, &= ~_PAGE_EXT_USER_EXEC); -PTE_BIT_FUNC(high, mkexec, |= _PAGE_EXT_USER_EXEC | _PAGE_EXT_KERN_EXEC); -PTE_BIT_FUNC(high, mkhuge, |= _PAGE_SZHUGE); -#else -PTE_BIT_FUNC(low, rdprotect, &= ~_PAGE_USER); -PTE_BIT_FUNC(low, mkread, |= _PAGE_USER); -PTE_BIT_FUNC(low, wrprotect, &= ~_PAGE_RW); -PTE_BIT_FUNC(low, mkwrite, |= _PAGE_RW); -PTE_BIT_FUNC(low, exprotect, &= ~_PAGE_USER); -PTE_BIT_FUNC(low, mkexec, |= _PAGE_USER); -PTE_BIT_FUNC(low, mkhuge, |= _PAGE_SZHUGE); -#endif - -PTE_BIT_FUNC(low, mkclean, &= ~_PAGE_DIRTY); -PTE_BIT_FUNC(low, mkdirty, |= _PAGE_DIRTY); -PTE_BIT_FUNC(low, mkold, &= ~_PAGE_ACCESSED); -PTE_BIT_FUNC(low, mkyoung, |= _PAGE_ACCESSED); - /* * Macro and implementation to make a page protection as uncachable. */ @@ -466,14 +258,13 @@ static inline pgprot_t pgprot_noncached(pgprot_t _prot) #define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) -{ - set_pte(&pte, __pte((pte_val(pte) & _PAGE_CHG_MASK) | - pgprot_val(newprot))); - return pte; -} +{ set_pte(&pte, __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot))); return pte; } + +#define pmd_page_vaddr(pmd) \ +((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) -#define pmd_page_vaddr(pmd) pmd_val(pmd) -#define pmd_page(pmd) (virt_to_page(pmd_val(pmd))) +#define pmd_page(pmd) \ + (phys_to_page(pmd_val(pmd))) /* to find an entry in a page-table-directory. */ #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) @@ -492,15 +283,8 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) #define pte_unmap(pte) do { } while (0) #define pte_unmap_nested(pte) do { } while (0) -#ifdef CONFIG_X2TLB -#define pte_ERROR(e) \ - printk("%s:%d: bad pte %p(%08lx%08lx).\n", __FILE__, __LINE__, \ - &(e), (e).pte_high, (e).pte_low) -#else #define pte_ERROR(e) \ printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) -#endif - #define pgd_ERROR(e) \ printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) @@ -553,9 +337,6 @@ extern unsigned int kobjsize(const void *objp); extern pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep); #endif -extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; -extern void paging_init(void); - #include #endif /* !__ASSEMBLY__ */ diff --git a/trunk/include/asm-sh/processor.h b/trunk/include/asm-sh/processor.h index 6f1dd7ca1b1d..45bb74e35d32 100644 --- a/trunk/include/asm-sh/processor.h +++ b/trunk/include/asm-sh/processor.h @@ -36,10 +36,7 @@ */ enum cpu_type { /* SH-2 types */ - CPU_SH7604, CPU_SH7619, - - /* SH-2A types */ - CPU_SH7206, + CPU_SH7604, /* SH-3 types */ CPU_SH7705, CPU_SH7706, CPU_SH7707, @@ -50,10 +47,7 @@ enum cpu_type { /* SH-4 types */ CPU_SH7750, CPU_SH7750S, CPU_SH7750R, CPU_SH7751, CPU_SH7751R, CPU_SH7760, CPU_ST40RA, CPU_ST40GX1, CPU_SH4_202, CPU_SH4_501, - - /* SH-4A types */ CPU_SH73180, CPU_SH7343, CPU_SH7770, CPU_SH7780, CPU_SH7781, - CPU_SH7785, /* Unknown subtype */ CPU_SH_NONE @@ -136,11 +130,12 @@ union sh_fpu_union { }; struct thread_struct { - /* Saved registers when thread is descheduled */ unsigned long sp; unsigned long pc; - /* Hardware debugging registers */ + unsigned long trap_no, error_code; + unsigned long address; + /* Hardware debugging registers may come here */ unsigned long ubc_pc; /* floating point info */ @@ -155,7 +150,12 @@ typedef struct { extern int ubc_usercnt; #define INIT_THREAD { \ - .sp = sizeof(init_stack) + (long) &init_stack, \ + sizeof(init_stack) + (long) &init_stack, /* sp */ \ + 0, /* pc */ \ + 0, 0, \ + 0, \ + 0, \ + {{{0,}},} /* fpu state */ \ } /* @@ -259,8 +259,8 @@ void show_trace(struct task_struct *tsk, unsigned long *sp, struct pt_regs *regs); extern unsigned long get_wchan(struct task_struct *p); -#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc) -#define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[15]) +#define KSTK_EIP(tsk) ((tsk)->thread.pc) +#define KSTK_ESP(tsk) ((tsk)->thread.sp) #define cpu_sleep() __asm__ __volatile__ ("sleep" : : : "memory") #define cpu_relax() barrier() diff --git a/trunk/include/asm-sh/push-switch.h b/trunk/include/asm-sh/push-switch.h deleted file mode 100644 index dfc6bad567f0..000000000000 --- a/trunk/include/asm-sh/push-switch.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef __ASM_SH_PUSH_SWITCH_H -#define __ASM_SH_PUSH_SWITCH_H - -#include -#include -#include - -struct push_switch { - /* switch state */ - unsigned int state:1; - /* debounce timer */ - struct timer_list debounce; - /* workqueue */ - struct work_struct work; -}; - -struct push_switch_platform_info { - /* IRQ handler */ - irqreturn_t (*irq_handler)(int irq, void *data); - /* Special IRQ flags */ - unsigned int irq_flags; - /* Bit location of switch */ - unsigned int bit; - /* Symbolic switch name */ - const char *name; -}; - -#endif /* __ASM_SH_PUSH_SWITCH_H */ diff --git a/trunk/include/asm-sh/rwsem.h b/trunk/include/asm-sh/rwsem.h index 4931ba817d73..9d2aea5e8488 100644 --- a/trunk/include/asm-sh/rwsem.h +++ b/trunk/include/asm-sh/rwsem.h @@ -25,21 +25,11 @@ struct rw_semaphore { #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) spinlock_t wait_lock; struct list_head wait_list; -#ifdef CONFIG_DEBUG_LOCK_ALLOC - struct lockdep_map dep_map; -#endif }; -#ifdef CONFIG_DEBUG_LOCK_ALLOC -# define __RWSEM_DEP_MAP_INIT(lockname) , .dep_map = { .name = #lockname } -#else -# define __RWSEM_DEP_MAP_INIT(lockname) -#endif - #define __RWSEM_INITIALIZER(name) \ { RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \ - LIST_HEAD_INIT((name).wait_list) \ - __RWSEM_DEP_MAP_INIT(name) } + LIST_HEAD_INIT((name).wait_list) } #define DECLARE_RWSEM(name) \ struct rw_semaphore name = __RWSEM_INITIALIZER(name) @@ -49,16 +39,6 @@ extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem); extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem); extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem); -extern void __init_rwsem(struct rw_semaphore *sem, const char *name, - struct lock_class_key *key); - -#define init_rwsem(sem) \ -do { \ - static struct lock_class_key __key; \ - \ - __init_rwsem((sem), #sem, &__key); \ -} while (0) - static inline void init_rwsem(struct rw_semaphore *sem) { sem->count = RWSEM_UNLOCKED_VALUE; @@ -161,11 +141,6 @@ static inline void __downgrade_write(struct rw_semaphore *sem) rwsem_downgrade_wake(sem); } -static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) -{ - __down_write(sem); -} - /* * implement exchange and add functionality */ diff --git a/trunk/include/asm-sh/se7206.h b/trunk/include/asm-sh/se7206.h deleted file mode 100644 index 698eb80389ab..000000000000 --- a/trunk/include/asm-sh/se7206.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __ASM_SH_SE7206_H -#define __ASM_SH_SE7206_H - -#define PA_SMSC 0x30000000 -#define PA_MRSHPC 0x34000000 -#define PA_LED 0x31400000 - -void init_se7206_IRQ(void); - -#define __IO_PREFIX se7206 -#include - -#endif /* __ASM_SH_SE7206_H */ diff --git a/trunk/include/asm-sh/system.h b/trunk/include/asm-sh/system.h index b1e42e7f998b..3340126f4e0f 100644 --- a/trunk/include/asm-sh/system.h +++ b/trunk/include/asm-sh/system.h @@ -6,7 +6,6 @@ * Copyright (C) 2002 Paul Mundt */ -#include #include /* @@ -132,6 +131,103 @@ static inline unsigned long tas(volatile int *m) #define set_mb(var, value) do { xchg(&var, value); } while (0) +/* Interrupt Control */ +#ifdef CONFIG_CPU_HAS_SR_RB +static inline void local_irq_enable(void) +{ + unsigned long __dummy0, __dummy1; + + __asm__ __volatile__("stc sr, %0\n\t" + "and %1, %0\n\t" + "stc r6_bank, %1\n\t" + "or %1, %0\n\t" + "ldc %0, sr" + : "=&r" (__dummy0), "=r" (__dummy1) + : "1" (~0x000000f0) + : "memory"); +} +#else +static inline void local_irq_enable(void) +{ + unsigned long __dummy0, __dummy1; + + __asm__ __volatile__ ( + "stc sr, %0\n\t" + "and %1, %0\n\t" + "ldc %0, sr\n\t" + : "=&r" (__dummy0), "=r" (__dummy1) + : "1" (~0x000000f0) + : "memory"); +} +#endif + +static inline void local_irq_disable(void) +{ + unsigned long __dummy; + __asm__ __volatile__("stc sr, %0\n\t" + "or #0xf0, %0\n\t" + "ldc %0, sr" + : "=&z" (__dummy) + : /* no inputs */ + : "memory"); +} + +static inline void set_bl_bit(void) +{ + unsigned long __dummy0, __dummy1; + + __asm__ __volatile__ ("stc sr, %0\n\t" + "or %2, %0\n\t" + "and %3, %0\n\t" + "ldc %0, sr" + : "=&r" (__dummy0), "=r" (__dummy1) + : "r" (0x10000000), "r" (0xffffff0f) + : "memory"); +} + +static inline void clear_bl_bit(void) +{ + unsigned long __dummy0, __dummy1; + + __asm__ __volatile__ ("stc sr, %0\n\t" + "and %2, %0\n\t" + "ldc %0, sr" + : "=&r" (__dummy0), "=r" (__dummy1) + : "1" (~0x10000000) + : "memory"); +} + +#define local_save_flags(x) \ + __asm__("stc sr, %0; and #0xf0, %0" : "=&z" (x) :/**/: "memory" ) + +#define irqs_disabled() \ +({ \ + unsigned long flags; \ + local_save_flags(flags); \ + (flags != 0); \ +}) + +static inline unsigned long local_irq_save(void) +{ + unsigned long flags, __dummy; + + __asm__ __volatile__("stc sr, %1\n\t" + "mov %1, %0\n\t" + "or #0xf0, %0\n\t" + "ldc %0, sr\n\t" + "mov %1, %0\n\t" + "and #0xf0, %0" + : "=&z" (flags), "=&r" (__dummy) + :/**/ + : "memory" ); + return flags; +} + +#define local_irq_restore(x) do { \ + if ((x & 0x000000f0) != 0x000000f0) \ + local_irq_enable(); \ +} while (0) + /* * Jump to P2 area. * When handling TLB or caches, we need to do it from P2 area. @@ -168,6 +264,9 @@ do { \ : "=&r" (__dummy)); \ } while (0) +/* For spinlocks etc */ +#define local_irq_save(x) x = local_irq_save() + static inline unsigned long xchg_u32(volatile u32 *m, unsigned long val) { unsigned long flags, retval; diff --git a/trunk/include/asm-sh/thread_info.h b/trunk/include/asm-sh/thread_info.h index 0c01dc550819..3ebc3f9039eb 100644 --- a/trunk/include/asm-sh/thread_info.h +++ b/trunk/include/asm-sh/thread_info.h @@ -90,7 +90,13 @@ static inline struct thread_info *current_thread_info(void) #endif #define free_thread_info(ti) kfree(ti) -#endif /* __ASSEMBLY__ */ +#else /* !__ASSEMBLY__ */ + +/* how to get the thread information struct from ASM */ +#define GET_THREAD_INFO(reg) \ + stc r7_bank, reg + +#endif /* * thread information flags diff --git a/trunk/include/asm-sh/timer.h b/trunk/include/asm-sh/timer.h index 17b5e76a4c31..5df842bcf7b6 100644 --- a/trunk/include/asm-sh/timer.h +++ b/trunk/include/asm-sh/timer.h @@ -18,32 +18,11 @@ struct sys_timer { struct sys_device dev; struct sys_timer_ops *ops; - -#ifdef CONFIG_NO_IDLE_HZ - struct dyn_tick_timer *dyn_tick; -#endif }; -#ifdef CONFIG_NO_IDLE_HZ -#define DYN_TICK_ENABLED (1 << 1) - -struct dyn_tick_timer { - spinlock_t lock; - unsigned int state; /* Current state */ - int (*enable)(void); /* Enables dynamic tick */ - int (*disable)(void); /* Disables dynamic tick */ - void (*reprogram)(unsigned long); /* Reprograms the timer */ - int (*handler)(int, void *); -}; - -void timer_dyn_reprogram(void); -#else -#define timer_dyn_reprogram() do { } while (0) -#endif - #define TICK_SIZE (tick_nsec / 1000) -extern struct sys_timer tmu_timer, cmt_timer, mtu2_timer; +extern struct sys_timer tmu_timer; extern struct sys_timer *sys_timer; #ifndef CONFIG_GENERIC_TIME diff --git a/trunk/include/asm-sh/titan.h b/trunk/include/asm-sh/titan.h index 03f3583c8918..270a4f4bc8a9 100644 --- a/trunk/include/asm-sh/titan.h +++ b/trunk/include/asm-sh/titan.h @@ -1,8 +1,9 @@ /* * Platform defintions for Titan */ -#ifndef _ASM_SH_TITAN_H -#define _ASM_SH_TITAN_H + +#ifndef _ASM_SH_TITAN_TITAN_H +#define _ASM_SH_TITAN_TITAN_H #define __IO_PREFIX titan #include @@ -14,4 +15,29 @@ #define TITAN_IRQ_MPCIB 11 /* mPCI B */ #define TITAN_IRQ_USB 11 /* USB */ -#endif /* __ASM_SH_TITAN_H */ +/* + * The external interrupt lines, these take up ints 0 - 15 inclusive + * depending on the priority for the interrupt. In fact the priority + * is the interrupt :-) + */ +#define IRL0_IRQ 0 +#define IRL0_IPR_ADDR INTC_IPRD +#define IRL0_IPR_POS 3 +#define IRL0_PRIORITY 8 + +#define IRL1_IRQ 1 +#define IRL1_IPR_ADDR INTC_IPRD +#define IRL1_IPR_POS 2 +#define IRL1_PRIORITY 8 + +#define IRL2_IRQ 2 +#define IRL2_IPR_ADDR INTC_IPRD +#define IRL2_IPR_POS 1 +#define IRL2_PRIORITY 8 + +#define IRL3_IRQ 3 +#define IRL3_IPR_ADDR INTC_IPRD +#define IRL3_IPR_POS 0 +#define IRL3_PRIORITY 8 + +#endif diff --git a/trunk/include/asm-sh/unistd.h b/trunk/include/asm-sh/unistd.h index 0cae1d248761..1c2abde122cd 100644 --- a/trunk/include/asm-sh/unistd.h +++ b/trunk/include/asm-sh/unistd.h @@ -349,30 +349,12 @@ do { \ return (type) (res); \ } while (0) -#if defined(__sh2__) || defined(__SH2E__) || defined(__SH2A__) -#define SYSCALL_ARG0 "trapa #0x20" -#define SYSCALL_ARG1 "trapa #0x21" -#define SYSCALL_ARG2 "trapa #0x22" -#define SYSCALL_ARG3 "trapa #0x23" -#define SYSCALL_ARG4 "trapa #0x24" -#define SYSCALL_ARG5 "trapa #0x25" -#define SYSCALL_ARG6 "trapa #0x26" -#else -#define SYSCALL_ARG0 "trapa #0x10" -#define SYSCALL_ARG1 "trapa #0x11" -#define SYSCALL_ARG2 "trapa #0x12" -#define SYSCALL_ARG3 "trapa #0x13" -#define SYSCALL_ARG4 "trapa #0x14" -#define SYSCALL_ARG5 "trapa #0x15" -#define SYSCALL_ARG6 "trapa #0x16" -#endif - /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ #define _syscall0(type,name) \ type name(void) \ { \ register long __sc0 __asm__ ("r3") = __NR_##name; \ -__asm__ __volatile__ (SYSCALL_ARG0 \ +__asm__ __volatile__ ("trapa #0x10" \ : "=z" (__sc0) \ : "0" (__sc0) \ : "memory" ); \ @@ -384,7 +366,7 @@ type name(type1 arg1) \ { \ register long __sc0 __asm__ ("r3") = __NR_##name; \ register long __sc4 __asm__ ("r4") = (long) arg1; \ -__asm__ __volatile__ (SYSCALL_ARG1 \ +__asm__ __volatile__ ("trapa #0x11" \ : "=z" (__sc0) \ : "0" (__sc0), "r" (__sc4) \ : "memory"); \ @@ -397,7 +379,7 @@ type name(type1 arg1,type2 arg2) \ register long __sc0 __asm__ ("r3") = __NR_##name; \ register long __sc4 __asm__ ("r4") = (long) arg1; \ register long __sc5 __asm__ ("r5") = (long) arg2; \ -__asm__ __volatile__ (SYSCALL_ARG2 \ +__asm__ __volatile__ ("trapa #0x12" \ : "=z" (__sc0) \ : "0" (__sc0), "r" (__sc4), "r" (__sc5) \ : "memory"); \ @@ -411,7 +393,7 @@ register long __sc0 __asm__ ("r3") = __NR_##name; \ register long __sc4 __asm__ ("r4") = (long) arg1; \ register long __sc5 __asm__ ("r5") = (long) arg2; \ register long __sc6 __asm__ ("r6") = (long) arg3; \ -__asm__ __volatile__ (SYSCALL_ARG3 \ +__asm__ __volatile__ ("trapa #0x13" \ : "=z" (__sc0) \ : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6) \ : "memory"); \ @@ -426,7 +408,7 @@ register long __sc4 __asm__ ("r4") = (long) arg1; \ register long __sc5 __asm__ ("r5") = (long) arg2; \ register long __sc6 __asm__ ("r6") = (long) arg3; \ register long __sc7 __asm__ ("r7") = (long) arg4; \ -__asm__ __volatile__ (SYSCALL_ARG4 \ +__asm__ __volatile__ ("trapa #0x14" \ : "=z" (__sc0) \ : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6), \ "r" (__sc7) \ @@ -443,7 +425,7 @@ register long __sc5 __asm__ ("r5") = (long) arg2; \ register long __sc6 __asm__ ("r6") = (long) arg3; \ register long __sc7 __asm__ ("r7") = (long) arg4; \ register long __sc0 __asm__ ("r0") = (long) arg5; \ -__asm__ __volatile__ (SYSCALL_ARG5 \ +__asm__ __volatile__ ("trapa #0x15" \ : "=z" (__sc0) \ : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6), "r" (__sc7), \ "r" (__sc3) \ @@ -461,7 +443,7 @@ register long __sc6 __asm__ ("r6") = (long) arg3; \ register long __sc7 __asm__ ("r7") = (long) arg4; \ register long __sc0 __asm__ ("r0") = (long) arg5; \ register long __sc1 __asm__ ("r1") = (long) arg6; \ -__asm__ __volatile__ (SYSCALL_ARG6 \ +__asm__ __volatile__ ("trapa #0x16" \ : "=z" (__sc0) \ : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6), "r" (__sc7), \ "r" (__sc3), "r" (__sc1) \ diff --git a/trunk/include/asm-x86_64/atomic.h b/trunk/include/asm-x86_64/atomic.h index 93849f7abc24..007e88d6d43f 100644 --- a/trunk/include/asm-x86_64/atomic.h +++ b/trunk/include/asm-x86_64/atomic.h @@ -21,7 +21,7 @@ * on us. We need to use _exactly_ the address the user gave us, * not some alias that contains the same information. */ -typedef struct { int counter; } atomic_t; +typedef struct { volatile int counter; } atomic_t; #define ATOMIC_INIT(i) { (i) } diff --git a/trunk/include/asm-x86_64/spinlock_types.h b/trunk/include/asm-x86_64/spinlock_types.h index 4da9345c1500..59efe849f351 100644 --- a/trunk/include/asm-x86_64/spinlock_types.h +++ b/trunk/include/asm-x86_64/spinlock_types.h @@ -6,13 +6,13 @@ #endif typedef struct { - unsigned int slock; + volatile unsigned int slock; } raw_spinlock_t; #define __RAW_SPIN_LOCK_UNLOCKED { 1 } typedef struct { - unsigned int lock; + volatile unsigned int lock; } raw_rwlock_t; #define __RAW_RW_LOCK_UNLOCKED { RW_LOCK_BIAS } 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)