diff --git a/[refs] b/[refs] index f96a7a7cec31..2f30ba8d50a2 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: a052f4473603765eb6b4c19754689977601dc1d1 +refs/heads/master: 3bba11e5c47dfc1d381a1ece26464fb7eea2d79c diff --git a/trunk/Documentation/accounting/getdelays.c b/trunk/Documentation/accounting/getdelays.c index d6cb1a86fd61..ab82b7f53312 100644 --- a/trunk/Documentation/accounting/getdelays.c +++ b/trunk/Documentation/accounting/getdelays.c @@ -25,7 +25,6 @@ #include #include -#include /* * Generic macros for dealing with netlink sockets. Might be duplicated @@ -79,7 +78,6 @@ static void usage(void) fprintf(stderr, " -i: print IO accounting (works only with -p)\n"); fprintf(stderr, " -l: listen forever\n"); fprintf(stderr, " -v: debug on\n"); - fprintf(stderr, " -C: container path\n"); } /* @@ -214,14 +212,6 @@ void task_context_switch_counts(struct taskstats *t) t->nvcsw, t->nivcsw); } -void print_cgroupstats(struct cgroupstats *c) -{ - printf("sleeping %llu, blocked %llu, running %llu, stopped %llu, " - "uninterruptible %llu\n", c->nr_sleeping, c->nr_io_wait, - c->nr_running, c->nr_stopped, c->nr_uninterruptible); -} - - void print_ioacct(struct taskstats *t) { printf("%s: read=%llu, write=%llu, cancelled_write=%llu\n", @@ -249,14 +239,11 @@ int main(int argc, char *argv[]) int maskset = 0; char *logfile = NULL; int loop = 0; - int containerset = 0; - char containerpath[1024]; - int cfd = 0; struct msgtemplate msg; while (1) { - c = getopt(argc, argv, "qdiw:r:m:t:p:vlC:"); + c = getopt(argc, argv, "qdiw:r:m:t:p:vl"); if (c < 0) break; @@ -273,10 +260,6 @@ int main(int argc, char *argv[]) printf("printing task/process context switch rates\n"); print_task_context_switch_counts = 1; break; - case 'C': - containerset = 1; - strncpy(containerpath, optarg, strlen(optarg) + 1); - break; case 'w': logfile = strdup(optarg); printf("write to file %s\n", logfile); @@ -351,11 +334,6 @@ int main(int argc, char *argv[]) } } - if (tid && containerset) { - fprintf(stderr, "Select either -t or -C, not both\n"); - goto err; - } - if (tid) { rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET, cmd_type, &tid, sizeof(__u32)); @@ -366,20 +344,6 @@ int main(int argc, char *argv[]) } } - if (containerset) { - cfd = open(containerpath, O_RDONLY); - if (cfd < 0) { - perror("error opening container file"); - goto err; - } - rc = send_cmd(nl_sd, id, mypid, CGROUPSTATS_CMD_GET, - CGROUPSTATS_CMD_ATTR_FD, &cfd, sizeof(__u32)); - if (rc < 0) { - perror("error sending cgroupstats command"); - goto err; - } - } - do { int i; @@ -458,9 +422,6 @@ int main(int argc, char *argv[]) } break; - case CGROUPSTATS_TYPE_CGROUP_STATS: - print_cgroupstats(NLA_DATA(na)); - break; default: fprintf(stderr, "Unknown nla_type %d\n", na->nla_type); @@ -482,7 +443,5 @@ int main(int argc, char *argv[]) close(nl_sd); if (fd) close(fd); - if (cfd) - close(cfd); return 0; } diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index 20c4c8bac9d7..6bb9be54ab76 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -181,6 +181,15 @@ Who: Nick Piggin --------------------------- +What: Interrupt only SA_* flags +When: September 2007 +Why: The interrupt related SA_* flags are replaced by IRQF_* to move them + out of the signal namespace. + +Who: Thomas Gleixner + +--------------------------- + What: PHYSDEVPATH, PHYSDEVBUS, PHYSDEVDRIVER in the uevent environment When: October 2008 Why: The stacking of class devices makes these values misleading and diff --git a/trunk/Documentation/markers.txt b/trunk/Documentation/markers.txt index d9f50a19fa0c..295a71bc301e 100644 --- a/trunk/Documentation/markers.txt +++ b/trunk/Documentation/markers.txt @@ -35,14 +35,12 @@ In order to use the macro trace_mark, you should include linux/marker.h. And, -trace_mark(subsystem_event, "myint %d mystring %s", someint, somestring); +trace_mark(subsystem_event, "%d %s", someint, somestring); Where : - subsystem_event is an identifier unique to your event - subsystem is the name of your subsystem. - event is the name of the event to mark. -- "myint %d mystring %s" is the formatted string for the serializer. "myint" and - "mystring" are repectively the field names associated with the first and - second parameter. +- "%d %s" is the formatted string for the serializer. - someint is an integer. - somestring is a char pointer. diff --git a/trunk/Documentation/rtc.txt b/trunk/Documentation/rtc.txt index e20b19c1b60d..c931d613f641 100644 --- a/trunk/Documentation/rtc.txt +++ b/trunk/Documentation/rtc.txt @@ -180,10 +180,9 @@ driver returns ENOIOCTLCMD. Some common examples: * RTC_IRQP_SET, RTC_IRQP_READ: the irq_set_freq function will be called to set the frequency while the framework will handle the read for you since the frequency is stored in the irq_freq member of the rtc_device - structure. Your driver needs to initialize the irq_freq member during - init. Make sure you check the requested frequency is in range of your - hardware in the irq_set_freq function. If you cannot actually change - the frequency, just return -ENOTTY. + structure. Also make sure you set the max_user_freq member in your + initialization routines so the framework can sanity check the user + input for you. If all else fails, check out the rtc-test.c driver! diff --git a/trunk/Makefile b/trunk/Makefile index 9c9c4bfb0e51..e28dde8887d7 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -197,15 +197,8 @@ CROSS_COMPILE ?= UTS_MACHINE := $(ARCH) SRCARCH := $(ARCH) -# Additional ARCH settings for x86 -ifeq ($(ARCH),i386) - SRCARCH := x86 - K64BIT := n -endif -ifeq ($(ARCH),x86_64) - SRCARCH := x86 - K64BIT := y -endif +# for i386 and x86_64 we use SRCARCH equal to x86 +SRCARCH := $(if $(filter x86_64 i386,$(SRCARCH)),x86,$(SRCARCH)) KCONFIG_CONFIG ?= .config @@ -341,7 +334,7 @@ KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null) KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION -export ARCH SRCARCH K64BIT CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC +export ARCH SRCARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC export CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS diff --git a/trunk/README b/trunk/README index 592f8a238281..159912cf5155 100644 --- a/trunk/README +++ b/trunk/README @@ -194,8 +194,6 @@ CONFIGURING the kernel: "make *config" checks for a file named "all{yes/mod/no/random}.config" for symbol values that are to be forced. If this file is not found, it checks for a file named "all.config" to contain forced values. - Finally it checks the environment variable K64BIT and if found, sets - the config symbol "64BIT" to the value of the K64BIT variable. NOTES on "make config": - having unnecessary drivers will make the kernel bigger, and can diff --git a/trunk/arch/cris/Kconfig b/trunk/arch/cris/Kconfig index 222da1501f47..21900a9378bb 100644 --- a/trunk/arch/cris/Kconfig +++ b/trunk/arch/cris/Kconfig @@ -13,10 +13,6 @@ config ZONE_DMA bool default y -config NO_DMA - bool - default y - config RWSEM_GENERIC_SPINLOCK bool default y @@ -61,10 +57,6 @@ menu "General setup" source "fs/Kconfig.binfmt" -config GENERIC_HARDIRQS - bool - default y - config ETRAX_CMDLINE string "Kernel command line" default "root=/dev/mtdblock3" @@ -157,8 +149,7 @@ source "net/Kconfig" # bring in ETRAX built-in drivers menu "Drivers for built-in interfaces" -# arch/cris/arch is a symlink to correct arch (arch-v10 or arch-v32) -source arch/cris/arch/drivers/Kconfig +source arch/cris/arch-v10/drivers/Kconfig endmenu @@ -189,10 +180,6 @@ source "drivers/isdn/Kconfig" source "drivers/telephony/Kconfig" -source "drivers/i2c/Kconfig" - -source "drivers/rtc/Kconfig" - # # input before char - char/joystick depends on it. As does USB. # @@ -207,10 +194,6 @@ source "fs/Kconfig" source "sound/Kconfig" -source "drivers/pcmcia/Kconfig" - -source "drivers/pci/Kconfig" - source "drivers/usb/Kconfig" source "kernel/Kconfig.instrumentation" diff --git a/trunk/arch/cris/arch-v10/defconfig b/trunk/arch/cris/arch-v10/defconfig index 572f11926399..710c20ba2be7 100644 --- a/trunk/arch/cris/arch-v10/defconfig +++ b/trunk/arch/cris/arch-v10/defconfig @@ -99,6 +99,7 @@ CONFIG_MTD=y CONFIG_MTD_CFI=y # CONFIG_MTD_CFI_INTELEXT is not set CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_AMDSTD=y CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_ETRAX_I2C=y @@ -144,6 +145,7 @@ CONFIG_MTD_CFI=y # CONFIG_MTD_CFI_GEOMETRY is not set # CONFIG_MTD_CFI_INTELEXT is not set CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_AMDSTD=y # CONFIG_MTD_SHARP is not set # CONFIG_MTD_PHYSMAP is not set # CONFIG_MTD_NORA is not set diff --git a/trunk/arch/cris/arch-v10/drivers/Kconfig b/trunk/arch/cris/arch-v10/drivers/Kconfig index faf8b4d3ca01..03e2e68f947d 100644 --- a/trunk/arch/cris/arch-v10/drivers/Kconfig +++ b/trunk/arch/cris/arch-v10/drivers/Kconfig @@ -2,7 +2,6 @@ config ETRAX_ETHERNET bool "Ethernet support" depends on ETRAX_ARCH_V10 select NET_ETHERNET - select MII help This option enables the ETRAX 100LX built-in 10/100Mbit Ethernet controller. @@ -606,6 +605,8 @@ config ETRAX_AXISFLASHMAP select MTD select MTD_CFI select MTD_CFI_AMDSTD + select MTD_OBSOLETE_CHIPS + select MTD_AMDSTD select MTD_CHAR select MTD_BLOCK select MTD_PARTITIONS diff --git a/trunk/arch/cris/arch-v10/drivers/axisflashmap.c b/trunk/arch/cris/arch-v10/drivers/axisflashmap.c index ea3cf2e39a14..efd7b0f3a910 100644 --- a/trunk/arch/cris/arch-v10/drivers/axisflashmap.c +++ b/trunk/arch/cris/arch-v10/drivers/axisflashmap.c @@ -312,12 +312,12 @@ static struct mtd_info *probe_cs(struct map_info *map_cs) "%s: Probing a 0x%08lx bytes large window at 0x%08lx.\n", map_cs->name, map_cs->size, map_cs->map_priv_1); -#ifdef CONFIG_MTD_CFI - mtd_cs = do_map_probe("cfi_probe", map_cs); +#ifdef CONFIG_MTD_AMDSTD + mtd_cs = do_map_probe("amd_flash", map_cs); #endif -#ifdef CONFIG_MTD_JEDECPROBE +#ifdef CONFIG_MTD_CFI if (!mtd_cs) { - mtd_cs = do_map_probe("jedec_probe", map_cs); + mtd_cs = do_map_probe("cfi_probe", map_cs); } #endif diff --git a/trunk/arch/cris/arch-v10/drivers/gpio.c b/trunk/arch/cris/arch-v10/drivers/gpio.c index 0d347a705835..f389ed6998fe 100644 --- a/trunk/arch/cris/arch-v10/drivers/gpio.c +++ b/trunk/arch/cris/arch-v10/drivers/gpio.c @@ -297,10 +297,8 @@ gpio_poll(struct file *file, data = *R_PORT_PB_DATA; else if (priv->minor == GPIO_MINOR_G) data = *R_PORT_G_DATA; - else { - spin_unlock(&gpio_lock); + else return 0; - } if ((data & priv->highalarm) || (~data & priv->lowalarm)) { @@ -383,21 +381,18 @@ static ssize_t gpio_write(struct file * file, const char * buf, size_t count, ssize_t retval = count; if (priv->minor !=GPIO_MINOR_A && priv->minor != GPIO_MINOR_B) { - retval = -EFAULT; - goto out; + return -EFAULT; } if (!access_ok(VERIFY_READ, buf, count)) { - retval = -EFAULT; - goto out; + return -EFAULT; } clk_mask = priv->clk_mask; data_mask = priv->data_mask; /* It must have been configured using the IO_CFG_WRITE_MODE */ /* Perhaps a better error code? */ if (clk_mask == 0 || data_mask == 0) { - retval = -EPERM; - goto out; + return -EPERM; } write_msb = priv->write_msb; D(printk("gpio_write: %lu to data 0x%02X clk 0x%02X msb: %i\n",count, data_mask, clk_mask, write_msb)); @@ -430,7 +425,6 @@ static ssize_t gpio_write(struct file * file, const char * buf, size_t count, } } } -out: spin_unlock(&gpio_lock); return retval; } @@ -512,7 +506,6 @@ gpio_release(struct inode *inode, struct file *filp) while (p) { if (p->highalarm | p->lowalarm) { gpio_some_alarms = 1; - spin_unlock(&gpio_lock); return 0; } p = p->next; diff --git a/trunk/arch/cris/arch-v10/kernel/entry.S b/trunk/arch/cris/arch-v10/kernel/entry.S index ec62c951fa3c..c5844cb70f09 100644 --- a/trunk/arch/cris/arch-v10/kernel/entry.S +++ b/trunk/arch/cris/arch-v10/kernel/entry.S @@ -500,8 +500,9 @@ _work_notifysig: ;; deal with pending signals and notify-resume requests move.d $r9, $r10 ; do_notify_resume syscall/irq param - move.d $sp, $r11 ; the regs param - move.d $r1, $r12 ; the thread_info_flags parameter + moveq 0, $r11 ; oldset param - 0 in this case + move.d $sp, $r12 ; the regs param + move.d $r1, $r13 ; the thread_info_flags parameter jsr do_notify_resume ba _Rexit @@ -677,19 +678,13 @@ IRQ1_interrupt: push $r10 ; push orig_r10 clear.d [$sp=$sp-4] ; frametype == 0, normal frame - ;; If there is a glitch on the NMI pin shorter than ~100ns - ;; (i.e. non-active by the time we get here) then the nmi_pin bit - ;; in R_IRQ_MASK0_RD will already be cleared. The watchdog_nmi bit - ;; is cleared by us however (when feeding the watchdog), which is why - ;; we use that bit to determine what brought us here. - move.d [R_IRQ_MASK0_RD], $r1 ; External NMI or watchdog? - and.d (1<<30), $r1 - bne wdog + and.d 0x80000000, $r1 + beq wdog move.d $sp, $r10 jsr handle_nmi setf m ; Enable NMI again - ba _Rexit ; Return the standard way + retb ; Return from NMI nop wdog: #if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM) @@ -780,9 +775,22 @@ multiple_interrupt: push $r10 ; push orig_r10 clear.d [$sp=$sp-4] ; frametype == 0, normal frame - move.d $sp, $r10 - jsr do_multiple_IRQ + moveq 2, $r2 ; first bit we care about is the timer0 irq + move.d [R_VECT_MASK_RD], $r0; read the irq bits that triggered the multiple irq + move.d $r0, [R_VECT_MASK_CLR] ; Block all active IRQs +1: + btst $r2, $r0 ; check for the irq given by bit r2 + bpl 2f + move.d $r2, $r10 ; First argument to do_IRQ + move.d $sp, $r11 ; second argument to do_IRQ + jsr do_IRQ +2: + addq 1, $r2 ; next vector bit + cmp.b 32, $r2 + bne 1b ; process all irq's up to and including number 31 + moveq 0, $r9 ; make ret_from_intr realise we came from an ir + move.d $r0, [R_VECT_MASK_SET] ; Unblock all the IRQs jump ret_from_intr do_sigtrap: @@ -829,13 +837,6 @@ _ugdb_handle_breakpoint: ba do_sigtrap ; SIGTRAP the offending process. pop $dccr ; Restore dccr in delay slot. - .global kernel_execve -kernel_execve: - move.d __NR_execve, $r9 - break 13 - ret - nop - .data hw_bp_trigs: @@ -1134,42 +1135,6 @@ sys_call_table: .long sys_add_key .long sys_request_key .long sys_keyctl - .long sys_ioprio_set - .long sys_ioprio_get /* 290 */ - .long sys_inotify_init - .long sys_inotify_add_watch - .long sys_inotify_rm_watch - .long sys_migrate_pages - .long sys_openat /* 295 */ - .long sys_mkdirat - .long sys_mknodat - .long sys_fchownat - .long sys_futimesat - .long sys_fstatat64 /* 300 */ - .long sys_unlinkat - .long sys_renameat - .long sys_linkat - .long sys_symlinkat - .long sys_readlinkat /* 305 */ - .long sys_fchmodat - .long sys_faccessat - .long sys_pselect6 - .long sys_ppoll - .long sys_unshare /* 310 */ - .long sys_set_robust_list - .long sys_get_robust_list - .long sys_splice - .long sys_sync_file_range - .long sys_tee /* 315 */ - .long sys_vmsplice - .long sys_move_pages - .long sys_getcpu - .long sys_epoll_pwait - .long sys_utimensat /* 320 */ - .long sys_signalfd - .long sys_timerfd - .long sys_eventfd - .long sys_fallocate /* * NOTE!! This doesn't have to be exact - we just have diff --git a/trunk/arch/cris/arch-v10/kernel/fasttimer.c b/trunk/arch/cris/arch-v10/kernel/fasttimer.c index c1a3a2100ee7..d3ea052e5ee1 100644 --- a/trunk/arch/cris/arch-v10/kernel/fasttimer.c +++ b/trunk/arch/cris/arch-v10/kernel/fasttimer.c @@ -1,9 +1,97 @@ -/* +/* $Id: fasttimer.c,v 1.9 2005/03/04 08:16:16 starvik Exp $ * linux/arch/cris/kernel/fasttimer.c * * Fast timers for ETRAX100/ETRAX100LX + * This may be useful in other OS than Linux so use 2 space indentation... * - * Copyright (C) 2000-2007 Axis Communications AB, Lund, Sweden + * $Log: fasttimer.c,v $ + * Revision 1.9 2005/03/04 08:16:16 starvik + * Merge of Linux 2.6.11. + * + * Revision 1.8 2005/01/05 06:09:29 starvik + * cli()/sti() will be obsolete in 2.6.11. + * + * Revision 1.7 2005/01/03 13:35:46 starvik + * Removed obsolete stuff. + * Mark fast timer IRQ as not shared. + * + * Revision 1.6 2004/05/14 10:18:39 starvik + * Export fast_timer_list + * + * Revision 1.5 2004/05/14 07:58:01 starvik + * Merge of changes from 2.4 + * + * Revision 1.4 2003/07/04 08:27:41 starvik + * Merge of Linux 2.5.74 + * + * Revision 1.3 2002/12/12 08:26:32 starvik + * Don't use C-comments inside CVS comments + * + * Revision 1.2 2002/12/11 15:42:02 starvik + * Extracted v10 (ETRAX 100LX) specific stuff from arch/cris/kernel/ + * + * Revision 1.1 2002/11/18 07:58:06 starvik + * Fast timers (from Linux 2.4) + * + * Revision 1.5 2002/10/15 06:21:39 starvik + * Added call to init_waitqueue_head + * + * Revision 1.4 2002/05/28 17:47:59 johana + * Added del_fast_timer() + * + * Revision 1.3 2002/05/28 16:16:07 johana + * Handle empty fast_timer_list + * + * Revision 1.2 2002/05/27 15:38:42 johana + * Made it compile without warnings on Linux 2.4. + * (includes, wait_queue, PROC_FS and snprintf) + * + * Revision 1.1 2002/05/27 15:32:25 johana + * arch/etrax100/kernel/fasttimer.c v1.8 from the elinux tree. + * + * Revision 1.8 2001/11/27 13:50:40 pkj + * Disable interrupts while stopping the timer and while modifying the + * list of active timers in timer1_handler() as it may be interrupted + * by other interrupts (e.g., the serial interrupt) which may add fast + * timers. + * + * Revision 1.7 2001/11/22 11:50:32 pkj + * * Only store information about the last 16 timers. + * * proc_fasttimer_read() now uses an allocated buffer, since it + * requires more space than just a page even for only writing the + * last 16 timers. The buffer is only allocated on request, so + * unless /proc/fasttimer is read, it is never allocated. + * * Renamed fast_timer_started to fast_timers_started to match + * fast_timers_added and fast_timers_expired. + * * Some clean-up. + * + * Revision 1.6 2000/12/13 14:02:08 johana + * Removed volatile for fast_timer_list + * + * Revision 1.5 2000/12/13 13:55:35 johana + * Added DEBUG_LOG, added som cli() and cleanup + * + * Revision 1.4 2000/12/05 13:48:50 johana + * Added range check when writing proc file, modified timer int handling + * + * Revision 1.3 2000/11/23 10:10:20 johana + * More debug/logging possibilities. + * Moved GET_JIFFIES_USEC() to timex.h and time.c + * + * Revision 1.2 2000/11/01 13:41:04 johana + * Clean up and bugfixes. + * Created new do_gettimeofday_fast() that gets a timeval struct + * with time based on jiffies and *R_TIMER0_DATA, uses a table + * for fast conversion of timer value to microseconds. + * (Much faster the standard do_gettimeofday() and we don't really + * want to use the true time - we want the "uptime" so timers don't screw up + * when we change the time. + * TODO: Add efficient support for continuous timers as well. + * + * Revision 1.1 2000/10/26 15:49:16 johana + * Added fasttimer, highresolution timers. + * + * Copyright (C) 2000,2001 2002 Axis Communications AB, Lund, Sweden */ #include @@ -37,7 +125,7 @@ #ifdef FAST_TIMER_SANITY_CHECKS #define SANITYCHECK(x) x -static int sanity_failed; +static int sanity_failed = 0; #else #define SANITYCHECK(x) #endif @@ -46,13 +134,15 @@ static int sanity_failed; #define D2(x) #define DP(x) -static unsigned int fast_timer_running; -static unsigned int fast_timers_added; -static unsigned int fast_timers_started; -static unsigned int fast_timers_expired; -static unsigned int fast_timers_deleted; -static unsigned int fast_timer_is_init; -static unsigned int fast_timer_ints; +#define __INLINE__ inline + +static int fast_timer_running = 0; +static int fast_timers_added = 0; +static int fast_timers_started = 0; +static int fast_timers_expired = 0; +static int fast_timers_deleted = 0; +static int fast_timer_is_init = 0; +static int fast_timer_ints = 0; struct fast_timer *fast_timer_list = NULL; @@ -60,8 +150,8 @@ struct fast_timer *fast_timer_list = NULL; #define DEBUG_LOG_MAX 128 static const char * debug_log_string[DEBUG_LOG_MAX]; static unsigned long debug_log_value[DEBUG_LOG_MAX]; -static unsigned int debug_log_cnt; -static unsigned int debug_log_cnt_wrapped; +static int debug_log_cnt = 0; +static int debug_log_cnt_wrapped = 0; #define DEBUG_LOG(string, value) \ { \ @@ -116,29 +206,45 @@ int timer_freq_settings[NUM_TIMER_STATS]; int timer_delay_settings[NUM_TIMER_STATS]; /* Not true gettimeofday, only checks the jiffies (uptime) + useconds */ -inline void do_gettimeofday_fast(struct fasttime_t *tv) +void __INLINE__ do_gettimeofday_fast(struct timeval *tv) { - tv->tv_jiff = jiffies; - tv->tv_usec = GET_JIFFIES_USEC(); + unsigned long sec = jiffies; + unsigned long usec = GET_JIFFIES_USEC(); + + usec += (sec % HZ) * (1000000 / HZ); + sec = sec / HZ; + + if (usec > 1000000) + { + usec -= 1000000; + sec++; + } + tv->tv_sec = sec; + tv->tv_usec = usec; } -inline int fasttime_cmp(struct fasttime_t *t0, struct fasttime_t *t1) +int __INLINE__ timeval_cmp(struct timeval *t0, struct timeval *t1) { - /* Compare jiffies. Takes care of wrapping */ - if (time_before(t0->tv_jiff, t1->tv_jiff)) - return -1; - else if (time_after(t0->tv_jiff, t1->tv_jiff)) - return 1; - - /* Compare us */ - if (t0->tv_usec < t1->tv_usec) - return -1; - else if (t0->tv_usec > t1->tv_usec) - return 1; - return 0; + if (t0->tv_sec < t1->tv_sec) + { + return -1; + } + else if (t0->tv_sec > t1->tv_sec) + { + return 1; + } + if (t0->tv_usec < t1->tv_usec) + { + return -1; + } + else if (t0->tv_usec > t1->tv_usec) + { + return 1; + } + return 0; } -inline void start_timer1(unsigned long delay_us) +void __INLINE__ start_timer1(unsigned long delay_us) { int freq_index = 0; /* This is the lowest resolution */ unsigned long upper_limit = MAX_DELAY_US; @@ -179,7 +285,7 @@ inline void start_timer1(unsigned long delay_us) timer_freq_settings[fast_timers_started % NUM_TIMER_STATS] = freq_index; timer_delay_settings[fast_timers_started % NUM_TIMER_STATS] = delay_us; - D1(printk(KERN_DEBUG "start_timer1 : %d us freq: %i div: %i\n", + D1(printk("start_timer1 : %d us freq: %i div: %i\n", delay_us, freq_index, div)); /* Clear timer1 irq */ *R_IRQ_MASK0_CLR = IO_STATE(R_IRQ_MASK0_CLR, timer1, clr); @@ -234,7 +340,7 @@ void start_one_shot_timer(struct fast_timer *t, printk(KERN_WARNING "timer name: %s data: 0x%08lX already in list!\n", name, data); sanity_failed++; - goto done; + return; } else { @@ -250,11 +356,11 @@ void start_one_shot_timer(struct fast_timer *t, t->name = name; t->tv_expires.tv_usec = t->tv_set.tv_usec + delay_us % 1000000; - t->tv_expires.tv_jiff = t->tv_set.tv_jiff + delay_us / 1000000 / HZ; + t->tv_expires.tv_sec = t->tv_set.tv_sec + delay_us / 1000000; if (t->tv_expires.tv_usec > 1000000) { t->tv_expires.tv_usec -= 1000000; - t->tv_expires.tv_jiff += HZ; + t->tv_expires.tv_sec++; } #ifdef FAST_TIMER_LOG timer_added_log[fast_timers_added % NUM_TIMER_STATS] = *t; @@ -262,7 +368,7 @@ void start_one_shot_timer(struct fast_timer *t, fast_timers_added++; /* Check if this should timeout before anything else */ - if (tmp == NULL || fasttime_cmp(&t->tv_expires, &tmp->tv_expires) < 0) + if (tmp == NULL || timeval_cmp(&t->tv_expires, &tmp->tv_expires) < 0) { /* Put first in list and modify the timer value */ t->prev = NULL; @@ -278,8 +384,8 @@ void start_one_shot_timer(struct fast_timer *t, start_timer1(delay_us); } else { /* Put in correct place in list */ - while (tmp->next && fasttime_cmp(&t->tv_expires, - &tmp->next->tv_expires) > 0) + while (tmp->next && + timeval_cmp(&t->tv_expires, &tmp->next->tv_expires) > 0) { tmp = tmp->next; } @@ -295,7 +401,6 @@ void start_one_shot_timer(struct fast_timer *t, D2(printk("start_one_shot_timer: %d us done\n", delay_us)); -done: local_irq_restore(flags); } /* start_one_shot_timer */ @@ -339,18 +444,11 @@ int del_fast_timer(struct fast_timer * t) /* Timer 1 interrupt handler */ static irqreturn_t -timer1_handler(int irq, void *dev_id) +timer1_handler(int irq, void *dev_id, struct pt_regs *regs) { struct fast_timer *t; unsigned long flags; - /* We keep interrupts disabled not only when we modify the - * fast timer list, but any time we hold a reference to a - * timer in the list, since del_fast_timer may be called - * from (another) interrupt context. Thus, the only time - * when interrupts are enabled is when calling the timer - * callback function. - */ local_irq_save(flags); /* Clear timer1 irq */ @@ -368,19 +466,18 @@ timer1_handler(int irq, void *dev_id) fast_timer_running = 0; fast_timer_ints++; + local_irq_restore(flags); + t = fast_timer_list; while (t) { - struct fasttime_t tv; - fast_timer_function_type *f; - unsigned long d; + struct timeval tv; /* Has it really expired? */ do_gettimeofday_fast(&tv); - D1(printk(KERN_DEBUG "t: %is %06ius\n", - tv.tv_jiff, tv.tv_usec)); + D1(printk("t: %is %06ius\n", tv.tv_sec, tv.tv_usec)); - if (fasttime_cmp(&t->tv_expires, &tv) <= 0) + if (timeval_cmp(&t->tv_expires, &tv) <= 0) { /* Yes it has expired */ #ifdef FAST_TIMER_LOG @@ -389,6 +486,7 @@ timer1_handler(int irq, void *dev_id) fast_timers_expired++; /* Remove this timer before call, since it may reuse the timer */ + local_irq_save(flags); if (t->prev) { t->prev->next = t->next; @@ -403,23 +501,16 @@ timer1_handler(int irq, void *dev_id) } t->prev = NULL; t->next = NULL; + local_irq_restore(flags); - /* Save function callback data before enabling - * interrupts, since the timer may be removed and - * we don't know how it was allocated - * (e.g. ->function and ->data may become overwritten - * after deletion if the timer was stack-allocated). - */ - f = t->function; - d = t->data; - - if (f != NULL) { - /* Run callback with interrupts enabled. */ - local_irq_restore(flags); - f(d); - local_irq_save(flags); - } else + if (t->function != NULL) + { + t->function(t->data); + } + else + { DEBUG_LOG("!timer1 %i function==NULL!\n", fast_timer_ints); + } } else { @@ -427,20 +518,16 @@ timer1_handler(int irq, void *dev_id) D1(printk(".\n")); } + local_irq_save(flags); if ((t = fast_timer_list) != NULL) { /* Start next timer.. */ - long us = 0; - struct fasttime_t tv; + long us; + struct timeval tv; do_gettimeofday_fast(&tv); - - /* time_after_eq takes care of wrapping */ - if (time_after_eq(t->tv_expires.tv_jiff, tv.tv_jiff)) - us = ((t->tv_expires.tv_jiff - tv.tv_jiff) * - 1000000 / HZ + t->tv_expires.tv_usec - - tv.tv_usec); - + us = ((t->tv_expires.tv_sec - tv.tv_sec) * 1000000 + + t->tv_expires.tv_usec - tv.tv_usec); if (us > 0) { if (!fast_timer_running) @@ -450,6 +537,7 @@ timer1_handler(int irq, void *dev_id) #endif start_timer1(us); } + local_irq_restore(flags); break; } else @@ -460,10 +548,9 @@ timer1_handler(int irq, void *dev_id) D1(printk("e! %d\n", us)); } } + local_irq_restore(flags); } - local_irq_restore(flags); - if (!t) { D1(printk("t1 stop!\n")); @@ -488,17 +575,28 @@ static void wake_up_func(unsigned long data) void schedule_usleep(unsigned long us) { struct fast_timer t; +#ifdef DECLARE_WAITQUEUE wait_queue_head_t sleep_wait; init_waitqueue_head(&sleep_wait); + { + DECLARE_WAITQUEUE(wait, current); +#else + struct wait_queue *sleep_wait = NULL; + struct wait_queue wait = { current, NULL }; +#endif D1(printk("schedule_usleep(%d)\n", us)); + add_wait_queue(&sleep_wait, &wait); + set_current_state(TASK_INTERRUPTIBLE); start_one_shot_timer(&t, wake_up_func, (unsigned long)&sleep_wait, us, "usleep"); - /* Uninterruptible sleep on the fast timer. (The condition is somewhat - * redundant since the timer is what wakes us up.) */ - wait_event(sleep_wait, !fast_timer_pending(&t)); - + schedule(); + set_current_state(TASK_RUNNING); + remove_wait_queue(&sleep_wait, &wait); D1(printk("done schedule_usleep(%d)\n", us)); +#ifdef DECLARE_WAITQUEUE + } +#endif } #ifdef CONFIG_PROC_FS @@ -518,7 +616,7 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len unsigned long flags; int i = 0; int num_to_show; - struct fasttime_t tv; + struct timeval tv; struct fast_timer *t, *nextt; static char *bigbuf = NULL; static unsigned long used; @@ -526,8 +624,7 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len if (!bigbuf && !(bigbuf = vmalloc(BIG_BUF_SIZE))) { used = 0; - if (buf) - buf[0] = '\0'; + bigbuf[0] = '\0'; return 0; } @@ -549,7 +646,7 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len used += sprintf(bigbuf + used, "Fast timer running: %s\n", fast_timer_running ? "yes" : "no"); used += sprintf(bigbuf + used, "Current time: %lu.%06lu\n", - (unsigned long)tv.tv_jiff, + (unsigned long)tv.tv_sec, (unsigned long)tv.tv_usec); #ifdef FAST_TIMER_SANITY_CHECKS used += sprintf(bigbuf + used, "Sanity failed: %i\n", @@ -599,9 +696,9 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len "d: %6li us data: 0x%08lX" "\n", t->name, - (unsigned long)t->tv_set.tv_jiff, + (unsigned long)t->tv_set.tv_sec, (unsigned long)t->tv_set.tv_usec, - (unsigned long)t->tv_expires.tv_jiff, + (unsigned long)t->tv_expires.tv_sec, (unsigned long)t->tv_expires.tv_usec, t->delay_us, t->data @@ -621,9 +718,9 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len "d: %6li us data: 0x%08lX" "\n", t->name, - (unsigned long)t->tv_set.tv_jiff, + (unsigned long)t->tv_set.tv_sec, (unsigned long)t->tv_set.tv_usec, - (unsigned long)t->tv_expires.tv_jiff, + (unsigned long)t->tv_expires.tv_sec, (unsigned long)t->tv_expires.tv_usec, t->delay_us, t->data @@ -641,9 +738,9 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len "d: %6li us data: 0x%08lX" "\n", t->name, - (unsigned long)t->tv_set.tv_jiff, + (unsigned long)t->tv_set.tv_sec, (unsigned long)t->tv_set.tv_usec, - (unsigned long)t->tv_expires.tv_jiff, + (unsigned long)t->tv_expires.tv_sec, (unsigned long)t->tv_expires.tv_usec, t->delay_us, t->data @@ -664,15 +761,15 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len /* " func: 0x%08lX" */ "\n", t->name, - (unsigned long)t->tv_set.tv_jiff, + (unsigned long)t->tv_set.tv_sec, (unsigned long)t->tv_set.tv_usec, - (unsigned long)t->tv_expires.tv_jiff, + (unsigned long)t->tv_expires.tv_sec, (unsigned long)t->tv_expires.tv_usec, t->delay_us, t->data /* , t->function */ ); - local_irq_save(flags); + local_irq_disable(); if (t->next != nextt) { printk(KERN_WARNING "timer removed!\n"); @@ -701,7 +798,7 @@ static volatile int num_test_timeout = 0; static struct fast_timer tr[10]; static int exp_num[10]; -static struct fasttime_t tv_exp[100]; +static struct timeval tv_exp[100]; static void test_timeout(unsigned long data) { @@ -739,7 +836,7 @@ static void fast_timer_test(void) int prev_num; int j; - struct fasttime_t tv, tv0, tv1, tv2; + struct timeval tv, tv0, tv1, tv2; printk("fast_timer_test() start\n"); do_gettimeofday_fast(&tv); @@ -752,8 +849,7 @@ static void fast_timer_test(void) { do_gettimeofday_fast(&tv_exp[j]); } - printk(KERN_DEBUG "fast_timer_test() %is %06i\n", - tv.tv_jiff, tv.tv_usec); + printk("fast_timer_test() %is %06i\n", tv.tv_sec, tv.tv_usec); for (j = 0; j < 1000; j++) { @@ -762,12 +858,12 @@ static void fast_timer_test(void) } for (j = 0; j < 100; j++) { - printk(KERN_DEBUG "%i.%i %i.%i %i.%i %i.%i %i.%i\n", - tv_exp[j].tv_jiff, tv_exp[j].tv_usec, - tv_exp[j+1].tv_jiff, tv_exp[j+1].tv_usec, - tv_exp[j+2].tv_jiff, tv_exp[j+2].tv_usec, - tv_exp[j+3].tv_jiff, tv_exp[j+3].tv_usec, - tv_exp[j+4].tv_jiff, tv_exp[j+4].tv_usec); + printk("%i.%i %i.%i %i.%i %i.%i %i.%i\n", + tv_exp[j].tv_sec,tv_exp[j].tv_usec, + tv_exp[j+1].tv_sec,tv_exp[j+1].tv_usec, + tv_exp[j+2].tv_sec,tv_exp[j+2].tv_usec, + tv_exp[j+3].tv_sec,tv_exp[j+3].tv_usec, + tv_exp[j+4].tv_sec,tv_exp[j+4].tv_usec); j += 4; } do_gettimeofday_fast(&tv0); @@ -799,12 +895,9 @@ static void fast_timer_test(void) } } do_gettimeofday_fast(&tv2); - printk(KERN_DEBUG "Timers started %is %06i\n", - tv0.tv_jiff, tv0.tv_usec); - printk(KERN_DEBUG "Timers started at %is %06i\n", - tv1.tv_jiff, tv1.tv_usec); - printk(KERN_DEBUG "Timers done %is %06i\n", - tv2.tv_jiff, tv2.tv_usec); + printk("Timers started %is %06i\n", tv0.tv_sec, tv0.tv_usec); + printk("Timers started at %is %06i\n", tv1.tv_sec, tv1.tv_usec); + printk("Timers done %is %06i\n", tv2.tv_sec, tv2.tv_usec); DP(printk("buf0:\n"); printk(buf0); printk("buf1:\n"); @@ -826,9 +919,9 @@ static void fast_timer_test(void) printk("%-10s set: %6is %06ius exp: %6is %06ius " "data: 0x%08X func: 0x%08X\n", t->name, - t->tv_set.tv_jiff, + t->tv_set.tv_sec, t->tv_set.tv_usec, - t->tv_expires.tv_jiff, + t->tv_expires.tv_sec, t->tv_expires.tv_usec, t->data, t->function @@ -836,12 +929,10 @@ static void fast_timer_test(void) printk(" del: %6ius did exp: %6is %06ius as #%i error: %6li\n", t->delay_us, - tv_exp[j].tv_jiff, + tv_exp[j].tv_sec, tv_exp[j].tv_usec, exp_num[j], - (tv_exp[j].tv_jiff - t->tv_expires.tv_jiff) * - 1000000 + tv_exp[j].tv_usec - - t->tv_expires.tv_usec); + (tv_exp[j].tv_sec - t->tv_expires.tv_sec)*1000000 + tv_exp[j].tv_usec - t->tv_expires.tv_usec); } proc_fasttimer_read(buf5, NULL, 0, 0, 0); printk("buf5 after all done:\n"); @@ -851,7 +942,7 @@ static void fast_timer_test(void) #endif -int fast_timer_init(void) +void fast_timer_init(void) { /* For some reason, request_irq() hangs when called froom time_init() */ if (!fast_timer_is_init) @@ -884,6 +975,4 @@ int fast_timer_init(void) fast_timer_test(); #endif } - return 0; } -__initcall(fast_timer_init); diff --git a/trunk/arch/cris/arch-v10/kernel/io_interface_mux.c b/trunk/arch/cris/arch-v10/kernel/io_interface_mux.c index 3a9114e89edf..29d48ad00df9 100644 --- a/trunk/arch/cris/arch-v10/kernel/io_interface_mux.c +++ b/trunk/arch/cris/arch-v10/kernel/io_interface_mux.c @@ -304,7 +304,7 @@ static unsigned char clear_group_from_set(const unsigned char groups, struct if_ static struct if_group *get_group(const unsigned char groups) { int i; - for (i = 0; i < ARRAY_SIZE(if_groups); i++) { + for (i = 0; i < sizeof(if_groups)/sizeof(struct if_group); i++) { if (groups & if_groups[i].group) { return &if_groups[i]; } diff --git a/trunk/arch/cris/arch-v10/kernel/irq.c b/trunk/arch/cris/arch-v10/kernel/irq.c index e06ab0050d37..845c95f6e871 100644 --- a/trunk/arch/cris/arch-v10/kernel/irq.c +++ b/trunk/arch/cris/arch-v10/kernel/irq.c @@ -12,16 +12,10 @@ */ #include -#include #include -#include #include #include -/* From kgdb.c. */ -extern void kgdb_init(void); -extern void breakpoint(void); - #define mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr)); #define unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr)); @@ -81,8 +75,8 @@ BUILD_IRQ(12, 0x1000) BUILD_IRQ(13, 0x2000) void mmu_bus_fault(void); /* IRQ 14 is the bus fault interrupt */ void multiple_interrupt(void); /* IRQ 15 is the multiple IRQ interrupt */ -BUILD_IRQ(16, 0x10000 | 0x20000) /* ethernet tx interrupt needs to block rx */ -BUILD_IRQ(17, 0x20000 | 0x10000) /* ...and vice versa */ +BUILD_IRQ(16, 0x10000) +BUILD_IRQ(17, 0x20000) BUILD_IRQ(18, 0x40000) BUILD_IRQ(19, 0x80000) BUILD_IRQ(20, 0x100000) @@ -153,55 +147,6 @@ void system_call(void); /* from entry.S */ void do_sigtrap(void); /* from entry.S */ void gdb_handle_breakpoint(void); /* from entry.S */ -extern void do_IRQ(int irq, struct pt_regs * regs); - -/* Handle multiple IRQs */ -void do_multiple_IRQ(struct pt_regs* regs) -{ - int bit; - unsigned masked; - unsigned mask; - unsigned ethmask = 0; - - /* Get interrupts to mask and handle */ - mask = masked = *R_VECT_MASK_RD; - - /* Never mask timer IRQ */ - mask &= ~(IO_MASK(R_VECT_MASK_RD, timer0)); - - /* - * If either ethernet interrupt (rx or tx) is active then block - * the other one too. Unblock afterwards also. - */ - if (mask & - (IO_STATE(R_VECT_MASK_RD, dma0, active) | - IO_STATE(R_VECT_MASK_RD, dma1, active))) { - ethmask = (IO_MASK(R_VECT_MASK_RD, dma0) | - IO_MASK(R_VECT_MASK_RD, dma1)); - } - - /* Block them */ - *R_VECT_MASK_CLR = (mask | ethmask); - - /* An extra irq_enter here to prevent softIRQs to run after - * each do_IRQ. This will decrease the interrupt latency. - */ - irq_enter(); - - /* Handle all IRQs */ - for (bit = 2; bit < 32; bit++) { - if (masked & (1 << bit)) { - do_IRQ(bit, regs); - } - } - - /* This irq_exit() will trigger the soft IRQs. */ - irq_exit(); - - /* Unblock the IRQs again */ - *R_VECT_MASK_SET = (masked | ethmask); -} - /* init_IRQ() is called by start_kernel and is responsible for fixing IRQ masks and setting the irq vector table. */ diff --git a/trunk/arch/cris/arch-v10/kernel/setup.c b/trunk/arch/cris/arch-v10/kernel/setup.c index de27b50b72a2..682ef955aec4 100644 --- a/trunk/arch/cris/arch-v10/kernel/setup.c +++ b/trunk/arch/cris/arch-v10/kernel/setup.c @@ -13,7 +13,6 @@ #include #include #include -#include #ifdef CONFIG_PROC_FS #define HAS_FPU 0x0001 @@ -57,8 +56,8 @@ int show_cpuinfo(struct seq_file *m, void *v) revision = rdvr(); - if (revision >= ARRAY_SIZE(cpu_info)) - info = &cpu_info[ARRAY_SIZE(cpu_info) - 1]; + if (revision >= sizeof cpu_info/sizeof *cpu_info) + info = &cpu_info[sizeof cpu_info/sizeof *cpu_info - 1]; else info = &cpu_info[revision]; diff --git a/trunk/arch/cris/arch-v10/kernel/time.c b/trunk/arch/cris/arch-v10/kernel/time.c index 5976f6199c47..575a14bb1106 100644 --- a/trunk/arch/cris/arch-v10/kernel/time.c +++ b/trunk/arch/cris/arch-v10/kernel/time.c @@ -1,4 +1,5 @@ -/* +/* $Id: time.c,v 1.5 2004/09/29 06:12:46 starvik Exp $ + * * linux/arch/cris/arch-v10/kernel/time.c * * Copyright (C) 1991, 1992, 1995 Linus Torvalds @@ -19,7 +20,6 @@ #include #include #include -#include /* define this if you need to use print_timestamp */ /* it will make jiffies at 96 hz instead of 100 hz though */ @@ -201,9 +201,8 @@ static long last_rtc_update = 0; extern void cris_do_profile(struct pt_regs *regs); static inline irqreturn_t -timer_interrupt(int irq, void *dev_id) +timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct pt_regs *regs = get_irq_regs(); /* acknowledge the timer irq */ #ifdef USE_CASCADE_TIMERS @@ -222,11 +221,9 @@ timer_interrupt(int irq, void *dev_id) #endif /* reset watchdog otherwise it resets us! */ + reset_watchdog(); - /* Update statistics. */ - update_process_times(user_mode(regs)); - /* call the real timer interrupt handler */ do_timer(1); diff --git a/trunk/arch/cris/arch-v10/lib/memset.c b/trunk/arch/cris/arch-v10/lib/memset.c index 42c1101043a3..82bb66839171 100644 --- a/trunk/arch/cris/arch-v10/lib/memset.c +++ b/trunk/arch/cris/arch-v10/lib/memset.c @@ -66,7 +66,7 @@ void *memset(void *pdst, { register char *dst __asm__ ("r13") = pdst; - + /* This is NONPORTABLE, but since this whole routine is */ /* grossly nonportable that doesn't matter. */ @@ -110,52 +110,52 @@ void *memset(void *pdst, If you want to check that the allocation was right; then check the equalities in the first comment. It should say "r13=r13, r12=r12, r11=r11" */ - __asm__ volatile ("\n\ - ;; Check that the following is true (same register names on \n\ - ;; both sides of equal sign, as in r8=r8): \n\ - ;; %0=r13, %1=r12, %4=r11 \n\ - ;; \n\ - ;; Save the registers we'll clobber in the movem process \n\ - ;; on the stack. Don't mention them to gcc, it will only be \n\ - ;; upset. \n\ - subq 11*4,$sp \n\ - movem $r10,[$sp] \n\ - \n\ - move.d $r11,$r0 \n\ - move.d $r11,$r1 \n\ - move.d $r11,$r2 \n\ - move.d $r11,$r3 \n\ - move.d $r11,$r4 \n\ - move.d $r11,$r5 \n\ - move.d $r11,$r6 \n\ - move.d $r11,$r7 \n\ - move.d $r11,$r8 \n\ - move.d $r11,$r9 \n\ - move.d $r11,$r10 \n\ - \n\ - ;; Now we've got this: \n\ - ;; r13 - dst \n\ - ;; r12 - n \n\ - \n\ - ;; Update n for the first loop \n\ - subq 12*4,$r12 \n\ -0: \n\ - subq 12*4,$r12 \n\ - bge 0b \n\ - movem $r11,[$r13+] \n\ - \n\ - addq 12*4,$r12 ;; compensate for last loop underflowing n \n\ - \n\ - ;; Restore registers from stack \n\ - movem [$sp+],$r10" + __asm__ volatile (" + ;; Check that the following is true (same register names on + ;; both sides of equal sign, as in r8=r8): + ;; %0=r13, %1=r12, %4=r11 + ;; + ;; Save the registers we'll clobber in the movem process + ;; on the stack. Don't mention them to gcc, it will only be + ;; upset. + subq 11*4,$sp + movem $r10,[$sp] + + move.d $r11,$r0 + move.d $r11,$r1 + move.d $r11,$r2 + move.d $r11,$r3 + move.d $r11,$r4 + move.d $r11,$r5 + move.d $r11,$r6 + move.d $r11,$r7 + move.d $r11,$r8 + move.d $r11,$r9 + move.d $r11,$r10 + + ;; Now we've got this: + ;; r13 - dst + ;; r12 - n + + ;; Update n for the first loop + subq 12*4,$r12 +0: + subq 12*4,$r12 + bge 0b + movem $r11,[$r13+] + + addq 12*4,$r12 ;; compensate for last loop underflowing n + + ;; Restore registers from stack + movem [$sp+],$r10" /* Outputs */ : "=r" (dst), "=r" (n) /* Inputs */ : "0" (dst), "1" (n), "r" (lc)); - + } /* Either we directly starts copying, using dword copying - in a loop, or we copy as much as possible with 'movem' + in a loop, or we copy as much as possible with 'movem' and then the last block (<44 bytes) is copied here. This will work since 'movem' will have updated src,dst,n. */ diff --git a/trunk/arch/cris/arch-v10/lib/string.c b/trunk/arch/cris/arch-v10/lib/string.c index 7161a2bef4fe..15d6662b03b1 100644 --- a/trunk/arch/cris/arch-v10/lib/string.c +++ b/trunk/arch/cris/arch-v10/lib/string.c @@ -95,33 +95,33 @@ void *memcpy(void *pdst, If you want to check that the allocation was right; then check the equalities in the first comment. It should say "r13=r13, r11=r11, r12=r12" */ - __asm__ volatile ("\n\ - ;; Check that the following is true (same register names on \n\ - ;; both sides of equal sign, as in r8=r8): \n\ - ;; %0=r13, %1=r11, %2=r12 \n\ - ;; \n\ - ;; Save the registers we'll use in the movem process \n\ - ;; on the stack. \n\ - subq 11*4,$sp \n\ - movem $r10,[$sp] \n\ - \n\ - ;; Now we've got this: \n\ - ;; r11 - src \n\ - ;; r13 - dst \n\ - ;; r12 - n \n\ - \n\ - ;; Update n for the first loop \n\ - subq 44,$r12 \n\ -0: \n\ - movem [$r11+],$r10 \n\ - subq 44,$r12 \n\ - bge 0b \n\ - movem $r10,[$r13+] \n\ - \n\ - addq 44,$r12 ;; compensate for last loop underflowing n \n\ - \n\ - ;; Restore registers from stack \n\ - movem [$sp+],$r10" + __asm__ volatile (" + ;; Check that the following is true (same register names on + ;; both sides of equal sign, as in r8=r8): + ;; %0=r13, %1=r11, %2=r12 + ;; + ;; Save the registers we'll use in the movem process + ;; on the stack. + subq 11*4,$sp + movem $r10,[$sp] + + ;; Now we've got this: + ;; r11 - src + ;; r13 - dst + ;; r12 - n + + ;; Update n for the first loop + subq 44,$r12 +0: + movem [$r11+],$r10 + subq 44,$r12 + bge 0b + movem $r10,[$r13+] + + addq 44,$r12 ;; compensate for last loop underflowing n + + ;; Restore registers from stack + movem [$sp+],$r10" /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n) /* Inputs */ : "0" (dst), "1" (src), "2" (n)); diff --git a/trunk/arch/cris/arch-v10/lib/usercopy.c b/trunk/arch/cris/arch-v10/lib/usercopy.c index b8e6c0430e5b..a12c708afc9a 100644 --- a/trunk/arch/cris/arch-v10/lib/usercopy.c +++ b/trunk/arch/cris/arch-v10/lib/usercopy.c @@ -92,58 +92,58 @@ __copy_user (void __user *pdst, const void *psrc, unsigned long pn) .ifnc %0%1%2%3,$r13$r11$r12$r10 \n\ .err \n\ .endif \n\ - \n\ - ;; Save the registers we'll use in the movem process \n\ - ;; on the stack. \n\ - subq 11*4,$sp \n\ - movem $r10,[$sp] \n\ - \n\ - ;; Now we've got this: \n\ - ;; r11 - src \n\ - ;; r13 - dst \n\ - ;; r12 - n \n\ - \n\ - ;; Update n for the first loop \n\ - subq 44,$r12 \n\ - \n\ -; Since the noted PC of a faulting instruction in a delay-slot of a taken \n\ -; branch, is that of the branch target, we actually point at the from-movem \n\ -; for this case. There is no ambiguity here; if there was a fault in that \n\ -; instruction (meaning a kernel oops), the faulted PC would be the address \n\ -; after *that* movem. \n\ - \n\ -0: \n\ - movem [$r11+],$r10 \n\ - subq 44,$r12 \n\ - bge 0b \n\ - movem $r10,[$r13+] \n\ -1: \n\ - addq 44,$r12 ;; compensate for last loop underflowing n \n\ - \n\ - ;; Restore registers from stack \n\ - movem [$sp+],$r10 \n\ -2: \n\ - .section .fixup,\"ax\" \n\ - \n\ -; To provide a correct count in r10 of bytes that failed to be copied, \n\ -; we jump back into the loop if the loop-branch was taken. There is no \n\ -; performance penalty for sany use; the program will segfault soon enough.\n\ - \n\ -3: \n\ - move.d [$sp],$r10 \n\ - addq 44,$r10 \n\ - move.d $r10,[$sp] \n\ - jump 0b \n\ -4: \n\ - movem [$sp+],$r10 \n\ - addq 44,$r10 \n\ - addq 44,$r12 \n\ - jump 2b \n\ - \n\ - .previous \n\ - .section __ex_table,\"a\" \n\ - .dword 0b,3b \n\ - .dword 1b,4b \n\ + + ;; Save the registers we'll use in the movem process + ;; on the stack. + subq 11*4,$sp + movem $r10,[$sp] + + ;; Now we've got this: + ;; r11 - src + ;; r13 - dst + ;; r12 - n + + ;; Update n for the first loop + subq 44,$r12 + +; Since the noted PC of a faulting instruction in a delay-slot of a taken +; branch, is that of the branch target, we actually point at the from-movem +; for this case. There is no ambiguity here; if there was a fault in that +; instruction (meaning a kernel oops), the faulted PC would be the address +; after *that* movem. + +0: + movem [$r11+],$r10 + subq 44,$r12 + bge 0b + movem $r10,[$r13+] +1: + addq 44,$r12 ;; compensate for last loop underflowing n + + ;; Restore registers from stack + movem [$sp+],$r10 +2: + .section .fixup,\"ax\" + +; To provide a correct count in r10 of bytes that failed to be copied, +; we jump back into the loop if the loop-branch was taken. There is no +; performance penalty for sany use; the program will segfault soon enough. + +3: + move.d [$sp],$r10 + addq 44,$r10 + move.d $r10,[$sp] + jump 0b +4: + movem [$sp+],$r10 + addq 44,$r10 + addq 44,$r12 + jump 2b + + .previous + .section __ex_table,\"a\" + .dword 0b,3b + .dword 1b,4b .previous" /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n), "=r" (retn) @@ -253,59 +253,59 @@ __copy_user_zeroing (void __user *pdst, const void *psrc, unsigned long pn) If you want to check that the allocation was right; then check the equalities in the first comment. It should say "r13=r13, r11=r11, r12=r12" */ - __asm__ volatile ("\n\ + __asm__ volatile (" .ifnc %0%1%2%3,$r13$r11$r12$r10 \n\ .err \n\ .endif \n\ - \n\ - ;; Save the registers we'll use in the movem process \n\ - ;; on the stack. \n\ - subq 11*4,$sp \n\ - movem $r10,[$sp] \n\ - \n\ - ;; Now we've got this: \n\ - ;; r11 - src \n\ - ;; r13 - dst \n\ - ;; r12 - n \n\ - \n\ - ;; Update n for the first loop \n\ - subq 44,$r12 \n\ -0: \n\ - movem [$r11+],$r10 \n\ -1: \n\ - subq 44,$r12 \n\ - bge 0b \n\ - movem $r10,[$r13+] \n\ - \n\ - addq 44,$r12 ;; compensate for last loop underflowing n \n\ - \n\ - ;; Restore registers from stack \n\ - movem [$sp+],$r10 \n\ -4: \n\ - .section .fixup,\"ax\" \n\ - \n\ -;; Do not jump back into the loop if we fail. For some uses, we get a \n\ -;; page fault somewhere on the line. Without checking for page limits, \n\ -;; we don't know where, but we need to copy accurately and keep an \n\ -;; accurate count; not just clear the whole line. To do that, we fall \n\ -;; down in the code below, proceeding with smaller amounts. It should \n\ -;; be kept in mind that we have to cater to code like what at one time \n\ -;; was in fs/super.c: \n\ -;; i = size - copy_from_user((void *)page, data, size); \n\ -;; which would cause repeated faults while clearing the remainder of \n\ -;; the SIZE bytes at PAGE after the first fault. \n\ -;; A caveat here is that we must not fall through from a failing page \n\ -;; to a valid page. \n\ - \n\ -3: \n\ - movem [$sp+],$r10 \n\ - addq 44,$r12 ;; Get back count before faulting point. \n\ - subq 44,$r11 ;; Get back pointer to faulting movem-line. \n\ - jump 4b ;; Fall through, pretending the fault didn't happen.\n\ - \n\ - .previous \n\ - .section __ex_table,\"a\" \n\ - .dword 1b,3b \n\ + + ;; Save the registers we'll use in the movem process + ;; on the stack. + subq 11*4,$sp + movem $r10,[$sp] + + ;; Now we've got this: + ;; r11 - src + ;; r13 - dst + ;; r12 - n + + ;; Update n for the first loop + subq 44,$r12 +0: + movem [$r11+],$r10 +1: + subq 44,$r12 + bge 0b + movem $r10,[$r13+] + + addq 44,$r12 ;; compensate for last loop underflowing n + + ;; Restore registers from stack + movem [$sp+],$r10 +4: + .section .fixup,\"ax\" + +;; Do not jump back into the loop if we fail. For some uses, we get a +;; page fault somewhere on the line. Without checking for page limits, +;; we don't know where, but we need to copy accurately and keep an +;; accurate count; not just clear the whole line. To do that, we fall +;; down in the code below, proceeding with smaller amounts. It should +;; be kept in mind that we have to cater to code like what at one time +;; was in fs/super.c: +;; i = size - copy_from_user((void *)page, data, size); +;; which would cause repeated faults while clearing the remainder of +;; the SIZE bytes at PAGE after the first fault. +;; A caveat here is that we must not fall through from a failing page +;; to a valid page. + +3: + movem [$sp+],$r10 + addq 44,$r12 ;; Get back count before faulting point. + subq 44,$r11 ;; Get back pointer to faulting movem-line. + jump 4b ;; Fall through, pretending the fault didn't happen. + + .previous + .section __ex_table,\"a\" + .dword 1b,3b .previous" /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n), "=r" (retn) @@ -425,64 +425,64 @@ __do_clear_user (void __user *pto, unsigned long pn) If you want to check that the allocation was right; then check the equalities in the first comment. It should say something like "r13=r13, r11=r11, r12=r12". */ - __asm__ volatile ("\n\ + __asm__ volatile (" .ifnc %0%1%2,$r13$r12$r10 \n\ .err \n\ .endif \n\ - \n\ - ;; Save the registers we'll clobber in the movem process \n\ - ;; on the stack. Don't mention them to gcc, it will only be \n\ - ;; upset. \n\ - subq 11*4,$sp \n\ - movem $r10,[$sp] \n\ - \n\ - clear.d $r0 \n\ - clear.d $r1 \n\ - clear.d $r2 \n\ - clear.d $r3 \n\ - clear.d $r4 \n\ - clear.d $r5 \n\ - clear.d $r6 \n\ - clear.d $r7 \n\ - clear.d $r8 \n\ - clear.d $r9 \n\ - clear.d $r10 \n\ - clear.d $r11 \n\ - \n\ - ;; Now we've got this: \n\ - ;; r13 - dst \n\ - ;; r12 - n \n\ - \n\ - ;; Update n for the first loop \n\ - subq 12*4,$r12 \n\ -0: \n\ - subq 12*4,$r12 \n\ - bge 0b \n\ - movem $r11,[$r13+] \n\ -1: \n\ - addq 12*4,$r12 ;; compensate for last loop underflowing n\n\ - \n\ - ;; Restore registers from stack \n\ - movem [$sp+],$r10 \n\ -2: \n\ - .section .fixup,\"ax\" \n\ -3: \n\ - move.d [$sp],$r10 \n\ - addq 12*4,$r10 \n\ - move.d $r10,[$sp] \n\ - clear.d $r10 \n\ - jump 0b \n\ - \n\ -4: \n\ - movem [$sp+],$r10 \n\ - addq 12*4,$r10 \n\ - addq 12*4,$r12 \n\ - jump 2b \n\ - \n\ - .previous \n\ - .section __ex_table,\"a\" \n\ - .dword 0b,3b \n\ - .dword 1b,4b \n\ + + ;; Save the registers we'll clobber in the movem process + ;; on the stack. Don't mention them to gcc, it will only be + ;; upset. + subq 11*4,$sp + movem $r10,[$sp] + + clear.d $r0 + clear.d $r1 + clear.d $r2 + clear.d $r3 + clear.d $r4 + clear.d $r5 + clear.d $r6 + clear.d $r7 + clear.d $r8 + clear.d $r9 + clear.d $r10 + clear.d $r11 + + ;; Now we've got this: + ;; r13 - dst + ;; r12 - n + + ;; Update n for the first loop + subq 12*4,$r12 +0: + subq 12*4,$r12 + bge 0b + movem $r11,[$r13+] +1: + addq 12*4,$r12 ;; compensate for last loop underflowing n + + ;; Restore registers from stack + movem [$sp+],$r10 +2: + .section .fixup,\"ax\" +3: + move.d [$sp],$r10 + addq 12*4,$r10 + move.d $r10,[$sp] + clear.d $r10 + jump 0b + +4: + movem [$sp+],$r10 + addq 12*4,$r10 + addq 12*4,$r12 + jump 2b + + .previous + .section __ex_table,\"a\" + .dword 0b,3b + .dword 1b,4b .previous" /* Outputs */ : "=r" (dst), "=r" (n), "=r" (retn) diff --git a/trunk/arch/cris/arch-v32/drivers/Kconfig b/trunk/arch/cris/arch-v32/drivers/Kconfig index 7f72d7c9e1ce..cc6ba5423754 100644 --- a/trunk/arch/cris/arch-v32/drivers/Kconfig +++ b/trunk/arch/cris/arch-v32/drivers/Kconfig @@ -362,6 +362,8 @@ config ETRAX_AXISFLASHMAP select MTD select MTD_CFI select MTD_CFI_AMDSTD + select MTD_OBSOLETE_CHIPS + select MTD_AMDSTD select MTD_CHAR select MTD_BLOCK select MTD_PARTITIONS diff --git a/trunk/arch/cris/arch-v32/drivers/axisflashmap.c b/trunk/arch/cris/arch-v32/drivers/axisflashmap.c index c5ff95e18269..3ec12ea44e8e 100644 --- a/trunk/arch/cris/arch-v32/drivers/axisflashmap.c +++ b/trunk/arch/cris/arch-v32/drivers/axisflashmap.c @@ -190,12 +190,13 @@ static struct mtd_info *probe_cs(struct map_info *map_cs) "%s: Probing a 0x%08lx bytes large window at 0x%08lx.\n", map_cs->name, map_cs->size, map_cs->map_priv_1); +#ifdef CONFIG_MTD_AMDSTD + mtd_cs = do_map_probe("amd_flash", map_cs); +#endif #ifdef CONFIG_MTD_CFI + if (!mtd_cs) { mtd_cs = do_map_probe("cfi_probe", map_cs); -#endif -#ifdef CONFIG_MTD_JEDECPROBE - if (!mtd_cs) - mtd_cs = do_map_probe("jedec_probe", map_cs); + } #endif return mtd_cs; diff --git a/trunk/arch/cris/arch-v32/drivers/sync_serial.c b/trunk/arch/cris/arch-v32/drivers/sync_serial.c index d581b0a92a3f..df89298aafc4 100644 --- a/trunk/arch/cris/arch-v32/drivers/sync_serial.c +++ b/trunk/arch/cris/arch-v32/drivers/sync_serial.c @@ -185,7 +185,7 @@ static struct sync_port ports[]= } }; -#define NUMBER_OF_PORTS ARRAY_SIZE(ports) +#define NUMBER_OF_PORTS (sizeof(ports)/sizeof(sync_port)) static const struct file_operations sync_serial_fops = { .owner = THIS_MODULE, diff --git a/trunk/arch/cris/arch-v32/kernel/cache.c b/trunk/arch/cris/arch-v32/kernel/cache.c deleted file mode 100644 index 80da7b88a72b..000000000000 --- a/trunk/arch/cris/arch-v32/kernel/cache.c +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include -#include -#include - -/* This file is used to workaround a cache bug, Guinness TR 106. */ - -inline void flush_dma_descr(struct dma_descr_data *descr, int flush_buf) -{ - /* Flush descriptor to make sure we get correct in_eop and after. */ - asm volatile ("ftagd [%0]" :: "r" (descr)); - /* Flush buffer pointed out by descriptor. */ - if (flush_buf) - cris_flush_cache_range(phys_to_virt((unsigned)descr->buf), - (unsigned)(descr->after - descr->buf)); -} -EXPORT_SYMBOL(flush_dma_descr); - -void flush_dma_list(struct dma_descr_data *descr) -{ - while (1) { - flush_dma_descr(descr, 1); - if (descr->eol) - break; - descr = phys_to_virt((unsigned)descr->next); - } -} -EXPORT_SYMBOL(flush_dma_list); - -/* From cacheflush.S */ -EXPORT_SYMBOL(cris_flush_cache); -/* From cacheflush.S */ -EXPORT_SYMBOL(cris_flush_cache_range); diff --git a/trunk/arch/cris/arch-v32/kernel/cacheflush.S b/trunk/arch/cris/arch-v32/kernel/cacheflush.S deleted file mode 100644 index 956e8fb82f01..000000000000 --- a/trunk/arch/cris/arch-v32/kernel/cacheflush.S +++ /dev/null @@ -1,94 +0,0 @@ - .global cris_flush_cache_range -cris_flush_cache_range: - move.d 1024, $r12 - cmp.d $r11, $r12 - bhi cris_flush_1KB - nop - add.d $r10, $r11 - ftagd [$r10] -cris_flush_last: - addq 32, $r10 - cmp.d $r11, $r10 - blt cris_flush_last - ftagd [$r10] - ret - nop -cris_flush_1KB: - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ftagd [$r10] - addq 32, $r10 - ba cris_flush_cache_range - sub.d $r12, $r11 - - .global cris_flush_cache -cris_flush_cache: - moveq 0, $r10 -cris_flush_line: - move.d 16*1024, $r11 - addq 16, $r10 - cmp.d $r10, $r11 - blt cris_flush_line - fidxd [$r10] - ret - nop diff --git a/trunk/arch/cris/arch-v32/kernel/io.c b/trunk/arch/cris/arch-v32/kernel/io.c index a22a9e02e093..dfbfcb8d2585 100644 --- a/trunk/arch/cris/arch-v32/kernel/io.c +++ b/trunk/arch/cris/arch-v32/kernel/io.c @@ -49,7 +49,7 @@ struct crisv32_ioport crisv32_ioports[] = } }; -#define NBR_OF_PORTS ARRAY_SIZE(crisv32_ioports) +#define NBR_OF_PORTS sizeof(crisv32_ioports)/sizeof(struct crisv32_ioport) struct crisv32_iopin crisv32_led1_green; struct crisv32_iopin crisv32_led1_red; diff --git a/trunk/arch/cris/arch-v32/kernel/setup.c b/trunk/arch/cris/arch-v32/kernel/setup.c index 72e9e8331f63..4662f363df63 100644 --- a/trunk/arch/cris/arch-v32/kernel/setup.c +++ b/trunk/arch/cris/arch-v32/kernel/setup.c @@ -54,10 +54,12 @@ show_cpuinfo(struct seq_file *m, void *v) { int i; int cpu = (int)v - 1; + int entries; unsigned long revision; struct cpu_info *info; - info = &cpinfo[ARRAY_SIZE(cpinfo) - 1]; + entries = sizeof cpinfo / sizeof(struct cpu_info); + info = &cpinfo[entries - 1]; #ifdef CONFIG_SMP if (!cpu_online(cpu)) @@ -66,7 +68,7 @@ show_cpuinfo(struct seq_file *m, void *v) revision = rdvr(); - for (i = 0; i < ARRAY_SIZE(cpinfo); i++) { + for (i = 0; i < entries; i++) { if (cpinfo[i].rev == revision) { info = &cpinfo[i]; break; diff --git a/trunk/arch/cris/defconfig b/trunk/arch/cris/defconfig index 9c33ae659934..142a10818af3 100644 --- a/trunk/arch/cris/defconfig +++ b/trunk/arch/cris/defconfig @@ -226,6 +226,8 @@ CONFIG_MTD_CFI_UTIL=y CONFIG_MTD_RAM=y # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set +CONFIG_MTD_OBSOLETE_CHIPS=y +CONFIG_MTD_AMDSTD=y # CONFIG_MTD_SHARP is not set # CONFIG_MTD_JEDEC is not set @@ -274,7 +276,6 @@ CONFIG_MTDRAM_ABS_POS=0x0 # CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y @@ -301,14 +302,16 @@ CONFIG_IOSCHED_CFQ=y # # ATA/ATAPI/MFM/RLL support # -# CONFIG_IDE is not set -# CONFIG_PARIDE is not set +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y # # Please see Documentation/ide.txt for help/info on IDE drives # # CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_BLK_DEV_IDECD=y # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set # CONFIG_IDE_TASK_IOCTL is not set @@ -318,6 +321,7 @@ CONFIG_IOSCHED_CFQ=y # # CONFIG_IDE_GENERIC is not set # CONFIG_IDE_ARM is not set +CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -325,7 +329,6 @@ CONFIG_IOSCHED_CFQ=y # SCSI device support # # CONFIG_SCSI is not set -# CONFIG_ISCSI_TCP is not set # # IEEE 1394 (FireWire) support @@ -411,11 +414,26 @@ CONFIG_NETFILTER=y # CONFIG_NET_POLL_CONTROLLER is not set # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set -# CONFIG_AF_RXRPC is not set -# CONFIG_AF_RXRPC_DEBUG is not set -# CONFIG_BT is not set -# CONFIG_I2C is not set - +CONFIG_BT=y +CONFIG_BT_L2CAP=y +# CONFIG_BT_SCO is not set +CONFIG_BT_RFCOMM=y +# CONFIG_BT_RFCOMM_TTY is not set +CONFIG_BT_BNEP=y +# CONFIG_BT_BNEP_MC_FILTER is not set +# CONFIG_BT_BNEP_PROTO_FILTER is not set +# CONFIG_BT_HIDP is not set + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIUSB=y +# CONFIG_BT_HCIUSB_SCO is not set +# CONFIG_BT_HCIUART is not set +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +# CONFIG_BT_HCIBFUSB is not set +# CONFIG_BT_HCIVHCI is not set CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set @@ -467,17 +485,31 @@ CONFIG_NET_ETHERNET=y # # Input device support # -# CONFIG_INPUT is not set +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set # # Input I/O drivers # +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y CONFIG_SERIO=y # CONFIG_SERIO_I8042 is not set # CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_CT82C710 is not set +CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set -# CONFIG_GAMEPORT is not set # # Input Device Drivers @@ -493,7 +525,6 @@ CONFIG_MOUSE_PS2=y # CONFIG_MOUSE_SERIAL is not set # CONFIG_MOUSE_VSXXXAA is not set # CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set @@ -511,8 +542,6 @@ CONFIG_MOUSE_PS2=y # # Non-8250 serial port support # -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -530,8 +559,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set -# CONFIG_RTC_LIB is not set -# CONFIG_RTC_CLASS is not set # # Ftape, the floppy tape device driver @@ -633,9 +660,7 @@ CONFIG_NFS_V3=y # CONFIG_NFSD is not set CONFIG_LOCKD=y CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y -# CONFIG_SUNRPC_BIND34 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -660,22 +685,10 @@ CONFIG_MSDOS_PARTITION=y # # CONFIG_SOUND is not set -# -# Generic devices -# -# CONFIG_SND_MPU401_UART is not set -# CONFIG_SND_DUMMY is not set -# CONFIG_SND_VIRMIDI is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set - # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set -# CONFIG_PARPORT_PC_PCMCIA is not set -# CONFIG_NET_PCMCIA is not set # # PC-card bridges @@ -721,7 +734,6 @@ CONFIG_USB_DEVICEFS=y # USB Input Devices # # CONFIG_USB_HID is not set -# HID_SUPPORT is not set # # USB HID Boot Protocol drivers @@ -817,7 +829,7 @@ CONFIG_USB_RTL8150=y # # Hardware crypto devices -# CONFIG_CRYPTO_HW is not set +# # # Library routines diff --git a/trunk/arch/cris/kernel/crisksyms.c b/trunk/arch/cris/kernel/crisksyms.c index 62f0e752915a..105bb5ed48f7 100644 --- a/trunk/arch/cris/kernel/crisksyms.c +++ b/trunk/arch/cris/kernel/crisksyms.c @@ -27,7 +27,6 @@ extern void __Mod(void); extern void __ashldi3(void); extern void __ashrdi3(void); extern void __lshrdi3(void); -extern void __negdi2(void); extern void iounmap(volatile void * __iomem); /* Platform dependent support */ @@ -35,6 +34,19 @@ EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(get_cmos_time); EXPORT_SYMBOL(loops_per_usec); +/* String functions */ +EXPORT_SYMBOL(memcmp); +EXPORT_SYMBOL(memmove); +EXPORT_SYMBOL(strstr); +EXPORT_SYMBOL(strcpy); +EXPORT_SYMBOL(strchr); +EXPORT_SYMBOL(strcmp); +EXPORT_SYMBOL(strlen); +EXPORT_SYMBOL(strcat); +EXPORT_SYMBOL(strncat); +EXPORT_SYMBOL(strncmp); +EXPORT_SYMBOL(strncpy); + /* Math functions */ EXPORT_SYMBOL(__Udiv); EXPORT_SYMBOL(__Umod); @@ -43,7 +55,6 @@ EXPORT_SYMBOL(__Mod); EXPORT_SYMBOL(__ashldi3); EXPORT_SYMBOL(__ashrdi3); EXPORT_SYMBOL(__lshrdi3); -EXPORT_SYMBOL(__negdi2); /* Memory functions */ EXPORT_SYMBOL(__ioremap); @@ -73,4 +84,4 @@ EXPORT_SYMBOL(start_one_shot_timer); EXPORT_SYMBOL(del_fast_timer); EXPORT_SYMBOL(schedule_usleep); #endif -EXPORT_SYMBOL(csum_partial); + diff --git a/trunk/arch/cris/kernel/irq.c b/trunk/arch/cris/kernel/irq.c index 2dfac8c79090..5c27ff86121b 100644 --- a/trunk/arch/cris/kernel/irq.c +++ b/trunk/arch/cris/kernel/irq.c @@ -2,7 +2,7 @@ * * linux/arch/cris/kernel/irq.c * - * Copyright (c) 2000,2007 Axis Communications AB + * Copyright (c) 2000,2001 Axis Communications AB * * Authors: Bjorn Wesen (bjornw@axis.com) * @@ -92,16 +92,14 @@ int show_interrupts(struct seq_file *p, void *v) asmlinkage void do_IRQ(int irq, struct pt_regs * regs) { unsigned long sp; - struct pt_regs *old_regs = set_irq_regs(regs); irq_enter(); sp = rdsp(); if (unlikely((sp & (PAGE_SIZE - 1)) < (PAGE_SIZE/8))) { printk("do_IRQ: stack overflow: %lX\n", sp); show_stack(NULL, (unsigned long *)sp); } - __do_IRQ(irq); + __do_IRQ(irq, regs); irq_exit(); - set_irq_regs(old_regs); } void weird_irq(void) diff --git a/trunk/arch/cris/kernel/process.c b/trunk/arch/cris/kernel/process.c index 9ca558fc5bc8..123451c44154 100644 --- a/trunk/arch/cris/kernel/process.c +++ b/trunk/arch/cris/kernel/process.c @@ -195,11 +195,6 @@ EXPORT_SYMBOL(enable_hlt); */ void (*pm_idle)(void); -extern void default_idle(void); - -void (*pm_power_off)(void); -EXPORT_SYMBOL(pm_power_off); - /* * The idle thread. There's no useful work to be * done, so just try to conserve power and have a diff --git a/trunk/arch/cris/kernel/ptrace.c b/trunk/arch/cris/kernel/ptrace.c index 3ccd20e85dce..1085d037027b 100644 --- a/trunk/arch/cris/kernel/ptrace.c +++ b/trunk/arch/cris/kernel/ptrace.c @@ -81,13 +81,13 @@ /* notification of userspace execution resumption * - triggered by current->work.notify_resume */ -extern int do_signal(int canrestart, struct pt_regs *regs); +extern int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs); -void do_notify_resume(int canrestart, struct pt_regs *regs, +void do_notify_resume(int canrestart, sigset_t *oldset, struct pt_regs *regs, __u32 thread_info_flags ) { /* deal with pending signal delivery */ if (thread_info_flags & _TIF_SIGPENDING) - do_signal(canrestart,regs); + do_signal(canrestart,oldset,regs); } diff --git a/trunk/arch/cris/kernel/sys_cris.c b/trunk/arch/cris/kernel/sys_cris.c index 8b9984197edc..514359b8122e 100644 --- a/trunk/arch/cris/kernel/sys_cris.c +++ b/trunk/arch/cris/kernel/sys_cris.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/cris/kernel/time.c b/trunk/arch/cris/kernel/time.c index 7a2cc7efbcf8..acfd04559405 100644 --- a/trunk/arch/cris/kernel/time.c +++ b/trunk/arch/cris/kernel/time.c @@ -171,6 +171,10 @@ get_cmos_time(void) mon = CMOS_READ(RTC_MONTH); year = CMOS_READ(RTC_YEAR); + printk(KERN_DEBUG + "rtc: sec 0x%x min 0x%x hour 0x%x day 0x%x mon 0x%x year 0x%x\n", + sec, min, hour, day, mon, year); + BCD_TO_BIN(sec); BCD_TO_BIN(min); BCD_TO_BIN(hour); @@ -203,12 +207,12 @@ void cris_do_profile(struct pt_regs* regs) { -#ifdef CONFIG_SYSTEM_PROFILER +#if CONFIG_SYSTEM_PROFILER cris_profile_sample(regs); #endif -#ifdef CONFIG_PROFILING - profile_tick(CPU_PROFILING); +#if CONFIG_PROFILING + profile_tick(CPU_PROFILING, regs); #endif } diff --git a/trunk/arch/ia64/kernel/efi.c b/trunk/arch/ia64/kernel/efi.c index 8e8f8b6193ee..5181bf551f3c 100644 --- a/trunk/arch/ia64/kernel/efi.c +++ b/trunk/arch/ia64/kernel/efi.c @@ -1113,7 +1113,7 @@ efi_initialize_iomem_resources(struct resource *code_resource, if (md->num_pages == 0) /* should not happen */ continue; - flags = IORESOURCE_MEM | IORESOURCE_BUSY; + flags = IORESOURCE_MEM; switch (md->type) { case EFI_MEMORY_MAPPED_IO: @@ -1135,11 +1135,12 @@ efi_initialize_iomem_resources(struct resource *code_resource, case EFI_ACPI_MEMORY_NVS: name = "ACPI Non-volatile Storage"; + flags |= IORESOURCE_BUSY; break; case EFI_UNUSABLE_MEMORY: name = "reserved"; - flags |= IORESOURCE_DISABLED; + flags |= IORESOURCE_BUSY | IORESOURCE_DISABLED; break; case EFI_RESERVED_TYPE: @@ -1148,6 +1149,7 @@ efi_initialize_iomem_resources(struct resource *code_resource, case EFI_ACPI_RECLAIM_MEMORY: default: name = "reserved"; + flags |= IORESOURCE_BUSY; break; } diff --git a/trunk/arch/mips/kernel/irixsig.c b/trunk/arch/mips/kernel/irixsig.c index 5b10ac133ec8..33506ff25910 100644 --- a/trunk/arch/mips/kernel/irixsig.c +++ b/trunk/arch/mips/kernel/irixsig.c @@ -430,7 +430,6 @@ asmlinkage int irix_sigprocmask(int how, irix_sigset_t __user *new, break; default: - spin_unlock_irq(¤t->sighand->siglock); return -EINVAL; } recalc_sigpending(); diff --git a/trunk/arch/mips/vr41xx/common/icu.c b/trunk/arch/mips/vr41xx/common/icu.c index 3f23d9fda662..1899601e5862 100644 --- a/trunk/arch/mips/vr41xx/common/icu.c +++ b/trunk/arch/mips/vr41xx/common/icu.c @@ -525,7 +525,6 @@ static inline int set_sysint1_assign(unsigned int irq, unsigned char assign) intassign1 |= (uint16_t)assign << 9; break; default: - spin_unlock_irq(&desc->lock); return -EINVAL; } @@ -593,7 +592,6 @@ static inline int set_sysint2_assign(unsigned int irq, unsigned char assign) intassign3 |= (uint16_t)assign << 12; break; default: - spin_unlock_irq(&desc->lock); return -EINVAL; } diff --git a/trunk/arch/um/Makefile b/trunk/arch/um/Makefile index 31999bc1c8a4..768a5d14b755 100644 --- a/trunk/arch/um/Makefile +++ b/trunk/arch/um/Makefile @@ -168,7 +168,7 @@ ifneq ($(KBUILD_SRC),) $(Q)mkdir -p $(objtree)/include/asm-um $(Q)ln -fsn $(srctree)/include/asm-$(HEADER_ARCH) include/asm-um/arch else - $(Q)cd $(TOPDIR)/include/asm-um && ln -fsn ../asm-$(SUBARCH) arch + $(Q)cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(HEADER_ARCH) arch endif $(objtree)/$(ARCH_DIR)/include: @@ -180,7 +180,7 @@ $(ARCH_DIR)/include/sysdep: $(objtree)/$(ARCH_DIR)/include ifneq ($(KBUILD_SRC),) $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/include/sysdep-$(SUBARCH) $(ARCH_DIR)/include/sysdep else - $(Q)cd $(ARCH_DIR)/include && ln -fsn sysdep-$(SUBARCH) sysdep + $(Q)cd $(ARCH_DIR)/include && ln -sf sysdep-$(SUBARCH) sysdep endif $(ARCH_DIR)/os: @@ -188,7 +188,7 @@ $(ARCH_DIR)/os: ifneq ($(KBUILD_SRC),) $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/os-$(OS) $(ARCH_DIR)/os else - $(Q)cd $(ARCH_DIR) && ln -fsn os-$(OS) os + $(Q)cd $(ARCH_DIR) && ln -sf os-$(OS) os endif # Generated files diff --git a/trunk/arch/um/drivers/net_kern.c b/trunk/arch/um/drivers/net_kern.c index 73681f14f9fc..8c01fa81a1ae 100644 --- a/trunk/arch/um/drivers/net_kern.c +++ b/trunk/arch/um/drivers/net_kern.c @@ -753,7 +753,6 @@ static struct mc_device net_mc = { .remove = net_remove, }; -#ifdef CONFIG_INET static int uml_inetaddr_event(struct notifier_block *this, unsigned long event, void *ptr) { @@ -790,13 +789,14 @@ struct notifier_block uml_inetaddr_notifier = { .notifier_call = uml_inetaddr_event, }; -static void inet_register(void) +static int uml_net_init(void) { struct list_head *ele; struct uml_net_private *lp; struct in_device *ip; struct in_ifaddr *in; + mconsole_register_dev(&net_mc); register_inetaddr_notifier(¨_inetaddr_notifier); /* Devices may have been opened already, so the uml_inetaddr_notifier @@ -816,17 +816,7 @@ static void inet_register(void) } } spin_unlock(&opened_lock); -} -#else -static inline void inet_register(void) -{ -} -#endif -static int uml_net_init(void) -{ - mconsole_register_dev(&net_mc); - inet_register(); return 0; } diff --git a/trunk/arch/um/include/user.h b/trunk/arch/um/include/user.h index 1723fac6f40d..99033ff28a78 100644 --- a/trunk/arch/um/include/user.h +++ b/trunk/arch/um/include/user.h @@ -1,13 +1,11 @@ /* - * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ #ifndef __USER_H__ #define __USER_H__ -#include "uml-config.h" - /* * The usual definition - copied here because the kernel provides its own, * fancier, type-safe, definition. Using that one would require @@ -25,17 +23,8 @@ extern void panic(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); - -#ifdef UML_CONFIG_PRINTK extern int printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); -#else -static inline int printk(const char *fmt, ...) -{ - return 0; -} -#endif - extern void schedule(void); extern int in_aton(char *str); extern int open_gdb_chan(void); diff --git a/trunk/arch/um/kernel/irq.c b/trunk/arch/um/kernel/irq.c index ba11ccd6a8a3..70c2d625b070 100644 --- a/trunk/arch/um/kernel/irq.c +++ b/trunk/arch/um/kernel/irq.c @@ -347,15 +347,14 @@ int um_request_irq(unsigned int irq, int fd, int type, { int err; - if (fd != -1) { - err = activate_fd(irq, fd, type, dev_id); - if (err) - return err; - } + err = request_irq(irq, handler, irqflags, devname, dev_id); + if (err) + return err; - return request_irq(irq, handler, irqflags, devname, dev_id); + if (fd != -1) + err = activate_fd(irq, fd, type, dev_id); + return err; } - EXPORT_SYMBOL(um_request_irq); EXPORT_SYMBOL(reactivate_fd); diff --git a/trunk/arch/um/kernel/skas/clone.c b/trunk/arch/um/kernel/skas/clone.c index 8d07a7acb909..d119f4f7d897 100644 --- a/trunk/arch/um/kernel/skas/clone.c +++ b/trunk/arch/um/kernel/skas/clone.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "as-layout.h" #include "ptrace_user.h" #include "skas.h" diff --git a/trunk/arch/um/os-Linux/file.c b/trunk/arch/um/os-Linux/file.c index f83462758627..b542a3a021bf 100644 --- a/trunk/arch/um/os-Linux/file.c +++ b/trunk/arch/um/os-Linux/file.c @@ -496,7 +496,8 @@ int os_rcv_fd(int fd, int *helper_pid_out) n = recvmsg(fd, &msg, 0); if(n < 0) return -errno; - else if(n != iov.iov_len) + + else if(n != sizeof(iov.iov_len)) *helper_pid_out = -1; cmsg = CMSG_FIRSTHDR(&msg); diff --git a/trunk/arch/x86/Kconfig.cpu b/trunk/arch/x86/Kconfig.cpu index c30162202dc4..0e2adadf5905 100644 --- a/trunk/arch/x86/Kconfig.cpu +++ b/trunk/arch/x86/Kconfig.cpu @@ -3,12 +3,11 @@ if !X86_ELAN choice prompt "Processor family" - default M686 if X86_32 - default GENERIC_CPU if X86_64 + default M686 config M386 bool "386" - depends on X86_32 && !UML + depends on !UML ---help--- This is the processor type of your CPU. This information is used for optimizing purposes. In order to compile a kernel that can run on @@ -50,7 +49,6 @@ config M386 config M486 bool "486" - depends on X86_32 help Select this for a 486 series processor, either Intel or one of the compatible processors from AMD, Cyrix, IBM, or Intel. Includes DX, @@ -59,7 +57,6 @@ config M486 config M586 bool "586/K5/5x86/6x86/6x86MX" - depends on X86_32 help Select this for an 586 or 686 series processor such as the AMD K5, the Cyrix 5x86, 6x86 and 6x86MX. This choice does not @@ -67,21 +64,18 @@ config M586 config M586TSC bool "Pentium-Classic" - depends on X86_32 help Select this for a Pentium Classic processor with the RDTSC (Read Time Stamp Counter) instruction for benchmarking. config M586MMX bool "Pentium-MMX" - depends on X86_32 help Select this for a Pentium with the MMX graphics/multimedia extended instructions. config M686 bool "Pentium-Pro" - depends on X86_32 help Select this for Intel Pentium Pro chips. This enables the use of Pentium Pro extended instructions, and disables the init-time guard @@ -89,7 +83,6 @@ config M686 config MPENTIUMII bool "Pentium-II/Celeron(pre-Coppermine)" - depends on X86_32 help Select this for Intel chips based on the Pentium-II and pre-Coppermine Celeron core. This option enables an unaligned @@ -99,7 +92,6 @@ config MPENTIUMII config MPENTIUMIII bool "Pentium-III/Celeron(Coppermine)/Pentium-III Xeon" - depends on X86_32 help Select this for Intel chips based on the Pentium-III and Celeron-Coppermine core. This option enables use of some @@ -108,14 +100,19 @@ config MPENTIUMIII config MPENTIUMM bool "Pentium M" - depends on X86_32 help Select this for Intel Pentium M (not Pentium-4 M) notebook chips. +config MCORE2 + bool "Core 2/newer Xeon" + help + Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and 53xx) + CPUs. You can distinguish newer from older Xeons by the CPU family + in /proc/cpuinfo. Newer ones have 6 and older ones 15 (not a typo) + config MPENTIUM4 bool "Pentium-4/Celeron(P4-based)/Pentium-4 M/older Xeon" - depends on X86_32 help Select this for Intel Pentium 4 chips. This includes the Pentium 4, Pentium D, P4-based Celeron and Xeon, and @@ -151,7 +148,6 @@ config MPENTIUM4 config MK6 bool "K6/K6-II/K6-III" - depends on X86_32 help Select this for an AMD K6-family processor. Enables use of some extended instructions, and passes appropriate optimization @@ -159,7 +155,6 @@ config MK6 config MK7 bool "Athlon/Duron/K7" - depends on X86_32 help Select this for an AMD Athlon K7-family processor. Enables use of some extended instructions, and passes appropriate optimization @@ -174,7 +169,6 @@ config MK8 config MCRUSOE bool "Crusoe" - depends on X86_32 help Select this for a Transmeta Crusoe processor. Treats the processor like a 586 with TSC, and sets some GCC optimization flags (like a @@ -182,13 +176,11 @@ config MCRUSOE config MEFFICEON bool "Efficeon" - depends on X86_32 help Select this for a Transmeta Efficeon processor. config MWINCHIPC6 bool "Winchip-C6" - depends on X86_32 help Select this for an IDT Winchip C6 chip. Linux and GCC treat this chip as a 586TSC with some extended instructions @@ -196,7 +188,6 @@ config MWINCHIPC6 config MWINCHIP2 bool "Winchip-2" - depends on X86_32 help Select this for an IDT Winchip-2. Linux and GCC treat this chip as a 586TSC with some extended instructions @@ -204,7 +195,6 @@ config MWINCHIP2 config MWINCHIP3D bool "Winchip-2A/Winchip-3" - depends on X86_32 help Select this for an IDT Winchip-2A or 3. Linux and GCC treat this chip as a 586TSC with some extended instructions @@ -214,19 +204,16 @@ config MWINCHIP3D config MGEODEGX1 bool "GeodeGX1" - depends on X86_32 help Select this for a Geode GX1 (Cyrix MediaGX) chip. config MGEODE_LX bool "Geode GX/LX" - depends on X86_32 help Select this for AMD Geode GX and LX processors. config MCYRIXIII bool "CyrixIII/VIA-C3" - depends on X86_32 help Select this for a Cyrix III or C3 chip. Presently Linux and GCC treat this chip as a generic 586. Whilst the CPU is 686 class, @@ -238,7 +225,6 @@ config MCYRIXIII config MVIAC3_2 bool "VIA C3-2 (Nehemiah)" - depends on X86_32 help Select this for a VIA C3 "Nehemiah". Selecting this enables usage of SSE and tells gcc to treat the CPU as a 686. @@ -246,42 +232,15 @@ config MVIAC3_2 config MVIAC7 bool "VIA C7" - depends on X86_32 help Select this for a VIA C7. Selecting this uses the correct cache shift and tells gcc to treat the CPU as a 686. -config MPSC - bool "Intel P4 / older Netburst based Xeon" - depends on X86_64 - help - Optimize for Intel Pentium 4, Pentium D and older Nocona/Dempsey - Xeon CPUs with Intel 64bit which is compatible with x86-64. - Note that the latest Xeons (Xeon 51xx and 53xx) are not based on the - Netburst core and shouldn't use this option. You can distinguish them - using the cpu family field - in /proc/cpuinfo. Family 15 is an older Xeon, Family 6 a newer one. - -config MCORE2 - bool "Core 2/newer Xeon" - help - Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and 53xx) - CPUs. You can distinguish newer from older Xeons by the CPU family - in /proc/cpuinfo. Newer ones have 6 and older ones 15 (not a typo) - -config GENERIC_CPU - bool "Generic-x86-64" - depends on X86_64 - help - Generic x86-64 CPU. - Run equally well on all x86-64 CPUs. - endchoice config X86_GENERIC - bool "Generic x86 support" - depends on X86_32 - help + bool "Generic x86 support" + help Instead of just including optimizations for the selected x86 variant (e.g. PII, Crusoe or Athlon), include some more generic optimizations as well. This will make the kernel @@ -294,31 +253,44 @@ endif # # Define implied options from the CPU selection here -config X86_L1_CACHE_BYTES - int - default "128" if GENERIC_CPU || MPSC - default "64" if MK8 || MCORE2 - depends on X86_64 - -config X86_INTERNODE_CACHE_BYTES - int - default "4096" if X86_VSMP - default X86_L1_CACHE_BYTES if !X86_VSMP - depends on X86_64 - +# config X86_CMPXCHG - def_bool X86_64 || (X86_32 && !M386) + bool + depends on !M386 + default y config X86_L1_CACHE_SHIFT int - default "7" if MPENTIUM4 || X86_GENERIC || GENERIC_CPU || MPSC + default "7" if MPENTIUM4 || X86_GENERIC default "4" if X86_ELAN || M486 || M386 || MGEODEGX1 default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MVIAC7 config X86_XADD bool - depends on X86_32 && !M386 + depends on !M386 + default y + +config RWSEM_GENERIC_SPINLOCK + bool + depends on !X86_XADD + default y + +config RWSEM_XCHGADD_ALGORITHM + bool + depends on X86_XADD + default y + +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + +config GENERIC_CALIBRATE_DELAY + bool default y config X86_PPRO_FENCE @@ -333,22 +305,22 @@ config X86_F00F_BUG config X86_WP_WORKS_OK bool - depends on X86_32 && !M386 + depends on !M386 default y config X86_INVLPG bool - depends on X86_32 && !M386 + depends on !M386 default y config X86_BSWAP bool - depends on X86_32 && !M386 + depends on !M386 default y config X86_POPAD_OK bool - depends on X86_32 && !M386 + depends on !M386 default y config X86_ALIGNMENT_16 @@ -358,7 +330,7 @@ config X86_ALIGNMENT_16 config X86_GOOD_APIC bool - depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON || MCORE2 || MVIAC7 || X86_64 + depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON || MCORE2 || MVIAC7 default y config X86_INTEL_USERCOPY @@ -383,7 +355,7 @@ config X86_OOSTORE config X86_TSC bool - depends on ((MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ) || X86_64 + depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ default y # this should be set for all -march=.. options where the compiler @@ -395,7 +367,6 @@ config X86_CMOV config X86_MINIMUM_CPU_FAMILY int - default "64" if X86_64 - default "4" if X86_32 && (X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK) + default "4" if X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK default "3" diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig.i386 similarity index 75% rename from trunk/arch/x86/Kconfig rename to trunk/arch/x86/Kconfig.i386 index 1eb59971af5d..7331efe891a7 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig.i386 @@ -1,24 +1,18 @@ -# x86 configuration -mainmenu "Linux Kernel Configuration for x86" +# +# For a description of the syntax of this configuration file, +# see Documentation/kbuild/kconfig-language.txt. +# -# Select 32 or 64 bit -config 64BIT - bool "64-bit kernel" - default n - help - Say yes to build a 64-bit kernel - formerly known as x86_64 - Say no to build a 32-bit kernel - formerly known as i386 +mainmenu "Linux Kernel Configuration" config X86_32 - def_bool !64BIT - -config X86_64 - def_bool 64BIT - -### Arch settings -config X86 bool default y + help + This is Linux's home port. Linux was originally native to the Intel + 386, and runs on all the later x86 processors including the Intel + 486, 586, Pentiums, and various instruction-set-compatible chips by + AMD, Cyrix, and others. config GENERIC_TIME bool @@ -39,7 +33,7 @@ config GENERIC_CLOCKEVENTS config GENERIC_CLOCKEVENTS_BROADCAST bool default y - depends on X86_64 || (X86_32 && X86_LOCAL_APIC) + depends on X86_LOCAL_APIC config LOCKDEP_SUPPORT bool @@ -53,6 +47,10 @@ config SEMAPHORE_SLEEPERS bool default y +config X86 + bool + default y + config MMU bool default y @@ -63,7 +61,7 @@ config ZONE_DMA config QUICKLIST bool - default X86_32 + default y config SBUS bool @@ -93,76 +91,6 @@ config DMI bool default y -config RWSEM_GENERIC_SPINLOCK - def_bool !X86_XADD - -config RWSEM_XCHGADD_ALGORITHM - def_bool X86_XADD - -config ARCH_HAS_ILOG2_U32 - def_bool n - -config ARCH_HAS_ILOG2_U64 - def_bool n - -config GENERIC_CALIBRATE_DELAY - def_bool y - -config GENERIC_TIME_VSYSCALL - bool - default X86_64 - - - - - -config ZONE_DMA32 - bool - default X86_64 - -config ARCH_POPULATES_NODE_MAP - def_bool y - -config AUDIT_ARCH - bool - default X86_64 - -# Use the generic interrupt handling code in kernel/irq/: -config GENERIC_HARDIRQS - bool - default y - -config GENERIC_IRQ_PROBE - bool - default y - -config GENERIC_PENDING_IRQ - bool - depends on GENERIC_HARDIRQS && SMP - default y - -config X86_SMP - bool - depends on X86_32 && SMP && !X86_VOYAGER - default y - -config X86_HT - bool - depends on SMP && !(X86_VISWS || X86_VOYAGER || MK8) - default y - -config X86_BIOS_REBOOT - bool - depends on X86_32 && !(X86_VISWS || X86_VOYAGER) - default y - -config X86_TRAMPOLINE - bool - depends on X86_SMP || (X86_VOYAGER && SMP) - default y - -config KTIME_SCALAR - def_bool X86_32 source "init/Kconfig" menu "Processor type and features" @@ -209,7 +137,6 @@ config X86_PC config X86_ELAN bool "AMD Elan" - depends on X86_32 help Select this for an AMD Elan processor. @@ -219,7 +146,6 @@ config X86_ELAN config X86_VOYAGER bool "Voyager (NCR)" - depends on X86_32 select SMP if !BROKEN help Voyager is an MCA-based 32-way capable SMP architecture proprietary @@ -234,7 +160,6 @@ config X86_NUMAQ bool "NUMAQ (IBM/Sequent)" select SMP select NUMA - depends on X86_32 help This option is used for getting Linux to run on a (IBM/Sequent) NUMA multiquad box. This changes the way that processors are bootstrapped, @@ -244,7 +169,7 @@ config X86_NUMAQ config X86_SUMMIT bool "Summit/EXA (IBM x440)" - depends on X86_32 && SMP + depends on SMP help This option is needed for IBM systems that use the Summit/EXA chipset. In particular, it is needed for the x440. @@ -254,7 +179,7 @@ config X86_SUMMIT config X86_BIGSMP bool "Support for other sub-arch SMP systems with more than 8 CPUs" - depends on X86_32 && SMP + depends on SMP help This option is needed for the systems that have more than 8 CPUs and if the system is not of any sub-arch type above. @@ -263,7 +188,6 @@ config X86_BIGSMP config X86_VISWS bool "SGI 320/540 (Visual Workstation)" - depends on X86_32 help The SGI Visual Workstation series is an IA32-based workstation based on SGI systems chips with some legacy PC hardware attached. @@ -275,7 +199,6 @@ config X86_VISWS config X86_GENERICARCH bool "Generic architecture (Summit, bigsmp, ES7000, default)" - depends on X86_32 help This option compiles in the Summit, bigsmp, ES7000, default subarchitectures. It is intended for a generic binary kernel. @@ -283,27 +206,18 @@ config X86_GENERICARCH config X86_ES7000 bool "Support for Unisys ES7000 IA32 series" - depends on X86_32 && SMP + depends on SMP help Support for Unisys ES7000 systems. Say 'Y' here if this kernel is supposed to run on an IA32-based Unisys ES7000 system. Only choose this option if you have such a system, otherwise you should say N here. -config X86_VSMP - bool "Support for ScaleMP vSMP" - depends on X86_64 && PCI - help - Support for ScaleMP vSMP systems. Say 'Y' here if this kernel is - supposed to run on these EM64T-based machines. Only choose this option - if you have one of these machines. - endchoice config SCHED_NO_NO_OMIT_FRAME_POINTER bool "Single-depth WCHAN output" default y - depends on X86_32 help Calculate simpler /proc//wchan values. If this option is disabled then wchan values will recurse back to the @@ -314,7 +228,7 @@ config SCHED_NO_NO_OMIT_FRAME_POINTER config PARAVIRT bool - depends on X86_32 && !(X86_VISWS || X86_VOYAGER) + depends on !(X86_VISWS || X86_VOYAGER) help This changes the kernel so it can modify itself when it is run under a hypervisor, potentially improving performance significantly @@ -323,7 +237,6 @@ config PARAVIRT menuconfig PARAVIRT_GUEST bool "Paravirtualized guest support" - depends on X86_32 help Say Y here to get to see options related to running Linux under various hypervisors. This option alone does not add any kernel code. @@ -351,7 +264,7 @@ endif config ACPI_SRAT bool default y - depends on X86_32 && ACPI && NUMA && (X86_SUMMIT || X86_GENERICARCH) + depends on ACPI && NUMA && (X86_SUMMIT || X86_GENERICARCH) select ACPI_NUMA config HAVE_ARCH_PARSE_SRAT @@ -362,12 +275,12 @@ config HAVE_ARCH_PARSE_SRAT config X86_SUMMIT_NUMA bool default y - depends on X86_32 && NUMA && (X86_SUMMIT || X86_GENERICARCH) + depends on NUMA && (X86_SUMMIT || X86_GENERICARCH) config X86_CYCLONE_TIMER bool default y - depends on X86_32 && X86_SUMMIT || X86_GENERICARCH + depends on X86_SUMMIT || X86_GENERICARCH config ES7000_CLUSTERED_APIC bool @@ -377,89 +290,21 @@ config ES7000_CLUSTERED_APIC source "arch/x86/Kconfig.cpu" config HPET_TIMER - bool - prompt "HPET Timer Support" if X86_32 - default X86_64 + bool "HPET Timer Support" help - Use the IA-PC HPET (High Precision Event Timer) to manage - time in preference to the PIT and RTC, if a HPET is - present. - HPET is the next generation timer replacing legacy 8254s. - The HPET provides a stable time base on SMP - systems, unlike the TSC, but it is more expensive to access, - as it is off-chip. You can find the HPET spec at - . + This enables the use of the HPET for the kernel's internal timer. + HPET is the next generation timer replacing legacy 8254s. + You can safely choose Y here. However, HPET will only be + activated if the platform and the BIOS support this feature. + Otherwise the 8254 will be used for timing services. - You can safely choose Y here. However, HPET will only be - activated if the platform and the BIOS support this feature. - Otherwise the 8254 will be used for timing services. - - Choose N to continue using the legacy 8254 timer. + Choose N to continue using the legacy 8254 timer. config HPET_EMULATE_RTC bool depends on HPET_TIMER && RTC=y default y -# Mark as embedded because too many people got it wrong. -# The code disables itself when not needed. -config GART_IOMMU - bool "GART IOMMU support" if EMBEDDED - default y - select SWIOTLB - select AGP - depends on X86_64 && PCI - help - Support for full DMA access of devices with 32bit memory access only - on systems with more than 3GB. This is usually needed for USB, - sound, many IDE/SATA chipsets and some other devices. - Provides a driver for the AMD Athlon64/Opteron/Turion/Sempron GART - based hardware IOMMU and a software bounce buffer based IOMMU used - on Intel systems and as fallback. - The code is only active when needed (enough memory and limited - device) unless CONFIG_IOMMU_DEBUG or iommu=force is specified - too. - -config CALGARY_IOMMU - bool "IBM Calgary IOMMU support" - select SWIOTLB - depends on X86_64 && PCI && EXPERIMENTAL - help - Support for hardware IOMMUs in IBM's xSeries x366 and x460 - systems. Needed to run systems with more than 3GB of memory - properly with 32-bit PCI devices that do not support DAC - (Double Address Cycle). Calgary also supports bus level - isolation, where all DMAs pass through the IOMMU. This - prevents them from going anywhere except their intended - destination. This catches hard-to-find kernel bugs and - mis-behaving drivers and devices that do not use the DMA-API - properly to set up their DMA buffers. The IOMMU can be - turned off at boot time with the iommu=off parameter. - Normally the kernel will make the right choice by itself. - If unsure, say Y. - -config CALGARY_IOMMU_ENABLED_BY_DEFAULT - bool "Should Calgary be enabled by default?" - default y - depends on CALGARY_IOMMU - help - Should Calgary be enabled by default? if you choose 'y', Calgary - will be used (if it exists). If you choose 'n', Calgary will not be - used even if it exists. If you choose 'n' and would like to use - Calgary anyway, pass 'iommu=calgary' on the kernel command line. - If unsure, say Y. - -# need this always selected by IOMMU for the VIA workaround -config SWIOTLB - bool - help - Support for software bounce buffers used on x86-64 systems - which don't have a hardware IOMMU (e.g. the current generation - of Intel's x86-64 CPUs). Using this PCI devices which can only - access 32-bits of memory can be used on systems with more than - 3 GB of memory. If unsure, say Y. - - config NR_CPUS int "Maximum number of CPUs (2-255)" range 2 255 @@ -476,7 +321,7 @@ config NR_CPUS config SCHED_SMT bool "SMT (Hyperthreading) scheduler support" - depends on (X86_64 && SMP) || (X86_32 && X86_HT) + depends on X86_HT help SMT scheduler support improves the CPU scheduler's decision making when dealing with Intel Pentium 4 chips with HyperThreading at a @@ -485,7 +330,7 @@ config SCHED_SMT config SCHED_MC bool "Multi-core scheduler support" - depends on (X86_64 && SMP) || (X86_32 && X86_HT) + depends on X86_HT default y help Multi-core scheduler support improves the CPU scheduler's decision @@ -496,7 +341,7 @@ source "kernel/Kconfig.preempt" config X86_UP_APIC bool "Local APIC support on uniprocessors" - depends on X86_32 && !SMP && !(X86_VISWS || X86_VOYAGER || X86_GENERICARCH) + depends on !SMP && !(X86_VISWS || X86_VOYAGER || X86_GENERICARCH) help A local APIC (Advanced Programmable Interrupt Controller) is an integrated interrupt controller in the CPU. If you have a single-CPU @@ -521,17 +366,17 @@ config X86_UP_IOAPIC config X86_LOCAL_APIC bool - depends on X86_64 || (X86_32 && (X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER) || X86_GENERICARCH)) + depends on X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER) || X86_GENERICARCH default y config X86_IO_APIC bool - depends on X86_64 || (X86_32 && (X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER)) || X86_GENERICARCH)) + depends on X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER)) || X86_GENERICARCH default y config X86_VISWS_APIC bool - depends on X86_32 && X86_VISWS + depends on X86_VISWS default y config X86_MCE @@ -551,25 +396,9 @@ config X86_MCE to disable it. MCE support simply ignores non-MCE processors like the 386 and 486, so nearly everyone can say Y here. -config X86_MCE_INTEL - bool "Intel MCE features" - depends on X86_64 && X86_MCE && X86_LOCAL_APIC - default y - help - Additional support for intel specific MCE features such as - the thermal monitor. - -config X86_MCE_AMD - bool "AMD MCE features" - depends on X86_64 && X86_MCE && X86_LOCAL_APIC - default y - help - Additional support for AMD specific MCE features such as - the DRAM Error Threshold. - config X86_MCE_NONFATAL tristate "Check for non-fatal errors on AMD Athlon/Duron / Intel Pentium 4" - depends on X86_32 && X86_MCE + depends on X86_MCE help Enabling this feature starts a timer that triggers every 5 seconds which will look at the machine check registers to see if anything happened. @@ -582,15 +411,14 @@ config X86_MCE_NONFATAL config X86_MCE_P4THERMAL bool "check for P4 thermal throttling interrupt." - depends on X86_32 && X86_MCE && (X86_UP_APIC || SMP) && !X86_VISWS + depends on X86_MCE && (X86_UP_APIC || SMP) && !X86_VISWS help Enabling this feature will cause a message to be printed when the P4 enters thermal throttling. config VM86 - bool "Enable VM86 support" if EMBEDDED default y - depends on X86_32 + bool "Enable VM86 support" if EMBEDDED help This option is required by programs like DOSEMU to run 16-bit legacy code on X86 processors. It also may be needed by software like @@ -599,7 +427,6 @@ config VM86 config TOSHIBA tristate "Toshiba Laptop support" - depends on X86_32 ---help--- This adds a driver to safely access the System Management Mode of the CPU on Toshiba portables with a genuine Toshiba BIOS. It does @@ -615,7 +442,6 @@ config TOSHIBA config I8K tristate "Dell laptop support" - depends on X86_32 ---help--- This adds a driver to safely access the System Management Mode of the CPU on the Dell Inspiron 8000. The System Management Mode @@ -636,7 +462,7 @@ config I8K config X86_REBOOTFIXUPS bool "Enable X86 board specific fixups for reboot" - depends on X86_32 && X86 + depends on X86 default n ---help--- This enables chipset and/or board specific fixups to be done @@ -691,11 +517,12 @@ config X86_CPUID with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to /dev/cpu/31/cpuid. +source "drivers/firmware/Kconfig" + choice prompt "High Memory Support" default HIGHMEM4G if !X86_NUMAQ default HIGHMEM64G if X86_NUMAQ - depends on X86_32 config NOHIGHMEM bool "off" @@ -755,7 +582,6 @@ choice depends on EXPERIMENTAL prompt "Memory split" if EMBEDDED default VMSPLIT_3G - depends on X86_32 help Select the desired split between kernel and user memory. @@ -793,17 +619,16 @@ config PAGE_OFFSET default 0x78000000 if VMSPLIT_2G_OPT default 0x40000000 if VMSPLIT_1G default 0xC0000000 - depends on X86_32 config HIGHMEM bool - depends on X86_32 && (HIGHMEM64G || HIGHMEM4G) + depends on HIGHMEM64G || HIGHMEM4G default y config X86_PAE bool "PAE (Physical Address Extension) Support" default n - depends on X86_32 && !HIGHMEM4G + depends on !HIGHMEM4G select RESOURCES_64BIT help PAE is required for NX support, and furthermore enables @@ -814,82 +639,46 @@ config X86_PAE # Common NUMA Features config NUMA bool "Numa Memory Allocation and Scheduler Support (EXPERIMENTAL)" - depends on SMP - depends on X86_64 || (X86_32 && HIGHMEM64G && (X86_NUMAQ || (X86_SUMMIT || X86_GENERICARCH) && ACPI) && EXPERIMENTAL) + depends on SMP && HIGHMEM64G && (X86_NUMAQ || (X86_SUMMIT || X86_GENERICARCH) && ACPI) && EXPERIMENTAL default n if X86_PC default y if (X86_NUMAQ || X86_SUMMIT) help - Enable NUMA (Non Uniform Memory Access) support. - The kernel will try to allocate memory used by a CPU on the - local memory controller of the CPU and add some more - NUMA awareness to the kernel. - - For i386 this is currently highly experimental and should be only - used for kernel development. It might also cause boot failures. - For x86_64 this is recommended on all multiprocessor Opteron systems. - If the system is EM64T, you should say N unless your system is - EM64T NUMA. + NUMA support for i386. This is currently highly experimental + and should be only used for kernel development. It might also + cause boot failures. comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI" - depends on X86_32 && X86_SUMMIT && (!HIGHMEM64G || !ACPI) - -config K8_NUMA - bool "Old style AMD Opteron NUMA detection" - depends on X86_64 && NUMA && PCI - default y - help - Enable K8 NUMA node topology detection. You should say Y here if - you have a multi processor AMD K8 system. This uses an old - method to read the NUMA configuration directly from the builtin - Northbridge of Opteron. It is recommended to use X86_64_ACPI_NUMA - instead, which also takes priority if both are compiled in. - -config X86_64_ACPI_NUMA - bool "ACPI NUMA detection" - depends on X86_64 && NUMA && ACPI && PCI - select ACPI_NUMA - default y - help - Enable ACPI SRAT based node topology detection. - -config NUMA_EMU - bool "NUMA emulation" - depends on X86_64 && NUMA - help - Enable NUMA emulation. A flat machine will be split - into virtual nodes when booted with "numa=fake=N", where N is the - number of nodes. This is only useful for debugging. + depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI) config NODES_SHIFT int - default "6" if X86_64 default "4" if X86_NUMAQ default "3" depends on NEED_MULTIPLE_NODES config HAVE_ARCH_BOOTMEM_NODE bool - depends on X86_32 && NUMA + depends on NUMA default y config ARCH_HAVE_MEMORY_PRESENT bool - depends on X86_32 && DISCONTIGMEM + depends on DISCONTIGMEM default y config NEED_NODE_MEMMAP_SIZE bool - depends on X86_32 && (DISCONTIGMEM || SPARSEMEM) + depends on DISCONTIGMEM || SPARSEMEM default y config HAVE_ARCH_ALLOC_REMAP bool - depends on X86_32 && NUMA + depends on NUMA default y config ARCH_FLATMEM_ENABLE def_bool y - depends on (X86_32 && ARCH_SELECT_MEMORY_MODEL && X86_PC) || (X86_64 && !NUMA) + depends on (ARCH_SELECT_MEMORY_MODEL && X86_PC) config ARCH_DISCONTIGMEM_ENABLE def_bool y @@ -901,23 +690,21 @@ config ARCH_DISCONTIGMEM_DEFAULT config ARCH_SPARSEMEM_ENABLE def_bool y - depends on NUMA || (EXPERIMENTAL && (X86_PC || X86_64)) - select SPARSEMEM_STATIC if X86_32 - select SPARSEMEM_VMEMMAP_ENABLE if X86_64 + depends on (NUMA || (X86_PC && EXPERIMENTAL)) + select SPARSEMEM_STATIC config ARCH_SELECT_MEMORY_MODEL def_bool y - depends on X86_32 && ARCH_SPARSEMEM_ENABLE + depends on ARCH_SPARSEMEM_ENABLE -config ARCH_MEMORY_PROBE - def_bool X86_64 - depends on MEMORY_HOTPLUG +config ARCH_POPULATES_NODE_MAP + def_bool y source "mm/Kconfig" config HIGHPTE bool "Allocate 3rd-level pagetables from highmem" - depends on X86_32 && (HIGHMEM4G || HIGHMEM64G) + depends on HIGHMEM4G || HIGHMEM64G help The VM uses one page table entry for each page of physical memory. For systems with a lot of RAM, this can be wasteful of precious @@ -925,8 +712,7 @@ config HIGHPTE entries in high memory. config MATH_EMULATION - bool - prompt "Math emulation" if X86_32 + bool "Math emulation" ---help--- Linux can emulate a math coprocessor (used for floating point operations) if you don't have one. 486DX and Pentium processors have @@ -986,7 +772,7 @@ config MTRR config EFI bool "Boot from EFI support" - depends on X86_32 && ACPI + depends on ACPI default n ---help--- This enables the kernel to boot on EFI platforms using @@ -1003,18 +789,18 @@ config EFI kernel should continue to boot on existing non-EFI platforms. config IRQBALANCE - bool "Enable kernel irq balancing" - depends on X86_32 && SMP && X86_IO_APIC + bool "Enable kernel irq balancing" + depends on SMP && X86_IO_APIC default y help - The default yes will allow the kernel to do irq load balancing. + The default yes will allow the kernel to do irq load balancing. Saying no will keep the kernel from doing irq load balancing. # turning this on wastes a bunch of space. # Summit needs it only when NUMA is on config BOOT_IOREMAP bool - depends on X86_32 && (((X86_SUMMIT || X86_GENERICARCH) && NUMA) || (X86 && EFI)) + depends on (((X86_SUMMIT || X86_GENERICARCH) && NUMA) || (X86 && EFI)) default y config SECCOMP @@ -1034,30 +820,6 @@ config SECCOMP If unsure, say Y. Only embedded should say N here. -config CC_STACKPROTECTOR - bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" - depends on X86_64 && EXPERIMENTAL - help - This option turns on the -fstack-protector GCC feature. This - feature puts, at the beginning of critical functions, a canary - value on the stack just before the return address, and validates - the value just before actually returning. Stack based buffer - overflows (that need to overwrite this return address) now also - overwrite the canary, which gets detected and the attack is then - neutralized via a kernel panic. - - This feature requires gcc version 4.2 or above, or a distribution - gcc with the feature backported. Older versions are automatically - detected and for those versions, this configuration option is ignored. - -config CC_STACKPROTECTOR_ALL - bool "Use stack-protector for all functions" - depends on CC_STACKPROTECTOR - help - Normally, GCC only inserts the canary value protection for - functions that use large-ish on-stack buffers. By enabling - this option, GCC will be asked to do this for ALL functions. - source kernel/Kconfig.hz config KEXEC @@ -1079,7 +841,7 @@ config KEXEC config CRASH_DUMP bool "kernel crash dumps (EXPERIMENTAL)" depends on EXPERIMENTAL - depends on X86_64 || (X86_32 && HIGHMEM) + depends on HIGHMEM help Generate crash dump after being started by kexec. This should be normally only set in special crash dump kernels @@ -1094,7 +856,6 @@ config CRASH_DUMP config PHYSICAL_START hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP) default "0x1000000" if X86_NUMAQ - default "0x200000" if X86_64 default "0x100000" help This gives the physical address where the kernel is loaded. @@ -1147,31 +908,25 @@ config RELOCATABLE must live at a different physical address than the primary kernel. - Note: If CONFIG_RELOCATABLE=y, then the kernel runs from the address - it has been loaded at and the compile time physical address - (CONFIG_PHYSICAL_START) is ignored. - config PHYSICAL_ALIGN - hex - prompt "Alignment value to which kernel should be aligned" if X86_32 - default "0x100000" if X86_32 - default "0x200000" if X86_64 + hex "Alignment value to which kernel should be aligned" + default "0x100000" range 0x2000 0x400000 help This value puts the alignment restrictions on physical address - where kernel is loaded and run from. Kernel is compiled for an - address which meets above alignment restriction. - - If bootloader loads the kernel at a non-aligned address and - CONFIG_RELOCATABLE is set, kernel will move itself to nearest - address aligned to above value and run from there. - - If bootloader loads the kernel at a non-aligned address and - CONFIG_RELOCATABLE is not set, kernel will ignore the run time - load address and decompress itself to the address it has been - compiled for and run from there. The address for which kernel is - compiled already meets above alignment restrictions. Hence the - end result is that kernel runs from a physical address meeting + where kernel is loaded and run from. Kernel is compiled for an + address which meets above alignment restriction. + + If bootloader loads the kernel at a non-aligned address and + CONFIG_RELOCATABLE is set, kernel will move itself to nearest + address aligned to above value and run from there. + + If bootloader loads the kernel at a non-aligned address and + CONFIG_RELOCATABLE is not set, kernel will ignore the run time + load address and decompress itself to the address it has been + compiled for and run from there. The address for which kernel is + compiled already meets above alignment restrictions. Hence the + end result is that kernel runs from a physical address meeting above alignment restrictions. Don't change this unless you know what you are doing. @@ -1183,13 +938,10 @@ config HOTPLUG_CPU Say Y here to experiment with turning CPUs off and on, and to enable suspend on SMP systems. CPUs can be controlled through /sys/devices/system/cpu. - Say N if you want to disable CPU hotplug and don't need to - suspend. config COMPAT_VDSO bool "Compat VDSO support" default y - depends on X86_32 help Map the VDSO to the predictable old-style address too. ---help--- @@ -1203,35 +955,18 @@ endmenu config ARCH_ENABLE_MEMORY_HOTPLUG def_bool y - depends on X86_64 || (X86_32 && HIGHMEM) - -config MEMORY_HOTPLUG_RESERVE - def_bool X86_64 - depends on (MEMORY_HOTPLUG && DISCONTIGMEM) - -config HAVE_ARCH_EARLY_PFN_TO_NID - def_bool X86_64 - depends on NUMA + depends on HIGHMEM -config OUT_OF_LINE_PFN_TO_PAGE - def_bool X86_64 - depends on DISCONTIGMEM - -menu "Power management options" +menu "Power management options (ACPI, APM)" depends on !X86_VOYAGER -config ARCH_HIBERNATION_HEADER - bool - depends on X86_64 && HIBERNATION - default y - -source "kernel/power/Kconfig" +source kernel/power/Kconfig source "drivers/acpi/Kconfig" menuconfig APM tristate "APM (Advanced Power Management) BIOS support" - depends on X86_32 && PM_SLEEP && !X86_VISWS + depends on PM_SLEEP && !X86_VISWS ---help--- APM is a BIOS specification for saving power using several different techniques. This is mostly useful for battery powered laptops with @@ -1357,14 +1092,13 @@ config APM_REAL_MODE_POWER_OFF endif # APM -source "arch/x86/kernel/cpu/cpufreq/Kconfig" +source "arch/x86/kernel/cpu/cpufreq/Kconfig_32" source "drivers/cpuidle/Kconfig" endmenu - -menu "Bus options (PCI etc.)" +menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)" config PCI bool "PCI support" if !X86_VISWS @@ -1384,7 +1118,7 @@ config PCI choice prompt "PCI access mode" - depends on X86_32 && PCI && !X86_VISWS + depends on PCI && !X86_VISWS default PCI_GOANY ---help--- On PCI systems, the BIOS can be used to detect the PCI devices and @@ -1417,18 +1151,17 @@ endchoice config PCI_BIOS bool - depends on X86_32 && !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY) + depends on !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY) default y -# x86-64 doesn't support PCI BIOS access from long mode so always go direct. config PCI_DIRECT bool - depends on PCI && (X86_64 || (PCI_GODIRECT || PCI_GOANY) || X86_VISWS) + depends on PCI && ((PCI_GODIRECT || PCI_GOANY) || X86_VISWS) default y config PCI_MMCONFIG bool - depends on X86_32 && PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY) + depends on PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY) default y config PCI_DOMAINS @@ -1436,52 +1169,14 @@ config PCI_DOMAINS depends on PCI default y -config PCI_MMCONFIG - bool "Support mmconfig PCI config space access" - depends on X86_64 && PCI && ACPI - -config DMAR - bool "Support for DMA Remapping Devices (EXPERIMENTAL)" - depends on X86_64 && PCI_MSI && ACPI && EXPERIMENTAL - help - DMA remapping (DMAR) devices support enables independent address - translations for Direct Memory Access (DMA) from devices. - These DMA remapping devices are reported via ACPI tables - and include PCI device scope covered by these DMA - remapping devices. - -config DMAR_GFX_WA - bool "Support for Graphics workaround" - depends on DMAR - default y - help - Current Graphics drivers tend to use physical address - for DMA and avoid using DMA APIs. Setting this config - option permits the IOMMU driver to set a unity map for - all the OS-visible memory. Hence the driver can continue - to use physical addresses for DMA. - -config DMAR_FLOPPY_WA - bool - depends on DMAR - default y - help - Floppy disk drivers are know to bypass DMA API calls - thereby failing to work when IOMMU is enabled. This - workaround will setup a 1:1 mapping for the first - 16M to make floppy (an ISA device) work. - source "drivers/pci/pcie/Kconfig" source "drivers/pci/Kconfig" -# x86_64 have no ISA slots, but do have ISA-style DMA. config ISA_DMA_API bool default y -if X86_32 - config ISA bool "ISA support" depends on !(X86_VOYAGER || X86_VISWS) @@ -1553,11 +1248,9 @@ config GEODE_MFGPT_TIMER MFGPTs have a better resolution and max interval than the generic PIT, and are suitable for use as high-res timers. -endif # X86_32 - config K8_NB def_bool y - depends on AGP_AMD64 || (X86_64 && (GART_IOMMU || (PCI && NUMA))) + depends on AGP_AMD64 source "drivers/pcmcia/Kconfig" @@ -1565,48 +1258,16 @@ source "drivers/pci/hotplug/Kconfig" endmenu - -menu "Executable file formats / Emulations" +menu "Executable file formats" source "fs/Kconfig.binfmt" -config IA32_EMULATION - bool "IA32 Emulation" - depends on X86_64 - help - Include code to run 32-bit programs under a 64-bit kernel. You should - likely turn this on, unless you're 100% sure that you don't have any - 32-bit programs left. - -config IA32_AOUT - tristate "IA32 a.out support" - depends on IA32_EMULATION - help - Support old a.out binaries in the 32bit emulation. - -config COMPAT - bool - depends on IA32_EMULATION - default y - -config COMPAT_FOR_U64_ALIGNMENT - def_bool COMPAT - depends on X86_64 - -config SYSVIPC_COMPAT - bool - depends on X86_64 && COMPAT && SYSVIPC - default y - endmenu - source "net/Kconfig" source "drivers/Kconfig" -source "drivers/firmware/Kconfig" - source "fs/Kconfig" source "kernel/Kconfig.instrumentation" @@ -1618,3 +1279,43 @@ source "security/Kconfig" source "crypto/Kconfig" source "lib/Kconfig" + +# +# Use the generic interrupt handling code in kernel/irq/: +# +config GENERIC_HARDIRQS + bool + default y + +config GENERIC_IRQ_PROBE + bool + default y + +config GENERIC_PENDING_IRQ + bool + depends on GENERIC_HARDIRQS && SMP + default y + +config X86_SMP + bool + depends on SMP && !X86_VOYAGER + default y + +config X86_HT + bool + depends on SMP && !(X86_VISWS || X86_VOYAGER) + default y + +config X86_BIOS_REBOOT + bool + depends on !(X86_VISWS || X86_VOYAGER) + default y + +config X86_TRAMPOLINE + bool + depends on X86_SMP || (X86_VOYAGER && SMP) + default y + +config KTIME_SCALAR + bool + default y diff --git a/trunk/arch/x86/Kconfig.x86_64 b/trunk/arch/x86/Kconfig.x86_64 new file mode 100644 index 000000000000..cc468ea61240 --- /dev/null +++ b/trunk/arch/x86/Kconfig.x86_64 @@ -0,0 +1,839 @@ +# +# For a description of the syntax of this configuration file, +# see Documentation/kbuild/kconfig-language.txt. +# +# Note: ISA is disabled and will hopefully never be enabled. +# If you managed to buy an ISA x86-64 box you'll have to fix all the +# ISA drivers you need yourself. +# + +mainmenu "Linux Kernel Configuration" + +config X86_64 + bool + default y + help + Port to the x86-64 architecture. x86-64 is a 64-bit extension to the + classical 32-bit x86 architecture. For details see + . + +config 64BIT + def_bool y + +config X86 + bool + default y + +config GENERIC_TIME + bool + default y + +config GENERIC_TIME_VSYSCALL + bool + default y + +config GENERIC_CMOS_UPDATE + bool + default y + +config CLOCKSOURCE_WATCHDOG + bool + default y + +config GENERIC_CLOCKEVENTS + bool + default y + +config GENERIC_CLOCKEVENTS_BROADCAST + bool + default y + +config ZONE_DMA32 + bool + default y + +config LOCKDEP_SUPPORT + bool + default y + +config STACKTRACE_SUPPORT + bool + default y + +config SEMAPHORE_SLEEPERS + bool + default y + +config MMU + bool + default y + +config ZONE_DMA + bool + default y + +config ISA + bool + +config SBUS + bool + +config RWSEM_GENERIC_SPINLOCK + bool + default y + +config RWSEM_XCHGADD_ALGORITHM + bool + +config GENERIC_HWEIGHT + bool + default y + +config GENERIC_CALIBRATE_DELAY + bool + default y + +config X86_CMPXCHG + bool + default y + +config GENERIC_ISA_DMA + bool + default y + +config GENERIC_IOMAP + bool + default y + +config ARCH_MAY_HAVE_PC_FDC + bool + default y + +config ARCH_POPULATES_NODE_MAP + def_bool y + +config DMI + bool + default y + +config AUDIT_ARCH + bool + default y + +config GENERIC_BUG + bool + default y + depends on BUG + +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + +source "init/Kconfig" + + +menu "Processor type and features" + +source "kernel/time/Kconfig" + +choice + prompt "Subarchitecture Type" + default X86_PC + +config X86_PC + bool "PC-compatible" + help + Choose this option if your computer is a standard PC or compatible. + +config X86_VSMP + bool "Support for ScaleMP vSMP" + depends on PCI + help + Support for ScaleMP vSMP systems. Say 'Y' here if this kernel is + supposed to run on these EM64T-based machines. Only choose this option + if you have one of these machines. + +endchoice + +choice + prompt "Processor family" + default GENERIC_CPU + +config MK8 + bool "AMD-Opteron/Athlon64" + help + Optimize for AMD Opteron/Athlon64/Hammer/K8 CPUs. + +config MPSC + bool "Intel P4 / older Netburst based Xeon" + help + Optimize for Intel Pentium 4, Pentium D and older Nocona/Dempsey + Xeon CPUs with Intel 64bit which is compatible with x86-64. + Note that the latest Xeons (Xeon 51xx and 53xx) are not based on the + Netburst core and shouldn't use this option. You can distinguish them + using the cpu family field + in /proc/cpuinfo. Family 15 is an older Xeon, Family 6 a newer one. + +config MCORE2 + bool "Intel Core2 / newer Xeon" + help + Optimize for Intel Core2 and newer Xeons (51xx) + You can distinguish the newer Xeons from the older ones using + the cpu family field in /proc/cpuinfo. 15 is an older Xeon + (use CONFIG_MPSC then), 6 is a newer one. + +config GENERIC_CPU + bool "Generic-x86-64" + help + Generic x86-64 CPU. + Run equally well on all x86-64 CPUs. + +endchoice + +# +# Define implied options from the CPU selection here +# +config X86_L1_CACHE_BYTES + int + default "128" if GENERIC_CPU || MPSC + default "64" if MK8 || MCORE2 + +config X86_L1_CACHE_SHIFT + int + default "7" if GENERIC_CPU || MPSC + default "6" if MK8 || MCORE2 + +config X86_INTERNODE_CACHE_BYTES + int + default "4096" if X86_VSMP + default X86_L1_CACHE_BYTES if !X86_VSMP + +config X86_TSC + bool + default y + +config X86_GOOD_APIC + bool + default y + +config MICROCODE + tristate "/dev/cpu/microcode - Intel CPU microcode support" + select FW_LOADER + ---help--- + If you say Y here the 'File systems' section, you will be + able to update the microcode on Intel processors. You will + obviously need the actual microcode binary data itself which is + not shipped with the Linux kernel. + + For latest news and information on obtaining all the required + ingredients for this driver, check: + . + + To compile this driver as a module, choose M here: the + module will be called microcode. + If you use modprobe or kmod you may also want to add the line + 'alias char-major-10-184 microcode' to your /etc/modules.conf file. + +config MICROCODE_OLD_INTERFACE + bool + depends on MICROCODE + default y + +config X86_MSR + tristate "/dev/cpu/*/msr - Model-specific register support" + help + This device gives privileged processes access to the x86 + Model-Specific Registers (MSRs). It is a character device with + major 202 and minors 0 to 31 for /dev/cpu/0/msr to /dev/cpu/31/msr. + MSR accesses are directed to a specific CPU on multi-processor + systems. + +config X86_CPUID + tristate "/dev/cpu/*/cpuid - CPU information support" + help + This device gives processes access to the x86 CPUID instruction to + be executed on a specific processor. It is a character device + with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to + /dev/cpu/31/cpuid. + +config X86_HT + bool + depends on SMP && !MK8 + default y + +config MATH_EMULATION + bool + +config MCA + bool + +config EISA + bool + +config X86_IO_APIC + bool + default y + +config X86_LOCAL_APIC + bool + default y + +config MTRR + bool "MTRR (Memory Type Range Register) support" + ---help--- + On Intel P6 family processors (Pentium Pro, Pentium II and later) + the Memory Type Range Registers (MTRRs) may be used to control + processor access to memory ranges. This is most useful if you have + a video (VGA) card on a PCI or AGP bus. Enabling write-combining + allows bus write transfers to be combined into a larger transfer + before bursting over the PCI/AGP bus. This can increase performance + of image write operations 2.5 times or more. Saying Y here creates a + /proc/mtrr file which may be used to manipulate your processor's + MTRRs. Typically the X server should use this. + + This code has a reasonably generic interface so that similar + control registers on other processors can be easily supported + as well. + + Saying Y here also fixes a problem with buggy SMP BIOSes which only + set the MTRRs for the boot CPU and not for the secondary CPUs. This + can lead to all sorts of problems, so it's good to say Y here. + + Just say Y here, all x86-64 machines support MTRRs. + + See for more information. + +config SMP + bool "Symmetric multi-processing support" + ---help--- + This enables support for systems with more than one CPU. If you have + a system with only one CPU, like most personal computers, say N. If + you have a system with more than one CPU, say Y. + + If you say N here, the kernel will run on single and multiprocessor + machines, but will use only one CPU of a multiprocessor machine. If + you say Y here, the kernel will run on many, but not all, + singleprocessor machines. On a singleprocessor machine, the kernel + will run faster if you say N here. + + If you don't know what to do here, say N. + +config SCHED_SMT + bool "SMT (Hyperthreading) scheduler support" + depends on SMP + default n + help + SMT scheduler support improves the CPU scheduler's decision making + when dealing with Intel Pentium 4 chips with HyperThreading at a + cost of slightly increased overhead in some places. If unsure say + N here. + +config SCHED_MC + bool "Multi-core scheduler support" + depends on SMP + default y + help + Multi-core scheduler support improves the CPU scheduler's decision + making when dealing with multi-core CPU chips at a cost of slightly + increased overhead in some places. If unsure say N here. + +source "kernel/Kconfig.preempt" + +config NUMA + bool "Non Uniform Memory Access (NUMA) Support" + depends on SMP + help + Enable NUMA (Non Uniform Memory Access) support. The kernel + will try to allocate memory used by a CPU on the local memory + controller of the CPU and add some more NUMA awareness to the kernel. + This code is recommended on all multiprocessor Opteron systems. + If the system is EM64T, you should say N unless your system is EM64T + NUMA. + +config K8_NUMA + bool "Old style AMD Opteron NUMA detection" + depends on NUMA && PCI + default y + help + Enable K8 NUMA node topology detection. You should say Y here if + you have a multi processor AMD K8 system. This uses an old + method to read the NUMA configuration directly from the builtin + Northbridge of Opteron. It is recommended to use X86_64_ACPI_NUMA + instead, which also takes priority if both are compiled in. + +config NODES_SHIFT + int + default "6" + depends on NEED_MULTIPLE_NODES + +# Dummy CONFIG option to select ACPI_NUMA from drivers/acpi/Kconfig. + +config X86_64_ACPI_NUMA + bool "ACPI NUMA detection" + depends on NUMA + select ACPI + select PCI + select ACPI_NUMA + default y + help + Enable ACPI SRAT based node topology detection. + +config NUMA_EMU + bool "NUMA emulation" + depends on NUMA + help + Enable NUMA emulation. A flat machine will be split + into virtual nodes when booted with "numa=fake=N", where N is the + number of nodes. This is only useful for debugging. + +config ARCH_DISCONTIGMEM_ENABLE + bool + depends on NUMA + default y + +config ARCH_DISCONTIGMEM_DEFAULT + def_bool y + depends on NUMA + +config ARCH_SPARSEMEM_ENABLE + def_bool y + depends on (NUMA || EXPERIMENTAL) + select SPARSEMEM_VMEMMAP_ENABLE + +config ARCH_MEMORY_PROBE + def_bool y + depends on MEMORY_HOTPLUG + +config ARCH_FLATMEM_ENABLE + def_bool y + depends on !NUMA + +source "mm/Kconfig" + +config MEMORY_HOTPLUG_RESERVE + def_bool y + depends on (MEMORY_HOTPLUG && DISCONTIGMEM) + +config HAVE_ARCH_EARLY_PFN_TO_NID + def_bool y + depends on NUMA + +config OUT_OF_LINE_PFN_TO_PAGE + def_bool y + depends on DISCONTIGMEM + +config NR_CPUS + int "Maximum number of CPUs (2-255)" + range 2 255 + depends on SMP + default "8" + help + This allows you to specify the maximum number of CPUs which this + kernel will support. Current maximum is 255 CPUs due to + APIC addressing limits. Less depending on the hardware. + + This is purely to save memory - each supported CPU requires + memory in the static kernel configuration. + +config PHYSICAL_ALIGN + hex + default "0x200000" + +config HOTPLUG_CPU + bool "Support for suspend on SMP and hot-pluggable CPUs (EXPERIMENTAL)" + depends on SMP && HOTPLUG && EXPERIMENTAL + help + Say Y here to experiment with turning CPUs off and on. CPUs + can be controlled through /sys/devices/system/cpu/cpu#. + This is also required for suspend/hibernation on SMP systems. + + Say N if you want to disable CPU hotplug and don't need to + suspend. + +config ARCH_ENABLE_MEMORY_HOTPLUG + def_bool y + +config HPET_TIMER + bool + default y + help + Use the IA-PC HPET (High Precision Event Timer) to manage + time in preference to the PIT and RTC, if a HPET is + present. The HPET provides a stable time base on SMP + systems, unlike the TSC, but it is more expensive to access, + as it is off-chip. You can find the HPET spec at + . + +config HPET_EMULATE_RTC + bool + depends on HPET_TIMER && RTC=y + default y + +# Mark as embedded because too many people got it wrong. +# The code disables itself when not needed. +config GART_IOMMU + bool "GART IOMMU support" if EMBEDDED + default y + select SWIOTLB + select AGP + depends on PCI + help + Support for full DMA access of devices with 32bit memory access only + on systems with more than 3GB. This is usually needed for USB, + sound, many IDE/SATA chipsets and some other devices. + Provides a driver for the AMD Athlon64/Opteron/Turion/Sempron GART + based hardware IOMMU and a software bounce buffer based IOMMU used + on Intel systems and as fallback. + The code is only active when needed (enough memory and limited + device) unless CONFIG_IOMMU_DEBUG or iommu=force is specified + too. + +config CALGARY_IOMMU + bool "IBM Calgary IOMMU support" + select SWIOTLB + depends on PCI && EXPERIMENTAL + help + Support for hardware IOMMUs in IBM's xSeries x366 and x460 + systems. Needed to run systems with more than 3GB of memory + properly with 32-bit PCI devices that do not support DAC + (Double Address Cycle). Calgary also supports bus level + isolation, where all DMAs pass through the IOMMU. This + prevents them from going anywhere except their intended + destination. This catches hard-to-find kernel bugs and + mis-behaving drivers and devices that do not use the DMA-API + properly to set up their DMA buffers. The IOMMU can be + turned off at boot time with the iommu=off parameter. + Normally the kernel will make the right choice by itself. + If unsure, say Y. + +config CALGARY_IOMMU_ENABLED_BY_DEFAULT + bool "Should Calgary be enabled by default?" + default y + depends on CALGARY_IOMMU + help + Should Calgary be enabled by default? if you choose 'y', Calgary + will be used (if it exists). If you choose 'n', Calgary will not be + used even if it exists. If you choose 'n' and would like to use + Calgary anyway, pass 'iommu=calgary' on the kernel command line. + If unsure, say Y. + +# need this always selected by IOMMU for the VIA workaround +config SWIOTLB + bool + help + Support for software bounce buffers used on x86-64 systems + which don't have a hardware IOMMU (e.g. the current generation + of Intel's x86-64 CPUs). Using this PCI devices which can only + access 32-bits of memory can be used on systems with more than + 3 GB of memory. If unsure, say Y. + +config X86_MCE + bool "Machine check support" if EMBEDDED + default y + help + Include a machine check error handler to report hardware errors. + This version will require the mcelog utility to decode some + machine check error logs. See + ftp://ftp.x86-64.org/pub/linux/tools/mcelog + +config X86_MCE_INTEL + bool "Intel MCE features" + depends on X86_MCE && X86_LOCAL_APIC + default y + help + Additional support for intel specific MCE features such as + the thermal monitor. + +config X86_MCE_AMD + bool "AMD MCE features" + depends on X86_MCE && X86_LOCAL_APIC + default y + help + Additional support for AMD specific MCE features such as + the DRAM Error Threshold. + +config KEXEC + bool "kexec system call" + help + kexec is a system call that implements the ability to shutdown your + current kernel, and to start another kernel. It is like a reboot + but it is independent of the system firmware. And like a reboot + you can start any kernel with it, not just Linux. + + The name comes from the similarity to the exec system call. + + It is an ongoing process to be certain the hardware in a machine + is properly shutdown, so do not be surprised if this code does not + initially work for you. It may help to enable device hotplugging + support. As of this writing the exact hardware interface is + strongly in flux, so no good recommendation can be made. + +config CRASH_DUMP + bool "kernel crash dumps (EXPERIMENTAL)" + depends on EXPERIMENTAL + help + Generate crash dump after being started by kexec. + This should be normally only set in special crash dump kernels + which are loaded in the main kernel with kexec-tools into + a specially reserved region and then later executed after + a crash by kdump/kexec. The crash dump kernel must be compiled + to a memory address not used by the main kernel or BIOS using + PHYSICAL_START, or it must be built as a relocatable image + (CONFIG_RELOCATABLE=y). + For more details see Documentation/kdump/kdump.txt + +config RELOCATABLE + bool "Build a relocatable kernel (EXPERIMENTAL)" + depends on EXPERIMENTAL + help + Builds a relocatable kernel. This enables loading and running + a kernel binary from a different physical address than it has + been compiled for. + + One use is for the kexec on panic case where the recovery kernel + must live at a different physical address than the primary + kernel. + + Note: If CONFIG_RELOCATABLE=y, then the kernel runs from the address + it has been loaded at and the compile time physical address + (CONFIG_PHYSICAL_START) is ignored. + +config PHYSICAL_START + hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP) + default "0x200000" + help + This gives the physical address where the kernel is loaded. It + should be aligned to 2MB boundary. + + If kernel is a not relocatable (CONFIG_RELOCATABLE=n) then + bzImage will decompress itself to above physical address and + run from there. Otherwise, bzImage will run from the address where + it has been loaded by the boot loader and will ignore above physical + address. + + In normal kdump cases one does not have to set/change this option + as now bzImage can be compiled as a completely relocatable image + (CONFIG_RELOCATABLE=y) and be used to load and run from a different + address. This option is mainly useful for the folks who don't want + to use a bzImage for capturing the crash dump and want to use a + vmlinux instead. + + So if you are using bzImage for capturing the crash dump, leave + the value here unchanged to 0x200000 and set CONFIG_RELOCATABLE=y. + Otherwise if you plan to use vmlinux for capturing the crash dump + change this value to start of the reserved region (Typically 16MB + 0x1000000). In other words, it can be set based on the "X" value as + specified in the "crashkernel=YM@XM" command line boot parameter + passed to the panic-ed kernel. Typically this parameter is set as + crashkernel=64M@16M. Please take a look at + Documentation/kdump/kdump.txt for more details about crash dumps. + + Usage of bzImage for capturing the crash dump is advantageous as + one does not have to build two kernels. Same kernel can be used + as production kernel and capture kernel. + + Don't change this unless you know what you are doing. + +config SECCOMP + bool "Enable seccomp to safely compute untrusted bytecode" + depends on PROC_FS + default y + help + This kernel feature is useful for number crunching applications + that may need to compute untrusted bytecode during their + execution. By using pipes or other transports made available to + the process as file descriptors supporting the read/write + syscalls, it's possible to isolate those applications in + their own address space using seccomp. Once seccomp is + enabled via /proc//seccomp, it cannot be disabled + and the task is only allowed to execute a few safe syscalls + defined by each seccomp mode. + + If unsure, say Y. Only embedded should say N here. + +config CC_STACKPROTECTOR + bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" + depends on EXPERIMENTAL + help + This option turns on the -fstack-protector GCC feature. This + feature puts, at the beginning of critical functions, a canary + value on the stack just before the return address, and validates + the value just before actually returning. Stack based buffer + overflows (that need to overwrite this return address) now also + overwrite the canary, which gets detected and the attack is then + neutralized via a kernel panic. + + This feature requires gcc version 4.2 or above, or a distribution + gcc with the feature backported. Older versions are automatically + detected and for those versions, this configuration option is ignored. + +config CC_STACKPROTECTOR_ALL + bool "Use stack-protector for all functions" + depends on CC_STACKPROTECTOR + help + Normally, GCC only inserts the canary value protection for + functions that use large-ish on-stack buffers. By enabling + this option, GCC will be asked to do this for ALL functions. + +source kernel/Kconfig.hz + +config K8_NB + def_bool y + depends on AGP_AMD64 || GART_IOMMU || (PCI && NUMA) + +endmenu + +# +# Use the generic interrupt handling code in kernel/irq/: +# +config GENERIC_HARDIRQS + bool + default y + +config GENERIC_IRQ_PROBE + bool + default y + +# we have no ISA slots, but we do have ISA-style DMA. +config ISA_DMA_API + bool + default y + +config GENERIC_PENDING_IRQ + bool + depends on GENERIC_HARDIRQS && SMP + default y + +menu "Power management options" + +source kernel/power/Kconfig + +config ARCH_HIBERNATION_HEADER + bool + depends on HIBERNATION + default y + +source "drivers/acpi/Kconfig" + +source "arch/x86/kernel/cpu/cpufreq/Kconfig_64" + +source "drivers/cpuidle/Kconfig" + +endmenu + +menu "Bus options (PCI etc.)" + +config PCI + bool "PCI support" + select ARCH_SUPPORTS_MSI if (X86_LOCAL_APIC && X86_IO_APIC) + +# x86-64 doesn't support PCI BIOS access from long mode so always go direct. +config PCI_DIRECT + bool + depends on PCI + default y + +config PCI_MMCONFIG + bool "Support mmconfig PCI config space access" + depends on PCI && ACPI + +config PCI_DOMAINS + bool + depends on PCI + default y + +config DMAR + bool "Support for DMA Remapping Devices (EXPERIMENTAL)" + depends on PCI_MSI && ACPI && EXPERIMENTAL + help + DMA remapping (DMAR) devices support enables independent address + translations for Direct Memory Access (DMA) from devices. + These DMA remapping devices are reported via ACPI tables + and include PCI device scope covered by these DMA + remapping devices. + +config DMAR_GFX_WA + bool "Support for Graphics workaround" + depends on DMAR + default y + help + Current Graphics drivers tend to use physical address + for DMA and avoid using DMA APIs. Setting this config + option permits the IOMMU driver to set a unity map for + all the OS-visible memory. Hence the driver can continue + to use physical addresses for DMA. + +config DMAR_FLOPPY_WA + bool + depends on DMAR + default y + help + Floppy disk drivers are know to bypass DMA API calls + thereby failing to work when IOMMU is enabled. This + workaround will setup a 1:1 mapping for the first + 16M to make floppy (an ISA device) work. + +source "drivers/pci/pcie/Kconfig" + +source "drivers/pci/Kconfig" + +source "drivers/pcmcia/Kconfig" + +source "drivers/pci/hotplug/Kconfig" + +endmenu + + +menu "Executable file formats / Emulations" + +source "fs/Kconfig.binfmt" + +config IA32_EMULATION + bool "IA32 Emulation" + help + Include code to run 32-bit programs under a 64-bit kernel. You should + likely turn this on, unless you're 100% sure that you don't have any + 32-bit programs left. + +config IA32_AOUT + tristate "IA32 a.out support" + depends on IA32_EMULATION + help + Support old a.out binaries in the 32bit emulation. + +config COMPAT + bool + depends on IA32_EMULATION + default y + +config COMPAT_FOR_U64_ALIGNMENT + def_bool COMPAT + +config SYSVIPC_COMPAT + bool + depends on COMPAT && SYSVIPC + default y + +endmenu + +source "net/Kconfig" + +source drivers/Kconfig + +source "drivers/firmware/Kconfig" + +source fs/Kconfig + +source "kernel/Kconfig.instrumentation" + +source "arch/x86/Kconfig.debug" + +source "security/Kconfig" + +source "crypto/Kconfig" + +source "lib/Kconfig" diff --git a/trunk/arch/x86/Makefile b/trunk/arch/x86/Makefile index 116b03a45636..309597386a77 100644 --- a/trunk/arch/x86/Makefile +++ b/trunk/arch/x86/Makefile @@ -1,16 +1,12 @@ # Unified Makefile for i386 and x86_64 # select defconfig based on actual architecture -ifeq ($(ARCH),x86) - KBUILD_DEFCONFIG := i386_defconfig -else - KBUILD_DEFCONFIG := $(ARCH)_defconfig -endif +KBUILD_DEFCONFIG := $(ARCH)_defconfig -# No need to remake these files +# # No need to remake these files $(srctree)/arch/x86/Makefile%: ; -ifeq ($(CONFIG_X86_32),y) +ifeq ($(ARCH),i386) include $(srctree)/arch/x86/Makefile_32 else include $(srctree)/arch/x86/Makefile_64 diff --git a/trunk/arch/x86/Makefile_32 b/trunk/arch/x86/Makefile_32 index 50394da2f6c1..346ac0766875 100644 --- a/trunk/arch/x86/Makefile_32 +++ b/trunk/arch/x86/Makefile_32 @@ -160,7 +160,7 @@ archclean: $(Q)$(MAKE) $(clean)=arch/x86/boot define archhelp - echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)' + echo '* bzImage - Compressed kernel image (arch/$(ARCH)/boot/bzImage)' echo ' install - Install kernel using' echo ' (your) ~/bin/installkernel or' echo ' (distribution) /sbin/installkernel or' @@ -170,6 +170,6 @@ define archhelp echo ' isoimage - Create a boot CD-ROM image' endef -CLEAN_FILES += arch/x86/boot/fdimage \ - arch/x86/boot/image.iso \ - arch/x86/boot/mtools.conf +CLEAN_FILES += arch/$(ARCH)/boot/fdimage \ + arch/$(ARCH)/boot/image.iso \ + arch/$(ARCH)/boot/mtools.conf diff --git a/trunk/arch/x86/Makefile_64 b/trunk/arch/x86/Makefile_64 index a804860022e6..57e714a47af7 100644 --- a/trunk/arch/x86/Makefile_64 +++ b/trunk/arch/x86/Makefile_64 @@ -127,7 +127,7 @@ archclean: $(Q)$(MAKE) $(clean)=$(boot) define archhelp - echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)' + echo '* bzImage - Compressed kernel image (arch/$(ARCH)/boot/bzImage)' echo ' install - Install kernel using' echo ' (your) ~/bin/installkernel or' echo ' (distribution) /sbin/installkernel or' @@ -137,8 +137,8 @@ define archhelp echo ' isoimage - Create a boot CD-ROM image' endef -CLEAN_FILES += arch/x86/boot/fdimage \ - arch/x86/boot/image.iso \ - arch/x86/boot/mtools.conf +CLEAN_FILES += arch/$(ARCH)/boot/fdimage \ + arch/$(ARCH)/boot/image.iso \ + arch/$(ARCH)/boot/mtools.conf diff --git a/trunk/arch/x86/boot/Makefile b/trunk/arch/x86/boot/Makefile index 7a3116ccf387..89dbf970e058 100644 --- a/trunk/arch/x86/boot/Makefile +++ b/trunk/arch/x86/boot/Makefile @@ -49,10 +49,10 @@ HOSTCFLAGS_build.o := $(LINUXINCLUDE) # How to compile the 16-bit code. Note we always compile for -march=i386, # that way we can complain to the user if the CPU is insufficient. -cflags-$(CONFIG_X86_32) := -cflags-$(CONFIG_X86_64) := -m32 +cflags-i386 := +cflags-x86_64 := -m32 KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \ - $(cflags-y) \ + $(cflags-$(ARCH)) \ -Wall -Wstrict-prototypes \ -march=i386 -mregparm=3 \ -include $(srctree)/$(src)/code16gcc.h \ diff --git a/trunk/arch/x86/boot/cpucheck.c b/trunk/arch/x86/boot/cpucheck.c index 769065bd23d7..e655a89c5510 100644 --- a/trunk/arch/x86/boot/cpucheck.c +++ b/trunk/arch/x86/boot/cpucheck.c @@ -42,7 +42,13 @@ static struct cpu_features cpu; static u32 cpu_vendor[3]; static u32 err_flags[NCAPINTS]; +#ifdef CONFIG_X86_64 +static const int req_level = 64; +#elif defined(CONFIG_X86_MINIMUM_CPU_FAMILY) static const int req_level = CONFIG_X86_MINIMUM_CPU_FAMILY; +#else +static const int req_level = 3; +#endif static const u32 req_flags[NCAPINTS] = { diff --git a/trunk/arch/x86/kernel/Makefile_32 b/trunk/arch/x86/kernel/Makefile_32 index a7bc93c27662..b9d679820306 100644 --- a/trunk/arch/x86/kernel/Makefile_32 +++ b/trunk/arch/x86/kernel/Makefile_32 @@ -3,7 +3,6 @@ # extra-y := head_32.o init_task.o vmlinux.lds -CPPFLAGS_vmlinux.lds += -Ui386 obj-y := process_32.o signal_32.o entry_32.o traps_32.o irq_32.o \ ptrace_32.o time_32.o ioport_32.o ldt_32.o setup_32.o i8259_32.o sys_i386_32.o \ @@ -61,7 +60,7 @@ quiet_cmd_syscall = SYSCALL $@ cmd_syscall = $(CC) -m elf_i386 -nostdlib $(SYSCFLAGS_$(@F)) \ -Wl,-T,$(filter-out FORCE,$^) -o $@ -export CPPFLAGS_vsyscall_32.lds += -P -C -Ui386 +export CPPFLAGS_vsyscall_32.lds += -P -C -U$(ARCH) vsyscall-flags = -shared -s -Wl,-soname=linux-gate.so.1 \ $(call ld-option, -Wl$(comma)--hash-style=sysv) diff --git a/trunk/arch/x86/kernel/Makefile_64 b/trunk/arch/x86/kernel/Makefile_64 index 5a88890d8ee9..24671c3838b3 100644 --- a/trunk/arch/x86/kernel/Makefile_64 +++ b/trunk/arch/x86/kernel/Makefile_64 @@ -3,9 +3,7 @@ # extra-y := head_64.o head64.o init_task.o vmlinux.lds -CPPFLAGS_vmlinux.lds += -Ux86_64 EXTRA_AFLAGS := -traditional - obj-y := process_64.o signal_64.o entry_64.o traps_64.o irq_64.o \ ptrace_64.o time_64.o ioport_64.o ldt_64.o setup_64.o i8259_64.o sys_x86_64.o \ x8664_ksyms_64.o i387_64.o syscall_64.o vsyscall_64.o \ diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/Kconfig b/trunk/arch/x86/kernel/cpu/cpufreq/Kconfig_32 similarity index 77% rename from trunk/arch/x86/kernel/cpu/cpufreq/Kconfig rename to trunk/arch/x86/kernel/cpu/cpufreq/Kconfig_32 index 151eda0a23fc..d8c6f132dc7a 100644 --- a/trunk/arch/x86/kernel/cpu/cpufreq/Kconfig +++ b/trunk/arch/x86/kernel/cpu/cpufreq/Kconfig_32 @@ -19,9 +19,6 @@ config X86_ACPI_CPUFREQ Processor Performance States. This driver also supports Intel Enhanced Speedstep. - To compile this driver as a module, choose M here: the - module will be called acpi-cpufreq. - For details, take a look at . If in doubt, say N. @@ -29,7 +26,7 @@ config X86_ACPI_CPUFREQ config ELAN_CPUFREQ tristate "AMD Elan SC400 and SC410" select CPU_FREQ_TABLE - depends on X86_32 && X86_ELAN + depends on X86_ELAN ---help--- This adds the CPUFreq driver for AMD Elan SC400 and SC410 processors. @@ -45,7 +42,7 @@ config ELAN_CPUFREQ config SC520_CPUFREQ tristate "AMD Elan SC520" select CPU_FREQ_TABLE - depends on X86_32 && X86_ELAN + depends on X86_ELAN ---help--- This adds the CPUFreq driver for AMD Elan SC520 processor. @@ -57,7 +54,6 @@ config SC520_CPUFREQ config X86_POWERNOW_K6 tristate "AMD Mobile K6-2/K6-3 PowerNow!" select CPU_FREQ_TABLE - depends on X86_32 help This adds the CPUFreq driver for mobile AMD K6-2+ and mobile AMD K6-3+ processors. @@ -69,7 +65,6 @@ config X86_POWERNOW_K6 config X86_POWERNOW_K7 tristate "AMD Mobile Athlon/Duron PowerNow!" select CPU_FREQ_TABLE - depends on X86_32 help This adds the CPUFreq driver for mobile AMD K7 mobile processors. @@ -81,27 +76,23 @@ config X86_POWERNOW_K7_ACPI bool depends on X86_POWERNOW_K7 && ACPI_PROCESSOR depends on !(X86_POWERNOW_K7 = y && ACPI_PROCESSOR = m) - depends on X86_32 default y config X86_POWERNOW_K8 tristate "AMD Opteron/Athlon64 PowerNow!" select CPU_FREQ_TABLE + depends on EXPERIMENTAL help This adds the CPUFreq driver for mobile AMD Opteron/Athlon64 processors. - To compile this driver as a module, choose M here: the - module will be called powernow-k8. - For details, take a look at . If in doubt, say N. config X86_POWERNOW_K8_ACPI - bool - prompt "ACPI Support" if X86_32 - depends on ACPI && X86_POWERNOW_K8 && ACPI_PROCESSOR - depends on !(X86_POWERNOW_K8 = y && ACPI_PROCESSOR = m) + bool "ACPI Support" + select ACPI_PROCESSOR + depends on ACPI && X86_POWERNOW_K8 default y help This provides access to the K8s Processor Performance States via ACPI. @@ -113,7 +104,7 @@ config X86_POWERNOW_K8_ACPI config X86_GX_SUSPMOD tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation" - depends on X86_32 && PCI + depends on PCI help This add the CPUFreq driver for NatSemi Geode processors which support suspend modulation. @@ -123,20 +114,15 @@ config X86_GX_SUSPMOD If in doubt, say N. config X86_SPEEDSTEP_CENTRINO - tristate "Intel Enhanced SpeedStep (deprecated)" + tristate "Intel Enhanced SpeedStep" select CPU_FREQ_TABLE - select X86_SPEEDSTEP_CENTRINO_TABLE if X86_32 - depends on X86_32 || (X86_64 && ACPI_PROCESSOR) + select X86_SPEEDSTEP_CENTRINO_TABLE help - This is deprecated and this functionality is now merged into - acpi_cpufreq (X86_ACPI_CPUFREQ). Use that driver instead of - speedstep_centrino. This adds the CPUFreq driver for Enhanced SpeedStep enabled - mobile CPUs. This means Intel Pentium M (Centrino) CPUs - or 64bit enabled Intel Xeons. - - To compile this driver as a module, choose M here: the - module will be called speedstep-centrino. + mobile CPUs. This means Intel Pentium M (Centrino) CPUs. However, + you also need to say Y to "Use ACPI tables to decode..." below + [which might imply enabling ACPI] if you want to use this driver + on non-Banias CPUs. For details, take a look at . @@ -144,7 +130,7 @@ config X86_SPEEDSTEP_CENTRINO config X86_SPEEDSTEP_CENTRINO_TABLE bool "Built-in tables for Banias CPUs" - depends on X86_32 && X86_SPEEDSTEP_CENTRINO + depends on X86_SPEEDSTEP_CENTRINO default y help Use built-in tables for Banias CPUs if ACPI encoding @@ -155,7 +141,6 @@ config X86_SPEEDSTEP_CENTRINO_TABLE config X86_SPEEDSTEP_ICH tristate "Intel Speedstep on ICH-M chipsets (ioport interface)" select CPU_FREQ_TABLE - depends on X86_32 help This adds the CPUFreq driver for certain mobile Intel Pentium III (Coppermine), all mobile Intel Pentium III-M (Tualatin) and all @@ -169,7 +154,7 @@ config X86_SPEEDSTEP_ICH config X86_SPEEDSTEP_SMI tristate "Intel SpeedStep on 440BX/ZX/MX chipsets (SMI interface)" select CPU_FREQ_TABLE - depends on X86_32 && EXPERIMENTAL + depends on EXPERIMENTAL help This adds the CPUFreq driver for certain mobile Intel Pentium III (Coppermine), all mobile Intel Pentium III-M (Tualatin) @@ -184,24 +169,15 @@ config X86_P4_CLOCKMOD select CPU_FREQ_TABLE help This adds the CPUFreq driver for Intel Pentium 4 / XEON - processors. When enabled it will lower CPU temperature by skipping - clocks. - - This driver should be only used in exceptional - circumstances when very low power is needed because it causes severe - slowdowns and noticeable latencies. Normally Speedstep should be used - instead. - - To compile this driver as a module, choose M here: the - module will be called p4-clockmod. + processors. For details, take a look at . - Unless you are absolutely sure say N. + If in doubt, say N. config X86_CPUFREQ_NFORCE2 tristate "nVidia nForce2 FSB changing" - depends on X86_32 && EXPERIMENTAL + depends on EXPERIMENTAL help This adds the CPUFreq driver for FSB changing on nVidia nForce2 platforms. @@ -212,7 +188,6 @@ config X86_CPUFREQ_NFORCE2 config X86_LONGRUN tristate "Transmeta LongRun" - depends on X86_32 help This adds the CPUFreq driver for Transmeta Crusoe and Efficeon processors which support LongRun. @@ -224,7 +199,7 @@ config X86_LONGRUN config X86_LONGHAUL tristate "VIA Cyrix III Longhaul" select CPU_FREQ_TABLE - depends on X86_32 && ACPI_PROCESSOR + depends on ACPI_PROCESSOR help This adds the CPUFreq driver for VIA Samuel/CyrixIII, VIA Cyrix Samuel/C3, VIA Cyrix Ezra and VIA Cyrix Ezra-T @@ -237,7 +212,7 @@ config X86_LONGHAUL config X86_E_POWERSAVER tristate "VIA C7 Enhanced PowerSaver (EXPERIMENTAL)" select CPU_FREQ_TABLE - depends on X86_32 && EXPERIMENTAL + depends on EXPERIMENTAL help This adds the CPUFreq driver for VIA C7 processors. @@ -258,11 +233,11 @@ config X86_ACPI_CPUFREQ_PROC_INTF config X86_SPEEDSTEP_LIB tristate - default (X86_SPEEDSTEP_ICH || X86_SPEEDSTEP_SMI || X86_P4_CLOCKMOD) + default X86_SPEEDSTEP_ICH || X86_SPEEDSTEP_SMI || X86_P4_CLOCKMOD config X86_SPEEDSTEP_RELAXED_CAP_CHECK bool "Relaxed speedstep capability checks" - depends on X86_32 && (X86_SPEEDSTEP_SMI || X86_SPEEDSTEP_ICH) + depends on (X86_SPEEDSTEP_SMI || X86_SPEEDSTEP_ICH) help Don't perform all checks for a speedstep capable system which would normally be done. Some ancient or strange systems, though speedstep diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/Kconfig_64 b/trunk/arch/x86/kernel/cpu/cpufreq/Kconfig_64 new file mode 100644 index 000000000000..9c9699fdcf52 --- /dev/null +++ b/trunk/arch/x86/kernel/cpu/cpufreq/Kconfig_64 @@ -0,0 +1,108 @@ +# +# CPU Frequency scaling +# + +menu "CPU Frequency scaling" + +source "drivers/cpufreq/Kconfig" + +if CPU_FREQ + +comment "CPUFreq processor drivers" + +config X86_POWERNOW_K8 + tristate "AMD Opteron/Athlon64 PowerNow!" + select CPU_FREQ_TABLE + help + This adds the CPUFreq driver for mobile AMD Opteron/Athlon64 processors. + + To compile this driver as a module, choose M here: the + module will be called powernow-k8. + + For details, take a look at . + + If in doubt, say N. + +config X86_POWERNOW_K8_ACPI + bool + depends on X86_POWERNOW_K8 && ACPI_PROCESSOR + depends on !(X86_POWERNOW_K8 = y && ACPI_PROCESSOR = m) + default y + +config X86_SPEEDSTEP_CENTRINO + tristate "Intel Enhanced SpeedStep (deprecated)" + select CPU_FREQ_TABLE + depends on ACPI_PROCESSOR + help + This is deprecated and this functionality is now merged into + acpi_cpufreq (X86_ACPI_CPUFREQ). Use that driver instead of + speedstep_centrino. + This adds the CPUFreq driver for Enhanced SpeedStep enabled + mobile CPUs. This means Intel Pentium M (Centrino) CPUs + or 64bit enabled Intel Xeons. + + To compile this driver as a module, choose M here: the + module will be called speedstep-centrino. + + For details, take a look at . + + If in doubt, say N. + +config X86_ACPI_CPUFREQ + tristate "ACPI Processor P-States driver" + select CPU_FREQ_TABLE + depends on ACPI_PROCESSOR + help + This driver adds a CPUFreq driver which utilizes the ACPI + Processor Performance States. + This driver also supports Intel Enhanced Speedstep. + + To compile this driver as a module, choose M here: the + module will be called acpi-cpufreq. + + For details, take a look at . + + If in doubt, say N. + +comment "shared options" + +config X86_ACPI_CPUFREQ_PROC_INTF + bool "/proc/acpi/processor/../performance interface (deprecated)" + depends on PROC_FS + depends on X86_ACPI_CPUFREQ || X86_POWERNOW_K8_ACPI + help + This enables the deprecated /proc/acpi/processor/../performance + interface. While it is helpful for debugging, the generic, + cross-architecture cpufreq interfaces should be used. + + If in doubt, say N. + +config X86_P4_CLOCKMOD + tristate "Intel Pentium 4 clock modulation" + depends on EMBEDDED + select CPU_FREQ_TABLE + help + This adds the clock modulation driver for Intel Pentium 4 / XEON + processors. When enabled it will lower CPU temperature by skipping + clocks. + + This driver should be only used in exceptional + circumstances when very low power is needed because it causes severe + slowdowns and noticeable latencies. Normally Speedstep should be used + instead. + + To compile this driver as a module, choose M here: the + module will be called p4-clockmod. + + For details, take a look at . + + Unless you are absolutely sure say N. + + +config X86_SPEEDSTEP_LIB + tristate + default X86_P4_CLOCKMOD + +endif + +endmenu diff --git a/trunk/arch/x86/kernel/cpu/mcheck/mce_64.c b/trunk/arch/x86/kernel/cpu/mcheck/mce_64.c index 447b351f1f2a..b9f802e35209 100644 --- a/trunk/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/trunk/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -802,8 +802,6 @@ static struct sysdev_attribute *mce_attributes[] = { NULL }; -static cpumask_t mce_device_initialized = CPU_MASK_NONE; - /* Per cpu sysdev init. All of the cpus still share the same ctl bank */ static __cpuinit int mce_create_device(unsigned int cpu) { @@ -827,7 +825,6 @@ static __cpuinit int mce_create_device(unsigned int cpu) if (err) goto error; } - cpu_set(cpu, mce_device_initialized); return 0; error: @@ -844,14 +841,10 @@ static void mce_remove_device(unsigned int cpu) { int i; - if (!cpu_isset(cpu, mce_device_initialized)) - return; - for (i = 0; mce_attributes[i]; i++) sysdev_remove_file(&per_cpu(device_mce,cpu), mce_attributes[i]); sysdev_unregister(&per_cpu(device_mce,cpu)); - cpu_clear(cpu, mce_device_initialized); } /* Get notified when a cpu comes on/off. Be hotplug friendly. */ @@ -859,18 +852,21 @@ static int mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; + int err = 0; switch (action) { - case CPU_ONLINE: - case CPU_ONLINE_FROZEN: - mce_create_device(cpu); + case CPU_UP_PREPARE: + case CPU_UP_PREPARE_FROZEN: + err = mce_create_device(cpu); break; + case CPU_UP_CANCELED: + case CPU_UP_CANCELED_FROZEN: case CPU_DEAD: case CPU_DEAD_FROZEN: mce_remove_device(cpu); break; } - return NOTIFY_OK; + return err ? NOTIFY_BAD : NOTIFY_OK; } static struct notifier_block mce_cpu_notifier = { diff --git a/trunk/arch/x86/lib/delay_32.c b/trunk/arch/x86/lib/delay_32.c index aad9d95469dc..952e7a89c2ac 100644 --- a/trunk/arch/x86/lib/delay_32.c +++ b/trunk/arch/x86/lib/delay_32.c @@ -12,7 +12,6 @@ #include #include -#include #include #include @@ -43,13 +42,11 @@ static void delay_tsc(unsigned long loops) { unsigned long bclock, now; - preempt_disable(); /* TSC's are per-cpu */ rdtscl(bclock); do { rep_nop(); rdtscl(now); } while ((now-bclock) < loops); - preempt_enable(); } /* diff --git a/trunk/arch/x86/lib/delay_64.c b/trunk/arch/x86/lib/delay_64.c index 45cdd3fbd91c..0ebbfb9e7c7f 100644 --- a/trunk/arch/x86/lib/delay_64.c +++ b/trunk/arch/x86/lib/delay_64.c @@ -10,9 +10,7 @@ #include #include -#include #include - #include #include @@ -29,15 +27,14 @@ int read_current_timer(unsigned long *timer_value) void __delay(unsigned long loops) { unsigned bclock, now; - - preempt_disable(); /* TSC's are pre-cpu */ + rdtscl(bclock); - do { + do + { rep_nop(); rdtscl(now); } - while ((now-bclock) < loops); - preempt_enable(); + while((now-bclock) < loops); } EXPORT_SYMBOL(__delay); diff --git a/trunk/arch/x86/vdso/Makefile b/trunk/arch/x86/vdso/Makefile index e7bff0fbac23..7a2ba4583939 100644 --- a/trunk/arch/x86/vdso/Makefile +++ b/trunk/arch/x86/vdso/Makefile @@ -20,7 +20,7 @@ quiet_cmd_syscall = SYSCALL $@ cmd_syscall = $(CC) -m elf_x86_64 -nostdlib $(SYSCFLAGS_$(@F)) \ -Wl,-T,$(filter-out FORCE,$^) -o $@ -export CPPFLAGS_vdso.lds += -P -C +export CPPFLAGS_vdso.lds += -P -C -U$(ARCH) vdso-flags = -fPIC -shared -Wl,-soname=linux-vdso.so.1 \ $(call ld-option, -Wl$(comma)--hash-style=sysv) \ diff --git a/trunk/drivers/acpi/Kconfig b/trunk/drivers/acpi/Kconfig index 087a7028ae84..ce9dead0f499 100644 --- a/trunk/drivers/acpi/Kconfig +++ b/trunk/drivers/acpi/Kconfig @@ -50,7 +50,6 @@ config ACPI_SLEEP config ACPI_PROCFS bool "Deprecated /proc/acpi files" depends on PROC_FS - default y ---help--- For backwards compatibility, this option allows deprecated /proc/acpi/ files to exist, even when diff --git a/trunk/drivers/acpi/ac.c b/trunk/drivers/acpi/ac.c index 30238f6ff232..e03de37a750d 100644 --- a/trunk/drivers/acpi/ac.c +++ b/trunk/drivers/acpi/ac.c @@ -27,10 +27,8 @@ #include #include #include -#ifdef CONFIG_ACPI_PROCFS #include #include -#endif #include #include #include @@ -51,15 +49,12 @@ MODULE_AUTHOR("Paul Diefenbaugh"); MODULE_DESCRIPTION("ACPI AC Adapter Driver"); MODULE_LICENSE("GPL"); -#ifdef CONFIG_ACPI_PROCFS extern struct proc_dir_entry *acpi_lock_ac_dir(void); extern void *acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir); -static int acpi_ac_open_fs(struct inode *inode, struct file *file); -#endif static int acpi_ac_add(struct acpi_device *device); static int acpi_ac_remove(struct acpi_device *device, int type); -static int acpi_ac_resume(struct acpi_device *device); +static int acpi_ac_open_fs(struct inode *inode, struct file *file); const static struct acpi_device_id ac_device_ids[] = { {"ACPI0003", 0}, @@ -74,7 +69,6 @@ static struct acpi_driver acpi_ac_driver = { .ops = { .add = acpi_ac_add, .remove = acpi_ac_remove, - .resume = acpi_ac_resume, }, }; @@ -86,15 +80,12 @@ struct acpi_ac { #define to_acpi_ac(x) container_of(x, struct acpi_ac, charger); -#ifdef CONFIG_ACPI_PROCFS static const struct file_operations acpi_ac_fops = { .open = acpi_ac_open_fs, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; -#endif - static int get_ac_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) @@ -136,7 +127,6 @@ static int acpi_ac_get_state(struct acpi_ac *ac) return 0; } -#ifdef CONFIG_ACPI_PROCFS /* -------------------------------------------------------------------------- FS Interface (/proc) -------------------------------------------------------------------------- */ @@ -216,7 +206,6 @@ static int acpi_ac_remove_fs(struct acpi_device *device) return 0; } -#endif /* -------------------------------------------------------------------------- Driver Model @@ -275,9 +264,7 @@ static int acpi_ac_add(struct acpi_device *device) if (result) goto end; -#ifdef CONFIG_ACPI_PROCFS result = acpi_ac_add_fs(device); -#endif if (result) goto end; ac->charger.name = acpi_device_bid(device); @@ -300,30 +287,13 @@ static int acpi_ac_add(struct acpi_device *device) end: if (result) { -#ifdef CONFIG_ACPI_PROCFS acpi_ac_remove_fs(device); -#endif kfree(ac); } return result; } -static int acpi_ac_resume(struct acpi_device *device) -{ - struct acpi_ac *ac; - unsigned old_state; - if (!device || !acpi_driver_data(device)) - return -EINVAL; - ac = acpi_driver_data(device); - old_state = ac->state; - if (acpi_ac_get_state(ac)) - return 0; - if (old_state != ac->state) - kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); - return 0; -} - static int acpi_ac_remove(struct acpi_device *device, int type) { acpi_status status = AE_OK; @@ -339,9 +309,7 @@ static int acpi_ac_remove(struct acpi_device *device, int type) ACPI_ALL_NOTIFY, acpi_ac_notify); if (ac->charger.dev) power_supply_unregister(&ac->charger); -#ifdef CONFIG_ACPI_PROCFS acpi_ac_remove_fs(device); -#endif kfree(ac); @@ -355,17 +323,13 @@ static int __init acpi_ac_init(void) if (acpi_disabled) return -ENODEV; -#ifdef CONFIG_ACPI_PROCFS acpi_ac_dir = acpi_lock_ac_dir(); if (!acpi_ac_dir) return -ENODEV; -#endif result = acpi_bus_register_driver(&acpi_ac_driver); if (result < 0) { -#ifdef CONFIG_ACPI_PROCFS acpi_unlock_ac_dir(acpi_ac_dir); -#endif return -ENODEV; } @@ -377,9 +341,7 @@ static void __exit acpi_ac_exit(void) acpi_bus_unregister_driver(&acpi_ac_driver); -#ifdef CONFIG_ACPI_PROCFS acpi_unlock_ac_dir(acpi_ac_dir); -#endif return; } diff --git a/trunk/drivers/acpi/toshiba_acpi.c b/trunk/drivers/acpi/toshiba_acpi.c index 9e8c20c6a0b7..a736ef7bdee4 100644 --- a/trunk/drivers/acpi/toshiba_acpi.c +++ b/trunk/drivers/acpi/toshiba_acpi.c @@ -591,12 +591,9 @@ static int __init toshiba_acpi_init(void) NULL, &toshiba_backlight_data); if (IS_ERR(toshiba_backlight_device)) { - int ret = PTR_ERR(toshiba_backlight_device); - printk(KERN_ERR "Could not register toshiba backlight device\n"); toshiba_backlight_device = NULL; toshiba_acpi_exit(); - return ret; } toshiba_backlight_device->props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; diff --git a/trunk/drivers/block/paride/pf.c b/trunk/drivers/block/paride/pf.c index e7fe6ca97dd8..ceffa6034e20 100644 --- a/trunk/drivers/block/paride/pf.c +++ b/trunk/drivers/block/paride/pf.c @@ -488,11 +488,13 @@ static int pf_atapi(struct pf_unit *pf, char *cmd, int dlen, char *buf, char *fu return r; } +#define DBMSG(msg) ((verbose>1)?(msg):NULL) + static void pf_lock(struct pf_unit *pf, int func) { char lo_cmd[12] = { ATAPI_LOCK, pf->lun << 5, 0, 0, func, 0, 0, 0, 0, 0, 0, 0 }; - pf_atapi(pf, lo_cmd, 0, pf_scratch, func ? "lock" : "unlock"); + pf_atapi(pf, lo_cmd, 0, pf_scratch, func ? "unlock" : "lock"); } static void pf_eject(struct pf_unit *pf) @@ -553,7 +555,7 @@ static void pf_mode_sense(struct pf_unit *pf) { ATAPI_MODE_SENSE, pf->lun << 5, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0 }; char buf[8]; - pf_atapi(pf, ms_cmd, 8, buf, "mode sense"); + pf_atapi(pf, ms_cmd, 8, buf, DBMSG("mode sense")); pf->media_status = PF_RW; if (buf[3] & 0x80) pf->media_status = PF_RO; @@ -589,7 +591,7 @@ static void pf_get_capacity(struct pf_unit *pf) char buf[8]; int bs; - if (pf_atapi(pf, rc_cmd, 8, buf, "get capacity")) { + if (pf_atapi(pf, rc_cmd, 8, buf, DBMSG("get capacity"))) { pf->media_status = PF_NM; return; } @@ -802,18 +804,13 @@ static int pf_next_buf(void) pf_buf += 512; pf_block++; if (!pf_run) + return 0; + if (!pf_count) return 1; - if (!pf_count) { - spin_lock_irqsave(&pf_spin_lock, saved_flags); - pf_end_request(1); - pf_req = elv_next_request(pf_queue); - spin_unlock_irqrestore(&pf_spin_lock, saved_flags); - if (!pf_req) - return 1; - pf_count = pf_req->current_nr_sectors; - pf_buf = pf_req->buffer; - } - return 0; + spin_lock_irqsave(&pf_spin_lock, saved_flags); + pf_end_request(1); + spin_unlock_irqrestore(&pf_spin_lock, saved_flags); + return 1; } static inline void next_request(int success) diff --git a/trunk/drivers/block/rd.c b/trunk/drivers/block/rd.c index 82f4eecc8699..47f8ac6cce57 100644 --- a/trunk/drivers/block/rd.c +++ b/trunk/drivers/block/rd.c @@ -189,18 +189,6 @@ static int ramdisk_set_page_dirty(struct page *page) return 0; } -/* - * releasepage is called by pagevec_strip/try_to_release_page if - * buffers_heads_over_limit is true. Without a releasepage function - * try_to_free_buffers is called instead. That can unset the dirty - * bit of our ram disk pages, which will be eventually freed, even - * if the page is still in use. - */ -static int ramdisk_releasepage(struct page *page, gfp_t dummy) -{ - return 0; -} - static const struct address_space_operations ramdisk_aops = { .readpage = ramdisk_readpage, .prepare_write = ramdisk_prepare_write, @@ -208,7 +196,6 @@ static const struct address_space_operations ramdisk_aops = { .writepage = ramdisk_writepage, .set_page_dirty = ramdisk_set_page_dirty, .writepages = ramdisk_writepages, - .releasepage = ramdisk_releasepage, }; static int rd_blkdev_pagecache_IO(int rw, struct bio_vec *vec, sector_t sector, diff --git a/trunk/drivers/char/pcmcia/cm4000_cs.c b/trunk/drivers/char/pcmcia/cm4000_cs.c index 02518da6a386..cc5d77797def 100644 --- a/trunk/drivers/char/pcmcia/cm4000_cs.c +++ b/trunk/drivers/char/pcmcia/cm4000_cs.c @@ -47,7 +47,7 @@ /* #define ATR_CSUM */ #ifdef PCMCIA_DEBUG -#define reader_to_dev(x) (&handle_to_dev(x->p_dev)) +#define reader_to_dev(x) (&handle_to_dev(x->p_dev->handle)) static int pc_debug = PCMCIA_DEBUG; module_param(pc_debug, int, 0600); #define DEBUGP(n, rdr, x, args...) do { \ diff --git a/trunk/drivers/char/pcmcia/cm4040_cs.c b/trunk/drivers/char/pcmcia/cm4040_cs.c index 5f291bf739a6..a0b9c8728d56 100644 --- a/trunk/drivers/char/pcmcia/cm4040_cs.c +++ b/trunk/drivers/char/pcmcia/cm4040_cs.c @@ -41,7 +41,7 @@ #ifdef PCMCIA_DEBUG -#define reader_to_dev(x) (&handle_to_dev(x->p_dev)) +#define reader_to_dev(x) (&handle_to_dev(x->p_dev->handle)) static int pc_debug = PCMCIA_DEBUG; module_param(pc_debug, int, 0600); #define DEBUGP(n, rdr, x, args...) do { \ diff --git a/trunk/drivers/char/random.c b/trunk/drivers/char/random.c index 5fee05661823..1756b1f7cb72 100644 --- a/trunk/drivers/char/random.c +++ b/trunk/drivers/char/random.c @@ -1494,7 +1494,7 @@ __u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr, seq = twothirdsMD4Transform((const __u32 *)daddr, hash) & HASH_MASK; seq += keyptr->count; - seq += ktime_to_ns(ktime_get_real()); + seq += ktime_get_real().tv64; return seq; } @@ -1556,7 +1556,7 @@ __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, * overlaps less than one time per MSL (2 minutes). * Choosing a clock of 64 ns period is OK. (period of 274 s) */ - seq += ktime_to_ns(ktime_get_real()) >> 6; + seq += ktime_get_real().tv64 >> 6; #if 0 printk("init_seq(%lx, %lx, %d, %d) = %d\n", saddr, daddr, sport, dport, seq); @@ -1616,7 +1616,7 @@ u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, seq = half_md4_transform(hash, keyptr->secret); seq |= ((u64)keyptr->count) << (32 - HASH_BITS); - seq += ktime_to_ns(ktime_get_real()); + seq += ktime_get_real().tv64; seq &= (1ull << 48) - 1; #if 0 printk("dccp init_seq(%lx, %lx, %d, %d) = %d\n", diff --git a/trunk/drivers/char/rtc.c b/trunk/drivers/char/rtc.c index 0c66b802736a..ec6b65ec69ea 100644 --- a/trunk/drivers/char/rtc.c +++ b/trunk/drivers/char/rtc.c @@ -918,31 +918,6 @@ static const struct file_operations rtc_proc_fops = { }; #endif -static resource_size_t rtc_size; - -static struct resource * __init rtc_request_region(resource_size_t size) -{ - struct resource *r; - - if (RTC_IOMAPPED) - r = request_region(RTC_PORT(0), size, "rtc"); - else - r = request_mem_region(RTC_PORT(0), size, "rtc"); - - if (r) - rtc_size = size; - - return r; -} - -static void rtc_release_region(void) -{ - if (RTC_IOMAPPED) - release_region(RTC_PORT(0), rtc_size); - else - release_mem_region(RTC_PORT(0), rtc_size); -} - static int __init rtc_init(void) { #ifdef CONFIG_PROC_FS @@ -993,17 +968,10 @@ static int __init rtc_init(void) } no_irq: #else - r = rtc_request_region(RTC_IO_EXTENT); - - /* - * If we've already requested a smaller range (for example, because - * PNPBIOS or ACPI told us how the device is configured), the request - * above might fail because it's too big. - * - * If so, request just the range we actually use. - */ - if (!r) - r = rtc_request_region(RTC_IO_EXTENT_USED); + if (RTC_IOMAPPED) + r = request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc"); + else + r = request_mem_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc"); if (!r) { #ifdef RTC_IRQ rtc_has_irq = 0; @@ -1024,7 +992,10 @@ static int __init rtc_init(void) /* Yeah right, seeing as irq 8 doesn't even hit the bus. */ rtc_has_irq = 0; printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ); - rtc_release_region(); + if (RTC_IOMAPPED) + release_region(RTC_PORT(0), RTC_IO_EXTENT); + else + release_mem_region(RTC_PORT(0), RTC_IO_EXTENT); return -EIO; } hpet_rtc_timer_init(); @@ -1038,7 +1009,7 @@ static int __init rtc_init(void) free_irq(RTC_IRQ, NULL); rtc_has_irq = 0; #endif - rtc_release_region(); + release_region(RTC_PORT(0), RTC_IO_EXTENT); return -ENODEV; } @@ -1120,7 +1091,10 @@ static void __exit rtc_exit (void) if (rtc_has_irq) free_irq (rtc_irq, &rtc_port); #else - rtc_release_region(); + if (RTC_IOMAPPED) + release_region(RTC_PORT(0), RTC_IO_EXTENT); + else + release_mem_region(RTC_PORT(0), RTC_IO_EXTENT); #ifdef RTC_IRQ if (rtc_has_irq) free_irq (RTC_IRQ, NULL); diff --git a/trunk/drivers/dma/dmaengine.c b/trunk/drivers/dma/dmaengine.c index d59b2f417306..82489923af09 100644 --- a/trunk/drivers/dma/dmaengine.c +++ b/trunk/drivers/dma/dmaengine.c @@ -182,9 +182,10 @@ static void dma_client_chan_alloc(struct dma_client *client) /* we are done once this client rejects * an available resource */ - if (ack == DMA_ACK) + if (ack == DMA_ACK) { dma_chan_get(chan); - else if (ack == DMA_NAK) + kref_get(&device->refcount); + } else if (ack == DMA_NAK) return; } } @@ -271,8 +272,11 @@ static void dma_clients_notify_removed(struct dma_chan *chan) /* client was holding resources for this channel so * free it */ - if (ack == DMA_ACK) + if (ack == DMA_ACK) { dma_chan_put(chan); + kref_put(&chan->device->refcount, + dma_async_device_cleanup); + } } mutex_unlock(&dma_list_mutex); @@ -312,8 +316,11 @@ void dma_async_client_unregister(struct dma_client *client) ack = client->event_callback(client, chan, DMA_RESOURCE_REMOVED); - if (ack == DMA_ACK) + if (ack == DMA_ACK) { dma_chan_put(chan); + kref_put(&chan->device->refcount, + dma_async_device_cleanup); + } } list_del(&client->global_node); @@ -390,8 +397,6 @@ int dma_async_device_register(struct dma_device *device) goto err_out; } - /* One for the channel, one of the class device */ - kref_get(&device->refcount); kref_get(&device->refcount); kref_init(&chan->refcount); chan->slow_ref = 0; diff --git a/trunk/drivers/dma/ioat.c b/trunk/drivers/dma/ioat.c index 16e0fd8facfb..f204c39fb412 100644 --- a/trunk/drivers/dma/ioat.c +++ b/trunk/drivers/dma/ioat.c @@ -39,14 +39,10 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Intel Corporation"); static struct pci_device_id ioat_pci_tbl[] = { - /* I/OAT v1 platforms */ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_CNB) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SCNB) }, { PCI_DEVICE(PCI_VENDOR_ID_UNISYS, PCI_DEVICE_ID_UNISYS_DMA_DIRECTOR) }, - - /* I/OAT v2 platforms */ - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB) }, { 0, } }; @@ -78,17 +74,10 @@ static int ioat_setup_functionality(struct pci_dev *pdev, void __iomem *iobase) if (device->dma && ioat_dca_enabled) device->dca = ioat_dca_init(pdev, iobase); break; - case IOAT_VER_2_0: - device->dma = ioat_dma_probe(pdev, iobase); - if (device->dma && ioat_dca_enabled) - device->dca = ioat2_dca_init(pdev, iobase); - break; default: err = -ENODEV; break; } - if (!device->dma) - err = -ENODEV; return err; } diff --git a/trunk/drivers/dma/ioat_dca.c b/trunk/drivers/dma/ioat_dca.c index 0fa8a98051a8..ba985715b803 100644 --- a/trunk/drivers/dma/ioat_dca.c +++ b/trunk/drivers/dma/ioat_dca.c @@ -261,167 +261,3 @@ struct dca_provider *ioat_dca_init(struct pci_dev *pdev, void __iomem *iobase) return dca; } - -static int ioat2_dca_add_requester(struct dca_provider *dca, struct device *dev) -{ - struct ioat_dca_priv *ioatdca = dca_priv(dca); - struct pci_dev *pdev; - int i; - u16 id; - u16 global_req_table; - - /* This implementation only supports PCI-Express */ - if (dev->bus != &pci_bus_type) - return -ENODEV; - pdev = to_pci_dev(dev); - id = dcaid_from_pcidev(pdev); - - if (ioatdca->requester_count == ioatdca->max_requesters) - return -ENODEV; - - for (i = 0; i < ioatdca->max_requesters; i++) { - if (ioatdca->req_slots[i].pdev == NULL) { - /* found an empty slot */ - ioatdca->requester_count++; - ioatdca->req_slots[i].pdev = pdev; - ioatdca->req_slots[i].rid = id; - global_req_table = - readw(ioatdca->dca_base + IOAT_DCA_GREQID_OFFSET); - writel(id | IOAT_DCA_GREQID_VALID, - ioatdca->iobase + global_req_table + (i * 4)); - return i; - } - } - /* Error, ioatdma->requester_count is out of whack */ - return -EFAULT; -} - -static int ioat2_dca_remove_requester(struct dca_provider *dca, - struct device *dev) -{ - struct ioat_dca_priv *ioatdca = dca_priv(dca); - struct pci_dev *pdev; - int i; - u16 global_req_table; - - /* This implementation only supports PCI-Express */ - if (dev->bus != &pci_bus_type) - return -ENODEV; - pdev = to_pci_dev(dev); - - for (i = 0; i < ioatdca->max_requesters; i++) { - if (ioatdca->req_slots[i].pdev == pdev) { - global_req_table = - readw(ioatdca->dca_base + IOAT_DCA_GREQID_OFFSET); - writel(0, ioatdca->iobase + global_req_table + (i * 4)); - ioatdca->req_slots[i].pdev = NULL; - ioatdca->req_slots[i].rid = 0; - ioatdca->requester_count--; - return i; - } - } - return -ENODEV; -} - -static u8 ioat2_dca_get_tag(struct dca_provider *dca, int cpu) -{ - u8 tag; - - tag = ioat_dca_get_tag(dca, cpu); - tag = (~tag) & 0x1F; - return tag; -} - -static struct dca_ops ioat2_dca_ops = { - .add_requester = ioat2_dca_add_requester, - .remove_requester = ioat2_dca_remove_requester, - .get_tag = ioat2_dca_get_tag, -}; - -static int ioat2_dca_count_dca_slots(void *iobase, u16 dca_offset) -{ - int slots = 0; - u32 req; - u16 global_req_table; - - global_req_table = readw(iobase + dca_offset + IOAT_DCA_GREQID_OFFSET); - if (global_req_table == 0) - return 0; - do { - req = readl(iobase + global_req_table + (slots * sizeof(u32))); - slots++; - } while ((req & IOAT_DCA_GREQID_LASTID) == 0); - - return slots; -} - -struct dca_provider *ioat2_dca_init(struct pci_dev *pdev, void __iomem *iobase) -{ - struct dca_provider *dca; - struct ioat_dca_priv *ioatdca; - int slots; - int i; - int err; - u32 tag_map; - u16 dca_offset; - u16 csi_fsb_control; - u16 pcie_control; - u8 bit; - - if (!system_has_dca_enabled(pdev)) - return NULL; - - dca_offset = readw(iobase + IOAT_DCAOFFSET_OFFSET); - if (dca_offset == 0) - return NULL; - - slots = ioat2_dca_count_dca_slots(iobase, dca_offset); - if (slots == 0) - return NULL; - - dca = alloc_dca_provider(&ioat2_dca_ops, - sizeof(*ioatdca) - + (sizeof(struct ioat_dca_slot) * slots)); - if (!dca) - return NULL; - - ioatdca = dca_priv(dca); - ioatdca->iobase = iobase; - ioatdca->dca_base = iobase + dca_offset; - ioatdca->max_requesters = slots; - - /* some bios might not know to turn these on */ - csi_fsb_control = readw(ioatdca->dca_base + IOAT_FSB_CAP_ENABLE_OFFSET); - if ((csi_fsb_control & IOAT_FSB_CAP_ENABLE_PREFETCH) == 0) { - csi_fsb_control |= IOAT_FSB_CAP_ENABLE_PREFETCH; - writew(csi_fsb_control, - ioatdca->dca_base + IOAT_FSB_CAP_ENABLE_OFFSET); - } - pcie_control = readw(ioatdca->dca_base + IOAT_PCI_CAP_ENABLE_OFFSET); - if ((pcie_control & IOAT_PCI_CAP_ENABLE_MEMWR) == 0) { - pcie_control |= IOAT_PCI_CAP_ENABLE_MEMWR; - writew(pcie_control, - ioatdca->dca_base + IOAT_PCI_CAP_ENABLE_OFFSET); - } - - - /* TODO version, compatibility and configuration checks */ - - /* copy out the APIC to DCA tag map */ - tag_map = readl(ioatdca->dca_base + IOAT_APICID_TAG_MAP_OFFSET); - for (i = 0; i < 5; i++) { - bit = (tag_map >> (4 * i)) & 0x0f; - if (bit < 8) - ioatdca->tag_map[i] = bit | DCA_TAG_MAP_VALID; - else - ioatdca->tag_map[i] = 0; - } - - err = register_dca_provider(dca, &pdev->dev); - if (err) { - free_dca_provider(dca); - return NULL; - } - - return dca; -} diff --git a/trunk/drivers/dma/ioat_dma.c b/trunk/drivers/dma/ioat_dma.c index c1c2dcc6fc2e..7e4a785c2dff 100644 --- a/trunk/drivers/dma/ioat_dma.c +++ b/trunk/drivers/dma/ioat_dma.c @@ -36,24 +36,18 @@ #include "ioatdma_registers.h" #include "ioatdma_hw.h" +#define INITIAL_IOAT_DESC_COUNT 128 + #define to_ioat_chan(chan) container_of(chan, struct ioat_dma_chan, common) #define to_ioatdma_device(dev) container_of(dev, struct ioatdma_device, common) #define to_ioat_desc(lh) container_of(lh, struct ioat_desc_sw, node) #define tx_to_ioat_desc(tx) container_of(tx, struct ioat_desc_sw, async_tx) -static int ioat_pending_level = 4; -module_param(ioat_pending_level, int, 0644); -MODULE_PARM_DESC(ioat_pending_level, - "high-water mark for pushing ioat descriptors (default: 4)"); - /* internal functions */ static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan); static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan); - -static struct ioat_desc_sw * -ioat1_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan); static struct ioat_desc_sw * -ioat2_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan); +ioat_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan); static inline struct ioat_dma_chan *ioat_lookup_chan_by_index( struct ioatdma_device *device, @@ -136,12 +130,6 @@ static int ioat_dma_enumerate_channels(struct ioatdma_device *device) ioat_chan->device = device; ioat_chan->reg_base = device->reg_base + (0x80 * (i + 1)); ioat_chan->xfercap = xfercap; - ioat_chan->desccount = 0; - if (ioat_chan->device->version != IOAT_VER_1_2) { - writel(IOAT_DCACTRL_CMPL_WRITE_ENABLE - | IOAT_DMA_DCA_ANY_CPU, - ioat_chan->reg_base + IOAT_DCACTRL_OFFSET); - } spin_lock_init(&ioat_chan->cleanup_lock); spin_lock_init(&ioat_chan->desc_lock); INIT_LIST_HEAD(&ioat_chan->free_desc); @@ -173,17 +161,13 @@ static void ioat_set_dest(dma_addr_t addr, tx_to_ioat_desc(tx)->dst = addr; } -static inline void __ioat1_dma_memcpy_issue_pending( - struct ioat_dma_chan *ioat_chan); -static inline void __ioat2_dma_memcpy_issue_pending( - struct ioat_dma_chan *ioat_chan); - -static dma_cookie_t ioat1_tx_submit(struct dma_async_tx_descriptor *tx) +static dma_cookie_t ioat_tx_submit(struct dma_async_tx_descriptor *tx) { struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan); struct ioat_desc_sw *first = tx_to_ioat_desc(tx); struct ioat_desc_sw *prev, *new; struct ioat_dma_descriptor *hw; + int append = 0; dma_cookie_t cookie; LIST_HEAD(new_chain); u32 copy; @@ -225,7 +209,7 @@ static dma_cookie_t ioat1_tx_submit(struct dma_async_tx_descriptor *tx) list_add_tail(&new->node, &new_chain); desc_count++; prev = new; - } while (len && (new = ioat1_dma_get_next_descriptor(ioat_chan))); + } while (len && (new = ioat_dma_get_next_descriptor(ioat_chan))); hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS; if (new->async_tx.callback) { @@ -262,98 +246,20 @@ static dma_cookie_t ioat1_tx_submit(struct dma_async_tx_descriptor *tx) first->async_tx.phys; __list_splice(&new_chain, ioat_chan->used_desc.prev); - ioat_chan->dmacount += desc_count; ioat_chan->pending += desc_count; - if (ioat_chan->pending >= ioat_pending_level) - __ioat1_dma_memcpy_issue_pending(ioat_chan); - spin_unlock_bh(&ioat_chan->desc_lock); - - return cookie; -} - -static dma_cookie_t ioat2_tx_submit(struct dma_async_tx_descriptor *tx) -{ - struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan); - struct ioat_desc_sw *first = tx_to_ioat_desc(tx); - struct ioat_desc_sw *new; - struct ioat_dma_descriptor *hw; - dma_cookie_t cookie; - u32 copy; - size_t len; - dma_addr_t src, dst; - int orig_ack; - unsigned int desc_count = 0; - - /* src and dest and len are stored in the initial descriptor */ - len = first->len; - src = first->src; - dst = first->dst; - orig_ack = first->async_tx.ack; - new = first; - - /* ioat_chan->desc_lock is still in force in version 2 path */ - - do { - copy = min((u32) len, ioat_chan->xfercap); - - new->async_tx.ack = 1; - - hw = new->hw; - hw->size = copy; - hw->ctl = 0; - hw->src_addr = src; - hw->dst_addr = dst; - - len -= copy; - dst += copy; - src += copy; - desc_count++; - } while (len && (new = ioat2_dma_get_next_descriptor(ioat_chan))); - - hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS; - if (new->async_tx.callback) { - hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN; - if (first != new) { - /* move callback into to last desc */ - new->async_tx.callback = first->async_tx.callback; - new->async_tx.callback_param - = first->async_tx.callback_param; - first->async_tx.callback = NULL; - first->async_tx.callback_param = NULL; - } + if (ioat_chan->pending >= 4) { + append = 1; + ioat_chan->pending = 0; } - - new->tx_cnt = desc_count; - new->async_tx.ack = orig_ack; /* client is in control of this ack */ - - /* store the original values for use in later cleanup */ - if (new != first) { - new->src = first->src; - new->dst = first->dst; - new->len = first->len; - } - - /* cookie incr and addition to used_list must be atomic */ - cookie = ioat_chan->common.cookie; - cookie++; - if (cookie < 0) - cookie = 1; - ioat_chan->common.cookie = new->async_tx.cookie = cookie; - - ioat_chan->dmacount += desc_count; - ioat_chan->pending += desc_count; - if (ioat_chan->pending >= ioat_pending_level) - __ioat2_dma_memcpy_issue_pending(ioat_chan); spin_unlock_bh(&ioat_chan->desc_lock); + if (append) + writeb(IOAT_CHANCMD_APPEND, + ioat_chan->reg_base + IOAT_CHANCMD_OFFSET); + return cookie; } -/** - * ioat_dma_alloc_descriptor - allocate and return a sw and hw descriptor pair - * @ioat_chan: the channel supplying the memory pool for the descriptors - * @flags: allocation flags - */ static struct ioat_desc_sw *ioat_dma_alloc_descriptor( struct ioat_dma_chan *ioat_chan, gfp_t flags) @@ -378,57 +284,15 @@ static struct ioat_desc_sw *ioat_dma_alloc_descriptor( dma_async_tx_descriptor_init(&desc_sw->async_tx, &ioat_chan->common); desc_sw->async_tx.tx_set_src = ioat_set_src; desc_sw->async_tx.tx_set_dest = ioat_set_dest; - switch (ioat_chan->device->version) { - case IOAT_VER_1_2: - desc_sw->async_tx.tx_submit = ioat1_tx_submit; - break; - case IOAT_VER_2_0: - desc_sw->async_tx.tx_submit = ioat2_tx_submit; - break; - } + desc_sw->async_tx.tx_submit = ioat_tx_submit; INIT_LIST_HEAD(&desc_sw->async_tx.tx_list); - desc_sw->hw = desc; desc_sw->async_tx.phys = phys; return desc_sw; } -static int ioat_initial_desc_count = 256; -module_param(ioat_initial_desc_count, int, 0644); -MODULE_PARM_DESC(ioat_initial_desc_count, - "initial descriptors per channel (default: 256)"); - -/** - * ioat2_dma_massage_chan_desc - link the descriptors into a circle - * @ioat_chan: the channel to be massaged - */ -static void ioat2_dma_massage_chan_desc(struct ioat_dma_chan *ioat_chan) -{ - struct ioat_desc_sw *desc, *_desc; - - /* setup used_desc */ - ioat_chan->used_desc.next = ioat_chan->free_desc.next; - ioat_chan->used_desc.prev = NULL; - - /* pull free_desc out of the circle so that every node is a hw - * descriptor, but leave it pointing to the list - */ - ioat_chan->free_desc.prev->next = ioat_chan->free_desc.next; - ioat_chan->free_desc.next->prev = ioat_chan->free_desc.prev; - - /* circle link the hw descriptors */ - desc = to_ioat_desc(ioat_chan->free_desc.next); - desc->hw->next = to_ioat_desc(desc->node.next)->async_tx.phys; - list_for_each_entry_safe(desc, _desc, ioat_chan->free_desc.next, node) { - desc->hw->next = to_ioat_desc(desc->node.next)->async_tx.phys; - } -} - -/** - * ioat_dma_alloc_chan_resources - returns the number of allocated descriptors - * @chan: the channel to be filled out - */ +/* returns the actual number of allocated descriptors */ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan) { struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); @@ -440,7 +304,7 @@ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan) /* have we already been set up? */ if (!list_empty(&ioat_chan->free_desc)) - return ioat_chan->desccount; + return INITIAL_IOAT_DESC_COUNT; /* Setup register to interrupt and write completion status on error */ chanctrl = IOAT_CHANCTRL_ERR_INT_EN | @@ -456,7 +320,7 @@ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan) } /* Allocate descriptors */ - for (i = 0; i < ioat_initial_desc_count; i++) { + for (i = 0; i < INITIAL_IOAT_DESC_COUNT; i++) { desc = ioat_dma_alloc_descriptor(ioat_chan, GFP_KERNEL); if (!desc) { dev_err(&ioat_chan->device->pdev->dev, @@ -466,10 +330,7 @@ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan) list_add_tail(&desc->node, &tmp_list); } spin_lock_bh(&ioat_chan->desc_lock); - ioat_chan->desccount = i; list_splice(&tmp_list, &ioat_chan->free_desc); - if (ioat_chan->device->version != IOAT_VER_1_2) - ioat2_dma_massage_chan_desc(ioat_chan); spin_unlock_bh(&ioat_chan->desc_lock); /* allocate a completion writeback area */ @@ -486,14 +347,10 @@ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan) ioat_chan->reg_base + IOAT_CHANCMP_OFFSET_HIGH); tasklet_enable(&ioat_chan->cleanup_task); - ioat_dma_start_null_desc(ioat_chan); /* give chain to dma device */ - return ioat_chan->desccount; + ioat_dma_start_null_desc(ioat_chan); + return i; } -/** - * ioat_dma_free_chan_resources - release all the descriptors - * @chan: the channel to be cleaned - */ static void ioat_dma_free_chan_resources(struct dma_chan *chan) { struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); @@ -507,45 +364,22 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan) /* Delay 100ms after reset to allow internal DMA logic to quiesce * before removing DMA descriptor resources. */ - writeb(IOAT_CHANCMD_RESET, - ioat_chan->reg_base - + IOAT_CHANCMD_OFFSET(ioat_chan->device->version)); + writeb(IOAT_CHANCMD_RESET, ioat_chan->reg_base + IOAT_CHANCMD_OFFSET); mdelay(100); spin_lock_bh(&ioat_chan->desc_lock); - switch (ioat_chan->device->version) { - case IOAT_VER_1_2: - list_for_each_entry_safe(desc, _desc, - &ioat_chan->used_desc, node) { - in_use_descs++; - list_del(&desc->node); - pci_pool_free(ioatdma_device->dma_pool, desc->hw, - desc->async_tx.phys); - kfree(desc); - } - list_for_each_entry_safe(desc, _desc, - &ioat_chan->free_desc, node) { - list_del(&desc->node); - pci_pool_free(ioatdma_device->dma_pool, desc->hw, - desc->async_tx.phys); - kfree(desc); - } - break; - case IOAT_VER_2_0: - list_for_each_entry_safe(desc, _desc, - ioat_chan->free_desc.next, node) { - list_del(&desc->node); - pci_pool_free(ioatdma_device->dma_pool, desc->hw, - desc->async_tx.phys); - kfree(desc); - } - desc = to_ioat_desc(ioat_chan->free_desc.next); + list_for_each_entry_safe(desc, _desc, &ioat_chan->used_desc, node) { + in_use_descs++; + list_del(&desc->node); + pci_pool_free(ioatdma_device->dma_pool, desc->hw, + desc->async_tx.phys); + kfree(desc); + } + list_for_each_entry_safe(desc, _desc, &ioat_chan->free_desc, node) { + list_del(&desc->node); pci_pool_free(ioatdma_device->dma_pool, desc->hw, desc->async_tx.phys); kfree(desc); - INIT_LIST_HEAD(&ioat_chan->free_desc); - INIT_LIST_HEAD(&ioat_chan->used_desc); - break; } spin_unlock_bh(&ioat_chan->desc_lock); @@ -561,7 +395,6 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan) ioat_chan->last_completion = ioat_chan->completion_addr = 0; ioat_chan->pending = 0; - ioat_chan->dmacount = 0; } /** @@ -573,7 +406,7 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan) * has run out. */ static struct ioat_desc_sw * -ioat1_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan) +ioat_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan) { struct ioat_desc_sw *new = NULL; @@ -592,82 +425,7 @@ ioat1_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan) return new; } -static struct ioat_desc_sw * -ioat2_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan) -{ - struct ioat_desc_sw *new = NULL; - - /* - * used.prev points to where to start processing - * used.next points to next free descriptor - * if used.prev == NULL, there are none waiting to be processed - * if used.next == used.prev.prev, there is only one free descriptor, - * and we need to use it to as a noop descriptor before - * linking in a new set of descriptors, since the device - * has probably already read the pointer to it - */ - if (ioat_chan->used_desc.prev && - ioat_chan->used_desc.next == ioat_chan->used_desc.prev->prev) { - - struct ioat_desc_sw *desc = NULL; - struct ioat_desc_sw *noop_desc = NULL; - int i; - - /* set up the noop descriptor */ - noop_desc = to_ioat_desc(ioat_chan->used_desc.next); - noop_desc->hw->size = 0; - noop_desc->hw->ctl = IOAT_DMA_DESCRIPTOR_NUL; - noop_desc->hw->src_addr = 0; - noop_desc->hw->dst_addr = 0; - - ioat_chan->used_desc.next = ioat_chan->used_desc.next->next; - ioat_chan->pending++; - ioat_chan->dmacount++; - - /* get a few more descriptors */ - for (i = 16; i; i--) { - desc = ioat_dma_alloc_descriptor(ioat_chan, GFP_ATOMIC); - BUG_ON(!desc); - list_add_tail(&desc->node, ioat_chan->used_desc.next); - - desc->hw->next - = to_ioat_desc(desc->node.next)->async_tx.phys; - to_ioat_desc(desc->node.prev)->hw->next - = desc->async_tx.phys; - ioat_chan->desccount++; - } - - ioat_chan->used_desc.next = noop_desc->node.next; - } - new = to_ioat_desc(ioat_chan->used_desc.next); - prefetch(new); - ioat_chan->used_desc.next = new->node.next; - - if (ioat_chan->used_desc.prev == NULL) - ioat_chan->used_desc.prev = &new->node; - - prefetch(new->hw); - return new; -} - -static struct ioat_desc_sw *ioat_dma_get_next_descriptor( - struct ioat_dma_chan *ioat_chan) -{ - if (!ioat_chan) - return NULL; - - switch (ioat_chan->device->version) { - case IOAT_VER_1_2: - return ioat1_dma_get_next_descriptor(ioat_chan); - break; - case IOAT_VER_2_0: - return ioat2_dma_get_next_descriptor(ioat_chan); - break; - } - return NULL; -} - -static struct dma_async_tx_descriptor *ioat1_dma_prep_memcpy( +static struct dma_async_tx_descriptor *ioat_dma_prep_memcpy( struct dma_chan *chan, size_t len, int int_en) @@ -683,62 +441,19 @@ static struct dma_async_tx_descriptor *ioat1_dma_prep_memcpy( return new ? &new->async_tx : NULL; } -static struct dma_async_tx_descriptor *ioat2_dma_prep_memcpy( - struct dma_chan *chan, - size_t len, - int int_en) -{ - struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); - struct ioat_desc_sw *new; - - spin_lock_bh(&ioat_chan->desc_lock); - new = ioat2_dma_get_next_descriptor(ioat_chan); - new->len = len; - - /* leave ioat_chan->desc_lock set in version 2 path */ - return new ? &new->async_tx : NULL; -} - - /** * ioat_dma_memcpy_issue_pending - push potentially unrecognized appended * descriptors to hw * @chan: DMA channel handle */ -static inline void __ioat1_dma_memcpy_issue_pending( - struct ioat_dma_chan *ioat_chan) -{ - ioat_chan->pending = 0; - writeb(IOAT_CHANCMD_APPEND, ioat_chan->reg_base + IOAT1_CHANCMD_OFFSET); -} - -static void ioat1_dma_memcpy_issue_pending(struct dma_chan *chan) +static void ioat_dma_memcpy_issue_pending(struct dma_chan *chan) { struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); if (ioat_chan->pending != 0) { - spin_lock_bh(&ioat_chan->desc_lock); - __ioat1_dma_memcpy_issue_pending(ioat_chan); - spin_unlock_bh(&ioat_chan->desc_lock); - } -} - -static inline void __ioat2_dma_memcpy_issue_pending( - struct ioat_dma_chan *ioat_chan) -{ - ioat_chan->pending = 0; - writew(ioat_chan->dmacount, - ioat_chan->reg_base + IOAT_CHAN_DMACOUNT_OFFSET); -} - -static void ioat2_dma_memcpy_issue_pending(struct dma_chan *chan) -{ - struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); - - if (ioat_chan->pending != 0) { - spin_lock_bh(&ioat_chan->desc_lock); - __ioat2_dma_memcpy_issue_pending(ioat_chan); - spin_unlock_bh(&ioat_chan->desc_lock); + ioat_chan->pending = 0; + writeb(IOAT_CHANCMD_APPEND, + ioat_chan->reg_base + IOAT_CHANCMD_OFFSET); } } @@ -750,17 +465,11 @@ static void ioat_dma_cleanup_tasklet(unsigned long data) chan->reg_base + IOAT_CHANCTRL_OFFSET); } -/** - * ioat_dma_memcpy_cleanup - cleanup up finished descriptors - * @chan: ioat channel to be cleaned up - */ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan) { unsigned long phys_complete; struct ioat_desc_sw *desc, *_desc; dma_cookie_t cookie = 0; - unsigned long desc_phys; - struct ioat_desc_sw *latest_desc; prefetch(ioat_chan->completion_virt); @@ -798,115 +507,56 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan) cookie = 0; spin_lock_bh(&ioat_chan->desc_lock); - switch (ioat_chan->device->version) { - case IOAT_VER_1_2: - list_for_each_entry_safe(desc, _desc, - &ioat_chan->used_desc, node) { + list_for_each_entry_safe(desc, _desc, &ioat_chan->used_desc, node) { + + /* + * Incoming DMA requests may use multiple descriptors, due to + * exceeding xfercap, perhaps. If so, only the last one will + * have a cookie, and require unmapping. + */ + if (desc->async_tx.cookie) { + cookie = desc->async_tx.cookie; /* - * Incoming DMA requests may use multiple descriptors, - * due to exceeding xfercap, perhaps. If so, only the - * last one will have a cookie, and require unmapping. + * yes we are unmapping both _page and _single alloc'd + * regions with unmap_page. Is this *really* that bad? */ - if (desc->async_tx.cookie) { - cookie = desc->async_tx.cookie; - - /* - * yes we are unmapping both _page and _single - * alloc'd regions with unmap_page. Is this - * *really* that bad? - */ - pci_unmap_page(ioat_chan->device->pdev, - pci_unmap_addr(desc, dst), - pci_unmap_len(desc, len), - PCI_DMA_FROMDEVICE); - pci_unmap_page(ioat_chan->device->pdev, - pci_unmap_addr(desc, src), - pci_unmap_len(desc, len), - PCI_DMA_TODEVICE); - - if (desc->async_tx.callback) { - desc->async_tx.callback(desc->async_tx.callback_param); - desc->async_tx.callback = NULL; - } + pci_unmap_page(ioat_chan->device->pdev, + pci_unmap_addr(desc, dst), + pci_unmap_len(desc, len), + PCI_DMA_FROMDEVICE); + pci_unmap_page(ioat_chan->device->pdev, + pci_unmap_addr(desc, src), + pci_unmap_len(desc, len), + PCI_DMA_TODEVICE); + if (desc->async_tx.callback) { + desc->async_tx.callback( + desc->async_tx.callback_param); + desc->async_tx.callback = NULL; } + } - if (desc->async_tx.phys != phys_complete) { - /* - * a completed entry, but not the last, so clean - * up if the client is done with the descriptor - */ - if (desc->async_tx.ack) { - list_del(&desc->node); - list_add_tail(&desc->node, - &ioat_chan->free_desc); - } else - desc->async_tx.cookie = 0; - } else { - /* - * last used desc. Do not remove, so we can - * append from it, but don't look at it next - * time, either - */ + if (desc->async_tx.phys != phys_complete) { + /* + * a completed entry, but not the last, so cleanup + * if the client is done with the descriptor + */ + if (desc->async_tx.ack) { + list_del(&desc->node); + list_add_tail(&desc->node, + &ioat_chan->free_desc); + } else desc->async_tx.cookie = 0; + } else { + /* + * last used desc. Do not remove, so we can append from + * it, but don't look at it next time, either + */ + desc->async_tx.cookie = 0; - /* TODO check status bits? */ - break; - } - } - break; - case IOAT_VER_2_0: - /* has some other thread has already cleaned up? */ - if (ioat_chan->used_desc.prev == NULL) + /* TODO check status bits? */ break; - - /* work backwards to find latest finished desc */ - desc = to_ioat_desc(ioat_chan->used_desc.next); - latest_desc = NULL; - do { - desc = to_ioat_desc(desc->node.prev); - desc_phys = (unsigned long)desc->async_tx.phys - & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR; - if (desc_phys == phys_complete) { - latest_desc = desc; - break; - } - } while (&desc->node != ioat_chan->used_desc.prev); - - if (latest_desc != NULL) { - - /* work forwards to clear finished descriptors */ - for (desc = to_ioat_desc(ioat_chan->used_desc.prev); - &desc->node != latest_desc->node.next && - &desc->node != ioat_chan->used_desc.next; - desc = to_ioat_desc(desc->node.next)) { - if (desc->async_tx.cookie) { - cookie = desc->async_tx.cookie; - desc->async_tx.cookie = 0; - - pci_unmap_page(ioat_chan->device->pdev, - pci_unmap_addr(desc, dst), - pci_unmap_len(desc, len), - PCI_DMA_FROMDEVICE); - pci_unmap_page(ioat_chan->device->pdev, - pci_unmap_addr(desc, src), - pci_unmap_len(desc, len), - PCI_DMA_TODEVICE); - - if (desc->async_tx.callback) { - desc->async_tx.callback(desc->async_tx.callback_param); - desc->async_tx.callback = NULL; - } - } - } - - /* move used.prev up beyond those that are finished */ - if (&desc->node == ioat_chan->used_desc.next) - ioat_chan->used_desc.prev = NULL; - else - ioat_chan->used_desc.prev = &desc->node; } - break; } spin_unlock_bh(&ioat_chan->desc_lock); @@ -971,6 +621,8 @@ static enum dma_status ioat_dma_is_complete(struct dma_chan *chan, return dma_async_is_complete(cookie, last_complete, last_used); } +/* PCI API */ + static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan) { struct ioat_desc_sw *desc; @@ -981,34 +633,21 @@ static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan) desc->hw->ctl = IOAT_DMA_DESCRIPTOR_NUL | IOAT_DMA_DESCRIPTOR_CTL_INT_GN | IOAT_DMA_DESCRIPTOR_CTL_CP_STS; + desc->hw->next = 0; desc->hw->size = 0; desc->hw->src_addr = 0; desc->hw->dst_addr = 0; desc->async_tx.ack = 1; - switch (ioat_chan->device->version) { - case IOAT_VER_1_2: - desc->hw->next = 0; - list_add_tail(&desc->node, &ioat_chan->used_desc); - - writel(((u64) desc->async_tx.phys) & 0x00000000FFFFFFFF, - ioat_chan->reg_base + IOAT1_CHAINADDR_OFFSET_LOW); - writel(((u64) desc->async_tx.phys) >> 32, - ioat_chan->reg_base + IOAT1_CHAINADDR_OFFSET_HIGH); - - writeb(IOAT_CHANCMD_START, ioat_chan->reg_base - + IOAT_CHANCMD_OFFSET(ioat_chan->device->version)); - break; - case IOAT_VER_2_0: - writel(((u64) desc->async_tx.phys) & 0x00000000FFFFFFFF, - ioat_chan->reg_base + IOAT2_CHAINADDR_OFFSET_LOW); - writel(((u64) desc->async_tx.phys) >> 32, - ioat_chan->reg_base + IOAT2_CHAINADDR_OFFSET_HIGH); - - ioat_chan->dmacount++; - __ioat2_dma_memcpy_issue_pending(ioat_chan); - break; - } + + list_add_tail(&desc->node, &ioat_chan->used_desc); spin_unlock_bh(&ioat_chan->desc_lock); + + writel(((u64) desc->async_tx.phys) & 0x00000000FFFFFFFF, + ioat_chan->reg_base + IOAT_CHAINADDR_OFFSET_LOW); + writel(((u64) desc->async_tx.phys) >> 32, + ioat_chan->reg_base + IOAT_CHAINADDR_OFFSET_HIGH); + + writeb(IOAT_CHANCMD_START, ioat_chan->reg_base + IOAT_CHANCMD_OFFSET); } /* @@ -1054,14 +693,14 @@ static int ioat_dma_self_test(struct ioatdma_device *device) dma_chan = container_of(device->common.channels.next, struct dma_chan, device_node); - if (device->common.device_alloc_chan_resources(dma_chan) < 1) { + if (ioat_dma_alloc_chan_resources(dma_chan) < 1) { dev_err(&device->pdev->dev, "selftest cannot allocate chan resource\n"); err = -ENODEV; goto out; } - tx = device->common.device_prep_dma_memcpy(dma_chan, IOAT_TEST_SIZE, 0); + tx = ioat_dma_prep_memcpy(dma_chan, IOAT_TEST_SIZE, 0); if (!tx) { dev_err(&device->pdev->dev, "Self-test prep failed, disabling\n"); @@ -1071,25 +710,24 @@ static int ioat_dma_self_test(struct ioatdma_device *device) async_tx_ack(tx); addr = dma_map_single(dma_chan->device->dev, src, IOAT_TEST_SIZE, - DMA_TO_DEVICE); - tx->tx_set_src(addr, tx, 0); + DMA_TO_DEVICE); + ioat_set_src(addr, tx, 0); addr = dma_map_single(dma_chan->device->dev, dest, IOAT_TEST_SIZE, - DMA_FROM_DEVICE); - tx->tx_set_dest(addr, tx, 0); + DMA_FROM_DEVICE); + ioat_set_dest(addr, tx, 0); tx->callback = ioat_dma_test_callback; tx->callback_param = (void *)0x8086; - cookie = tx->tx_submit(tx); + cookie = ioat_tx_submit(tx); if (cookie < 0) { dev_err(&device->pdev->dev, "Self-test setup failed, disabling\n"); err = -ENODEV; goto free_resources; } - device->common.device_issue_pending(dma_chan); + ioat_dma_memcpy_issue_pending(dma_chan); msleep(1); - if (device->common.device_is_tx_complete(dma_chan, cookie, NULL, NULL) - != DMA_SUCCESS) { + if (ioat_dma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { dev_err(&device->pdev->dev, "Self-test copy timed out, disabling\n"); err = -ENODEV; @@ -1103,7 +741,7 @@ static int ioat_dma_self_test(struct ioatdma_device *device) } free_resources: - device->common.device_free_chan_resources(dma_chan); + ioat_dma_free_chan_resources(dma_chan); out: kfree(src); kfree(dest); @@ -1303,28 +941,16 @@ struct ioatdma_device *ioat_dma_probe(struct pci_dev *pdev, INIT_LIST_HEAD(&device->common.channels); ioat_dma_enumerate_channels(device); + dma_cap_set(DMA_MEMCPY, device->common.cap_mask); device->common.device_alloc_chan_resources = ioat_dma_alloc_chan_resources; device->common.device_free_chan_resources = ioat_dma_free_chan_resources; - device->common.dev = &pdev->dev; - - dma_cap_set(DMA_MEMCPY, device->common.cap_mask); + device->common.device_prep_dma_memcpy = ioat_dma_prep_memcpy; device->common.device_is_tx_complete = ioat_dma_is_complete; + device->common.device_issue_pending = ioat_dma_memcpy_issue_pending; device->common.device_dependency_added = ioat_dma_dependency_added; - switch (device->version) { - case IOAT_VER_1_2: - device->common.device_prep_dma_memcpy = ioat1_dma_prep_memcpy; - device->common.device_issue_pending = - ioat1_dma_memcpy_issue_pending; - break; - case IOAT_VER_2_0: - device->common.device_prep_dma_memcpy = ioat2_dma_prep_memcpy; - device->common.device_issue_pending = - ioat2_dma_memcpy_issue_pending; - break; - } - + device->common.dev = &pdev->dev; dev_err(&device->pdev->dev, "Intel(R) I/OAT DMA Engine found," " %d channels, device version 0x%02x, driver version %s\n", diff --git a/trunk/drivers/dma/ioatdma.h b/trunk/drivers/dma/ioatdma.h index b668234ef654..5f9881e7b0ed 100644 --- a/trunk/drivers/dma/ioatdma.h +++ b/trunk/drivers/dma/ioatdma.h @@ -1,5 +1,5 @@ /* - * Copyright(c) 2004 - 2007 Intel Corporation. All rights reserved. + * Copyright(c) 2004 - 2006 Intel Corporation. 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 @@ -28,7 +28,7 @@ #include #include -#define IOAT_DMA_VERSION "2.04" +#define IOAT_DMA_VERSION "1.26" enum ioat_interrupt { none = 0, @@ -39,8 +39,6 @@ enum ioat_interrupt { }; #define IOAT_LOW_COMPLETION_MASK 0xffffffc0 -#define IOAT_DMA_DCA_ANY_CPU ~0 - /** * struct ioatdma_device - internal representation of a IOAT device @@ -49,9 +47,6 @@ enum ioat_interrupt { * @dma_pool: for allocating DMA descriptors * @common: embedded struct dma_device * @version: version of ioatdma device - * @irq_mode: which style irq to use - * @msix_entries: irq handlers - * @idx: per channel data */ struct ioatdma_device { @@ -68,7 +63,23 @@ struct ioatdma_device { /** * struct ioat_dma_chan - internal representation of a DMA channel + * @device: + * @reg_base: + * @sw_in_use: + * @completion: + * @completion_low: + * @completion_high: + * @completed_cookie: last cookie seen completed on cleanup + * @cookie: value of last cookie given to client + * @last_completion: + * @xfercap: + * @desc_lock: + * @free_desc: + * @used_desc: + * @resource: + * @device_node: */ + struct ioat_dma_chan { void __iomem *reg_base; @@ -84,8 +95,6 @@ struct ioat_dma_chan { struct list_head used_desc; int pending; - int dmacount; - int desccount; struct ioatdma_device *device; struct dma_chan common; @@ -125,13 +134,12 @@ struct ioat_desc_sw { struct ioatdma_device *ioat_dma_probe(struct pci_dev *pdev, void __iomem *iobase); void ioat_dma_remove(struct ioatdma_device *device); -struct dca_provider *ioat_dca_init(struct pci_dev *pdev, void __iomem *iobase); -struct dca_provider *ioat2_dca_init(struct pci_dev *pdev, void __iomem *iobase); +struct dca_provider *ioat_dca_init(struct pci_dev *pdev, + void __iomem *iobase); #else #define ioat_dma_probe(pdev, iobase) NULL #define ioat_dma_remove(device) do { } while (0) #define ioat_dca_init(pdev, iobase) NULL -#define ioat2_dca_init(pdev, iobase) NULL #endif #endif /* IOATDMA_H */ diff --git a/trunk/drivers/dma/ioatdma_hw.h b/trunk/drivers/dma/ioatdma_hw.h index dd470fa91d86..9e7434e1551f 100644 --- a/trunk/drivers/dma/ioatdma_hw.h +++ b/trunk/drivers/dma/ioatdma_hw.h @@ -1,5 +1,5 @@ /* - * Copyright(c) 2004 - 2007 Intel Corporation. All rights reserved. + * Copyright(c) 2004 - 2006 Intel Corporation. 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 @@ -22,19 +22,12 @@ #define _IOAT_HW_H_ /* PCI Configuration Space Values */ -#define IOAT_PCI_VID 0x8086 - -/* CB device ID's */ -#define IOAT_PCI_DID_5000 0x1A38 -#define IOAT_PCI_DID_CNB 0x360B -#define IOAT_PCI_DID_SCNB 0x65FF -#define IOAT_PCI_DID_SNB 0x402F - -#define IOAT_PCI_RID 0x00 -#define IOAT_PCI_SVID 0x8086 -#define IOAT_PCI_SID 0x8086 -#define IOAT_VER_1_2 0x12 /* Version 1.2 */ -#define IOAT_VER_2_0 0x20 /* Version 2.0 */ +#define IOAT_PCI_VID 0x8086 +#define IOAT_PCI_DID 0x1A38 +#define IOAT_PCI_RID 0x00 +#define IOAT_PCI_SVID 0x8086 +#define IOAT_PCI_SID 0x8086 +#define IOAT_VER_1_2 0x12 /* Version 1.2 */ struct ioat_dma_descriptor { uint32_t size; @@ -54,16 +47,6 @@ struct ioat_dma_descriptor { #define IOAT_DMA_DESCRIPTOR_CTL_CP_STS 0x00000008 #define IOAT_DMA_DESCRIPTOR_CTL_FRAME 0x00000010 #define IOAT_DMA_DESCRIPTOR_NUL 0x00000020 -#define IOAT_DMA_DESCRIPTOR_CTL_SP_BRK 0x00000040 -#define IOAT_DMA_DESCRIPTOR_CTL_DP_BRK 0x00000080 -#define IOAT_DMA_DESCRIPTOR_CTL_BNDL 0x00000100 -#define IOAT_DMA_DESCRIPTOR_CTL_DCA 0x00000200 -#define IOAT_DMA_DESCRIPTOR_CTL_BUFHINT 0x00000400 - -#define IOAT_DMA_DESCRIPTOR_CTL_OPCODE_CONTEXT 0xFF000000 -#define IOAT_DMA_DESCRIPTOR_CTL_OPCODE_DMA 0x00000000 - -#define IOAT_DMA_DESCRIPTOR_CTL_CONTEXT_DCA 0x00000001 -#define IOAT_DMA_DESCRIPTOR_CTL_OPCODE_MASK 0xFF000000 +#define IOAT_DMA_DESCRIPTOR_OPCODE 0xFF000000 #endif diff --git a/trunk/drivers/dma/ioatdma_registers.h b/trunk/drivers/dma/ioatdma_registers.h index 9832d7ebd931..baaab5ea146a 100644 --- a/trunk/drivers/dma/ioatdma_registers.h +++ b/trunk/drivers/dma/ioatdma_registers.h @@ -42,25 +42,26 @@ #define IOAT_INTRCTRL_MASTER_INT_EN 0x01 /* Master Interrupt Enable */ #define IOAT_INTRCTRL_INT_STATUS 0x02 /* ATTNSTATUS -or- Channel Int */ #define IOAT_INTRCTRL_INT 0x04 /* INT_STATUS -and- MASTER_INT_EN */ -#define IOAT_INTRCTRL_MSIX_VECTOR_CONTROL 0x08 /* Enable all MSI-X vectors */ +#define IOAT_INTRCTRL_MSIX_VECTOR_CONTROL 0x08 /* Enable all MSI-X vectors */ #define IOAT_ATTNSTATUS_OFFSET 0x04 /* Each bit is a channel */ #define IOAT_VER_OFFSET 0x08 /* 8-bit */ #define IOAT_VER_MAJOR_MASK 0xF0 #define IOAT_VER_MINOR_MASK 0x0F -#define GET_IOAT_VER_MAJOR(x) (((x) & IOAT_VER_MAJOR_MASK) >> 4) +#define GET_IOAT_VER_MAJOR(x) ((x) & IOAT_VER_MAJOR_MASK) #define GET_IOAT_VER_MINOR(x) ((x) & IOAT_VER_MINOR_MASK) #define IOAT_PERPORTOFFSET_OFFSET 0x0A /* 16-bit */ #define IOAT_INTRDELAY_OFFSET 0x0C /* 16-bit */ #define IOAT_INTRDELAY_INT_DELAY_MASK 0x3FFF /* Interrupt Delay Time */ -#define IOAT_INTRDELAY_COALESE_SUPPORT 0x8000 /* Interrupt Coalescing Supported */ +#define IOAT_INTRDELAY_COALESE_SUPPORT 0x8000 /* Interrupt Coalesing Supported */ #define IOAT_DEVICE_STATUS_OFFSET 0x0E /* 16-bit */ #define IOAT_DEVICE_STATUS_DEGRADED_MODE 0x0001 + #define IOAT_CHANNEL_MMIO_SIZE 0x80 /* Each Channel MMIO space is this size */ /* DMA Channel Registers */ @@ -73,101 +74,25 @@ #define IOAT_CHANCTRL_ERR_COMPLETION_EN 0x0004 #define IOAT_CHANCTRL_INT_DISABLE 0x0001 -#define IOAT_DMA_COMP_OFFSET 0x02 /* 16-bit DMA channel compatibility */ -#define IOAT_DMA_COMP_V1 0x0001 /* Compatibility with DMA version 1 */ -#define IOAT_DMA_COMP_V2 0x0002 /* Compatibility with DMA version 2 */ - - -#define IOAT1_CHANSTS_OFFSET 0x04 /* 64-bit Channel Status Register */ -#define IOAT2_CHANSTS_OFFSET 0x08 /* 64-bit Channel Status Register */ -#define IOAT_CHANSTS_OFFSET(ver) ((ver) < IOAT_VER_2_0 \ - ? IOAT1_CHANSTS_OFFSET : IOAT2_CHANSTS_OFFSET) -#define IOAT1_CHANSTS_OFFSET_LOW 0x04 -#define IOAT2_CHANSTS_OFFSET_LOW 0x08 -#define IOAT_CHANSTS_OFFSET_LOW(ver) ((ver) < IOAT_VER_2_0 \ - ? IOAT1_CHANSTS_OFFSET_LOW : IOAT2_CHANSTS_OFFSET_LOW) -#define IOAT1_CHANSTS_OFFSET_HIGH 0x08 -#define IOAT2_CHANSTS_OFFSET_HIGH 0x0C -#define IOAT_CHANSTS_OFFSET_HIGH(ver) ((ver) < IOAT_VER_2_0 \ - ? IOAT1_CHANSTS_OFFSET_HIGH : IOAT2_CHANSTS_OFFSET_HIGH) -#define IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR ~0x3F +#define IOAT_DMA_COMP_OFFSET 0x02 /* 16-bit DMA channel compatability */ +#define IOAT_DMA_COMP_V1 0x0001 /* Compatability with DMA version 1 */ + +#define IOAT_CHANSTS_OFFSET 0x04 /* 64-bit Channel Status Register */ +#define IOAT_CHANSTS_OFFSET_LOW 0x04 +#define IOAT_CHANSTS_OFFSET_HIGH 0x08 +#define IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR 0xFFFFFFFFFFFFFFC0UL #define IOAT_CHANSTS_SOFT_ERR 0x0000000000000010 -#define IOAT_CHANSTS_UNAFFILIATED_ERR 0x0000000000000008 #define IOAT_CHANSTS_DMA_TRANSFER_STATUS 0x0000000000000007 #define IOAT_CHANSTS_DMA_TRANSFER_STATUS_ACTIVE 0x0 #define IOAT_CHANSTS_DMA_TRANSFER_STATUS_DONE 0x1 #define IOAT_CHANSTS_DMA_TRANSFER_STATUS_SUSPENDED 0x2 #define IOAT_CHANSTS_DMA_TRANSFER_STATUS_HALTED 0x3 +#define IOAT_CHAINADDR_OFFSET 0x0C /* 64-bit Descriptor Chain Address Register */ +#define IOAT_CHAINADDR_OFFSET_LOW 0x0C +#define IOAT_CHAINADDR_OFFSET_HIGH 0x10 - -#define IOAT_CHAN_DMACOUNT_OFFSET 0x06 /* 16-bit DMA Count register */ - -#define IOAT_DCACTRL_OFFSET 0x30 /* 32 bit Direct Cache Access Control Register */ -#define IOAT_DCACTRL_CMPL_WRITE_ENABLE 0x10000 -#define IOAT_DCACTRL_TARGET_CPU_MASK 0xFFFF /* APIC ID */ - -/* CB DCA Memory Space Registers */ -#define IOAT_DCAOFFSET_OFFSET 0x14 -/* CB_BAR + IOAT_DCAOFFSET value */ -#define IOAT_DCA_VER_OFFSET 0x00 -#define IOAT_DCA_VER_MAJOR_MASK 0xF0 -#define IOAT_DCA_VER_MINOR_MASK 0x0F - -#define IOAT_DCA_COMP_OFFSET 0x02 -#define IOAT_DCA_COMP_V1 0x1 - -#define IOAT_FSB_CAPABILITY_OFFSET 0x04 -#define IOAT_FSB_CAPABILITY_PREFETCH 0x1 - -#define IOAT_PCI_CAPABILITY_OFFSET 0x06 -#define IOAT_PCI_CAPABILITY_MEMWR 0x1 - -#define IOAT_FSB_CAP_ENABLE_OFFSET 0x08 -#define IOAT_FSB_CAP_ENABLE_PREFETCH 0x1 - -#define IOAT_PCI_CAP_ENABLE_OFFSET 0x0A -#define IOAT_PCI_CAP_ENABLE_MEMWR 0x1 - -#define IOAT_APICID_TAG_MAP_OFFSET 0x0C -#define IOAT_APICID_TAG_MAP_TAG0 0x0000000F -#define IOAT_APICID_TAG_MAP_TAG0_SHIFT 0 -#define IOAT_APICID_TAG_MAP_TAG1 0x000000F0 -#define IOAT_APICID_TAG_MAP_TAG1_SHIFT 4 -#define IOAT_APICID_TAG_MAP_TAG2 0x00000F00 -#define IOAT_APICID_TAG_MAP_TAG2_SHIFT 8 -#define IOAT_APICID_TAG_MAP_TAG3 0x0000F000 -#define IOAT_APICID_TAG_MAP_TAG3_SHIFT 12 -#define IOAT_APICID_TAG_MAP_TAG4 0x000F0000 -#define IOAT_APICID_TAG_MAP_TAG4_SHIFT 16 -#define IOAT_APICID_TAG_CB2_VALID 0x8080808080 - -#define IOAT_DCA_GREQID_OFFSET 0x10 -#define IOAT_DCA_GREQID_SIZE 0x04 -#define IOAT_DCA_GREQID_MASK 0xFFFF -#define IOAT_DCA_GREQID_IGNOREFUN 0x10000000 -#define IOAT_DCA_GREQID_VALID 0x20000000 -#define IOAT_DCA_GREQID_LASTID 0x80000000 - - - -#define IOAT1_CHAINADDR_OFFSET 0x0C /* 64-bit Descriptor Chain Address Register */ -#define IOAT2_CHAINADDR_OFFSET 0x10 /* 64-bit Descriptor Chain Address Register */ -#define IOAT_CHAINADDR_OFFSET(ver) ((ver) < IOAT_VER_2_0 \ - ? IOAT1_CHAINADDR_OFFSET : IOAT2_CHAINADDR_OFFSET) -#define IOAT1_CHAINADDR_OFFSET_LOW 0x0C -#define IOAT2_CHAINADDR_OFFSET_LOW 0x10 -#define IOAT_CHAINADDR_OFFSET_LOW(ver) ((ver) < IOAT_VER_2_0 \ - ? IOAT1_CHAINADDR_OFFSET_LOW : IOAT2_CHAINADDR_OFFSET_LOW) -#define IOAT1_CHAINADDR_OFFSET_HIGH 0x10 -#define IOAT2_CHAINADDR_OFFSET_HIGH 0x14 -#define IOAT_CHAINADDR_OFFSET_HIGH(ver) ((ver) < IOAT_VER_2_0 \ - ? IOAT1_CHAINADDR_OFFSET_HIGH : IOAT2_CHAINADDR_OFFSET_HIGH) - -#define IOAT1_CHANCMD_OFFSET 0x14 /* 8-bit DMA Channel Command Register */ -#define IOAT2_CHANCMD_OFFSET 0x04 /* 8-bit DMA Channel Command Register */ -#define IOAT_CHANCMD_OFFSET(ver) ((ver) < IOAT_VER_2_0 \ - ? IOAT1_CHANCMD_OFFSET : IOAT2_CHANCMD_OFFSET) +#define IOAT_CHANCMD_OFFSET 0x14 /* 8-bit DMA Channel Command Register */ #define IOAT_CHANCMD_RESET 0x20 #define IOAT_CHANCMD_RESUME 0x10 #define IOAT_CHANCMD_ABORT 0x08 @@ -199,7 +124,6 @@ #define IOAT_CHANERR_COMPLETION_ADDR_ERR 0x1000 #define IOAT_CHANERR_INT_CONFIGURATION_ERR 0x2000 #define IOAT_CHANERR_SOFT_ERR 0x4000 -#define IOAT_CHANERR_UNAFFILIATED_ERR 0x8000 #define IOAT_CHANERR_MASK_OFFSET 0x2C /* 32-bit Channel Error Register */ diff --git a/trunk/drivers/edac/i5000_edac.c b/trunk/drivers/edac/i5000_edac.c index a1f24c42d5ff..96f7e63e3996 100644 --- a/trunk/drivers/edac/i5000_edac.c +++ b/trunk/drivers/edac/i5000_edac.c @@ -1462,7 +1462,7 @@ MODULE_DEVICE_TABLE(pci, i5000_pci_tbl); * */ static struct pci_driver i5000_driver = { - .name = KBUILD_BASENAME, + .name = __stringify(KBUILD_BASENAME), .probe = i5000_init_one, .remove = __devexit_p(i5000_remove_one), .id_table = i5000_pci_tbl, diff --git a/trunk/drivers/ide/Kconfig b/trunk/drivers/ide/Kconfig index e445fe6e4ba9..d1e8df187222 100644 --- a/trunk/drivers/ide/Kconfig +++ b/trunk/drivers/ide/Kconfig @@ -203,6 +203,10 @@ config BLK_DEV_IDECD CD-ROM drive, you can say N to all other CD-ROM options, but be sure to say Y or M to "ISO 9660 CD-ROM file system support". + Note that older versions of LILO (LInux LOader) cannot properly deal + with IDE/ATAPI CD-ROMs, so install LILO 16 or higher, available from + . + To compile this driver as a module, choose M here: the module will be called ide-cd. diff --git a/trunk/drivers/ide/cris/ide-cris.c b/trunk/drivers/ide/cris/ide-cris.c index 7f5bc2ee6c7e..e196aefa2070 100644 --- a/trunk/drivers/ide/cris/ide-cris.c +++ b/trunk/drivers/ide/cris/ide-cris.c @@ -748,7 +748,8 @@ static void cris_set_dma_mode(ide_drive_t *drive, const u8 speed) hold = ATA_DMA2_HOLD; break; default: - return; + BUG(); + break; } if (speed >= XFER_UDMA_0) diff --git a/trunk/drivers/ide/ide-io.c b/trunk/drivers/ide/ide-io.c index db22d1ff4e55..755011827afa 100644 --- a/trunk/drivers/ide/ide-io.c +++ b/trunk/drivers/ide/ide-io.c @@ -885,6 +885,7 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, return do_rw_taskfile(drive, args); } else if (rq->cmd_type == REQ_TYPE_ATA_TASK) { u8 *args = rq->buffer; + u8 sel; if (!args) goto done; @@ -902,7 +903,10 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, hwif->OUTB(args[3], IDE_SECTOR_REG); hwif->OUTB(args[4], IDE_LCYL_REG); hwif->OUTB(args[5], IDE_HCYL_REG); - hwif->OUTB((args[6] & 0xEF)|drive->select.all, IDE_SELECT_REG); + sel = (args[6] & ~0x10); + if (drive->select.b.unit) + sel |= 0x10; + hwif->OUTB(sel, IDE_SELECT_REG); ide_cmd(drive, args[0], args[2], &drive_cmd_intr); return ide_started; } else if (rq->cmd_type == REQ_TYPE_ATA_CMD) { diff --git a/trunk/drivers/ide/ide-lib.c b/trunk/drivers/ide/ide-lib.c index 1609b8604f56..af86433baede 100644 --- a/trunk/drivers/ide/ide-lib.c +++ b/trunk/drivers/ide/ide-lib.c @@ -514,7 +514,6 @@ static u8 ide_dump_ata_status(ide_drive_t *drive, const char *msg, u8 stat) if (drive->addressing == 1) { __u64 sectors = 0; u32 low = 0, high = 0; - hwif->OUTB(drive->ctl&~0x80, IDE_CONTROL_REG); low = ide_read_24(drive); hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG); high = ide_read_24(drive); diff --git a/trunk/drivers/ide/pci/cmd64x.c b/trunk/drivers/ide/pci/cmd64x.c index 51fca441c294..ea0143ef5fe5 100644 --- a/trunk/drivers/ide/pci/cmd64x.c +++ b/trunk/drivers/ide/pci/cmd64x.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/cmd64x.c Version 1.51 Nov 8, 2007 + * linux/drivers/ide/pci/cmd64x.c Version 1.50 May 10, 2007 * * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. * Due to massive hardware bugs, UltraDMA is only supported @@ -339,8 +339,7 @@ static int cmd648_ide_dma_end (ide_drive_t *drive) u8 mrdmode = inb(hwif->dma_master + 0x01); /* clear the interrupt bit */ - outb((mrdmode & ~(MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1)) | irq_mask, - hwif->dma_master + 0x01); + outb(mrdmode | irq_mask, hwif->dma_master + 0x01); return err; } diff --git a/trunk/drivers/ide/pci/cs5530.c b/trunk/drivers/ide/pci/cs5530.c index 547690395eee..599408952bd4 100644 --- a/trunk/drivers/ide/pci/cs5530.c +++ b/trunk/drivers/ide/pci/cs5530.c @@ -117,7 +117,8 @@ static void cs5530_set_dma_mode(ide_drive_t *drive, const u8 mode) case XFER_MW_DMA_1: timings = 0x00012121; break; case XFER_MW_DMA_2: timings = 0x00002020; break; default: - return; + BUG(); + break; } basereg = CS5530_BASEREG(drive->hwif); reg = inl(basereg + 4); /* get drive0 config register */ diff --git a/trunk/drivers/ide/pci/it821x.c b/trunk/drivers/ide/pci/it821x.c index 99b7d763b6c7..5c9975435319 100644 --- a/trunk/drivers/ide/pci/it821x.c +++ b/trunk/drivers/ide/pci/it821x.c @@ -653,7 +653,8 @@ static const struct ide_port_info it821x_chipsets[] __devinitdata = { static int __devinit it821x_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - return ide_setup_pci_device(dev, &it821x_chipsets[id->driver_data]); + ide_setup_pci_device(dev, &it821x_chipsets[id->driver_data]); + return 0; } static const struct pci_device_id it821x_pci_tbl[] = { diff --git a/trunk/drivers/ide/pci/jmicron.c b/trunk/drivers/ide/pci/jmicron.c index 0083eaf89c77..bdf64d997708 100644 --- a/trunk/drivers/ide/pci/jmicron.c +++ b/trunk/drivers/ide/pci/jmicron.c @@ -139,7 +139,8 @@ static const struct ide_port_info jmicron_chipset __devinitdata = { static int __devinit jmicron_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - return ide_setup_pci_device(dev, &jmicron_chipset); + ide_setup_pci_device(dev, &jmicron_chipset); + return 0; } /* All JMB PATA controllers have and will continue to have the same diff --git a/trunk/drivers/ide/pci/sc1200.c b/trunk/drivers/ide/pci/sc1200.c index 707d5ff66b03..0a7b3202066d 100644 --- a/trunk/drivers/ide/pci/sc1200.c +++ b/trunk/drivers/ide/pci/sc1200.c @@ -186,7 +186,8 @@ static void sc1200_set_dma_mode(ide_drive_t *drive, const u8 mode) } break; default: - return; + BUG(); + break; } if (unit == 0) { /* are we configuring drive0? */ diff --git a/trunk/drivers/ide/pci/sis5513.c b/trunk/drivers/ide/pci/sis5513.c index f6e2ab3dd166..6b7bb53acefd 100644 --- a/trunk/drivers/ide/pci/sis5513.c +++ b/trunk/drivers/ide/pci/sis5513.c @@ -356,6 +356,7 @@ static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed) sis_program_timings(drive, speed); break; default: + BUG(); break; } } diff --git a/trunk/drivers/ide/ppc/pmac.c b/trunk/drivers/ide/ppc/pmac.c index 5afdfef7264c..816b5311dad6 100644 --- a/trunk/drivers/ide/ppc/pmac.c +++ b/trunk/drivers/ide/ppc/pmac.c @@ -1138,7 +1138,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) hwif->drives[0].autotune = IDE_TUNE_AUTO; hwif->drives[1].autotune = IDE_TUNE_AUTO; hwif->host_flags = IDE_HFLAG_SET_PIO_MODE_KEEP_DMA | - IDE_HFLAG_PIO_NO_DOWNGRADE | IDE_HFLAG_POST_SET_MODE; hwif->pio_mask = ATA_PIO4; hwif->set_pio_mode = pmac_ide_set_pio_mode; diff --git a/trunk/drivers/ide/setup-pci.c b/trunk/drivers/ide/setup-pci.c index 25fd09053220..02d14bf85ab2 100644 --- a/trunk/drivers/ide/setup-pci.c +++ b/trunk/drivers/ide/setup-pci.c @@ -7,6 +7,11 @@ * May be copied or modified under the terms of the GNU General Public License */ +/* + * This module provides support for automatic detection and + * configuration of all PCI IDE interfaces present in a system. + */ + #include #include #include diff --git a/trunk/drivers/isdn/sc/card.h b/trunk/drivers/isdn/sc/card.h index 0120bcf88311..5992f63c383e 100644 --- a/trunk/drivers/isdn/sc/card.h +++ b/trunk/drivers/isdn/sc/card.h @@ -109,7 +109,7 @@ void memcpy_fromshmem(int card, void *dest, const void *src, size_t n); int get_card_from_id(int driver); int indicate_status(int card, int event, ulong Channel, char *Data); irqreturn_t interrupt_handler(int interrupt, void *cardptr); -int sndpkt(int devId, int channel, int ack, struct sk_buff *data); +int sndpkt(int devId, int channel, struct sk_buff *data); void rcvpkt(int card, RspMessage *rcvmsg); int command(isdn_ctrl *cmd); int reset(int card); diff --git a/trunk/drivers/isdn/sc/packet.c b/trunk/drivers/isdn/sc/packet.c index 5ff6ae868440..92016a2608e9 100644 --- a/trunk/drivers/isdn/sc/packet.c +++ b/trunk/drivers/isdn/sc/packet.c @@ -20,7 +20,7 @@ #include "message.h" #include "card.h" -int sndpkt(int devId, int channel, int ack, struct sk_buff *data) +int sndpkt(int devId, int channel, struct sk_buff *data) { LLData ReqLnkWrite; int status; diff --git a/trunk/drivers/isdn/sc/shmem.c b/trunk/drivers/isdn/sc/shmem.c index 712220cef139..e0331e0094f1 100644 --- a/trunk/drivers/isdn/sc/shmem.c +++ b/trunk/drivers/isdn/sc/shmem.c @@ -50,7 +50,7 @@ void memcpy_toshmem(int card, void *dest, const void *src, size_t n) outb(((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE) >> 14) | 0x80, sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport]); - memcpy_toio((void __iomem *)(sc_adapter[card]->rambase + dest_rem), src, n); + memcpy_toio(sc_adapter[card]->rambase + dest_rem, src, n); spin_unlock_irqrestore(&sc_adapter[card]->lock, flags); pr_debug("%s: set page to %#x\n",sc_adapter[card]->devicename, ((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80); diff --git a/trunk/drivers/lguest/lguest_user.c b/trunk/drivers/lguest/lguest_user.c index 3b92a61ba8d2..9d716fa42cad 100644 --- a/trunk/drivers/lguest/lguest_user.c +++ b/trunk/drivers/lguest/lguest_user.c @@ -184,7 +184,7 @@ static int initialize(struct file *file, const unsigned long __user *input) free_regs: free_page(lg->regs_page); release_guest: - kfree(lg); + memset(lg, 0, sizeof(*lg)); unlock: mutex_unlock(&lguest_lock); return err; diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index a5aad8cad843..1cfc984cc7b7 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -688,8 +688,7 @@ ops_run_prexor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx) } static struct dma_async_tx_descriptor * -ops_run_biodrain(struct stripe_head *sh, struct dma_async_tx_descriptor *tx, - unsigned long pending) +ops_run_biodrain(struct stripe_head *sh, struct dma_async_tx_descriptor *tx) { int disks = sh->disks; int pd_idx = sh->pd_idx, i; @@ -697,7 +696,7 @@ ops_run_biodrain(struct stripe_head *sh, struct dma_async_tx_descriptor *tx, /* check if prexor is active which means only process blocks * that are part of a read-modify-write (Wantprexor) */ - int prexor = test_bit(STRIPE_OP_PREXOR, &pending); + int prexor = test_bit(STRIPE_OP_PREXOR, &sh->ops.pending); pr_debug("%s: stripe %llu\n", __FUNCTION__, (unsigned long long)sh->sector); @@ -774,8 +773,7 @@ static void ops_complete_write(void *stripe_head_ref) } static void -ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx, - unsigned long pending) +ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx) { /* kernel stack size limits the total number of disks */ int disks = sh->disks; @@ -783,7 +781,7 @@ ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx, int count = 0, pd_idx = sh->pd_idx, i; struct page *xor_dest; - int prexor = test_bit(STRIPE_OP_PREXOR, &pending); + int prexor = test_bit(STRIPE_OP_PREXOR, &sh->ops.pending); unsigned long flags; dma_async_tx_callback callback; @@ -810,7 +808,7 @@ ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx, } /* check whether this postxor is part of a write */ - callback = test_bit(STRIPE_OP_BIODRAIN, &pending) ? + callback = test_bit(STRIPE_OP_BIODRAIN, &sh->ops.pending) ? ops_complete_write : ops_complete_postxor; /* 1/ if we prexor'd then the dest is reused as a source @@ -898,12 +896,12 @@ static void raid5_run_ops(struct stripe_head *sh, unsigned long pending) tx = ops_run_prexor(sh, tx); if (test_bit(STRIPE_OP_BIODRAIN, &pending)) { - tx = ops_run_biodrain(sh, tx, pending); + tx = ops_run_biodrain(sh, tx); overlap_clear++; } if (test_bit(STRIPE_OP_POSTXOR, &pending)) - ops_run_postxor(sh, tx, pending); + ops_run_postxor(sh, tx); if (test_bit(STRIPE_OP_CHECK, &pending)) ops_run_check(sh); diff --git a/trunk/drivers/misc/ioc4.c b/trunk/drivers/misc/ioc4.c index 05172d2613d6..6a5a05d1f392 100644 --- a/trunk/drivers/misc/ioc4.c +++ b/trunk/drivers/misc/ioc4.c @@ -244,11 +244,10 @@ ioc4_variant(struct ioc4_driver_data *idd) idd->idd_pdev->bus->number == pdev->bus->number && 3 == PCI_SLOT(pdev->devfn)) found = 1; - } while (pdev && !found); - if (NULL != pdev) { pci_dev_put(pdev); + } while (pdev && !found); + if (NULL != pdev) return IOC4_VARIANT_IO9; - } /* IO10: Look for a Vitesse VSC 7174 at the same bus and slot 3. */ pdev = NULL; @@ -259,11 +258,10 @@ ioc4_variant(struct ioc4_driver_data *idd) idd->idd_pdev->bus->number == pdev->bus->number && 3 == PCI_SLOT(pdev->devfn)) found = 1; - } while (pdev && !found); - if (NULL != pdev) { pci_dev_put(pdev); + } while (pdev && !found); + if (NULL != pdev) return IOC4_VARIANT_IO10; - } /* PCI-RT: No SCSI/SATA controller will be present */ return IOC4_VARIANT_PCI_RT; diff --git a/trunk/drivers/net/arm/ep93xx_eth.c b/trunk/drivers/net/arm/ep93xx_eth.c index 91a6590d107b..7f016f3d5bf0 100644 --- a/trunk/drivers/net/arm/ep93xx_eth.c +++ b/trunk/drivers/net/arm/ep93xx_eth.c @@ -417,7 +417,7 @@ static irqreturn_t ep93xx_irq(int irq, void *dev_id) if (status & REG_INTSTS_RX) { spin_lock(&ep->rx_lock); - if (likely(netif_rx_schedule_prep(dev, &ep->napi))) { + if (likely(__netif_rx_schedule_prep(dev, &ep->napi))) { wrl(ep, REG_INTEN, REG_INTEN_TX); __netif_rx_schedule(dev, &ep->napi); } diff --git a/trunk/drivers/net/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c index 423298c84a1d..a198404a3e36 100644 --- a/trunk/drivers/net/bonding/bond_main.c +++ b/trunk/drivers/net/bonding/bond_main.c @@ -1847,9 +1847,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) */ void bond_destroy(struct bonding *bond) { + unregister_netdevice(bond->dev); bond_deinit(bond->dev); bond_destroy_sysfs_entry(bond); - unregister_netdevice(bond->dev); } /* @@ -4475,8 +4475,8 @@ static void bond_free_all(void) bond_mc_list_destroy(bond); /* Release the bonded slaves */ bond_release_all(bond_dev); - bond_deinit(bond_dev); unregister_netdevice(bond_dev); + bond_deinit(bond_dev); } #ifdef CONFIG_PROC_FS diff --git a/trunk/drivers/net/cris/eth_v10.c b/trunk/drivers/net/cris/eth_v10.c index 917b7b46f1a7..edd6828f0a78 100644 --- a/trunk/drivers/net/cris/eth_v10.c +++ b/trunk/drivers/net/cris/eth_v10.c @@ -250,7 +250,6 @@ #include #include #include -#include //#define ETHDEBUG #define D(x) @@ -280,9 +279,6 @@ struct net_local { * by this lock as well. */ spinlock_t lock; - - spinlock_t led_lock; /* Protect LED state */ - spinlock_t transceiver_lock; /* Protect transceiver state. */ }; typedef struct etrax_eth_descr @@ -299,6 +295,8 @@ struct transceiver_ops void (*check_duplex)(struct net_device* dev); }; +struct transceiver_ops* transceiver; + /* Duplex settings */ enum duplex { @@ -309,7 +307,7 @@ enum duplex /* Dma descriptors etc. */ -#define MAX_MEDIA_DATA_SIZE 1522 +#define MAX_MEDIA_DATA_SIZE 1518 #define MIN_PACKET_LEN 46 #define ETHER_HEAD_LEN 14 @@ -334,8 +332,8 @@ enum duplex /*Intel LXT972A specific*/ #define MDIO_INT_STATUS_REG_2 0x0011 -#define MDIO_INT_FULL_DUPLEX_IND (1 << 9) -#define MDIO_INT_SPEED (1 << 14) +#define MDIO_INT_FULL_DUPLEX_IND ( 1 << 9 ) +#define MDIO_INT_SPEED ( 1 << 14 ) /* Network flash constants */ #define NET_FLASH_TIME (HZ/50) /* 20 ms */ @@ -346,8 +344,8 @@ enum duplex #define NO_NETWORK_ACTIVITY 0 #define NETWORK_ACTIVITY 1 -#define NBR_OF_RX_DESC 32 -#define NBR_OF_TX_DESC 16 +#define NBR_OF_RX_DESC 64 +#define NBR_OF_TX_DESC 256 /* Large packets are sent directly to upper layers while small packets are */ /* copied (to reduce memory waste). The following constant decides the breakpoint */ @@ -369,6 +367,7 @@ enum duplex static etrax_eth_descr *myNextRxDesc; /* Points to the next descriptor to to be processed */ static etrax_eth_descr *myLastRxDesc; /* The last processed descriptor */ +static etrax_eth_descr *myPrevRxDesc; /* The descriptor right before myNextRxDesc */ static etrax_eth_descr RxDescList[NBR_OF_RX_DESC] __attribute__ ((aligned(32))); @@ -378,6 +377,7 @@ static etrax_eth_descr* myNextTxDesc; /* Next descriptor to use */ static etrax_eth_descr TxDescList[NBR_OF_TX_DESC] __attribute__ ((aligned(32))); static unsigned int network_rec_config_shadow = 0; +static unsigned int mdio_phy_addr; /* Transciever address */ static unsigned int network_tr_ctrl_shadow = 0; @@ -411,7 +411,7 @@ static int e100_set_config(struct net_device* dev, struct ifmap* map); static void e100_tx_timeout(struct net_device *dev); static struct net_device_stats *e100_get_stats(struct net_device *dev); static void set_multicast_list(struct net_device *dev); -static void e100_hardware_send_packet(struct net_local* np, char *buf, int length); +static void e100_hardware_send_packet(char *buf, int length); static void update_rx_stats(struct net_device_stats *); static void update_tx_stats(struct net_device_stats *); static int e100_probe_transceiver(struct net_device* dev); @@ -434,10 +434,7 @@ static void e100_clear_network_leds(unsigned long dummy); static void e100_set_network_leds(int active); static const struct ethtool_ops e100_ethtool_ops; -#if defined(CONFIG_ETRAX_NO_PHY) -static void dummy_check_speed(struct net_device* dev); -static void dummy_check_duplex(struct net_device* dev); -#else + static void broadcom_check_speed(struct net_device* dev); static void broadcom_check_duplex(struct net_device* dev); static void tdk_check_speed(struct net_device* dev); @@ -446,28 +443,16 @@ static void intel_check_speed(struct net_device* dev); static void intel_check_duplex(struct net_device* dev); static void generic_check_speed(struct net_device* dev); static void generic_check_duplex(struct net_device* dev); -#endif -#ifdef CONFIG_NET_POLL_CONTROLLER -static void e100_netpoll(struct net_device* dev); -#endif - -static int autoneg_normal = 1; struct transceiver_ops transceivers[] = { -#if defined(CONFIG_ETRAX_NO_PHY) - {0x0000, dummy_check_speed, dummy_check_duplex} /* Dummy */ -#else {0x1018, broadcom_check_speed, broadcom_check_duplex}, /* Broadcom */ {0xC039, tdk_check_speed, tdk_check_duplex}, /* TDK 2120 */ {0x039C, tdk_check_speed, tdk_check_duplex}, /* TDK 2120C */ {0x04de, intel_check_speed, intel_check_duplex}, /* Intel LXT972A*/ {0x0000, generic_check_speed, generic_check_duplex} /* Generic, must be last */ -#endif }; -struct transceiver_ops* transceiver = &transceivers[0]; - #define tx_done(dev) (*R_DMA_CH0_CMD == 0) /* @@ -486,22 +471,14 @@ etrax_ethernet_init(void) int i, err; printk(KERN_INFO - "ETRAX 100LX 10/100MBit ethernet v2.0 (c) 1998-2007 Axis Communications AB\n"); - - if (cris_request_io_interface(if_eth, cardname)) { - printk(KERN_CRIT "etrax_ethernet_init failed to get IO interface\n"); - return -EBUSY; - } + "ETRAX 100LX 10/100MBit ethernet v2.0 (c) 2000-2003 Axis Communications AB\n"); dev = alloc_etherdev(sizeof(struct net_local)); + np = dev->priv; + if (!dev) return -ENOMEM; - np = netdev_priv(dev); - - /* we do our own locking */ - dev->features |= NETIF_F_LLTX; - dev->base_addr = (unsigned int)R_NETWORK_SA_0; /* just to have something to show */ /* now setup our etrax specific stuff */ @@ -521,22 +498,14 @@ etrax_ethernet_init(void) dev->do_ioctl = e100_ioctl; dev->set_config = e100_set_config; dev->tx_timeout = e100_tx_timeout; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = e100_netpoll; -#endif - - spin_lock_init(&np->lock); - spin_lock_init(&np->led_lock); - spin_lock_init(&np->transceiver_lock); /* Initialise the list of Etrax DMA-descriptors */ /* Initialise receive descriptors */ for (i = 0; i < NBR_OF_RX_DESC; i++) { - /* Allocate two extra cachelines to make sure that buffer used - * by DMA does not share cacheline with any other data (to - * avoid cache bug) + /* Allocate two extra cachelines to make sure that buffer used by DMA + * does not share cacheline with any other data (to avoid cache bug) */ RxDescList[i].skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE + 2 * L1_CACHE_BYTES); if (!RxDescList[i].skb) @@ -572,6 +541,7 @@ etrax_ethernet_init(void) myNextRxDesc = &RxDescList[0]; myLastRxDesc = &RxDescList[NBR_OF_RX_DESC - 1]; + myPrevRxDesc = &RxDescList[NBR_OF_RX_DESC - 1]; myFirstTxDesc = &TxDescList[0]; myNextTxDesc = &TxDescList[0]; myLastTxDesc = &TxDescList[NBR_OF_TX_DESC - 1]; @@ -592,11 +562,10 @@ etrax_ethernet_init(void) current_speed = 10; current_speed_selection = 0; /* Auto */ speed_timer.expires = jiffies + NET_LINK_UP_CHECK_INTERVAL; - speed_timer.data = (unsigned long)dev; + duplex_timer.data = (unsigned long)dev; speed_timer.function = e100_check_speed; clear_led_timer.function = e100_clear_network_leds; - clear_led_timer.data = (unsigned long)dev; full_duplex = 0; current_duplex = autoneg; @@ -605,6 +574,7 @@ etrax_ethernet_init(void) duplex_timer.function = e100_check_duplex; /* Initialize mii interface */ + np->mii_if.phy_id = mdio_phy_addr; np->mii_if.phy_id_mask = 0x1f; np->mii_if.reg_num_mask = 0x1f; np->mii_if.dev = dev; @@ -615,9 +585,6 @@ etrax_ethernet_init(void) /* unwanted addresses are matched */ *R_NETWORK_GA_0 = 0x00000000; *R_NETWORK_GA_1 = 0x00000000; - - /* Initialize next time the led can flash */ - led_next_time = jiffies; return 0; } @@ -628,9 +595,9 @@ etrax_ethernet_init(void) static int e100_set_mac_address(struct net_device *dev, void *p) { - struct net_local *np = netdev_priv(dev); + struct net_local *np = (struct net_local *)dev->priv; struct sockaddr *addr = p; - DECLARE_MAC_BUF(mac); + int i; spin_lock(&np->lock); /* preemption protection */ @@ -719,25 +686,6 @@ e100_open(struct net_device *dev) goto grace_exit2; } - /* - * Always allocate the DMA channels after the IRQ, - * and clean up on failure. - */ - - if (cris_request_dma(NETWORK_TX_DMA_NBR, - cardname, - DMA_VERBOSE_ON_ERROR, - dma_eth)) { - goto grace_exit3; - } - - if (cris_request_dma(NETWORK_RX_DMA_NBR, - cardname, - DMA_VERBOSE_ON_ERROR, - dma_eth)) { - goto grace_exit4; - } - /* give the HW an idea of what MAC address we want */ *R_NETWORK_SA_0 = dev->dev_addr[0] | (dev->dev_addr[1] << 8) | @@ -752,7 +700,6 @@ e100_open(struct net_device *dev) *R_NETWORK_REC_CONFIG = 0xd; /* broadcast rec, individ. rec, ma0 enabled */ #else - SETS(network_rec_config_shadow, R_NETWORK_REC_CONFIG, max_size, size1522); SETS(network_rec_config_shadow, R_NETWORK_REC_CONFIG, broadcast, receive); SETS(network_rec_config_shadow, R_NETWORK_REC_CONFIG, ma0, enable); SETF(network_rec_config_shadow, R_NETWORK_REC_CONFIG, duplex, full_duplex); @@ -772,7 +719,8 @@ e100_open(struct net_device *dev) SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, crc, enable); *R_NETWORK_TR_CTRL = network_tr_ctrl_shadow; - local_irq_save(flags); + save_flags(flags); + cli(); /* enable the irq's for ethernet DMA */ @@ -804,13 +752,12 @@ e100_open(struct net_device *dev) *R_DMA_CH0_FIRST = 0; *R_DMA_CH0_DESCR = virt_to_phys(myLastTxDesc); - netif_start_queue(dev); - local_irq_restore(flags); + restore_flags(flags); /* Probe for transceiver */ if (e100_probe_transceiver(dev)) - goto grace_exit5; + goto grace_exit3; /* Start duplex/speed timers */ add_timer(&speed_timer); @@ -819,14 +766,10 @@ e100_open(struct net_device *dev) /* We are now ready to accept transmit requeusts from * the queueing layer of the networking. */ - netif_carrier_on(dev); + netif_start_queue(dev); return 0; -grace_exit5: - cris_free_dma(NETWORK_RX_DMA_NBR, cardname); -grace_exit4: - cris_free_dma(NETWORK_TX_DMA_NBR, cardname); grace_exit3: free_irq(NETWORK_STATUS_IRQ_NBR, (void *)dev); grace_exit2: @@ -837,20 +780,12 @@ e100_open(struct net_device *dev) return -EAGAIN; } -#if defined(CONFIG_ETRAX_NO_PHY) -static void -dummy_check_speed(struct net_device* dev) -{ - current_speed = 100; -} -#else + static void generic_check_speed(struct net_device* dev) { unsigned long data; - struct net_local *np = netdev_priv(dev); - - data = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_ADVERTISE); + data = e100_get_mdio_reg(dev, mdio_phy_addr, MII_ADVERTISE); if ((data & ADVERTISE_100FULL) || (data & ADVERTISE_100HALF)) current_speed = 100; @@ -862,10 +797,7 @@ static void tdk_check_speed(struct net_device* dev) { unsigned long data; - struct net_local *np = netdev_priv(dev); - - data = e100_get_mdio_reg(dev, np->mii_if.phy_id, - MDIO_TDK_DIAGNOSTIC_REG); + data = e100_get_mdio_reg(dev, mdio_phy_addr, MDIO_TDK_DIAGNOSTIC_REG); current_speed = (data & MDIO_TDK_DIAGNOSTIC_RATE ? 100 : 10); } @@ -873,10 +805,7 @@ static void broadcom_check_speed(struct net_device* dev) { unsigned long data; - struct net_local *np = netdev_priv(dev); - - data = e100_get_mdio_reg(dev, np->mii_if.phy_id, - MDIO_AUX_CTRL_STATUS_REG); + data = e100_get_mdio_reg(dev, mdio_phy_addr, MDIO_AUX_CTRL_STATUS_REG); current_speed = (data & MDIO_BC_SPEED ? 100 : 10); } @@ -884,62 +813,46 @@ static void intel_check_speed(struct net_device* dev) { unsigned long data; - struct net_local *np = netdev_priv(dev); - - data = e100_get_mdio_reg(dev, np->mii_if.phy_id, - MDIO_INT_STATUS_REG_2); + data = e100_get_mdio_reg(dev, mdio_phy_addr, MDIO_INT_STATUS_REG_2); current_speed = (data & MDIO_INT_SPEED ? 100 : 10); } -#endif + static void e100_check_speed(unsigned long priv) { struct net_device* dev = (struct net_device*)priv; - struct net_local *np = netdev_priv(dev); static int led_initiated = 0; unsigned long data; int old_speed = current_speed; - spin_lock(&np->transceiver_lock); - - data = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_BMSR); + data = e100_get_mdio_reg(dev, mdio_phy_addr, MII_BMSR); if (!(data & BMSR_LSTATUS)) { current_speed = 0; } else { transceiver->check_speed(dev); } - spin_lock(&np->led_lock); if ((old_speed != current_speed) || !led_initiated) { led_initiated = 1; e100_set_network_leds(NO_NETWORK_ACTIVITY); - if (current_speed) - netif_carrier_on(dev); - else - netif_carrier_off(dev); } - spin_unlock(&np->led_lock); /* Reinitialize the timer. */ speed_timer.expires = jiffies + NET_LINK_UP_CHECK_INTERVAL; add_timer(&speed_timer); - - spin_unlock(&np->transceiver_lock); } static void e100_negotiate(struct net_device* dev) { - struct net_local *np = netdev_priv(dev); - unsigned short data = e100_get_mdio_reg(dev, np->mii_if.phy_id, - MII_ADVERTISE); + unsigned short data = e100_get_mdio_reg(dev, mdio_phy_addr, MII_ADVERTISE); /* Discard old speed and duplex settings */ data &= ~(ADVERTISE_100HALF | ADVERTISE_100FULL | ADVERTISE_10HALF | ADVERTISE_10FULL); switch (current_speed_selection) { - case 10: + case 10 : if (current_duplex == full) data |= ADVERTISE_10FULL; else if (current_duplex == half) @@ -948,7 +861,7 @@ e100_negotiate(struct net_device* dev) data |= ADVERTISE_10HALF | ADVERTISE_10FULL; break; - case 100: + case 100 : if (current_duplex == full) data |= ADVERTISE_100FULL; else if (current_duplex == half) @@ -957,7 +870,7 @@ e100_negotiate(struct net_device* dev) data |= ADVERTISE_100HALF | ADVERTISE_100FULL; break; - case 0: /* Auto */ + case 0 : /* Auto */ if (current_duplex == full) data |= ADVERTISE_100FULL | ADVERTISE_10FULL; else if (current_duplex == half) @@ -967,44 +880,35 @@ e100_negotiate(struct net_device* dev) ADVERTISE_100HALF | ADVERTISE_100FULL; break; - default: /* assume autoneg speed and duplex */ + default : /* assume autoneg speed and duplex */ data |= ADVERTISE_10HALF | ADVERTISE_10FULL | ADVERTISE_100HALF | ADVERTISE_100FULL; - break; } - e100_set_mdio_reg(dev, np->mii_if.phy_id, MII_ADVERTISE, data); + e100_set_mdio_reg(dev, mdio_phy_addr, MII_ADVERTISE, data); /* Renegotiate with link partner */ - if (autoneg_normal) { - data = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_BMCR); + data = e100_get_mdio_reg(dev, mdio_phy_addr, MII_BMCR); data |= BMCR_ANENABLE | BMCR_ANRESTART; - } - e100_set_mdio_reg(dev, np->mii_if.phy_id, MII_BMCR, data); + + e100_set_mdio_reg(dev, mdio_phy_addr, MII_BMCR, data); } static void e100_set_speed(struct net_device* dev, unsigned long speed) { - struct net_local *np = netdev_priv(dev); - - spin_lock(&np->transceiver_lock); if (speed != current_speed_selection) { current_speed_selection = speed; e100_negotiate(dev); } - spin_unlock(&np->transceiver_lock); } static void e100_check_duplex(unsigned long priv) { struct net_device *dev = (struct net_device *)priv; - struct net_local *np = netdev_priv(dev); - int old_duplex; - - spin_lock(&np->transceiver_lock); - old_duplex = full_duplex; + struct net_local *np = (struct net_local *)dev->priv; + int old_duplex = full_duplex; transceiver->check_duplex(dev); if (old_duplex != full_duplex) { /* Duplex changed */ @@ -1016,22 +920,13 @@ e100_check_duplex(unsigned long priv) duplex_timer.expires = jiffies + NET_DUPLEX_CHECK_INTERVAL; add_timer(&duplex_timer); np->mii_if.full_duplex = full_duplex; - spin_unlock(&np->transceiver_lock); -} -#if defined(CONFIG_ETRAX_NO_PHY) -static void -dummy_check_duplex(struct net_device* dev) -{ - full_duplex = 1; } -#else + static void generic_check_duplex(struct net_device* dev) { unsigned long data; - struct net_local *np = netdev_priv(dev); - - data = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_ADVERTISE); + data = e100_get_mdio_reg(dev, mdio_phy_addr, MII_ADVERTISE); if ((data & ADVERTISE_10FULL) || (data & ADVERTISE_100FULL)) full_duplex = 1; @@ -1043,10 +938,7 @@ static void tdk_check_duplex(struct net_device* dev) { unsigned long data; - struct net_local *np = netdev_priv(dev); - - data = e100_get_mdio_reg(dev, np->mii_if.phy_id, - MDIO_TDK_DIAGNOSTIC_REG); + data = e100_get_mdio_reg(dev, mdio_phy_addr, MDIO_TDK_DIAGNOSTIC_REG); full_duplex = (data & MDIO_TDK_DIAGNOSTIC_DPLX) ? 1 : 0; } @@ -1054,10 +946,7 @@ static void broadcom_check_duplex(struct net_device* dev) { unsigned long data; - struct net_local *np = netdev_priv(dev); - - data = e100_get_mdio_reg(dev, np->mii_if.phy_id, - MDIO_AUX_CTRL_STATUS_REG); + data = e100_get_mdio_reg(dev, mdio_phy_addr, MDIO_AUX_CTRL_STATUS_REG); full_duplex = (data & MDIO_BC_FULL_DUPLEX_IND) ? 1 : 0; } @@ -1065,55 +954,38 @@ static void intel_check_duplex(struct net_device* dev) { unsigned long data; - struct net_local *np = netdev_priv(dev); - - data = e100_get_mdio_reg(dev, np->mii_if.phy_id, - MDIO_INT_STATUS_REG_2); + data = e100_get_mdio_reg(dev, mdio_phy_addr, MDIO_INT_STATUS_REG_2); full_duplex = (data & MDIO_INT_FULL_DUPLEX_IND) ? 1 : 0; } -#endif + static void e100_set_duplex(struct net_device* dev, enum duplex new_duplex) { - struct net_local *np = netdev_priv(dev); - - spin_lock(&np->transceiver_lock); if (new_duplex != current_duplex) { current_duplex = new_duplex; e100_negotiate(dev); } - spin_unlock(&np->transceiver_lock); } static int e100_probe_transceiver(struct net_device* dev) { - int ret = 0; - -#if !defined(CONFIG_ETRAX_NO_PHY) unsigned int phyid_high; unsigned int phyid_low; unsigned int oui; struct transceiver_ops* ops = NULL; - struct net_local *np = netdev_priv(dev); - - spin_lock(&np->transceiver_lock); /* Probe MDIO physical address */ - for (np->mii_if.phy_id = 0; np->mii_if.phy_id <= 31; - np->mii_if.phy_id++) { - if (e100_get_mdio_reg(dev, - np->mii_if.phy_id, MII_BMSR) != 0xffff) + for (mdio_phy_addr = 0; mdio_phy_addr <= 31; mdio_phy_addr++) { + if (e100_get_mdio_reg(dev, mdio_phy_addr, MII_BMSR) != 0xffff) break; } - if (np->mii_if.phy_id == 32) { - ret = -ENODEV; - goto out; - } + if (mdio_phy_addr == 32) + return -ENODEV; /* Get manufacturer */ - phyid_high = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_PHYSID1); - phyid_low = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_PHYSID2); + phyid_high = e100_get_mdio_reg(dev, mdio_phy_addr, MII_PHYSID1); + phyid_low = e100_get_mdio_reg(dev, mdio_phy_addr, MII_PHYSID2); oui = (phyid_high << 6) | (phyid_low >> 10); for (ops = &transceivers[0]; ops->oui; ops++) { @@ -1121,10 +993,8 @@ e100_probe_transceiver(struct net_device* dev) break; } transceiver = ops; -out: - spin_unlock(&np->transceiver_lock); -#endif - return ret; + + return 0; } static int @@ -1218,14 +1088,13 @@ e100_receive_mdio_bit() static void e100_reset_transceiver(struct net_device* dev) { - struct net_local *np = netdev_priv(dev); unsigned short cmd; unsigned short data; int bitCounter; - data = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_BMCR); + data = e100_get_mdio_reg(dev, mdio_phy_addr, MII_BMCR); - cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (np->mii_if.phy_id << 7) | (MII_BMCR << 2); + cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (mdio_phy_addr << 7) | (MII_BMCR << 2); e100_send_mdio_cmd(cmd, 1); @@ -1243,7 +1112,7 @@ e100_reset_transceiver(struct net_device* dev) static void e100_tx_timeout(struct net_device *dev) { - struct net_local *np = netdev_priv(dev); + struct net_local *np = (struct net_local *)dev->priv; unsigned long flags; spin_lock_irqsave(&np->lock, flags); @@ -1265,7 +1134,8 @@ e100_tx_timeout(struct net_device *dev) e100_reset_transceiver(dev); /* and get rid of the packets that never got an interrupt */ - while (myFirstTxDesc != myNextTxDesc) { + while (myFirstTxDesc != myNextTxDesc) + { dev_kfree_skb(myFirstTxDesc->skb); myFirstTxDesc->skb = 0; myFirstTxDesc = phys_to_virt(myFirstTxDesc->descr.next); @@ -1291,7 +1161,7 @@ e100_tx_timeout(struct net_device *dev) static int e100_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct net_local *np = netdev_priv(dev); + struct net_local *np = (struct net_local *)dev->priv; unsigned char *buf = skb->data; unsigned long flags; @@ -1304,7 +1174,7 @@ e100_send_packet(struct sk_buff *skb, struct net_device *dev) dev->trans_start = jiffies; - e100_hardware_send_packet(np, buf, skb->len); + e100_hardware_send_packet(buf, skb->len); myNextTxDesc = phys_to_virt(myNextTxDesc->descr.next); @@ -1327,15 +1197,13 @@ static irqreturn_t e100rxtx_interrupt(int irq, void *dev_id) { struct net_device *dev = (struct net_device *)dev_id; - struct net_local *np = netdev_priv(dev); - unsigned long irqbits; - - /* - * Note that both rx and tx interrupts are blocked at this point, - * regardless of which got us here. - */ + struct net_local *np = (struct net_local *)dev->priv; + unsigned long irqbits = *R_IRQ_MASK2_RD; - irqbits = *R_IRQ_MASK2_RD; + /* Disable RX/TX IRQs to avoid reentrancy */ + *R_IRQ_MASK2_CLR = + IO_STATE(R_IRQ_MASK2_CLR, dma0_eop, clr) | + IO_STATE(R_IRQ_MASK2_CLR, dma1_eop, clr); /* Handle received packets */ if (irqbits & IO_STATE(R_IRQ_MASK2_RD, dma1_eop, active)) { @@ -1351,7 +1219,7 @@ e100rxtx_interrupt(int irq, void *dev_id) * allocate a new buffer to put a packet in. */ e100_rx(dev); - np->stats.rx_packets++; + ((struct net_local *)dev->priv)->stats.rx_packets++; /* restart/continue on the channel, for safety */ *R_DMA_CH1_CMD = IO_STATE(R_DMA_CH1_CMD, cmd, restart); /* clear dma channel 1 eop/descr irq bits */ @@ -1365,8 +1233,9 @@ e100rxtx_interrupt(int irq, void *dev_id) } /* Report any packets that have been sent */ - while (virt_to_phys(myFirstTxDesc) != *R_DMA_CH0_FIRST && - (netif_queue_stopped(dev) || myFirstTxDesc != myNextTxDesc)) { + while (myFirstTxDesc != phys_to_virt(*R_DMA_CH0_FIRST) && + myFirstTxDesc != myNextTxDesc) + { np->stats.tx_bytes += myFirstTxDesc->skb->len; np->stats.tx_packets++; @@ -1375,15 +1244,19 @@ e100rxtx_interrupt(int irq, void *dev_id) dev_kfree_skb_irq(myFirstTxDesc->skb); myFirstTxDesc->skb = 0; myFirstTxDesc = phys_to_virt(myFirstTxDesc->descr.next); - /* Wake up queue. */ - netif_wake_queue(dev); } if (irqbits & IO_STATE(R_IRQ_MASK2_RD, dma0_eop, active)) { - /* acknowledge the eop interrupt. */ + /* acknowledge the eop interrupt and wake up queue */ *R_DMA_CH0_CLR_INTR = IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do); + netif_wake_queue(dev); } + /* Enable RX/TX IRQs again */ + *R_IRQ_MASK2_SET = + IO_STATE(R_IRQ_MASK2_SET, dma0_eop, set) | + IO_STATE(R_IRQ_MASK2_SET, dma1_eop, set); + return IRQ_HANDLED; } @@ -1391,7 +1264,7 @@ static irqreturn_t e100nw_interrupt(int irq, void *dev_id) { struct net_device *dev = (struct net_device *)dev_id; - struct net_local *np = netdev_priv(dev); + struct net_local *np = (struct net_local *)dev->priv; unsigned long irqbits = *R_IRQ_MASK0_RD; /* check for underrun irq */ @@ -1413,6 +1286,7 @@ e100nw_interrupt(int irq, void *dev_id) SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, clr); *R_NETWORK_TR_CTRL = network_tr_ctrl_shadow; SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, nop); + *R_NETWORK_TR_CTRL = IO_STATE(R_NETWORK_TR_CTRL, clr_error, clr); np->stats.tx_errors++; D(printk("ethernet excessive collisions!\n")); } @@ -1425,13 +1299,12 @@ e100_rx(struct net_device *dev) { struct sk_buff *skb; int length = 0; - struct net_local *np = netdev_priv(dev); + struct net_local *np = (struct net_local *)dev->priv; unsigned char *skb_data_ptr; #ifdef ETHDEBUG int i; #endif - etrax_eth_descr *prevRxDesc; /* The descriptor right before myNextRxDesc */ - spin_lock(&np->led_lock); + if (!led_active && time_after(jiffies, led_next_time)) { /* light the network leds depending on the current speed. */ e100_set_network_leds(NETWORK_ACTIVITY); @@ -1441,10 +1314,9 @@ e100_rx(struct net_device *dev) led_active = 1; mod_timer(&clear_led_timer, jiffies + HZ/10); } - spin_unlock(&np->led_lock); length = myNextRxDesc->descr.hw_len - 4; - np->stats.rx_bytes += length; + ((struct net_local *)dev->priv)->stats.rx_bytes += length; #ifdef ETHDEBUG printk("Got a packet of length %d:\n", length); @@ -1464,7 +1336,7 @@ e100_rx(struct net_device *dev) if (!skb) { np->stats.rx_errors++; printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); - goto update_nextrxdesc; + return; } skb_put(skb, length - ETHER_HEAD_LEN); /* allocate room for the packet body */ @@ -1482,15 +1354,15 @@ e100_rx(struct net_device *dev) else { /* Large packet, send directly to upper layers and allocate new * memory (aligned to cache line boundary to avoid bug). - * Before sending the skb to upper layers we must make sure - * that skb->data points to the aligned start of the packet. + * Before sending the skb to upper layers we must make sure that + * skb->data points to the aligned start of the packet. */ int align; struct sk_buff *new_skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE + 2 * L1_CACHE_BYTES); if (!new_skb) { np->stats.rx_errors++; printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); - goto update_nextrxdesc; + return; } skb = myNextRxDesc->skb; align = (int)phys_to_virt(myNextRxDesc->descr.buf) - (int)skb->data; @@ -1505,10 +1377,9 @@ e100_rx(struct net_device *dev) /* Send the packet to the upper layers */ netif_rx(skb); - update_nextrxdesc: /* Prepare for next packet */ myNextRxDesc->descr.status = 0; - prevRxDesc = myNextRxDesc; + myPrevRxDesc = myNextRxDesc; myNextRxDesc = phys_to_virt(myNextRxDesc->descr.next); rx_queue_len++; @@ -1516,9 +1387,9 @@ e100_rx(struct net_device *dev) /* Check if descriptors should be returned */ if (rx_queue_len == RX_QUEUE_THRESHOLD) { flush_etrax_cache(); - prevRxDesc->descr.ctrl |= d_eol; + myPrevRxDesc->descr.ctrl |= d_eol; myLastRxDesc->descr.ctrl &= ~d_eol; - myLastRxDesc = prevRxDesc; + myLastRxDesc = myPrevRxDesc; rx_queue_len = 0; } } @@ -1527,7 +1398,7 @@ e100_rx(struct net_device *dev) static int e100_close(struct net_device *dev) { - struct net_local *np = netdev_priv(dev); + struct net_local *np = (struct net_local *)dev->priv; printk(KERN_INFO "Closing %s.\n", dev->name); @@ -1555,9 +1426,6 @@ e100_close(struct net_device *dev) free_irq(NETWORK_DMA_TX_IRQ_NBR, (void *)dev); free_irq(NETWORK_STATUS_IRQ_NBR, (void *)dev); - cris_free_dma(NETWORK_TX_DMA_NBR, cardname); - cris_free_dma(NETWORK_RX_DMA_NBR, cardname); - /* Update the statistics here. */ update_rx_stats(&np->stats); @@ -1575,11 +1443,18 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct mii_ioctl_data *data = if_mii(ifr); struct net_local *np = netdev_priv(dev); - int rc = 0; - int old_autoneg; spin_lock(&np->lock); /* Preempt protection */ switch (cmd) { + case SIOCGMIIPHY: /* Get PHY address */ + data->phy_id = mdio_phy_addr; + break; + case SIOCGMIIREG: /* Read MII register */ + data->val_out = e100_get_mdio_reg(dev, mdio_phy_addr, data->reg_num); + break; + case SIOCSMIIREG: /* Write MII register */ + e100_set_mdio_reg(dev, mdio_phy_addr, data->reg_num, data->val_in); + break; /* The ioctls below should be considered obsolete but are */ /* still present for compatability with old scripts/apps */ case SET_ETH_SPEED_10: /* 10 Mbps */ @@ -1588,47 +1463,60 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) case SET_ETH_SPEED_100: /* 100 Mbps */ e100_set_speed(dev, 100); break; - case SET_ETH_SPEED_AUTO: /* Auto-negotiate speed */ + case SET_ETH_SPEED_AUTO: /* Auto negotiate speed */ e100_set_speed(dev, 0); break; - case SET_ETH_DUPLEX_HALF: /* Half duplex */ + case SET_ETH_DUPLEX_HALF: /* Half duplex. */ e100_set_duplex(dev, half); break; - case SET_ETH_DUPLEX_FULL: /* Full duplex */ + case SET_ETH_DUPLEX_FULL: /* Full duplex. */ e100_set_duplex(dev, full); break; - case SET_ETH_DUPLEX_AUTO: /* Auto-negotiate duplex */ + case SET_ETH_DUPLEX_AUTO: /* Autonegotiate duplex*/ e100_set_duplex(dev, autoneg); break; - case SET_ETH_AUTONEG: - old_autoneg = autoneg_normal; - autoneg_normal = *(int*)data; - if (autoneg_normal != old_autoneg) - e100_negotiate(dev); - break; default: - rc = generic_mii_ioctl(&np->mii_if, if_mii(ifr), - cmd, NULL); - break; + return -EINVAL; } spin_unlock(&np->lock); - return rc; + return 0; } -static int e100_get_settings(struct net_device *dev, - struct ethtool_cmd *cmd) +static int e100_set_settings(struct net_device *dev, + struct ethtool_cmd *ecmd) { - struct net_local *np = netdev_priv(dev); - int err; + ecmd->supported = SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII | + SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full; + ecmd->port = PORT_TP; + ecmd->transceiver = XCVR_EXTERNAL; + ecmd->phy_address = mdio_phy_addr; + ecmd->speed = current_speed; + ecmd->duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF; + ecmd->advertising = ADVERTISED_TP; - spin_lock_irq(&np->lock); - err = mii_ethtool_gset(&np->mii_if, cmd); - spin_unlock_irq(&np->lock); + if (current_duplex == autoneg && current_speed_selection == 0) + ecmd->advertising |= ADVERTISED_Autoneg; + else { + ecmd->advertising |= + ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full; + if (current_speed_selection == 10) + ecmd->advertising &= ~(ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full); + else if (current_speed_selection == 100) + ecmd->advertising &= ~(ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full); + if (current_duplex == half) + ecmd->advertising &= ~(ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Full); + else if (current_duplex == full) + ecmd->advertising &= ~(ADVERTISED_10baseT_Half | + ADVERTISED_100baseT_Half); + } - /* The PHY may support 1000baseT, but the Etrax100 does not. */ - cmd->supported &= ~(SUPPORTED_1000baseT_Half - | SUPPORTED_1000baseT_Full); - return err; + ecmd->autoneg = AUTONEG_ENABLE; + return 0; } static int e100_set_settings(struct net_device *dev, @@ -1672,8 +1560,7 @@ static const struct ethtool_ops e100_ethtool_ops = { static int e100_set_config(struct net_device *dev, struct ifmap *map) { - struct net_local *np = netdev_priv(dev); - + struct net_local *np = (struct net_local *)dev->priv; spin_lock(&np->lock); /* Preempt protection */ switch(map->port) { @@ -1725,6 +1612,7 @@ update_tx_stats(struct net_device_stats *es) es->collisions += IO_EXTRACT(R_TR_COUNTERS, single_col, r) + IO_EXTRACT(R_TR_COUNTERS, multiple_col, r); + es->tx_errors += IO_EXTRACT(R_TR_COUNTERS, deferred, r); } /* @@ -1734,9 +1622,8 @@ update_tx_stats(struct net_device_stats *es) static struct net_device_stats * e100_get_stats(struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *)dev->priv; unsigned long flags; - spin_lock_irqsave(&lp->lock, flags); update_rx_stats(&lp->stats); @@ -1756,13 +1643,13 @@ e100_get_stats(struct net_device *dev) static void set_multicast_list(struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *)dev->priv; int num_addr = dev->mc_count; unsigned long int lo_bits; unsigned long int hi_bits; - spin_lock(&lp->lock); - if (dev->flags & IFF_PROMISC) { + if (dev->flags & IFF_PROMISC) + { /* promiscuous mode */ lo_bits = 0xfffffffful; hi_bits = 0xfffffffful; @@ -1792,10 +1679,9 @@ set_multicast_list(struct net_device *dev) struct dev_mc_list *dmi = dev->mc_list; int i; char *baddr; - lo_bits = 0x00000000ul; hi_bits = 0x00000000ul; - for (i = 0; i < num_addr; i++) { + for (i=0; i= 32) { hi_bits |= (1 << (hash_ix-32)); - } else { + } + else { lo_bits |= (1 << hash_ix); } dmi = dmi->next; @@ -1837,11 +1724,10 @@ set_multicast_list(struct net_device *dev) } void -e100_hardware_send_packet(struct net_local *np, char *buf, int length) +e100_hardware_send_packet(char *buf, int length) { D(printk("e100 send pack, buf 0x%x len %d\n", buf, length)); - spin_lock(&np->led_lock); if (!led_active && time_after(jiffies, led_next_time)) { /* light the network leds depending on the current speed. */ e100_set_network_leds(NETWORK_ACTIVITY); @@ -1851,7 +1737,6 @@ e100_hardware_send_packet(struct net_local *np, char *buf, int length) led_active = 1; mod_timer(&clear_led_timer, jiffies + HZ/10); } - spin_unlock(&np->led_lock); /* configure the tx dma descriptor */ myNextTxDesc->descr.sw_len = length; @@ -1869,11 +1754,6 @@ e100_hardware_send_packet(struct net_local *np, char *buf, int length) static void e100_clear_network_leds(unsigned long dummy) { - struct net_device *dev = (struct net_device *)dummy; - struct net_local *np = netdev_priv(dev); - - spin_lock(&np->led_lock); - if (led_active && time_after(jiffies, led_next_time)) { e100_set_network_leds(NO_NETWORK_ACTIVITY); @@ -1881,8 +1761,6 @@ e100_clear_network_leds(unsigned long dummy) led_next_time = jiffies + NET_FLASH_PAUSE; led_active = 0; } - - spin_unlock(&np->led_lock); } static void @@ -1903,25 +1781,19 @@ e100_set_network_leds(int active) #else LED_NETWORK_SET(LED_OFF); #endif - } else if (light_leds) { + } + else if (light_leds) { if (current_speed == 10) { LED_NETWORK_SET(LED_ORANGE); } else { LED_NETWORK_SET(LED_GREEN); } - } else { + } + else { LED_NETWORK_SET(LED_OFF); } } -#ifdef CONFIG_NET_POLL_CONTROLLER -static void -e100_netpoll(struct net_device* netdev) -{ - e100rxtx_interrupt(NETWORK_DMA_TX_IRQ_NBR, netdev, NULL); -} -#endif - static int etrax_init_module(void) { diff --git a/trunk/drivers/net/e1000/e1000_main.c b/trunk/drivers/net/e1000/e1000_main.c index cf39473ef90a..72deff0d4d90 100644 --- a/trunk/drivers/net/e1000/e1000_main.c +++ b/trunk/drivers/net/e1000/e1000_main.c @@ -4804,7 +4804,6 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) spin_unlock_irqrestore(&adapter->stats_lock, flags); return -EIO; } - spin_unlock_irqrestore(&adapter->stats_lock, flags); if (adapter->hw.media_type == e1000_media_type_copper) { switch (data->reg_num) { case PHY_CTRL: @@ -4825,8 +4824,12 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) DUPLEX_HALF; retval = e1000_set_spd_dplx(adapter, spddplx); - if (retval) + if (retval) { + spin_unlock_irqrestore( + &adapter->stats_lock, + flags); return retval; + } } if (netif_running(adapter->netdev)) e1000_reinit_locked(adapter); @@ -4835,8 +4838,11 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) break; case M88E1000_PHY_SPEC_CTRL: case M88E1000_EXT_PHY_SPEC_CTRL: - if (e1000_phy_reset(&adapter->hw)) + if (e1000_phy_reset(&adapter->hw)) { + spin_unlock_irqrestore( + &adapter->stats_lock, flags); return -EIO; + } break; } } else { @@ -4851,6 +4857,7 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) break; } } + spin_unlock_irqrestore(&adapter->stats_lock, flags); break; default: return -EOPNOTSUPP; diff --git a/trunk/drivers/net/fs_enet/Kconfig b/trunk/drivers/net/fs_enet/Kconfig index 562ea68ed99b..2765e49e07df 100644 --- a/trunk/drivers/net/fs_enet/Kconfig +++ b/trunk/drivers/net/fs_enet/Kconfig @@ -2,7 +2,6 @@ config FS_ENET tristate "Freescale Ethernet Driver" depends on CPM1 || CPM2 select MII - select PHYLIB config FS_ENET_HAS_SCC bool "Chip has an SCC usable for ethernet" @@ -12,19 +11,11 @@ config FS_ENET_HAS_SCC config FS_ENET_HAS_FCC bool "Chip has an FCC usable for ethernet" depends on FS_ENET && CPM2 + select MDIO_BITBANG default y config FS_ENET_HAS_FEC bool "Chip has an FEC usable for ethernet" depends on FS_ENET && CPM1 - select FS_ENET_MDIO_FEC default y -config FS_ENET_MDIO_FEC - tristate "MDIO driver for FEC" - depends on FS_ENET && CPM1 - -config FS_ENET_MDIO_FCC - tristate "MDIO driver for FCC" - depends on FS_ENET && CPM2 - select MDIO_BITBANG diff --git a/trunk/drivers/net/fs_enet/Makefile b/trunk/drivers/net/fs_enet/Makefile index 1ffbe0756a0c..02d4dc18ba69 100644 --- a/trunk/drivers/net/fs_enet/Makefile +++ b/trunk/drivers/net/fs_enet/Makefile @@ -4,16 +4,7 @@ obj-$(CONFIG_FS_ENET) += fs_enet.o -fs_enet-$(CONFIG_FS_ENET_HAS_SCC) += mac-scc.o -fs_enet-$(CONFIG_FS_ENET_HAS_FEC) += mac-fec.o -fs_enet-$(CONFIG_FS_ENET_HAS_FCC) += mac-fcc.o +obj-$(CONFIG_8xx) += mac-fec.o mac-scc.o mii-fec.o +obj-$(CONFIG_CPM2) += mac-fcc.o mii-bitbang.o -ifeq ($(CONFIG_PPC_CPM_NEW_BINDING),y) -obj-$(CONFIG_FS_ENET_MDIO_FEC) += mii-fec.o -obj-$(CONFIG_FS_ENET_MDIO_FCC) += mii-bitbang.o -else -fs_enet-$(CONFIG_FS_ENET_MDIO_FEC) += mii-fec.o -fs_enet-$(CONFIG_FS_ENET_MDIO_FCC) += mii-bitbang.o -endif - -fs_enet-objs := fs_enet-main.o $(fs_enet-m) +fs_enet-objs := fs_enet-main.o diff --git a/trunk/drivers/net/mlx4/alloc.c b/trunk/drivers/net/mlx4/alloc.c index f8d63d39f592..b226e019bc8b 100644 --- a/trunk/drivers/net/mlx4/alloc.c +++ b/trunk/drivers/net/mlx4/alloc.c @@ -171,9 +171,10 @@ void mlx4_buf_free(struct mlx4_dev *dev, int size, struct mlx4_buf *buf) buf->u.direct.map); else { for (i = 0; i < buf->nbufs; ++i) - dma_free_coherent(&dev->pdev->dev, PAGE_SIZE, - buf->u.page_list[i].buf, - buf->u.page_list[i].map); + if (buf->u.page_list[i].buf) + dma_free_coherent(&dev->pdev->dev, PAGE_SIZE, + buf->u.page_list[i].buf, + buf->u.page_list[i].map); kfree(buf->u.page_list); } } diff --git a/trunk/drivers/net/netx-eth.c b/trunk/drivers/net/netx-eth.c index 5267e031daa0..eb0aff787dfd 100644 --- a/trunk/drivers/net/netx-eth.c +++ b/trunk/drivers/net/netx-eth.c @@ -128,8 +128,8 @@ netx_eth_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) FIFO_PTR_FRAMELEN(len)); ndev->trans_start = jiffies; - ndev->stats.tx_packets++; - ndev->stats.tx_bytes += skb->len; + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; netif_stop_queue(ndev); spin_unlock_irq(&priv->lock); @@ -155,7 +155,7 @@ static void netx_eth_receive(struct net_device *ndev) if (unlikely(skb == NULL)) { printk(KERN_NOTICE "%s: Low memory, packet dropped.\n", ndev->name); - ndev->stats.rx_dropped++; + dev->stats.rx_dropped++; return; } diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c index 632666706247..b8c0e7b4ca1c 100644 --- a/trunk/drivers/net/s2io.c +++ b/trunk/drivers/net/s2io.c @@ -84,7 +84,7 @@ #include "s2io.h" #include "s2io-regs.h" -#define DRV_VERSION "2.0.26.6" +#define DRV_VERSION "2.0.26.5" /* S2io Driver name & version. */ static char s2io_driver_name[] = "Neterion"; @@ -3775,40 +3775,6 @@ static int __devinit s2io_test_msi(struct s2io_nic *sp) return err; } - -static void remove_msix_isr(struct s2io_nic *sp) -{ - int i; - u16 msi_control; - - for (i = 0; i < MAX_REQUESTED_MSI_X; i++) { - if (sp->s2io_entries[i].in_use == - MSIX_REGISTERED_SUCCESS) { - int vector = sp->entries[i].vector; - void *arg = sp->s2io_entries[i].arg; - free_irq(vector, arg); - } - } - - kfree(sp->entries); - kfree(sp->s2io_entries); - sp->entries = NULL; - sp->s2io_entries = NULL; - - pci_read_config_word(sp->pdev, 0x42, &msi_control); - msi_control &= 0xFFFE; /* Disable MSI */ - pci_write_config_word(sp->pdev, 0x42, msi_control); - - pci_disable_msix(sp->pdev); -} - -static void remove_inta_isr(struct s2io_nic *sp) -{ - struct net_device *dev = sp->dev; - - free_irq(sp->pdev->irq, dev); -} - /* ********************************************************* * * Functions defined below concern the OS part of the driver * * ********************************************************* */ @@ -3843,9 +3809,28 @@ static int s2io_open(struct net_device *dev) int ret = s2io_enable_msi_x(sp); if (!ret) { + u16 msi_control; + ret = s2io_test_msi(sp); + /* rollback MSI-X, will re-enable during add_isr() */ - remove_msix_isr(sp); + kfree(sp->entries); + sp->mac_control.stats_info->sw_stat.mem_freed += + (MAX_REQUESTED_MSI_X * + sizeof(struct msix_entry)); + kfree(sp->s2io_entries); + sp->mac_control.stats_info->sw_stat.mem_freed += + (MAX_REQUESTED_MSI_X * + sizeof(struct s2io_msix_entry)); + sp->entries = NULL; + sp->s2io_entries = NULL; + + pci_read_config_word(sp->pdev, 0x42, &msi_control); + msi_control &= 0xFFFE; /* Disable MSI */ + pci_write_config_word(sp->pdev, 0x42, msi_control); + + pci_disable_msix(sp->pdev); + } if (ret) { @@ -6734,22 +6719,15 @@ static int s2io_add_isr(struct s2io_nic * sp) } } if (err) { - remove_msix_isr(sp); DBG_PRINT(ERR_DBG,"%s:MSI-X-%d registration " "failed\n", dev->name, i); - DBG_PRINT(ERR_DBG, "%s: defaulting to INTA\n", - dev->name); - sp->config.intr_type = INTA; - break; + DBG_PRINT(ERR_DBG, "Returned: %d\n", err); + return -1; } sp->s2io_entries[i].in_use = MSIX_REGISTERED_SUCCESS; } - if (!err) { - printk(KERN_INFO "MSI-X-TX %d entries enabled\n", - msix_tx_cnt); - printk(KERN_INFO "MSI-X-RX %d entries enabled\n", - msix_rx_cnt); - } + printk("MSI-X-TX %d entries enabled\n",msix_tx_cnt); + printk("MSI-X-RX %d entries enabled\n",msix_rx_cnt); } if (sp->config.intr_type == INTA) { err = request_irq((int) sp->pdev->irq, s2io_isr, IRQF_SHARED, @@ -6764,10 +6742,40 @@ static int s2io_add_isr(struct s2io_nic * sp) } static void s2io_rem_isr(struct s2io_nic * sp) { - if (sp->config.intr_type == MSI_X) - remove_msix_isr(sp); - else - remove_inta_isr(sp); + struct net_device *dev = sp->dev; + struct swStat *stats = &sp->mac_control.stats_info->sw_stat; + + if (sp->config.intr_type == MSI_X) { + int i; + u16 msi_control; + + for (i=1; (sp->s2io_entries[i].in_use == + MSIX_REGISTERED_SUCCESS); i++) { + int vector = sp->entries[i].vector; + void *arg = sp->s2io_entries[i].arg; + + synchronize_irq(vector); + free_irq(vector, arg); + } + + kfree(sp->entries); + stats->mem_freed += + (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); + kfree(sp->s2io_entries); + stats->mem_freed += + (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); + sp->entries = NULL; + sp->s2io_entries = NULL; + + pci_read_config_word(sp->pdev, 0x42, &msi_control); + msi_control &= 0xFFFE; /* Disable MSI */ + pci_write_config_word(sp->pdev, 0x42, msi_control); + + pci_disable_msix(sp->pdev); + } else { + synchronize_irq(sp->pdev->irq); + free_irq(sp->pdev->irq, dev); + } } static void do_s2io_card_down(struct s2io_nic * sp, int do_io) diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c b/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c index ee752f1e21dd..be7c9f42a340 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -4850,7 +4850,7 @@ static irqreturn_t iwl_isr(int irq, void *data) if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) { /* Hardware disappeared */ IWL_WARNING("HARDWARE GONE?? INTA == 0x%080x\n", inta); - goto unplugged; + goto none; } IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", @@ -4858,7 +4858,6 @@ static irqreturn_t iwl_isr(int irq, void *data) /* iwl_irq_tasklet() will service interrupts and re-enable them */ tasklet_schedule(&priv->irq_tasklet); -unplugged: spin_unlock(&priv->lock); return IRQ_HANDLED; diff --git a/trunk/drivers/oprofile/cpu_buffer.c b/trunk/drivers/oprofile/cpu_buffer.c index c93d3d2640ab..a83c3db7d18f 100644 --- a/trunk/drivers/oprofile/cpu_buffer.c +++ b/trunk/drivers/oprofile/cpu_buffer.c @@ -64,8 +64,6 @@ int alloc_cpu_buffers(void) b->head_pos = 0; b->sample_received = 0; b->sample_lost_overflow = 0; - b->backtrace_aborted = 0; - b->sample_invalid_eip = 0; b->cpu = i; INIT_DELAYED_WORK(&b->work, wq_sync_buffer); } @@ -177,11 +175,6 @@ static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc, cpu_buf->sample_received++; - if (pc == ESCAPE_CODE) { - cpu_buf->sample_invalid_eip++; - return 0; - } - if (nr_available_slots(cpu_buf) < 3) { cpu_buf->sample_lost_overflow++; return 0; diff --git a/trunk/drivers/oprofile/cpu_buffer.h b/trunk/drivers/oprofile/cpu_buffer.h index c66c025abe75..49900d9e3235 100644 --- a/trunk/drivers/oprofile/cpu_buffer.h +++ b/trunk/drivers/oprofile/cpu_buffer.h @@ -42,7 +42,6 @@ struct oprofile_cpu_buffer { unsigned long sample_received; unsigned long sample_lost_overflow; unsigned long backtrace_aborted; - unsigned long sample_invalid_eip; int cpu; struct delayed_work work; } ____cacheline_aligned; diff --git a/trunk/drivers/oprofile/oprofile_stats.c b/trunk/drivers/oprofile/oprofile_stats.c index d1f6d776e9e4..f0acb661c253 100644 --- a/trunk/drivers/oprofile/oprofile_stats.c +++ b/trunk/drivers/oprofile/oprofile_stats.c @@ -26,8 +26,6 @@ void oprofile_reset_stats(void) cpu_buf = &cpu_buffer[i]; cpu_buf->sample_received = 0; cpu_buf->sample_lost_overflow = 0; - cpu_buf->backtrace_aborted = 0; - cpu_buf->sample_invalid_eip = 0; } atomic_set(&oprofile_stats.sample_lost_no_mm, 0); @@ -63,8 +61,6 @@ void oprofile_create_stats_files(struct super_block * sb, struct dentry * root) &cpu_buf->sample_lost_overflow); oprofilefs_create_ro_ulong(sb, cpudir, "backtrace_aborted", &cpu_buf->backtrace_aborted); - oprofilefs_create_ro_ulong(sb, cpudir, "sample_invalid_eip", - &cpu_buf->sample_invalid_eip); } oprofilefs_create_ro_atomic(sb, dir, "sample_lost_no_mm", diff --git a/trunk/drivers/rtc/Kconfig b/trunk/drivers/rtc/Kconfig index e5cdc0294aaa..cbde770eb121 100644 --- a/trunk/drivers/rtc/Kconfig +++ b/trunk/drivers/rtc/Kconfig @@ -36,9 +36,7 @@ config RTC_HCTOSYS_DEVICE help The RTC device that will be used to (re)initialize the system clock, usually rtc0. Initialization is done when the system - starts up, and when it resumes from a low power state. This - device should record time in UTC, since the kernel won't do - timezone correction. + starts up, and when it resumes from a low power state. The driver for this RTC device must be loaded before late_initcall functions run, so it must usually be statically linked. @@ -135,8 +133,8 @@ config RTC_DRV_DS1307 The first seven registers on these chips hold an RTC, and other registers may add features such as NVRAM, a trickle charger for - the RTC/NVRAM backup power, and alarms. NVRAM is visible in - sysfs, but other chip features may not be available. + the RTC/NVRAM backup power, and alarms. This driver may not + expose all those available chip features. This driver can also be built as a module. If so, the module will be called rtc-ds1307. diff --git a/trunk/drivers/rtc/hctosys.c b/trunk/drivers/rtc/hctosys.c index 33c0e98243ee..178527252c6a 100644 --- a/trunk/drivers/rtc/hctosys.c +++ b/trunk/drivers/rtc/hctosys.c @@ -47,8 +47,8 @@ static int __init rtc_hctosys(void) do_settimeofday(&tv); dev_info(rtc->dev.parent, - "setting system clock to " - "%d-%02d-%02d %02d:%02d:%02d UTC (%u)\n", + "setting the system clock to " + "%d-%02d-%02d %02d:%02d:%02d (%u)\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, (unsigned int) tv.tv_sec); diff --git a/trunk/drivers/rtc/rtc-ds1307.c b/trunk/drivers/rtc/rtc-ds1307.c index bc1c7fe94ad3..db6f3f0d8982 100644 --- a/trunk/drivers/rtc/rtc-ds1307.c +++ b/trunk/drivers/rtc/rtc-ds1307.c @@ -89,7 +89,6 @@ enum ds_type { struct ds1307 { u8 reg_addr; - bool has_nvram; u8 regs[8]; enum ds_type type; struct i2c_msg msg[2]; @@ -243,87 +242,6 @@ static const struct rtc_class_ops ds13xx_rtc_ops = { .set_time = ds1307_set_time, }; -/*----------------------------------------------------------------------*/ - -#define NVRAM_SIZE 56 - -static ssize_t -ds1307_nvram_read(struct kobject *kobj, struct bin_attribute *attr, - char *buf, loff_t off, size_t count) -{ - struct i2c_client *client; - struct ds1307 *ds1307; - struct i2c_msg msg[2]; - int result; - - client = to_i2c_client(container_of(kobj, struct device, kobj)); - ds1307 = i2c_get_clientdata(client); - - if (unlikely(off >= NVRAM_SIZE)) - return 0; - if ((off + count) > NVRAM_SIZE) - count = NVRAM_SIZE - off; - if (unlikely(!count)) - return count; - - msg[0].addr = client->addr; - msg[0].flags = 0; - msg[0].len = 1; - msg[0].buf = buf; - - buf[0] = 8 + off; - - msg[1].addr = client->addr; - msg[1].flags = I2C_M_RD; - msg[1].len = count; - msg[1].buf = buf; - - result = i2c_transfer(to_i2c_adapter(client->dev.parent), msg, 2); - if (result != 2) { - dev_err(&client->dev, "%s error %d\n", "nvram read", result); - return -EIO; - } - return count; -} - -static ssize_t -ds1307_nvram_write(struct kobject *kobj, struct bin_attribute *attr, - char *buf, loff_t off, size_t count) -{ - struct i2c_client *client; - u8 buffer[NVRAM_SIZE + 1]; - int ret; - - client = to_i2c_client(container_of(kobj, struct device, kobj)); - - if (unlikely(off >= NVRAM_SIZE)) - return -EFBIG; - if ((off + count) > NVRAM_SIZE) - count = NVRAM_SIZE - off; - if (unlikely(!count)) - return count; - - buffer[0] = 8 + off; - memcpy(buffer + 1, buf, count); - - ret = i2c_master_send(client, buffer, count + 1); - return (ret < 0) ? ret : (ret - 1); -} - -static struct bin_attribute nvram = { - .attr = { - .name = "nvram", - .mode = S_IRUGO | S_IWUSR, - .owner = THIS_MODULE, - }, - - .read = ds1307_nvram_read, - .write = ds1307_nvram_write, - .size = NVRAM_SIZE, -}; - -/*----------------------------------------------------------------------*/ - static struct i2c_driver ds1307_driver; static int __devinit ds1307_probe(struct i2c_client *client) @@ -495,14 +413,6 @@ static int __devinit ds1307_probe(struct i2c_client *client) goto exit_free; } - if (chip->nvram56) { - err = sysfs_create_bin_file(&client->dev.kobj, &nvram); - if (err == 0) { - ds1307->has_nvram = true; - dev_info(&client->dev, "56 bytes nvram\n"); - } - } - return 0; exit_bad: @@ -522,9 +432,6 @@ static int __devexit ds1307_remove(struct i2c_client *client) { struct ds1307 *ds1307 = i2c_get_clientdata(client); - if (ds1307->has_nvram) - sysfs_remove_bin_file(&client->dev.kobj, &nvram); - rtc_device_unregister(ds1307->rtc); kfree(ds1307); return 0; diff --git a/trunk/drivers/rtc/rtc-ds1553.c b/trunk/drivers/rtc/rtc-ds1553.c index d9e848dcd450..bb53c09bad16 100644 --- a/trunk/drivers/rtc/rtc-ds1553.c +++ b/trunk/drivers/rtc/rtc-ds1553.c @@ -291,7 +291,7 @@ static ssize_t ds1553_nvram_write(struct kobject *kobj, static struct bin_attribute ds1553_nvram_attr = { .attr = { .name = "nvram", - .mode = S_IRUGO | S_IWUSR, + .mode = S_IRUGO | S_IWUGO, }, .size = RTC_OFFSET, .read = ds1553_nvram_read, diff --git a/trunk/drivers/rtc/rtc-ds1742.c b/trunk/drivers/rtc/rtc-ds1742.c index 2e73f0b183b2..c535b78698e2 100644 --- a/trunk/drivers/rtc/rtc-ds1742.c +++ b/trunk/drivers/rtc/rtc-ds1742.c @@ -160,13 +160,10 @@ static ssize_t ds1742_nvram_write(struct kobject *kobj, static struct bin_attribute ds1742_nvram_attr = { .attr = { .name = "nvram", - .mode = S_IRUGO | S_IWUSR, + .mode = S_IRUGO | S_IWUGO, }, .read = ds1742_nvram_read, .write = ds1742_nvram_write, - /* REVISIT: size in sysfs won't match actual size... if it's - * not a constant, each RTC should have its own attribute. - */ }; static int __devinit ds1742_rtc_probe(struct platform_device *pdev) diff --git a/trunk/drivers/rtc/rtc-m48t59.c b/trunk/drivers/rtc/rtc-m48t59.c index cd0bbc0e8038..2bad1637330a 100644 --- a/trunk/drivers/rtc/rtc-m48t59.c +++ b/trunk/drivers/rtc/rtc-m48t59.c @@ -353,12 +353,11 @@ static ssize_t m48t59_nvram_write(struct kobject *kobj, static struct bin_attribute m48t59_nvram_attr = { .attr = { .name = "nvram", - .mode = S_IRUGO | S_IWUSR, + .mode = S_IRUGO | S_IWUGO, .owner = THIS_MODULE, }, .read = m48t59_nvram_read, .write = m48t59_nvram_write, - .size = M48T59_NVRAM_SIZE, }; static int __devinit m48t59_rtc_probe(struct platform_device *pdev) diff --git a/trunk/drivers/rtc/rtc-stk17ta8.c b/trunk/drivers/rtc/rtc-stk17ta8.c index a265da7c6ff8..8288b6b2bf2b 100644 --- a/trunk/drivers/rtc/rtc-stk17ta8.c +++ b/trunk/drivers/rtc/rtc-stk17ta8.c @@ -291,7 +291,7 @@ static ssize_t stk17ta8_nvram_write(struct kobject *kobj, static struct bin_attribute stk17ta8_nvram_attr = { .attr = { .name = "nvram", - .mode = S_IRUGO | S_IWUSR, + .mode = S_IRUGO | S_IWUGO, .owner = THIS_MODULE, }, .size = RTC_OFFSET, diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_sds.c b/trunk/drivers/scsi/aic94xx/aic94xx_sds.c index 06509bff71f7..5b0932f61473 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_sds.c +++ b/trunk/drivers/scsi/aic94xx/aic94xx_sds.c @@ -377,7 +377,7 @@ int asd_read_ocm(struct asd_ha_struct *asd_ha) #define FLASH_RESET 0xF0 -#define ASD_FLASH_SIZE 0x200000 +#define FLASH_SIZE 0x200000 #define FLASH_DIR_COOKIE "*** ADAPTEC FLASH DIRECTORY *** " #define FLASH_NEXT_ENTRY_OFFS 0x2000 #define FLASH_MAX_DIR_ENTRIES 32 @@ -609,7 +609,7 @@ static int asd_find_flash_dir(struct asd_ha_struct *asd_ha, struct asd_flash_dir *flash_dir) { u32 v; - for (v = 0; v < ASD_FLASH_SIZE; v += FLASH_NEXT_ENTRY_OFFS) { + for (v = 0; v < FLASH_SIZE; v += FLASH_NEXT_ENTRY_OFFS) { asd_read_flash_seg(asd_ha, flash_dir, v, sizeof(FLASH_DIR_COOKIE)-1); if (memcmp(flash_dir->cookie, FLASH_DIR_COOKIE, diff --git a/trunk/drivers/serial/8250_pnp.c b/trunk/drivers/serial/8250_pnp.c index 1de098e75497..926f58a674a1 100644 --- a/trunk/drivers/serial/8250_pnp.c +++ b/trunk/drivers/serial/8250_pnp.c @@ -69,8 +69,6 @@ static const struct pnp_device_id pnp_dev_table[] = { { "CTL3001", 0 }, /* Creative Labs Modem Blaster 28.8 DSVD PnP Voice */ { "CTL3011", 0 }, - /* Davicom ISA 33.6K Modem */ - { "DAV0336", 0 }, /* Creative */ /* Creative Modem Blaster Flash56 DI5601-1 */ { "DMB1032", 0 }, @@ -347,11 +345,6 @@ static const struct pnp_device_id pnp_dev_table[] = { /* Fujitsu Wacom Tablet PC devices */ { "FUJ02E5", 0 }, { "FUJ02E6", 0 }, - /* - * LG C1 EXPRESS DUAL (C1-PB11A3) touch screen (actually a FUJ02E6 in - * disguise) - */ - { "LTS0001", 0 }, /* Rockwell's (PORALiNK) 33600 INT PNP */ { "WCI0003", 0 }, /* Unkown PnP modems */ @@ -439,8 +432,7 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) } memset(&port, 0, sizeof(struct uart_port)); - if (pnp_irq_valid(dev, 0)) - port.irq = pnp_irq(dev, 0); + port.irq = pnp_irq(dev, 0); if (pnp_port_valid(dev, 0)) { port.iobase = pnp_port_start(dev, 0); port.iotype = UPIO_PORT; diff --git a/trunk/drivers/serial/atmel_serial.c b/trunk/drivers/serial/atmel_serial.c index 111da57f5334..4d6b3c56d20e 100644 --- a/trunk/drivers/serial/atmel_serial.c +++ b/trunk/drivers/serial/atmel_serial.c @@ -204,6 +204,8 @@ static u_int atmel_get_mctrl(struct uart_port *port) */ static void atmel_stop_tx(struct uart_port *port) { + struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port; + UART_PUT_IDR(port, ATMEL_US_TXRDY); } @@ -212,6 +214,8 @@ static void atmel_stop_tx(struct uart_port *port) */ static void atmel_start_tx(struct uart_port *port) { + struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port; + UART_PUT_IER(port, ATMEL_US_TXRDY); } @@ -220,6 +224,8 @@ static void atmel_start_tx(struct uart_port *port) */ static void atmel_stop_rx(struct uart_port *port) { + struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port; + UART_PUT_IDR(port, ATMEL_US_RXRDY); } @@ -403,6 +409,7 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id) */ static int atmel_startup(struct uart_port *port) { + struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port; int retval; /* @@ -449,6 +456,8 @@ static int atmel_startup(struct uart_port *port) */ static void atmel_shutdown(struct uart_port *port) { + struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port; + /* * Disable all interrupts, port and break condition. */ diff --git a/trunk/drivers/serial/crisv10.c b/trunk/drivers/serial/crisv10.c index a4e23cf47906..f523cdf4b02b 100644 --- a/trunk/drivers/serial/crisv10.c +++ b/trunk/drivers/serial/crisv10.c @@ -1,10 +1,426 @@ -/* +/* $Id: serial.c,v 1.25 2004/09/29 10:33:49 starvik Exp $ + * * Serial port driver for the ETRAX 100LX chip * - * Copyright (C) 1998-2007 Axis Communications AB + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Axis Communications AB * * Many, many authors. Based once upon a time on serial.c for 16x50. * + * $Log: serial.c,v $ + * Revision 1.25 2004/09/29 10:33:49 starvik + * Resolved a dealock when printing debug from kernel. + * + * Revision 1.24 2004/08/27 23:25:59 johana + * rs_set_termios() must call change_speed() if c_iflag has changed or + * automatic XOFF handling will be enabled and transmitter will stop + * if 0x13 is received. + * + * Revision 1.23 2004/08/24 06:57:13 starvik + * More whitespace cleanup + * + * Revision 1.22 2004/08/24 06:12:20 starvik + * Whitespace cleanup + * + * Revision 1.20 2004/05/24 12:00:20 starvik + * Big merge of stuff from Linux 2.4 (e.g. manual mode for the serial port). + * + * Revision 1.19 2004/05/17 13:12:15 starvik + * Kernel console hook + * Big merge from Linux 2.4 still pending. + * + * Revision 1.18 2003/10/28 07:18:30 starvik + * Compiles with debug info + * + * Revision 1.17 2003/07/04 08:27:37 starvik + * Merge of Linux 2.5.74 + * + * Revision 1.16 2003/06/13 10:05:19 johana + * Help the user to avoid trouble by: + * Forcing mixed mode for status/control lines if not all pins are used. + * + * Revision 1.15 2003/06/13 09:43:01 johana + * Merged in the following changes from os/linux/arch/cris/drivers/serial.c + * + some minor changes to reduce diff. + * + * Revision 1.49 2003/05/30 11:31:54 johana + * Merged in change-branch--serial9bit that adds CMSPAR support for sticky + * parity (mark/space) + * + * Revision 1.48 2003/05/30 11:03:57 johana + * Implemented rs_send_xchar() by disabling the DMA and writing manually. + * Added e100_disable_txdma_channel() and e100_enable_txdma_channel(). + * Fixed rs_throttle() and rs_unthrottle() to properly call rs_send_xchar + * instead of setting info->x_char and check the CRTSCTS flag before + * controlling the rts pin. + * + * Revision 1.14 2003/04/09 08:12:44 pkj + * Corrected typo changes made upstream. + * + * Revision 1.13 2003/04/09 05:20:47 starvik + * Merge of Linux 2.5.67 + * + * Revision 1.11 2003/01/22 06:48:37 starvik + * Fixed warnings issued by GCC 3.2.1 + * + * Revision 1.9 2002/12/13 09:07:47 starvik + * Alert user that RX_TIMEOUT_TICKS==0 doesn't work + * + * Revision 1.8 2002/12/11 13:13:57 starvik + * Added arch/ to v10 specific includes + * Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer) + * + * Revision 1.7 2002/12/06 07:13:57 starvik + * Corrected work queue stuff + * Removed CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST + * + * Revision 1.6 2002/11/21 07:17:46 starvik + * Change static inline to extern inline where otherwise outlined with gcc-3.2 + * + * Revision 1.5 2002/11/14 15:59:49 starvik + * Linux 2.5 port of the latest serial driver from 2.4. The work queue stuff + * probably doesn't work yet. + * + * Revision 1.42 2002/11/05 09:08:47 johana + * Better implementation of rs_stop() and rs_start() that uses the XOFF + * register to start/stop transmission. + * change_speed() also initilises XOFF register correctly so that + * auto_xoff is enabled when IXON flag is set by user. + * This gives fast XOFF response times. + * + * Revision 1.41 2002/11/04 18:40:57 johana + * Implemented rs_stop() and rs_start(). + * Simple tests using hwtestserial indicates that this should be enough + * to make it work. + * + * Revision 1.40 2002/10/14 05:33:18 starvik + * RS-485 uses fast timers even if SERIAL_FAST_TIMER is disabled + * + * Revision 1.39 2002/09/30 21:00:57 johana + * Support for CONFIG_ETRAX_SERx_DTR_RI_DSR_CD_MIXED where the status and + * control pins can be mixed between PA and PB. + * If no serial port uses MIXED old solution is used + * (saves a few bytes and cycles). + * control_pins struct uses masks instead of bit numbers. + * Corrected dummy values and polarity in line_info() so + * /proc/tty/driver/serial is now correct. + * (the E100_xxx_GET() macros is really active low - perhaps not obvious) + * + * Revision 1.38 2002/08/23 11:01:36 starvik + * Check that serial port is enabled in all interrupt handlers to avoid + * restarts of DMA channels not assigned to serial ports + * + * Revision 1.37 2002/08/13 13:02:37 bjornw + * Removed some warnings because of unused code + * + * Revision 1.36 2002/08/08 12:50:01 starvik + * Serial interrupt is shared with synchronous serial port driver + * + * Revision 1.35 2002/06/03 10:40:49 starvik + * Increased RS-485 RTS toggle timer to 2 characters + * + * Revision 1.34 2002/05/28 18:59:36 johana + * Whitespace and comment fixing to be more like etrax100ser.c 1.71. + * + * Revision 1.33 2002/05/28 17:55:43 johana + * RS-485 uses FAST_TIMER if enabled, and starts a short (one char time) + * timer from tranismit_chars (interrupt context). + * The timer toggles RTS in interrupt context when expired giving minimum + * latencies. + * + * Revision 1.32 2002/05/22 13:58:00 johana + * Renamed rs_write() to raw_write() and made it inline. + * New rs_write() handles RS-485 if configured and enabled + * (moved code from e100_write_rs485()). + * RS-485 ioctl's uses copy_from_user() instead of verify_area(). + * + * Revision 1.31 2002/04/22 11:20:03 johana + * Updated copyright years. + * + * Revision 1.30 2002/04/22 09:39:12 johana + * RS-485 support compiles. + * + * Revision 1.29 2002/01/14 16:10:01 pkj + * Allocate the receive buffers dynamically. The static 4kB buffer was + * too small for the peaks. This means that we can get rid of the extra + * buffer and the copying to it. It also means we require less memory + * under normal operations, but can use more when needed (there is a + * cap at 64kB for safety reasons). If there is no memory available + * we panic(), and die a horrible death... + * + * Revision 1.28 2001/12/18 15:04:53 johana + * Cleaned up write_rs485() - now it works correctly without padding extra + * char. + * Added sane default initialisation of rs485. + * Added #ifdef around dummy variables. + * + * Revision 1.27 2001/11/29 17:00:41 pkj + * 2kB seems to be too small a buffer when using 921600 bps, + * so increase it to 4kB (this was already done for the elinux + * version of the serial driver). + * + * Revision 1.26 2001/11/19 14:20:41 pkj + * Minor changes to comments and unused code. + * + * Revision 1.25 2001/11/12 20:03:43 pkj + * Fixed compiler warnings. + * + * Revision 1.24 2001/11/12 15:10:05 pkj + * Total redesign of the receiving part of the serial driver. + * Uses eight chained descriptors to write to a 4kB buffer. + * This data is then serialised into a 2kB buffer. From there it + * is copied into the TTY's flip buffers when they become available. + * A lot of copying, and the sizes of the buffers might need to be + * tweaked, but all in all it should work better than the previous + * version, without the need to modify the TTY code in any way. + * Also note that erroneous bytes are now correctly marked in the + * flag buffers (instead of always marking the first byte). + * + * Revision 1.23 2001/10/30 17:53:26 pkj + * * Set info->uses_dma to 0 when a port is closed. + * * Mark the timer1 interrupt as a fast one (SA_INTERRUPT). + * * Call start_flush_timer() in start_receive() if + * CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST is defined. + * + * Revision 1.22 2001/10/30 17:44:03 pkj + * Use %lu for received and transmitted counters in line_info(). + * + * Revision 1.21 2001/10/30 17:40:34 pkj + * Clean-up. The only change to functionality is that + * CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS(=5) is used instead of + * MAX_FLUSH_TIME(=8). + * + * Revision 1.20 2001/10/30 15:24:49 johana + * Added char_time stuff from 2.0 driver. + * + * Revision 1.19 2001/10/30 15:23:03 johana + * Merged with 1.13.2 branch + fixed indentation + * and changed CONFIG_ETRAX100_XYS to CONFIG_ETRAX_XYZ + * + * Revision 1.18 2001/09/24 09:27:22 pkj + * Completed ext_baud_table[] in cflag_to_baud() and cflag_to_etrax_baud(). + * + * Revision 1.17 2001/08/24 11:32:49 ronny + * More fixes for the CONFIG_ETRAX_SERIAL_PORT0 define. + * + * Revision 1.16 2001/08/24 07:56:22 ronny + * Added config ifdefs around ser0 irq requests. + * + * Revision 1.15 2001/08/16 09:10:31 bjarne + * serial.c - corrected the initialization of rs_table, the wrong defines + * where used. + * Corrected a test in timed_flush_handler. + * Changed configured to enabled. + * serial.h - Changed configured to enabled. + * + * Revision 1.14 2001/08/15 07:31:23 bjarne + * Introduced two new members to the e100_serial struct. + * configured - Will be set to 1 if the port has been configured in .config + * uses_dma - Should be set to 1 if the port uses DMA. Currently it is set + * to 1 + * when a port is opened. This is used to limit the DMA interrupt + * routines to only manipulate DMA channels actually used by the + * serial driver. + * + * Revision 1.13.2.2 2001/10/17 13:57:13 starvik + * Receiver was broken by the break fixes + * + * Revision 1.13.2.1 2001/07/20 13:57:39 ronny + * Merge with new stuff from etrax100ser.c. Works but haven't checked stuff + * like break handling. + * + * Revision 1.13 2001/05/09 12:40:31 johana + * Use DMA_NBR and IRQ_NBR defines from dma.h and irq.h + * + * Revision 1.12 2001/04/19 12:23:07 bjornw + * CONFIG_RS485 -> CONFIG_ETRAX_RS485 + * + * Revision 1.11 2001/04/05 14:29:48 markusl + * Updated according to review remarks i.e. + * -Use correct types in port structure to avoid compiler warnings + * -Try to use IO_* macros whenever possible + * -Open should never return -EBUSY + * + * Revision 1.10 2001/03/05 13:14:07 bjornw + * Another spelling fix + * + * Revision 1.9 2001/02/23 13:46:38 bjornw + * Spellling check + * + * Revision 1.8 2001/01/23 14:56:35 markusl + * Made use of ser1 optional + * Needed by USB + * + * Revision 1.7 2001/01/19 16:14:48 perf + * Added kernel options for serial ports 234. + * Changed option names from CONFIG_ETRAX100_XYZ to CONFIG_ETRAX_XYZ. + * + * Revision 1.6 2000/11/22 16:36:09 bjornw + * Please marketing by using the correct case when spelling Etrax. + * + * Revision 1.5 2000/11/21 16:43:37 bjornw + * Fixed so it compiles under CONFIG_SVINTO_SIM + * + * Revision 1.4 2000/11/15 17:34:12 bjornw + * Added a timeout timer for flushing input channels. The interrupt-based + * fast flush system should be easy to merge with this later (works the same + * way, only with an irq instead of a system timer_list) + * + * Revision 1.3 2000/11/13 17:19:57 bjornw + * * Incredibly, this almost complete rewrite of serial.c worked (at least + * for output) the first time. + * + * Items worth noticing: + * + * No Etrax100 port 1 workarounds (does only compile on 2.4 anyway now) + * RS485 is not ported (why can't it be done in userspace as on x86 ?) + * Statistics done through async_icount - if any more stats are needed, + * that's the place to put them or in an arch-dep version of it. + * timeout_interrupt and the other fast timeout stuff not ported yet + * There be dragons in this 3k+ line driver + * + * Revision 1.2 2000/11/10 16:50:28 bjornw + * First shot at a 2.4 port, does not compile totally yet + * + * Revision 1.1 2000/11/10 16:47:32 bjornw + * Added verbatim copy of rev 1.49 etrax100ser.c from elinux + * + * Revision 1.49 2000/10/30 15:47:14 tobiasa + * Changed version number. + * + * Revision 1.48 2000/10/25 11:02:43 johana + * Changed %ul to %lu in printf's + * + * Revision 1.47 2000/10/18 15:06:53 pkj + * Compile correctly with CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST and + * CONFIG_ETRAX_SERIAL_PROC_ENTRY together. + * Some clean-up of the /proc/serial file. + * + * Revision 1.46 2000/10/16 12:59:40 johana + * Added CONFIG_ETRAX_SERIAL_PROC_ENTRY for statistics and debug info. + * + * Revision 1.45 2000/10/13 17:10:59 pkj + * Do not flush DMAs while flipping TTY buffers. + * + * Revision 1.44 2000/10/13 16:34:29 pkj + * Added a delay in ser_interrupt() for 2.3ms when an error is detected. + * We do not know why this delay is required yet, but without it the + * irmaflash program does not work (this was the program that needed + * the ser_interrupt() to be needed in the first place). This should not + * affect normal use of the serial ports. + * + * Revision 1.43 2000/10/13 16:30:44 pkj + * New version of the fast flush of serial buffers code. This time + * it is localized to the serial driver and uses a fast timer to + * do the work. + * + * Revision 1.42 2000/10/13 14:54:26 bennyo + * Fix for switching RTS when using rs485 + * + * Revision 1.41 2000/10/12 11:43:44 pkj + * Cleaned up a number of comments. + * + * Revision 1.40 2000/10/10 11:58:39 johana + * Made RS485 support generic for all ports. + * Toggle rts in interrupt if no delay wanted. + * WARNING: No true transmitter empty check?? + * Set d_wait bit when sending data so interrupt is delayed until + * fifo flushed. (Fix tcdrain() problem) + * + * Revision 1.39 2000/10/04 16:08:02 bjornw + * * Use virt_to_phys etc. for DMA addresses + * * Removed CONFIG_FLUSH_DMA_FAST hacks + * * Indentation fix + * + * Revision 1.38 2000/10/02 12:27:10 mattias + * * added variable used when using fast flush on serial dma. + * (CONFIG_FLUSH_DMA_FAST) + * + * Revision 1.37 2000/09/27 09:44:24 pkj + * Uncomment definition of SERIAL_HANDLE_EARLY_ERRORS. + * + * Revision 1.36 2000/09/20 13:12:52 johana + * Support for CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS: + * Number of timer ticks between flush of receive fifo (1 tick = 10ms). + * Try 0-3 for low latency applications. Approx 5 for high load + * applications (e.g. PPP). Maybe this should be more adaptive some day... + * + * Revision 1.35 2000/09/20 10:36:08 johana + * Typo in get_lsr_info() + * + * Revision 1.34 2000/09/20 10:29:59 johana + * Let rs_chars_in_buffer() check fifo content as well. + * get_lsr_info() might work now (not tested). + * Easier to change the port to debug. + * + * Revision 1.33 2000/09/13 07:52:11 torbjore + * Support RS485 + * + * Revision 1.32 2000/08/31 14:45:37 bjornw + * After sending a break we need to reset the transmit DMA channel + * + * Revision 1.31 2000/06/21 12:13:29 johana + * Fixed wait for all chars sent when closing port. + * (Used to always take 1 second!) + * Added shadows for directions of status/ctrl signals. + * + * Revision 1.30 2000/05/29 16:27:55 bjornw + * Simulator ifdef moved a bit + * + * Revision 1.29 2000/05/09 09:40:30 mattias + * * Added description of dma registers used in timeout_interrupt + * * Removed old code + * + * Revision 1.28 2000/05/08 16:38:58 mattias + * * Bugfix for flushing fifo in timeout_interrupt + * Problem occurs when bluetooth stack waits for a small number of bytes + * containing an event acknowledging free buffers in bluetooth HW + * As before, data was stuck in fifo until more data came on uart and + * flushed it up to the stack. + * + * Revision 1.27 2000/05/02 09:52:28 jonasd + * Added fix for peculiar etrax behaviour when eop is forced on an empty + * fifo. This is used when flashing the IRMA chip. Disabled by default. + * + * Revision 1.26 2000/03/29 15:32:02 bjornw + * 2.0.34 updates + * + * Revision 1.25 2000/02/16 16:59:36 bjornw + * * Receive DMA directly into the flip-buffer, eliminating an intermediary + * receive buffer and a memcpy. Will avoid some overruns. + * * Error message on debug port if an overrun or flip buffer overrun occurs. + * * Just use the first byte in the flag flip buffer for errors. + * * Check for timeout on the serial ports only each 5/100 s, not 1/100. + * + * Revision 1.24 2000/02/09 18:02:28 bjornw + * * Clear serial errors (overrun, framing, parity) correctly. Before, the + * receiver would get stuck if an error occurred and we did not restart + * the input DMA. + * * Cosmetics (indentation, some code made into inlines) + * * Some more debug options + * * Actually shut down the serial port (DMA irq, DMA reset, receiver stop) + * when the last open is closed. Corresponding fixes in startup(). + * * rs_close() "tx FIFO wait" code moved into right place, bug & -> && fixed + * and make a special case out of port 1 (R_DMA_CHx_STATUS is broken for that) + * * e100_disable_rx/enable_rx just disables/enables the receiver, not RTS + * + * Revision 1.23 2000/01/24 17:46:19 johana + * Wait for flush of DMA/FIFO when closing port. + * + * Revision 1.22 2000/01/20 18:10:23 johana + * Added TIOCMGET ioctl to return modem status. + * Implemented modem status/control that works with the extra signals + * (DTR, DSR, RI,CD) as well. + * 3 different modes supported: + * ser0 on PB (Bundy), ser1 on PB (Lisa) and ser2 on PA (Bundy) + * Fixed DEF_TX value that caused the serial transmitter pin (txd) to go to 0 when + * closing the last filehandle, NASTY!. + * Added break generation, not tested though! + * Use IRQF_SHARED when request_irq() for ser2 and ser3 (shared with) par0 and par1. + * You can't use them at the same time (yet..), but you can hopefully switch + * between ser2/par0, ser3/par1 with the same kernel config. + * Replaced some magic constants with defines + * + * */ static char *serial_version = "$Revision: 1.25 $"; @@ -30,7 +446,6 @@ static char *serial_version = "$Revision: 1.25 $"; #include #include -#include #include #include @@ -39,9 +454,8 @@ static char *serial_version = "$Revision: 1.25 $"; /* non-arch dependent serial structures are in linux/serial.h */ #include /* while we keep our own stuff (struct e100_serial) in a local .h file */ -#include "crisv10.h" +#include "serial.h" #include -#include #ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER #ifndef CONFIG_ETRAX_FAST_TIMER @@ -90,6 +504,18 @@ struct tty_driver *serial_driver; from eLinux */ #define SERIAL_HANDLE_EARLY_ERRORS +/* Defined and used in n_tty.c, but we need it here as well */ +#define TTY_THRESHOLD_THROTTLE 128 + +/* Due to buffersizes and threshold values, our SERIAL_DESCR_BUF_SIZE + * must not be to high or flow control won't work if we leave it to the tty + * layer so we have our own throttling in flush_to_flip + * TTY_FLIPBUF_SIZE=512, + * TTY_THRESHOLD_THROTTLE/UNTHROTTLE=128 + * BUF_SIZE can't be > 128 + */ +#define CRIS_BUF_SIZE 512 + /* Currently 16 descriptors x 128 bytes = 2048 bytes */ #define SERIAL_DESCR_BUF_SIZE 256 @@ -162,13 +588,13 @@ unsigned long timer_data_to_ns(unsigned long timer_data); static void change_speed(struct e100_serial *info); static void rs_throttle(struct tty_struct * tty); static void rs_wait_until_sent(struct tty_struct *tty, int timeout); -static int rs_write(struct tty_struct *tty, - const unsigned char *buf, int count); +static int rs_write(struct tty_struct * tty, int from_user, + const unsigned char *buf, int count); #ifdef CONFIG_ETRAX_RS485 -static int e100_write_rs485(struct tty_struct *tty, - const unsigned char *buf, int count); +static int e100_write_rs485(struct tty_struct * tty, int from_user, + const unsigned char *buf, int count); #endif -static int get_lsr_info(struct e100_serial *info, unsigned int *value); +static int get_lsr_info(struct e100_serial * info, unsigned int *value); #define DEF_BAUD 115200 /* 115.2 kbit/s */ @@ -253,39 +679,20 @@ static struct e100_serial rs_table[] = { .rx_ctrl = DEF_RX, .tx_ctrl = DEF_TX, .iseteop = 2, - .dma_owner = dma_ser0, - .io_if = if_serial_0, #ifdef CONFIG_ETRAX_SERIAL_PORT0 .enabled = 1, #ifdef CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT .dma_out_enabled = 1, - .dma_out_nbr = SER0_TX_DMA_NBR, - .dma_out_irq_nbr = SER0_DMA_TX_IRQ_NBR, - .dma_out_irq_flags = IRQF_DISABLED, - .dma_out_irq_description = "serial 0 dma tr", #else .dma_out_enabled = 0, - .dma_out_nbr = UINT_MAX, - .dma_out_irq_nbr = 0, - .dma_out_irq_flags = 0, - .dma_out_irq_description = NULL, #endif #ifdef CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN .dma_in_enabled = 1, - .dma_in_nbr = SER0_RX_DMA_NBR, - .dma_in_irq_nbr = SER0_DMA_RX_IRQ_NBR, - .dma_in_irq_flags = IRQF_DISABLED, - .dma_in_irq_description = "serial 0 dma rec", #else - .dma_in_enabled = 0, - .dma_in_nbr = UINT_MAX, - .dma_in_irq_nbr = 0, - .dma_in_irq_flags = 0, - .dma_in_irq_description = NULL, + .dma_in_enabled = 0 #endif #else .enabled = 0, - .io_if_description = NULL, .dma_out_enabled = 0, .dma_in_enabled = 0 #endif @@ -307,42 +714,20 @@ static struct e100_serial rs_table[] = { .rx_ctrl = DEF_RX, .tx_ctrl = DEF_TX, .iseteop = 3, - .dma_owner = dma_ser1, - .io_if = if_serial_1, #ifdef CONFIG_ETRAX_SERIAL_PORT1 .enabled = 1, - .io_if_description = "ser1", #ifdef CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT .dma_out_enabled = 1, - .dma_out_nbr = SER1_TX_DMA_NBR, - .dma_out_irq_nbr = SER1_DMA_TX_IRQ_NBR, - .dma_out_irq_flags = IRQF_DISABLED, - .dma_out_irq_description = "serial 1 dma tr", #else .dma_out_enabled = 0, - .dma_out_nbr = UINT_MAX, - .dma_out_irq_nbr = 0, - .dma_out_irq_flags = 0, - .dma_out_irq_description = NULL, #endif #ifdef CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN .dma_in_enabled = 1, - .dma_in_nbr = SER1_RX_DMA_NBR, - .dma_in_irq_nbr = SER1_DMA_RX_IRQ_NBR, - .dma_in_irq_flags = IRQF_DISABLED, - .dma_in_irq_description = "serial 1 dma rec", #else - .dma_in_enabled = 0, - .dma_in_enabled = 0, - .dma_in_nbr = UINT_MAX, - .dma_in_irq_nbr = 0, - .dma_in_irq_flags = 0, - .dma_in_irq_description = NULL, + .dma_in_enabled = 0 #endif #else .enabled = 0, - .io_if_description = NULL, - .dma_in_irq_nbr = 0, .dma_out_enabled = 0, .dma_in_enabled = 0 #endif @@ -363,40 +748,20 @@ static struct e100_serial rs_table[] = { .rx_ctrl = DEF_RX, .tx_ctrl = DEF_TX, .iseteop = 0, - .dma_owner = dma_ser2, - .io_if = if_serial_2, #ifdef CONFIG_ETRAX_SERIAL_PORT2 .enabled = 1, - .io_if_description = "ser2", #ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT .dma_out_enabled = 1, - .dma_out_nbr = SER2_TX_DMA_NBR, - .dma_out_irq_nbr = SER2_DMA_TX_IRQ_NBR, - .dma_out_irq_flags = IRQF_DISABLED, - .dma_out_irq_description = "serial 2 dma tr", #else .dma_out_enabled = 0, - .dma_out_nbr = UINT_MAX, - .dma_out_irq_nbr = 0, - .dma_out_irq_flags = 0, - .dma_out_irq_description = NULL, #endif #ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN .dma_in_enabled = 1, - .dma_in_nbr = SER2_RX_DMA_NBR, - .dma_in_irq_nbr = SER2_DMA_RX_IRQ_NBR, - .dma_in_irq_flags = IRQF_DISABLED, - .dma_in_irq_description = "serial 2 dma rec", #else - .dma_in_enabled = 0, - .dma_in_nbr = UINT_MAX, - .dma_in_irq_nbr = 0, - .dma_in_irq_flags = 0, - .dma_in_irq_description = NULL, + .dma_in_enabled = 0 #endif #else .enabled = 0, - .io_if_description = NULL, .dma_out_enabled = 0, .dma_in_enabled = 0 #endif @@ -417,40 +782,20 @@ static struct e100_serial rs_table[] = { .rx_ctrl = DEF_RX, .tx_ctrl = DEF_TX, .iseteop = 1, - .dma_owner = dma_ser3, - .io_if = if_serial_3, #ifdef CONFIG_ETRAX_SERIAL_PORT3 .enabled = 1, - .io_if_description = "ser3", #ifdef CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT .dma_out_enabled = 1, - .dma_out_nbr = SER3_TX_DMA_NBR, - .dma_out_irq_nbr = SER3_DMA_TX_IRQ_NBR, - .dma_out_irq_flags = IRQF_DISABLED, - .dma_out_irq_description = "serial 3 dma tr", #else .dma_out_enabled = 0, - .dma_out_nbr = UINT_MAX, - .dma_out_irq_nbr = 0, - .dma_out_irq_flags = 0, - .dma_out_irq_description = NULL, #endif #ifdef CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN .dma_in_enabled = 1, - .dma_in_nbr = SER3_RX_DMA_NBR, - .dma_in_irq_nbr = SER3_DMA_RX_IRQ_NBR, - .dma_in_irq_flags = IRQF_DISABLED, - .dma_in_irq_description = "serial 3 dma rec", #else - .dma_in_enabled = 0, - .dma_in_nbr = UINT_MAX, - .dma_in_irq_nbr = 0, - .dma_in_irq_flags = 0, - .dma_in_irq_description = NULL + .dma_in_enabled = 0 #endif #else .enabled = 0, - .io_if_description = NULL, .dma_out_enabled = 0, .dma_in_enabled = 0 #endif @@ -1071,11 +1416,12 @@ e100_dtr(struct e100_serial *info, int set) { unsigned long flags; - local_irq_save(flags); + save_flags(flags); + cli(); *e100_modem_pins[info->line].dtr_shadow &= ~mask; *e100_modem_pins[info->line].dtr_shadow |= (set ? 0 : mask); *e100_modem_pins[info->line].dtr_port = *e100_modem_pins[info->line].dtr_shadow; - local_irq_restore(flags); + restore_flags(flags); } #ifdef SERIAL_DEBUG_IO @@ -1094,11 +1440,12 @@ e100_rts(struct e100_serial *info, int set) { #ifndef CONFIG_SVINTO_SIM unsigned long flags; - local_irq_save(flags); + save_flags(flags); + cli(); info->rx_ctrl &= ~E100_RTS_MASK; info->rx_ctrl |= (set ? 0 : E100_RTS_MASK); /* RTS is active low */ info->port[REG_REC_CTRL] = info->rx_ctrl; - local_irq_restore(flags); + restore_flags(flags); #ifdef SERIAL_DEBUG_IO printk("ser%i rts %i\n", info->line, set); #endif @@ -1116,11 +1463,12 @@ e100_ri_out(struct e100_serial *info, int set) unsigned char mask = e100_modem_pins[info->line].ri_mask; unsigned long flags; - local_irq_save(flags); + save_flags(flags); + cli(); *e100_modem_pins[info->line].ri_shadow &= ~mask; *e100_modem_pins[info->line].ri_shadow |= (set ? 0 : mask); *e100_modem_pins[info->line].ri_port = *e100_modem_pins[info->line].ri_shadow; - local_irq_restore(flags); + restore_flags(flags); } #endif } @@ -1133,11 +1481,12 @@ e100_cd_out(struct e100_serial *info, int set) unsigned char mask = e100_modem_pins[info->line].cd_mask; unsigned long flags; - local_irq_save(flags); + save_flags(flags); + cli(); *e100_modem_pins[info->line].cd_shadow &= ~mask; *e100_modem_pins[info->line].cd_shadow |= (set ? 0 : mask); *e100_modem_pins[info->line].cd_port = *e100_modem_pins[info->line].cd_shadow; - local_irq_restore(flags); + restore_flags(flags); } #endif } @@ -1211,7 +1560,8 @@ static void e100_disable_txdma_channel(struct e100_serial *info) /* Disable output DMA channel for the serial port in question * ( set to something other then serialX) */ - local_irq_save(flags); + save_flags(flags); + cli(); DFLOW(DEBUG_LOG(info->line, "disable_txdma_channel %i\n", info->line)); if (info->line == 0) { if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma6)) == @@ -1239,7 +1589,7 @@ static void e100_disable_txdma_channel(struct e100_serial *info) } } *R_GEN_CONFIG = genconfig_shadow; - local_irq_restore(flags); + restore_flags(flags); } @@ -1247,7 +1597,8 @@ static void e100_enable_txdma_channel(struct e100_serial *info) { unsigned long flags; - local_irq_save(flags); + save_flags(flags); + cli(); DFLOW(DEBUG_LOG(info->line, "enable_txdma_channel %i\n", info->line)); /* Enable output DMA channel for the serial port in question */ if (info->line == 0) { @@ -1264,7 +1615,7 @@ static void e100_enable_txdma_channel(struct e100_serial *info) genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma4, serial3); } *R_GEN_CONFIG = genconfig_shadow; - local_irq_restore(flags); + restore_flags(flags); } static void e100_disable_rxdma_channel(struct e100_serial *info) @@ -1274,7 +1625,8 @@ static void e100_disable_rxdma_channel(struct e100_serial *info) /* Disable input DMA channel for the serial port in question * ( set to something other then serialX) */ - local_irq_save(flags); + save_flags(flags); + cli(); if (info->line == 0) { if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma7)) == IO_STATE(R_GEN_CONFIG, dma7, serial0)) { @@ -1301,7 +1653,7 @@ static void e100_disable_rxdma_channel(struct e100_serial *info) } } *R_GEN_CONFIG = genconfig_shadow; - local_irq_restore(flags); + restore_flags(flags); } @@ -1309,7 +1661,8 @@ static void e100_enable_rxdma_channel(struct e100_serial *info) { unsigned long flags; - local_irq_save(flags); + save_flags(flags); + cli(); /* Enable input DMA channel for the serial port in question */ if (info->line == 0) { genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma7); @@ -1325,7 +1678,7 @@ static void e100_enable_rxdma_channel(struct e100_serial *info) genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma5, serial3); } *R_GEN_CONFIG = genconfig_shadow; - local_irq_restore(flags); + restore_flags(flags); } #ifdef SERIAL_HANDLE_EARLY_ERRORS @@ -1432,7 +1785,7 @@ e100_enable_rs485(struct tty_struct *tty,struct rs485_control *r) } static int -e100_write_rs485(struct tty_struct *tty, +e100_write_rs485(struct tty_struct *tty, int from_user, const unsigned char *buf, int count) { struct e100_serial * info = (struct e100_serial *)tty->driver_data; @@ -1445,7 +1798,7 @@ e100_write_rs485(struct tty_struct *tty, */ info->rs485.enabled = 1; /* rs_write now deals with RS485 if enabled */ - count = rs_write(tty, buf, count); + count = rs_write(tty, from_user, buf, count); info->rs485.enabled = old_enabled; return count; } @@ -1483,7 +1836,7 @@ rs_stop(struct tty_struct *tty) unsigned long flags; unsigned long xoff; - local_irq_save(flags); + save_flags(flags); cli(); DFLOW(DEBUG_LOG(info->line, "XOFF rs_stop xmit %i\n", CIRC_CNT(info->xmit.head, info->xmit.tail,SERIAL_XMIT_SIZE))); @@ -1495,7 +1848,7 @@ rs_stop(struct tty_struct *tty) } *((unsigned long *)&info->port[REG_XOFF]) = xoff; - local_irq_restore(flags); + restore_flags(flags); } } @@ -1507,7 +1860,7 @@ rs_start(struct tty_struct *tty) unsigned long flags; unsigned long xoff; - local_irq_save(flags); + save_flags(flags); cli(); DFLOW(DEBUG_LOG(info->line, "XOFF rs_start xmit %i\n", CIRC_CNT(info->xmit.head, info->xmit.tail,SERIAL_XMIT_SIZE))); @@ -1522,7 +1875,7 @@ rs_start(struct tty_struct *tty) info->xmit.head != info->xmit.tail && info->xmit.buf) e100_enable_serial_tx_ready_irq(info); - local_irq_restore(flags); + restore_flags(flags); } } @@ -1702,7 +2055,8 @@ static int serial_fast_timer_expired = 0; static void flush_timeout_function(unsigned long data); #define START_FLUSH_FAST_TIMER_TIME(info, string, usec) {\ unsigned long timer_flags; \ - local_irq_save(timer_flags); \ + save_flags(timer_flags); \ + cli(); \ if (fast_timers[info->line].function == NULL) { \ serial_fast_timer_started++; \ TIMERD(DEBUG_LOG(info->line, "start_timer %i ", info->line)); \ @@ -1716,7 +2070,7 @@ static void flush_timeout_function(unsigned long data); else { \ TIMERD(DEBUG_LOG(info->line, "timer %i already running\n", info->line)); \ } \ - local_irq_restore(timer_flags); \ + restore_flags(timer_flags); \ } #define START_FLUSH_FAST_TIMER(info, string) START_FLUSH_FAST_TIMER_TIME(info, string, info->flush_time_usec) @@ -1745,7 +2099,8 @@ append_recv_buffer(struct e100_serial *info, struct etrax_recv_buffer *buffer) { unsigned long flags; - local_irq_save(flags); + save_flags(flags); + cli(); if (!info->first_recv_buffer) info->first_recv_buffer = buffer; @@ -1758,7 +2113,7 @@ append_recv_buffer(struct e100_serial *info, struct etrax_recv_buffer *buffer) if (info->recv_cnt > info->max_recv_cnt) info->max_recv_cnt = info->recv_cnt; - local_irq_restore(flags); + restore_flags(flags); } static int @@ -1778,7 +2133,11 @@ add_char_and_flag(struct e100_serial *info, unsigned char data, unsigned char fl info->icount.rx++; } else { struct tty_struct *tty = info->tty; - tty_insert_flip_char(tty, data, flag); + *tty->flip.char_buf_ptr = data; + *tty->flip.flag_buf_ptr = flag; + tty->flip.flag_buf_ptr++; + tty->flip.char_buf_ptr++; + tty->flip.count++; info->icount.rx++; } @@ -1963,6 +2322,7 @@ start_receive(struct e100_serial *info) */ return; #endif + info->tty->flip.count = 0; if (info->uses_dma_in) { /* reset the input dma channel to be sure it works */ @@ -2124,20 +2484,32 @@ static void flush_to_flip_buffer(struct e100_serial *info) { struct tty_struct *tty; struct etrax_recv_buffer *buffer; + unsigned int length; unsigned long flags; + int max_flip_size; - local_irq_save(flags); - tty = info->tty; + if (!info->first_recv_buffer) + return; - if (!tty) { - local_irq_restore(flags); + save_flags(flags); + cli(); + + if (!(tty = info->tty)) { + restore_flags(flags); return; } while ((buffer = info->first_recv_buffer) != NULL) { unsigned int count = buffer->length; - tty_insert_flip_string(tty, buffer->buffer, count); + count = tty_buffer_request_room(tty, count); + if (count == 0) /* Throttle ?? */ + break; + + if (count > 1) + tty_insert_flip_strings(tty, buffer->buffer, count - 1); + tty_insert_flip_char(tty, buffer->buffer[count-1], buffer->error); + info->recv_cnt -= count; if (count == buffer->length) { @@ -2153,9 +2525,18 @@ static void flush_to_flip_buffer(struct e100_serial *info) if (!info->first_recv_buffer) info->last_recv_buffer = NULL; - local_irq_restore(flags); + restore_flags(flags); + + DFLIP( + if (1) { + DEBUG_LOG(info->line, "*** rxtot %i\n", info->icount.rx); + DEBUG_LOG(info->line, "ldisc %lu\n", tty->ldisc.chars_in_buffer(tty)); + DEBUG_LOG(info->line, "room %lu\n", tty->ldisc.receive_room(tty)); + } - /* This includes a check for low-latency */ + ); + + /* this includes a check for low-latency */ tty_flip_buffer_push(tty); } @@ -2298,7 +2679,21 @@ struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info) printk("!NO TTY!\n"); return info; } - + if (tty->flip.count >= CRIS_BUF_SIZE - TTY_THRESHOLD_THROTTLE) { + /* check TTY_THROTTLED first so it indicates our state */ + if (!test_and_set_bit(TTY_THROTTLED, &tty->flags)) { + DFLOW(DEBUG_LOG(info->line, "rs_throttle flip.count: %i\n", tty->flip.count)); + rs_throttle(tty); + } + } + if (tty->flip.count >= CRIS_BUF_SIZE) { + DEBUG_LOG(info->line, "force FLIP! %i\n", tty->flip.count); + tty->flip.work.func((void *) tty); + if (tty->flip.count >= CRIS_BUF_SIZE) { + DEBUG_LOG(info->line, "FLIP FULL! %i\n", tty->flip.count); + return info; /* if TTY_DONT_FLIP is set */ + } + } /* Read data and status at the same time */ data_read = *((unsigned long *)&info->port[REG_DATA_STATUS32]); more_data: @@ -2351,26 +2746,27 @@ struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info) DEBUG_LOG(info->line, "EBRK %i\n", info->break_detected_cnt); info->errorcode = ERRCODE_INSERT_BREAK; } else { - unsigned char data = IO_EXTRACT(R_SERIAL0_READ, - data_in, data_read); - char flag = TTY_NORMAL; if (info->errorcode == ERRCODE_INSERT_BREAK) { - struct tty_struct *tty = info->tty; - tty_insert_flip_char(tty, 0, flag); + info->icount.brk++; + *tty->flip.char_buf_ptr = 0; + *tty->flip.flag_buf_ptr = TTY_BREAK; + tty->flip.flag_buf_ptr++; + tty->flip.char_buf_ptr++; + tty->flip.count++; info->icount.rx++; } + *tty->flip.char_buf_ptr = IO_EXTRACT(R_SERIAL0_READ, data_in, data_read); if (data_read & IO_MASK(R_SERIAL0_READ, par_err)) { info->icount.parity++; - flag = TTY_PARITY; + *tty->flip.flag_buf_ptr = TTY_PARITY; } else if (data_read & IO_MASK(R_SERIAL0_READ, overrun)) { info->icount.overrun++; - flag = TTY_OVERRUN; + *tty->flip.flag_buf_ptr = TTY_OVERRUN; } else if (data_read & IO_MASK(R_SERIAL0_READ, framing_err)) { info->icount.frame++; - flag = TTY_FRAME; + *tty->flip.flag_buf_ptr = TTY_FRAME; } - tty_insert_flip_char(tty, data, flag); info->errorcode = 0; } info->break_detected_cnt = 0; @@ -2386,14 +2782,16 @@ struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info) log_int(rdpc(), 0, 0); } ); - tty_insert_flip_char(tty, - IO_EXTRACT(R_SERIAL0_READ, data_in, data_read), - TTY_NORMAL); + *tty->flip.char_buf_ptr = IO_EXTRACT(R_SERIAL0_READ, data_in, data_read); + *tty->flip.flag_buf_ptr = 0; } else { DEBUG_LOG(info->line, "ser_rx int but no data_avail %08lX\n", data_read); } + tty->flip.flag_buf_ptr++; + tty->flip.char_buf_ptr++; + tty->flip.count++; info->icount.rx++; data_read = *((unsigned long *)&info->port[REG_DATA_STATUS32]); if (data_read & IO_MASK(R_SERIAL0_READ, data_avail)) { @@ -2531,7 +2929,7 @@ static void handle_ser_tx_interrupt(struct e100_serial *info) if (info->x_char) { unsigned char rstat; DFLOW(DEBUG_LOG(info->line, "tx_int: xchar 0x%02X\n", info->x_char)); - local_irq_save(flags); + save_flags(flags); cli(); rstat = info->port[REG_STATUS]; DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat)); @@ -2540,7 +2938,7 @@ static void handle_ser_tx_interrupt(struct e100_serial *info) info->x_char = 0; /* We must enable since it is disabled in ser_interrupt */ e100_enable_serial_tx_ready_irq(info); - local_irq_restore(flags); + restore_flags(flags); return; } if (info->uses_dma_out) { @@ -2548,7 +2946,7 @@ static void handle_ser_tx_interrupt(struct e100_serial *info) int i; /* We only use normal tx interrupt when sending x_char */ DFLOW(DEBUG_LOG(info->line, "tx_int: xchar sent\n", 0)); - local_irq_save(flags); + save_flags(flags); cli(); rstat = info->port[REG_STATUS]; DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat)); e100_disable_serial_tx_ready_irq(info); @@ -2561,7 +2959,7 @@ static void handle_ser_tx_interrupt(struct e100_serial *info) nop(); *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, continue); - local_irq_restore(flags); + restore_flags(flags); return; } /* Normal char-by-char interrupt */ @@ -2575,7 +2973,7 @@ static void handle_ser_tx_interrupt(struct e100_serial *info) } DINTR2(DEBUG_LOG(info->line, "tx_int %c\n", info->xmit.buf[info->xmit.tail])); /* Send a byte, rs485 timing is critical so turn of ints */ - local_irq_save(flags); + save_flags(flags); cli(); info->port[REG_TR_DATA] = info->xmit.buf[info->xmit.tail]; info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1); info->icount.tx++; @@ -2599,7 +2997,7 @@ static void handle_ser_tx_interrupt(struct e100_serial *info) /* We must enable since it is disabled in ser_interrupt */ e100_enable_serial_tx_ready_irq(info); } - local_irq_restore(flags); + restore_flags(flags); if (CIRC_CNT(info->xmit.head, info->xmit.tail, @@ -2624,7 +3022,7 @@ ser_interrupt(int irq, void *dev_id) int handled = 0; static volatile unsigned long reentered_ready_mask = 0; - local_irq_save(flags); + save_flags(flags); cli(); irq_mask1_rd = *R_IRQ_MASK1_RD; /* First handle all rx interrupts with ints disabled */ info = rs_table; @@ -2669,7 +3067,7 @@ ser_interrupt(int irq, void *dev_id) /* Unblock the serial interrupt */ *R_VECT_MASK_SET = IO_STATE(R_VECT_MASK_SET, serial, set); - local_irq_enable(); + sti(); ready_mask = (1 << (8+1+2*0)); /* ser0 tr_ready */ info = rs_table; for (i = 0; i < NR_PORTS; i++) { @@ -2682,11 +3080,11 @@ ser_interrupt(int irq, void *dev_id) ready_mask <<= 2; } /* handle_ser_tx_interrupt enables tr_ready interrupts */ - local_irq_disable(); + cli(); /* Handle reentered TX interrupt */ irq_mask1_rd = reentered_ready_mask; } - local_irq_disable(); + cli(); tx_started = 0; } else { unsigned long ready_mask; @@ -2702,7 +3100,7 @@ ser_interrupt(int irq, void *dev_id) } } - local_irq_restore(flags); + restore_flags(flags); return IRQ_RETVAL(handled); } /* ser_interrupt */ #endif @@ -2723,13 +3121,11 @@ ser_interrupt(int irq, void *dev_id) * them using rs_sched_event(), and they get done here. */ static void -do_softint(struct work_struct *work) +do_softint(void *private_) { - struct e100_serial *info; + struct e100_serial *info = (struct e100_serial *) private_; struct tty_struct *tty; - info = container_of(work, struct e100_serial, work); - tty = info->tty; if (!tty) return; @@ -2749,12 +3145,13 @@ startup(struct e100_serial * info) if (!xmit_page) return -ENOMEM; - local_irq_save(flags); + save_flags(flags); + cli(); /* if it was already initialized, skip this */ if (info->flags & ASYNC_INITIALIZED) { - local_irq_restore(flags); + restore_flags(flags); free_page(xmit_page); return 0; } @@ -2880,7 +3277,7 @@ startup(struct e100_serial * info) info->flags |= ASYNC_INITIALIZED; - local_irq_restore(flags); + restore_flags(flags); return 0; } @@ -2931,7 +3328,8 @@ shutdown(struct e100_serial * info) info->irq); #endif - local_irq_save(flags); + save_flags(flags); + cli(); /* Disable interrupts */ if (info->xmit.buf) { free_page((unsigned long)info->xmit.buf); @@ -2955,7 +3353,7 @@ shutdown(struct e100_serial * info) set_bit(TTY_IO_ERROR, &info->tty->flags); info->flags &= ~ASYNC_INITIALIZED; - local_irq_restore(flags); + restore_flags(flags); } @@ -3013,6 +3411,7 @@ change_speed(struct e100_serial *info) DBAUD(printk("using external baudrate: %lu\n", CONFIG_ETRAX_EXTERN_PB6CLK_FREQ/8)); info->baud = CONFIG_ETRAX_EXTERN_PB6CLK_FREQ/8; } + } #endif else { @@ -3046,7 +3445,8 @@ change_speed(struct e100_serial *info) #ifndef CONFIG_SVINTO_SIM /* start with default settings and then fill in changes */ - local_irq_save(flags); + save_flags(flags); + cli(); /* 8 bit, no/even parity */ info->rx_ctrl &= ~(IO_MASK(R_SERIAL0_REC_CTRL, rec_bitnr) | IO_MASK(R_SERIAL0_REC_CTRL, rec_par_en) | @@ -3110,7 +3510,7 @@ change_speed(struct e100_serial *info) } *((unsigned long *)&info->port[REG_XOFF]) = xoff; - local_irq_restore(flags); + restore_flags(flags); #endif /* !CONFIG_SVINTO_SIM */ update_char_time(info); @@ -3138,12 +3538,13 @@ rs_flush_chars(struct tty_struct *tty) /* this protection might not exactly be necessary here */ - local_irq_save(flags); + save_flags(flags); + cli(); start_transmit(info); - local_irq_restore(flags); + restore_flags(flags); } -static int rs_raw_write(struct tty_struct *tty, +static int rs_raw_write(struct tty_struct * tty, int from_user, const unsigned char *buf, int count) { int c, ret = 0; @@ -3166,19 +3567,53 @@ static int rs_raw_write(struct tty_struct *tty, SIMCOUT(buf, count); return count; #endif - local_save_flags(flags); + save_flags(flags); DFLOW(DEBUG_LOG(info->line, "write count %i ", count)); DFLOW(DEBUG_LOG(info->line, "ldisc %i\n", tty->ldisc.chars_in_buffer(tty))); - /* The local_irq_disable/restore_flags pairs below are needed - * because the DMA interrupt handler moves the info->xmit values. - * the memcpy needs to be in the critical region unfortunately, - * because we need to read xmit values, memcpy, write xmit values - * in one atomic operation... this could perhaps be avoided by - * more clever design. + /* the cli/restore_flags pairs below are needed because the + * DMA interrupt handler moves the info->xmit values. the memcpy + * needs to be in the critical region unfortunately, because we + * need to read xmit values, memcpy, write xmit values in one + * atomic operation... this could perhaps be avoided by more clever + * design. */ - local_irq_disable(); + if (from_user) { + mutex_lock(&tmp_buf_mutex); + while (1) { + int c1; + c = CIRC_SPACE_TO_END(info->xmit.head, + info->xmit.tail, + SERIAL_XMIT_SIZE); + if (count < c) + c = count; + if (c <= 0) + break; + + c -= copy_from_user(tmp_buf, buf, c); + if (!c) { + if (!ret) + ret = -EFAULT; + break; + } + cli(); + c1 = CIRC_SPACE_TO_END(info->xmit.head, + info->xmit.tail, + SERIAL_XMIT_SIZE); + if (c1 < c) + c = c1; + memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c); + info->xmit.head = ((info->xmit.head + c) & + (SERIAL_XMIT_SIZE-1)); + restore_flags(flags); + buf += c; + count -= c; + ret += c; + } + mutex_unlock(&tmp_buf_mutex); + } else { + cli(); while (count) { c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, @@ -3196,7 +3631,8 @@ static int rs_raw_write(struct tty_struct *tty, count -= c; ret += c; } - local_irq_restore(flags); + restore_flags(flags); + } /* enable transmitter if not running, unless the tty is stopped * this does not need IRQ protection since if tr_running == 0 @@ -3215,7 +3651,7 @@ static int rs_raw_write(struct tty_struct *tty, } /* raw_raw_write() */ static int -rs_write(struct tty_struct *tty, +rs_write(struct tty_struct * tty, int from_user, const unsigned char *buf, int count) { #if defined(CONFIG_ETRAX_RS485) @@ -3242,7 +3678,7 @@ rs_write(struct tty_struct *tty, } #endif /* CONFIG_ETRAX_RS485 */ - count = rs_raw_write(tty, buf, count); + count = rs_raw_write(tty, from_user, buf, count); #if defined(CONFIG_ETRAX_RS485) if (info->rs485.enabled) @@ -3310,9 +3746,10 @@ rs_flush_buffer(struct tty_struct *tty) struct e100_serial *info = (struct e100_serial *)tty->driver_data; unsigned long flags; - local_irq_save(flags); + save_flags(flags); + cli(); info->xmit.head = info->xmit.tail = 0; - local_irq_restore(flags); + restore_flags(flags); tty_wakeup(tty); } @@ -3330,7 +3767,7 @@ static void rs_send_xchar(struct tty_struct *tty, char ch) { struct e100_serial *info = (struct e100_serial *)tty->driver_data; unsigned long flags; - local_irq_save(flags); + save_flags(flags); cli(); if (info->uses_dma_out) { /* Put the DMA on hold and disable the channel */ *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, hold); @@ -3347,7 +3784,7 @@ static void rs_send_xchar(struct tty_struct *tty, char ch) DFLOW(DEBUG_LOG(info->line, "rs_send_xchar 0x%02X\n", ch)); info->x_char = ch; e100_enable_serial_tx_ready_irq(info); - local_irq_restore(flags); + restore_flags(flags); } /* @@ -3559,61 +3996,21 @@ char *get_control_state_str(int MLines, char *s) } #endif -static void -rs_break(struct tty_struct *tty, int break_state) -{ - struct e100_serial *info = (struct e100_serial *)tty->driver_data; - unsigned long flags; - - if (!info->port) - return; - - local_irq_save(flags); - if (break_state == -1) { - /* Go to manual mode and set the txd pin to 0 */ - /* Clear bit 7 (txd) and 6 (tr_enable) */ - info->tx_ctrl &= 0x3F; - } else { - /* Set bit 7 (txd) and 6 (tr_enable) */ - info->tx_ctrl |= (0x80 | 0x40); - } - info->port[REG_TR_CTRL] = info->tx_ctrl; - local_irq_restore(flags); -} - -static int -rs_tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear) -{ - struct e100_serial *info = (struct e100_serial *)tty->driver_data; - - if (clear & TIOCM_RTS) - e100_rts(info, 0); - if (clear & TIOCM_DTR) - e100_dtr(info, 0); - /* Handle FEMALE behaviour */ - if (clear & TIOCM_RI) - e100_ri_out(info, 0); - if (clear & TIOCM_CD) - e100_cd_out(info, 0); - - if (set & TIOCM_RTS) - e100_rts(info, 1); - if (set & TIOCM_DTR) - e100_dtr(info, 1); - /* Handle FEMALE behaviour */ - if (set & TIOCM_RI) - e100_ri_out(info, 1); - if (set & TIOCM_CD) - e100_cd_out(info, 1); - return 0; -} - static int -rs_tiocmget(struct tty_struct *tty, struct file *file) +get_modem_info(struct e100_serial * info, unsigned int *value) { - struct e100_serial *info = (struct e100_serial *)tty->driver_data; unsigned int result; + /* Polarity isn't verified */ +#if 0 /*def SERIAL_DEBUG_IO */ + + printk("get_modem_info: RTS: %i DTR: %i CD: %i RI: %i DSR: %i CTS: %i\n", + E100_RTS_GET(info), + E100_DTR_GET(info), + E100_CD_GET(info), + E100_RI_GET(info), + E100_DSR_GET(info), + E100_CTS_GET(info)); +#endif result = (!E100_RTS_GET(info) ? TIOCM_RTS : 0) @@ -3624,20 +4021,95 @@ rs_tiocmget(struct tty_struct *tty, struct file *file) | (!E100_CTS_GET(info) ? TIOCM_CTS : 0); #ifdef SERIAL_DEBUG_IO - printk(KERN_DEBUG "ser%i: modem state: %i 0x%08X\n", - info->line, result, result); + printk("e100ser: modem state: %i 0x%08X\n", result, result); { char s[100]; get_control_state_str(result, s); - printk(KERN_DEBUG "state: %s\n", s); + printk("state: %s\n", s); } #endif - return result; + if (copy_to_user(value, &result, sizeof(int))) + return -EFAULT; + return 0; +} + +static int +set_modem_info(struct e100_serial * info, unsigned int cmd, + unsigned int *value) +{ + unsigned int arg; + + if (copy_from_user(&arg, value, sizeof(int))) + return -EFAULT; + + switch (cmd) { + case TIOCMBIS: + if (arg & TIOCM_RTS) { + e100_rts(info, 1); + } + if (arg & TIOCM_DTR) { + e100_dtr(info, 1); + } + /* Handle FEMALE behaviour */ + if (arg & TIOCM_RI) { + e100_ri_out(info, 1); + } + if (arg & TIOCM_CD) { + e100_cd_out(info, 1); + } + break; + case TIOCMBIC: + if (arg & TIOCM_RTS) { + e100_rts(info, 0); + } + if (arg & TIOCM_DTR) { + e100_dtr(info, 0); + } + /* Handle FEMALE behaviour */ + if (arg & TIOCM_RI) { + e100_ri_out(info, 0); + } + if (arg & TIOCM_CD) { + e100_cd_out(info, 0); + } + break; + case TIOCMSET: + e100_rts(info, arg & TIOCM_RTS); + e100_dtr(info, arg & TIOCM_DTR); + /* Handle FEMALE behaviour */ + e100_ri_out(info, arg & TIOCM_RI); + e100_cd_out(info, arg & TIOCM_CD); + break; + default: + return -EINVAL; + } + return 0; } +static void +rs_break(struct tty_struct *tty, int break_state) +{ + struct e100_serial * info = (struct e100_serial *)tty->driver_data; + unsigned long flags; + + if (!info->port) + return; + + save_flags(flags); + cli(); + if (break_state == -1) { + /* Go to manual mode and set the txd pin to 0 */ + info->tx_ctrl &= 0x3F; /* Clear bit 7 (txd) and 6 (tr_enable) */ + } else { + info->tx_ctrl |= (0x80 | 0x40); /* Set bit 7 (txd) and 6 (tr_enable) */ + } + info->port[REG_TR_CTRL] = info->tx_ctrl; + restore_flags(flags); +} + static int rs_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) @@ -3652,45 +4124,49 @@ rs_ioctl(struct tty_struct *tty, struct file * file, } switch (cmd) { - case TIOCGSERIAL: - return get_serial_info(info, - (struct serial_struct *) arg); - case TIOCSSERIAL: - return set_serial_info(info, - (struct serial_struct *) arg); - case TIOCSERGETLSR: /* Get line status register */ - return get_lsr_info(info, (unsigned int *) arg); - - case TIOCSERGSTRUCT: - if (copy_to_user((struct e100_serial *) arg, - info, sizeof(struct e100_serial))) - return -EFAULT; - return 0; + case TIOCMGET: + return get_modem_info(info, (unsigned int *) arg); + case TIOCMBIS: + case TIOCMBIC: + case TIOCMSET: + return set_modem_info(info, cmd, (unsigned int *) arg); + case TIOCGSERIAL: + return get_serial_info(info, + (struct serial_struct *) arg); + case TIOCSSERIAL: + return set_serial_info(info, + (struct serial_struct *) arg); + case TIOCSERGETLSR: /* Get line status register */ + return get_lsr_info(info, (unsigned int *) arg); + + case TIOCSERGSTRUCT: + if (copy_to_user((struct e100_serial *) arg, + info, sizeof(struct e100_serial))) + return -EFAULT; + return 0; #if defined(CONFIG_ETRAX_RS485) - case TIOCSERSETRS485: - { - struct rs485_control rs485ctrl; - if (copy_from_user(&rs485ctrl, (struct rs485_control *)arg, - sizeof(rs485ctrl))) - return -EFAULT; + case TIOCSERSETRS485: + { + struct rs485_control rs485ctrl; + if (copy_from_user(&rs485ctrl, (struct rs485_control*)arg, sizeof(rs485ctrl))) + return -EFAULT; - return e100_enable_rs485(tty, &rs485ctrl); - } + return e100_enable_rs485(tty, &rs485ctrl); + } - case TIOCSERWRRS485: - { - struct rs485_write rs485wr; - if (copy_from_user(&rs485wr, (struct rs485_write *)arg, - sizeof(rs485wr))) - return -EFAULT; + case TIOCSERWRRS485: + { + struct rs485_write rs485wr; + if (copy_from_user(&rs485wr, (struct rs485_write*)arg, sizeof(rs485wr))) + return -EFAULT; - return e100_write_rs485(tty, rs485wr.outc, rs485wr.outc_size); - } + return e100_write_rs485(tty, 1, rs485wr.outc, rs485wr.outc_size); + } #endif - default: - return -ENOIOCTLCMD; + default: + return -ENOIOCTLCMD; } return 0; } @@ -3715,6 +4191,46 @@ rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) } +/* In debugport.c - register a console write function that uses the normal + * serial driver + */ +typedef int (*debugport_write_function)(int i, const char *buf, unsigned int len); + +extern debugport_write_function debug_write_function; + +static int rs_debug_write_function(int i, const char *buf, unsigned int len) +{ + int cnt; + int written = 0; + struct tty_struct *tty; + static int recurse_cnt = 0; + + tty = rs_table[i].tty; + if (tty) { + unsigned long flags; + if (recurse_cnt > 5) /* We skip this debug output */ + return 1; + + local_irq_save(flags); + recurse_cnt++; + local_irq_restore(flags); + do { + cnt = rs_write(tty, 0, buf + written, len); + if (cnt >= 0) { + written += cnt; + buf += cnt; + len -= cnt; + } else + len = cnt; + } while(len > 0); + local_irq_save(flags); + recurse_cnt--; + local_irq_restore(flags); + return 1; + } + return 0; +} + /* * ------------------------------------------------------------ * rs_close() @@ -3736,10 +4252,11 @@ rs_close(struct tty_struct *tty, struct file * filp) /* interrupts are disabled for this entire function */ - local_irq_save(flags); + save_flags(flags); + cli(); if (tty_hung_up_p(filp)) { - local_irq_restore(flags); + restore_flags(flags); return; } @@ -3766,7 +4283,7 @@ rs_close(struct tty_struct *tty, struct file * filp) info->count = 0; } if (info->count) { - local_irq_restore(flags); + restore_flags(flags); return; } info->flags |= ASYNC_CLOSING; @@ -3820,7 +4337,7 @@ rs_close(struct tty_struct *tty, struct file * filp) } info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); wake_up_interruptible(&info->close_wait); - local_irq_restore(flags); + restore_flags(flags); /* port closed */ @@ -3842,28 +4359,6 @@ rs_close(struct tty_struct *tty, struct file * filp) #endif } #endif - - /* - * Release any allocated DMA irq's. - */ - if (info->dma_in_enabled) { - free_irq(info->dma_in_irq_nbr, info); - cris_free_dma(info->dma_in_nbr, info->dma_in_irq_description); - info->uses_dma_in = 0; -#ifdef SERIAL_DEBUG_OPEN - printk(KERN_DEBUG "DMA irq '%s' freed\n", - info->dma_in_irq_description); -#endif - } - if (info->dma_out_enabled) { - free_irq(info->dma_out_irq_nbr, info); - cris_free_dma(info->dma_out_nbr, info->dma_out_irq_description); - info->uses_dma_out = 0; -#ifdef SERIAL_DEBUG_OPEN - printk(KERN_DEBUG "DMA irq '%s' freed\n", - info->dma_out_irq_description); -#endif - } } /* @@ -3938,8 +4433,8 @@ block_til_ready(struct tty_struct *tty, struct file * filp, */ if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) { - wait_event_interruptible(info->close_wait, - !(info->flags & ASYNC_CLOSING)); + if (info->flags & ASYNC_CLOSING) + interruptible_sleep_on(&info->close_wait); #ifdef SERIAL_DO_RESTART if (info->flags & ASYNC_HUP_NOTIFY) return -EAGAIN; @@ -3977,19 +4472,21 @@ block_til_ready(struct tty_struct *tty, struct file * filp, printk("block_til_ready before block: ttyS%d, count = %d\n", info->line, info->count); #endif - local_irq_save(flags); + save_flags(flags); + cli(); if (!tty_hung_up_p(filp)) { extra_count++; info->count--; } - local_irq_restore(flags); + restore_flags(flags); info->blocked_open++; while (1) { - local_irq_save(flags); + save_flags(flags); + cli(); /* assert RTS and DTR */ e100_rts(info, 1); e100_dtr(info, 1); - local_irq_restore(flags); + restore_flags(flags); set_current_state(TASK_INTERRUPTIBLE); if (tty_hung_up_p(filp) || !(info->flags & ASYNC_INITIALIZED)) { @@ -4031,19 +4528,6 @@ block_til_ready(struct tty_struct *tty, struct file * filp, return 0; } -static void -deinit_port(struct e100_serial *info) -{ - if (info->dma_out_enabled) { - cris_free_dma(info->dma_out_nbr, info->dma_out_irq_description); - free_irq(info->dma_out_irq_nbr, info); - } - if (info->dma_in_enabled) { - cris_free_dma(info->dma_in_nbr, info->dma_in_irq_description); - free_irq(info->dma_in_irq_nbr, info); - } -} - /* * This routine is called whenever a serial port is opened. * It performs the serial-specific initialization for the tty structure. @@ -4054,9 +4538,9 @@ rs_open(struct tty_struct *tty, struct file * filp) struct e100_serial *info; int retval, line; unsigned long page; - int allocated_resources = 0; /* find which port we want to open */ + line = tty->index; if (line < 0 || line >= NR_PORTS) @@ -4096,8 +4580,8 @@ rs_open(struct tty_struct *tty, struct file * filp) */ if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) { - wait_event_interruptible(info->close_wait, - !(info->flags & ASYNC_CLOSING)); + if (info->flags & ASYNC_CLOSING) + interruptible_sleep_on(&info->close_wait); #ifdef SERIAL_DO_RESTART return ((info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); @@ -4106,86 +4590,13 @@ rs_open(struct tty_struct *tty, struct file * filp) #endif } - /* - * If DMA is enabled try to allocate the irq's. - */ - if (info->count == 1) { - allocated_resources = 1; - if (info->dma_in_enabled) { - if (request_irq(info->dma_in_irq_nbr, - rec_interrupt, - info->dma_in_irq_flags, - info->dma_in_irq_description, - info)) { - printk(KERN_WARNING "DMA irq '%s' busy; " - "falling back to non-DMA mode\n", - info->dma_in_irq_description); - /* Make sure we never try to use DMA in */ - /* for the port again. */ - info->dma_in_enabled = 0; - } else if (cris_request_dma(info->dma_in_nbr, - info->dma_in_irq_description, - DMA_VERBOSE_ON_ERROR, - info->dma_owner)) { - free_irq(info->dma_in_irq_nbr, info); - printk(KERN_WARNING "DMA '%s' busy; " - "falling back to non-DMA mode\n", - info->dma_in_irq_description); - /* Make sure we never try to use DMA in */ - /* for the port again. */ - info->dma_in_enabled = 0; - } -#ifdef SERIAL_DEBUG_OPEN - else - printk(KERN_DEBUG "DMA irq '%s' allocated\n", - info->dma_in_irq_description); -#endif - } - if (info->dma_out_enabled) { - if (request_irq(info->dma_out_irq_nbr, - tr_interrupt, - info->dma_out_irq_flags, - info->dma_out_irq_description, - info)) { - printk(KERN_WARNING "DMA irq '%s' busy; " - "falling back to non-DMA mode\n", - info->dma_out_irq_description); - /* Make sure we never try to use DMA out */ - /* for the port again. */ - info->dma_out_enabled = 0; - } else if (cris_request_dma(info->dma_out_nbr, - info->dma_out_irq_description, - DMA_VERBOSE_ON_ERROR, - info->dma_owner)) { - free_irq(info->dma_out_irq_nbr, info); - printk(KERN_WARNING "DMA '%s' busy; " - "falling back to non-DMA mode\n", - info->dma_out_irq_description); - /* Make sure we never try to use DMA out */ - /* for the port again. */ - info->dma_out_enabled = 0; - } -#ifdef SERIAL_DEBUG_OPEN - else - printk(KERN_DEBUG "DMA irq '%s' allocated\n", - info->dma_out_irq_description); -#endif - } - } - /* * Start up the serial port */ retval = startup(info); - if (retval) { - if (allocated_resources) - deinit_port(info); - - /* FIXME Decrease count info->count here too? */ + if (retval) return retval; - } - retval = block_til_ready(tty, filp, info); if (retval) { @@ -4193,9 +4604,6 @@ rs_open(struct tty_struct *tty, struct file * filp) printk("rs_open returning after block_til_ready with %d\n", retval); #endif - if (allocated_resources) - deinit_port(info); - return retval; } @@ -4385,8 +4793,6 @@ static const struct tty_operations rs_ops = { .send_xchar = rs_send_xchar, .wait_until_sent = rs_wait_until_sent, .read_proc = rs_read_proc, - .tiocmget = rs_tiocmget, - .tiocmset = rs_tiocmset }; static int __init @@ -4404,27 +4810,9 @@ rs_init(void) /* Setup the timed flush handler system */ #if !defined(CONFIG_ETRAX_SERIAL_FAST_TIMER) - setup_timer(&flush_timer, timed_flush_handler, 0); - mod_timer(&flush_timer, jiffies + 5); -#endif - -#if defined(CONFIG_ETRAX_RS485) -#if defined(CONFIG_ETRAX_RS485_ON_PA) - if (cris_io_interface_allocate_pins(if_ser0, 'a', rs485_pa_bit, - rs485_pa_bit)) { - printk(KERN_CRIT "ETRAX100LX serial: Could not allocate " - "RS485 pin\n"); - return -EBUSY; - } -#endif -#if defined(CONFIG_ETRAX_RS485_ON_PORT_G) - if (cris_io_interface_allocate_pins(if_ser0, 'g', rs485_pa_bit, - rs485_port_g_bit)) { - printk(KERN_CRIT "ETRAX100LX serial: Could not allocate " - "RS485 pin\n"); - return -EBUSY; - } -#endif + init_timer(&flush_timer); + flush_timer.function = timed_flush_handler; + mod_timer(&flush_timer, jiffies + CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS); #endif /* Initialize the tty_driver structure */ @@ -4451,16 +4839,6 @@ rs_init(void) /* do some initializing for the separate ports */ for (i = 0, info = rs_table; i < NR_PORTS; i++,info++) { - if (info->enabled) { - if (cris_request_io_interface(info->io_if, - info->io_if_description)) { - printk(KERN_CRIT "ETRAX100LX async serial: " - "Could not allocate IO pins for " - "%s, port %d\n", - info->io_if_description, i); - info->enabled = 0; - } - } info->uses_dma_in = 0; info->uses_dma_out = 0; info->line = i; @@ -4494,7 +4872,7 @@ rs_init(void) info->rs485.delay_rts_before_send = 0; info->rs485.enabled = 0; #endif - INIT_WORK(&info->work, do_softint); + INIT_WORK(&info->work, do_softint, info); if (info->enabled) { printk(KERN_INFO "%s%d at 0x%x is a builtin UART with DMA\n", @@ -4512,17 +4890,64 @@ rs_init(void) #endif #ifndef CONFIG_SVINTO_SIM -#ifndef CONFIG_ETRAX_KGDB /* Not needed in simulator. May only complicate stuff. */ /* hook the irq's for DMA channel 6 and 7, serial output and input, and some more... */ - if (request_irq(SERIAL_IRQ_NBR, ser_interrupt, - IRQF_SHARED | IRQF_DISABLED, "serial ", driver)) - panic("%s: Failed to request irq8", __FUNCTION__); + if (request_irq(SERIAL_IRQ_NBR, ser_interrupt, IRQF_SHARED | IRQF_DISABLED, "serial ", NULL)) + panic("irq8"); +#ifdef CONFIG_ETRAX_SERIAL_PORT0 +#ifdef CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT + if (request_irq(SER0_DMA_TX_IRQ_NBR, tr_interrupt, IRQF_DISABLED, "serial 0 dma tr", NULL)) + panic("irq22"); +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN + if (request_irq(SER0_DMA_RX_IRQ_NBR, rec_interrupt, IRQF_DISABLED, "serial 0 dma rec", NULL)) + panic("irq23"); +#endif +#endif + +#ifdef CONFIG_ETRAX_SERIAL_PORT1 +#ifdef CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT + if (request_irq(SER1_DMA_TX_IRQ_NBR, tr_interrupt, IRQF_DISABLED, "serial 1 dma tr", NULL)) + panic("irq24"); +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN + if (request_irq(SER1_DMA_RX_IRQ_NBR, rec_interrupt, IRQF_DISABLED, "serial 1 dma rec", NULL)) + panic("irq25"); +#endif +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT2 + /* DMA Shared with par0 (and SCSI0 and ATA) */ +#ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT + if (request_irq(SER2_DMA_TX_IRQ_NBR, tr_interrupt, IRQF_SHARED | IRQF_DISABLED, "serial 2 dma tr", NULL)) + panic("irq18"); +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN + if (request_irq(SER2_DMA_RX_IRQ_NBR, rec_interrupt, IRQF_SHARED | IRQF_DISABLED, "serial 2 dma rec", NULL)) + panic("irq19"); +#endif +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT3 + /* DMA Shared with par1 (and SCSI1 and Extern DMA 0) */ +#ifdef CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT + if (request_irq(SER3_DMA_TX_IRQ_NBR, tr_interrupt, IRQF_SHARED | IRQF_DISABLED, "serial 3 dma tr", NULL)) + panic("irq20"); +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN + if (request_irq(SER3_DMA_RX_IRQ_NBR, rec_interrupt, IRQF_SHARED | IRQF_DISABLED, "serial 3 dma rec", NULL)) + panic("irq21"); +#endif #endif -#endif /* CONFIG_SVINTO_SIM */ +#ifdef CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST + if (request_irq(TIMER1_IRQ_NBR, timeout_interrupt, IRQF_SHARED | IRQF_DISABLED, + "fast serial dma timeout", NULL)) { + printk(KERN_CRIT "err: timer1 irq\n"); + } +#endif +#endif /* CONFIG_SVINTO_SIM */ + debug_write_function = rs_debug_write_function; return 0; } diff --git a/trunk/drivers/serial/crisv10.h b/trunk/drivers/serial/crisv10.h deleted file mode 100644 index ccd0f32b7372..000000000000 --- a/trunk/drivers/serial/crisv10.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * serial.h: Arch-dep definitions for the Etrax100 serial driver. - * - * Copyright (C) 1998-2007 Axis Communications AB - */ - -#ifndef _ETRAX_SERIAL_H -#define _ETRAX_SERIAL_H - -#include -#include -#include -#include - -/* Software state per channel */ - -#ifdef __KERNEL__ -/* - * This is our internal structure for each serial port's state. - * - * Many fields are paralleled by the structure used by the serial_struct - * structure. - * - * For definitions of the flags field, see tty.h - */ - -#define SERIAL_RECV_DESCRIPTORS 8 - -struct etrax_recv_buffer { - struct etrax_recv_buffer *next; - unsigned short length; - unsigned char error; - unsigned char pad; - - unsigned char buffer[0]; -}; - -struct e100_serial { - int baud; - volatile u8 *port; /* R_SERIALx_CTRL */ - u32 irq; /* bitnr in R_IRQ_MASK2 for dmaX_descr */ - - /* Output registers */ - volatile u8 *oclrintradr; /* adr to R_DMA_CHx_CLR_INTR */ - volatile u32 *ofirstadr; /* adr to R_DMA_CHx_FIRST */ - volatile u8 *ocmdadr; /* adr to R_DMA_CHx_CMD */ - const volatile u8 *ostatusadr; /* adr to R_DMA_CHx_STATUS */ - - /* Input registers */ - volatile u8 *iclrintradr; /* adr to R_DMA_CHx_CLR_INTR */ - volatile u32 *ifirstadr; /* adr to R_DMA_CHx_FIRST */ - volatile u8 *icmdadr; /* adr to R_DMA_CHx_CMD */ - volatile u32 *idescradr; /* adr to R_DMA_CHx_DESCR */ - - int flags; /* defined in tty.h */ - - u8 rx_ctrl; /* shadow for R_SERIALx_REC_CTRL */ - u8 tx_ctrl; /* shadow for R_SERIALx_TR_CTRL */ - u8 iseteop; /* bit number for R_SET_EOP for the input dma */ - int enabled; /* Set to 1 if the port is enabled in HW config */ - - u8 dma_out_enabled; /* Set to 1 if DMA should be used */ - u8 dma_in_enabled; /* Set to 1 if DMA should be used */ - - /* end of fields defined in rs_table[] in .c-file */ - int dma_owner; - unsigned int dma_in_nbr; - unsigned int dma_out_nbr; - unsigned int dma_in_irq_nbr; - unsigned int dma_out_irq_nbr; - unsigned long dma_in_irq_flags; - unsigned long dma_out_irq_flags; - char *dma_in_irq_description; - char *dma_out_irq_description; - - enum cris_io_interface io_if; - char *io_if_description; - - u8 uses_dma_in; /* Set to 1 if DMA is used */ - u8 uses_dma_out; /* Set to 1 if DMA is used */ - u8 forced_eop; /* a fifo eop has been forced */ - int baud_base; /* For special baudrates */ - int custom_divisor; /* For special baudrates */ - struct etrax_dma_descr tr_descr; - struct etrax_dma_descr rec_descr[SERIAL_RECV_DESCRIPTORS]; - int cur_rec_descr; - - volatile int tr_running; /* 1 if output is running */ - - struct tty_struct *tty; - int read_status_mask; - int ignore_status_mask; - int x_char; /* xon/xoff character */ - int close_delay; - unsigned short closing_wait; - unsigned short closing_wait2; - unsigned long event; - unsigned long last_active; - int line; - int type; /* PORT_ETRAX */ - int count; /* # of fd on device */ - int blocked_open; /* # of blocked opens */ - struct circ_buf xmit; - struct etrax_recv_buffer *first_recv_buffer; - struct etrax_recv_buffer *last_recv_buffer; - unsigned int recv_cnt; - unsigned int max_recv_cnt; - - struct work_struct work; - struct async_icount icount; /* error-statistics etc.*/ - struct ktermios normal_termios; - struct ktermios callout_termios; - wait_queue_head_t open_wait; - wait_queue_head_t close_wait; - - unsigned long char_time_usec; /* The time for 1 char, in usecs */ - unsigned long flush_time_usec; /* How often we should flush */ - unsigned long last_tx_active_usec; /* Last tx usec in the jiffies */ - unsigned long last_tx_active; /* Last tx time in jiffies */ - unsigned long last_rx_active_usec; /* Last rx usec in the jiffies */ - unsigned long last_rx_active; /* Last rx time in jiffies */ - - int break_detected_cnt; - int errorcode; - -#ifdef CONFIG_ETRAX_RS485 - struct rs485_control rs485; /* RS-485 support */ -#endif -}; - -/* this PORT is not in the standard serial.h. it's not actually used for - * anything since we only have one type of async serial-port anyway in this - * system. - */ - -#define PORT_ETRAX 1 - -/* - * Events are used to schedule things to happen at timer-interrupt - * time, instead of at rs interrupt time. - */ -#define RS_EVENT_WRITE_WAKEUP 0 - -#endif /* __KERNEL__ */ - -#endif /* !_ETRAX_SERIAL_H */ diff --git a/trunk/drivers/spi/spi.c b/trunk/drivers/spi/spi.c index b31f4431849b..89769ce16f88 100644 --- a/trunk/drivers/spi/spi.c +++ b/trunk/drivers/spi/spi.c @@ -457,11 +457,10 @@ int spi_register_master(struct spi_master *master) EXPORT_SYMBOL_GPL(spi_register_master); -static int __unregister(struct device *dev, void *master_dev) +static int __unregister(struct device *dev, void *unused) { /* note: before about 2.6.14-rc1 this would corrupt memory: */ - if (dev != master_dev) - spi_unregister_device(to_spi_device(dev)); + spi_unregister_device(to_spi_device(dev)); return 0; } @@ -479,8 +478,7 @@ void spi_unregister_master(struct spi_master *master) { int dummy; - dummy = device_for_each_child(master->dev.parent, &master->dev, - __unregister); + dummy = device_for_each_child(master->dev.parent, NULL, __unregister); device_unregister(&master->dev); } EXPORT_SYMBOL_GPL(spi_unregister_master); diff --git a/trunk/drivers/spi/spi_txx9.c b/trunk/drivers/spi/spi_txx9.c index 363ac8e68821..cc5094f37dd3 100644 --- a/trunk/drivers/spi/spi_txx9.c +++ b/trunk/drivers/spi/spi_txx9.c @@ -24,7 +24,6 @@ #include #include #include -#include #include @@ -75,6 +74,7 @@ struct txx9spi { struct list_head queue; wait_queue_head_t waitq; void __iomem *membase; + int irq; int baseclk; struct clk *clk; u32 max_speed_hz, min_speed_hz; @@ -350,12 +350,12 @@ static int __init txx9spi_probe(struct platform_device *dev) struct resource *res; int ret = -ENODEV; u32 mcr; - int irq; master = spi_alloc_master(&dev->dev, sizeof(*c)); if (!master) return ret; c = spi_master_get_devdata(master); + c->irq = -1; platform_set_drvdata(dev, master); INIT_WORK(&c->work, txx9spi_work); @@ -381,36 +381,32 @@ static int __init txx9spi_probe(struct platform_device *dev) res = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!res) - goto exit_busy; - if (!devm_request_mem_region(&dev->dev, - res->start, res->end - res->start + 1, - "spi_txx9")) - goto exit_busy; - c->membase = devm_ioremap(&dev->dev, - res->start, res->end - res->start + 1); + goto exit; + c->membase = ioremap(res->start, res->end - res->start + 1); if (!c->membase) - goto exit_busy; + goto exit; /* enter config mode */ mcr = txx9spi_rd(c, TXx9_SPMCR); mcr &= ~(TXx9_SPMCR_OPMODE | TXx9_SPMCR_SPSTP | TXx9_SPMCR_BCLR); txx9spi_wr(c, mcr | TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR, TXx9_SPMCR); - irq = platform_get_irq(dev, 0); - if (irq < 0) - goto exit_busy; - ret = devm_request_irq(&dev->dev, irq, txx9spi_interrupt, 0, - "spi_txx9", c); - if (ret) + c->irq = platform_get_irq(dev, 0); + if (c->irq < 0) goto exit; + ret = request_irq(c->irq, txx9spi_interrupt, 0, dev->name, c); + if (ret) { + c->irq = -1; + goto exit; + } c->workqueue = create_singlethread_workqueue(master->dev.parent->bus_id); if (!c->workqueue) - goto exit_busy; + goto exit; c->last_chipselect = -1; dev_info(&dev->dev, "at %#llx, irq %d, %dMHz\n", - (unsigned long long)res->start, irq, + (unsigned long long)res->start, c->irq, (c->baseclk + 500000) / 1000000); master->bus_num = dev->id; @@ -422,11 +418,13 @@ static int __init txx9spi_probe(struct platform_device *dev) if (ret) goto exit; return 0; -exit_busy: - ret = -EBUSY; exit: if (c->workqueue) destroy_workqueue(c->workqueue); + if (c->irq >= 0) + free_irq(c->irq, c); + if (c->membase) + iounmap(c->membase); if (c->clk) { clk_disable(c->clk); clk_put(c->clk); @@ -444,6 +442,8 @@ static int __exit txx9spi_remove(struct platform_device *dev) spi_unregister_master(master); platform_set_drvdata(dev, NULL); destroy_workqueue(c->workqueue); + free_irq(c->irq, c); + iounmap(c->membase); clk_disable(c->clk); clk_put(c->clk); spi_master_put(master); diff --git a/trunk/drivers/spi/tle62x0.c b/trunk/drivers/spi/tle62x0.c index 455991fbe28f..6da58ca48b33 100644 --- a/trunk/drivers/spi/tle62x0.c +++ b/trunk/drivers/spi/tle62x0.c @@ -107,11 +107,8 @@ static ssize_t tle62x0_status_show(struct device *dev, mutex_lock(&st->lock); ret = tle62x0_read(st); + dev_dbg(dev, "tle62x0_read() returned %d\n", ret); - if (ret < 0) { - mutex_unlock(&st->lock); - return ret; - } for (ptr = 0; ptr < (st->nr_gpio * 2)/8; ptr += 1) { fault <<= 8; diff --git a/trunk/drivers/usb/serial/keyspan.c b/trunk/drivers/usb/serial/keyspan.c index 1f7ab15df36d..6bfdba6a213f 100644 --- a/trunk/drivers/usb/serial/keyspan.c +++ b/trunk/drivers/usb/serial/keyspan.c @@ -1215,18 +1215,20 @@ static int keyspan_chars_in_buffer (struct usb_serial_port *port) static int keyspan_open (struct usb_serial_port *port, struct file *filp) { - struct keyspan_port_private *p_priv; - struct keyspan_serial_private *s_priv; - struct usb_serial *serial = port->serial; + struct keyspan_port_private *p_priv; + struct keyspan_serial_private *s_priv; + struct usb_serial *serial = port->serial; const struct keyspan_device_details *d_details; int i, err; + int baud_rate, device_port; struct urb *urb; + unsigned int cflag; s_priv = usb_get_serial_data(serial); p_priv = usb_get_serial_port_data(port); d_details = p_priv->device_details; - - dbg("%s - port%d.", __FUNCTION__, port->number); + + dbg("%s - port%d.", __FUNCTION__, port->number); /* Set some sane defaults */ p_priv->rts_state = 1; @@ -1247,7 +1249,7 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp) urb->dev = serial->dev; /* make sure endpoint data toggle is synchronized with the device */ - + usb_clear_halt(urb->dev, urb->pipe); if ((err = usb_submit_urb(urb, GFP_KERNEL)) != 0) { @@ -1263,6 +1265,30 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp) /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 0); */ } + /* get the terminal config for the setup message now so we don't + * need to send 2 of them */ + + cflag = port->tty->termios->c_cflag; + device_port = port->number - port->serial->minor; + + /* Baud rate calculation takes baud rate as an integer + so other rates can be generated if desired. */ + baud_rate = tty_get_baud_rate(port->tty); + /* If no match or invalid, leave as default */ + if (baud_rate >= 0 + && d_details->calculate_baud_rate(baud_rate, d_details->baudclk, + NULL, NULL, NULL, device_port) == KEYSPAN_BAUD_RATE_OK) { + p_priv->baud = baud_rate; + } + + /* set CTS/RTS handshake etc. */ + p_priv->cflag = cflag; + p_priv->flow_control = (cflag & CRTSCTS)? flow_cts: flow_none; + + keyspan_send_setup(port, 1); + //mdelay(100); + //keyspan_set_termios(port, NULL); + return (0); } diff --git a/trunk/drivers/video/Kconfig b/trunk/drivers/video/Kconfig index 7d86e9eae915..cc4b60f899ca 100644 --- a/trunk/drivers/video/Kconfig +++ b/trunk/drivers/video/Kconfig @@ -503,7 +503,7 @@ config FB_VALKYRIE config FB_CT65550 bool "Chips 65550 display support" - depends on (FB = y) && PPC32 && PCI + depends on (FB = y) && PPC32 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT diff --git a/trunk/drivers/video/gbefb.c b/trunk/drivers/video/gbefb.c index 2e552d5bbb5d..b9b572b293d4 100644 --- a/trunk/drivers/video/gbefb.c +++ b/trunk/drivers/video/gbefb.c @@ -183,8 +183,8 @@ static struct fb_videomode default_mode_LCD __initdata = { .vmode = FB_VMODE_NONINTERLACED, }; -struct fb_videomode *default_mode __initdata = &default_mode_CRT; -struct fb_var_screeninfo *default_var __initdata = &default_var_CRT; +struct fb_videomode *default_mode = &default_mode_CRT; +struct fb_var_screeninfo *default_var = &default_var_CRT; static int flat_panel_enabled = 0; diff --git a/trunk/drivers/video/geode/lxfb.h b/trunk/drivers/video/geode/lxfb.h index ca13c48d19b0..6c227f9592a5 100644 --- a/trunk/drivers/video/geode/lxfb.h +++ b/trunk/drivers/video/geode/lxfb.h @@ -33,7 +33,7 @@ void lx_set_palette_reg(struct fb_info *, unsigned int, unsigned int, #define MSR_LX_GLD_CONFIG 0x48002001 #define MSR_LX_GLCP_DOTPLL 0x4c000015 -#define MSR_LX_DF_PADSEL 0x48002011 +#define MSR_LX_DF_PADSEL 0x48000011 #define MSR_LX_DC_SPARE 0x80000011 #define MSR_LX_DF_GLCONFIG 0x48002001 diff --git a/trunk/drivers/video/ps3fb.c b/trunk/drivers/video/ps3fb.c index 75836aa83191..b3463ddcfd60 100644 --- a/trunk/drivers/video/ps3fb.c +++ b/trunk/drivers/video/ps3fb.c @@ -727,7 +727,7 @@ static int ps3fb_blank(int blank, struct fb_info *info) static int ps3fb_get_vblank(struct fb_vblank *vblank) { - memset(vblank, 0, sizeof(*vblank)); + memset(vblank, 0, sizeof(&vblank)); vblank->flags = FB_VBLANK_HAVE_VSYNC; return 0; } diff --git a/trunk/drivers/video/s1d13xxxfb.c b/trunk/drivers/video/s1d13xxxfb.c index b829dc7c5edf..a5333c190789 100644 --- a/trunk/drivers/video/s1d13xxxfb.c +++ b/trunk/drivers/video/s1d13xxxfb.c @@ -540,7 +540,7 @@ s1d13xxxfb_probe(struct platform_device *pdev) int ret = 0; u8 revision; - dbg("probe called: device is %p\n", pdev); + dbg("probe called: device is %p\n", dev); printk(KERN_INFO "Epson S1D13XXX FB Driver\n"); @@ -753,11 +753,8 @@ static struct platform_driver s1d13xxxfb_driver = { static int __init s1d13xxxfb_init(void) { - -#ifndef MODULE if (fb_get_options("s1d13xxxfb", NULL)) return -ENODEV; -#endif return platform_driver_register(&s1d13xxxfb_driver); } diff --git a/trunk/drivers/video/sis/sis_main.c b/trunk/drivers/video/sis/sis_main.c index 37bd24b8d83b..bc7d23683735 100644 --- a/trunk/drivers/video/sis/sis_main.c +++ b/trunk/drivers/video/sis/sis_main.c @@ -1248,6 +1248,7 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in if(found_mode) { ivideo->sisfb_mode_idx = sisfb_validate_mode(ivideo, ivideo->sisfb_mode_idx, ivideo->currentvbflags); + ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]; } else { ivideo->sisfb_mode_idx = -1; } @@ -1259,8 +1260,6 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in return -EINVAL; } - ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]; - if(sisfb_search_refresh_rate(ivideo, ivideo->refresh_rate, ivideo->sisfb_mode_idx) == 0) { ivideo->rate_idx = sisbios_mode[ivideo->sisfb_mode_idx].rate_idx; ivideo->refresh_rate = 60; diff --git a/trunk/drivers/video/uvesafb.c b/trunk/drivers/video/uvesafb.c index d1d6c0facd54..b983d262ab78 100644 --- a/trunk/drivers/video/uvesafb.c +++ b/trunk/drivers/video/uvesafb.c @@ -926,10 +926,8 @@ static int uvesafb_setpalette(struct uvesafb_pal_entry *entries, int count, int start, struct fb_info *info) { struct uvesafb_ktask *task; -#ifdef CONFIG_X86 struct uvesafb_par *par = info->par; int i = par->mode_idx; -#endif int err = 0; /* @@ -1105,11 +1103,11 @@ static int uvesafb_pan_display(struct fb_var_screeninfo *var, static int uvesafb_blank(int blank, struct fb_info *info) { + struct uvesafb_par *par = info->par; struct uvesafb_ktask *task; int err = 1; -#ifdef CONFIG_X86 - struct uvesafb_par *par = info->par; +#ifdef CONFIG_X86 if (par->vbe_ib.capabilities & VBE_CAP_VGACOMPAT) { int loop = 10000; u8 seq = 0, crtc17 = 0; diff --git a/trunk/drivers/w1/masters/ds2490.c b/trunk/drivers/w1/masters/ds2490.c index b63b5e044a4c..299e274d241a 100644 --- a/trunk/drivers/w1/masters/ds2490.c +++ b/trunk/drivers/w1/masters/ds2490.c @@ -233,7 +233,7 @@ static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st, { int count, err; - memset(st, 0, sizeof(*st)); + memset(st, 0, sizeof(st)); count = 0; err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_STATUS]), buf, size, &count, 100); diff --git a/trunk/fs/bfs/bfs.h b/trunk/fs/bfs/bfs.h index ac7a8b1d6c3a..130f6c66c5ba 100644 --- a/trunk/fs/bfs/bfs.h +++ b/trunk/fs/bfs/bfs.h @@ -14,6 +14,8 @@ struct bfs_sb_info { unsigned long si_blocks; unsigned long si_freeb; unsigned long si_freei; + unsigned long si_lf_ioff; + unsigned long si_lf_sblk; unsigned long si_lf_eblk; unsigned long si_lasti; unsigned long * si_imap; @@ -37,7 +39,7 @@ static inline struct bfs_sb_info *BFS_SB(struct super_block *sb) static inline struct bfs_inode_info *BFS_I(struct inode *inode) { - return container_of(inode, struct bfs_inode_info, vfs_inode); + return list_entry(inode, struct bfs_inode_info, vfs_inode); } diff --git a/trunk/fs/bfs/dir.c b/trunk/fs/bfs/dir.c index 1fd056d0fc3d..097f1497f743 100644 --- a/trunk/fs/bfs/dir.c +++ b/trunk/fs/bfs/dir.c @@ -21,32 +21,29 @@ #define dprintf(x...) #endif -static int bfs_add_entry(struct inode *dir, const unsigned char *name, - int namelen, int ino); -static struct buffer_head *bfs_find_entry(struct inode *dir, - const unsigned char *name, int namelen, - struct bfs_dirent **res_dir); +static int bfs_add_entry(struct inode * dir, const unsigned char * name, int namelen, int ino); +static struct buffer_head * bfs_find_entry(struct inode * dir, + const unsigned char * name, int namelen, struct bfs_dirent ** res_dir); -static int bfs_readdir(struct file *f, void *dirent, filldir_t filldir) +static int bfs_readdir(struct file * f, void * dirent, filldir_t filldir) { - struct inode *dir = f->f_path.dentry->d_inode; - struct buffer_head *bh; - struct bfs_dirent *de; + struct inode * dir = f->f_path.dentry->d_inode; + struct buffer_head * bh; + struct bfs_dirent * de; unsigned int offset; int block; lock_kernel(); - if (f->f_pos & (BFS_DIRENT_SIZE - 1)) { - printf("Bad f_pos=%08lx for %s:%08lx\n", - (unsigned long)f->f_pos, - dir->i_sb->s_id, dir->i_ino); + if (f->f_pos & (BFS_DIRENT_SIZE-1)) { + printf("Bad f_pos=%08lx for %s:%08lx\n", (unsigned long)f->f_pos, + dir->i_sb->s_id, dir->i_ino); unlock_kernel(); return -EBADF; } while (f->f_pos < dir->i_size) { - offset = f->f_pos & (BFS_BSIZE - 1); + offset = f->f_pos & (BFS_BSIZE-1); block = BFS_I(dir)->i_sblock + (f->f_pos >> BFS_BSIZE_BITS); bh = sb_bread(dir->i_sb, block); if (!bh) { @@ -57,9 +54,7 @@ static int bfs_readdir(struct file *f, void *dirent, filldir_t filldir) de = (struct bfs_dirent *)(bh->b_data + offset); if (de->ino) { int size = strnlen(de->name, BFS_NAMELEN); - if (filldir(dirent, de->name, size, f->f_pos, - le16_to_cpu(de->ino), - DT_UNKNOWN) < 0) { + if (filldir(dirent, de->name, size, f->f_pos, le16_to_cpu(de->ino), DT_UNKNOWN) < 0) { brelse(bh); unlock_kernel(); return 0; @@ -67,7 +62,7 @@ static int bfs_readdir(struct file *f, void *dirent, filldir_t filldir) } offset += BFS_DIRENT_SIZE; f->f_pos += BFS_DIRENT_SIZE; - } while ((offset < BFS_BSIZE) && (f->f_pos < dir->i_size)); + } while (offset < BFS_BSIZE && f->f_pos < dir->i_size); brelse(bh); } @@ -83,13 +78,13 @@ const struct file_operations bfs_dir_operations = { extern void dump_imap(const char *, struct super_block *); -static int bfs_create(struct inode *dir, struct dentry *dentry, int mode, - struct nameidata *nd) +static int bfs_create(struct inode * dir, struct dentry * dentry, int mode, + struct nameidata *nd) { int err; - struct inode *inode; - struct super_block *s = dir->i_sb; - struct bfs_sb_info *info = BFS_SB(s); + struct inode * inode; + struct super_block * s = dir->i_sb; + struct bfs_sb_info * info = BFS_SB(s); unsigned long ino; inode = new_inode(s); @@ -102,7 +97,7 @@ static int bfs_create(struct inode *dir, struct dentry *dentry, int mode, iput(inode); return -ENOSPC; } - set_bit(ino, info->si_imap); + set_bit(ino, info->si_imap); info->si_freei--; inode->i_uid = current->fsuid; inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; @@ -118,10 +113,9 @@ static int bfs_create(struct inode *dir, struct dentry *dentry, int mode, BFS_I(inode)->i_eblock = 0; insert_inode_hash(inode); mark_inode_dirty(inode); - dump_imap("create", s); + dump_imap("create",s); - err = bfs_add_entry(dir, dentry->d_name.name, dentry->d_name.len, - inode->i_ino); + err = bfs_add_entry(dir, dentry->d_name.name, dentry->d_name.len, inode->i_ino); if (err) { inode_dec_link_count(inode); iput(inode); @@ -133,12 +127,11 @@ static int bfs_create(struct inode *dir, struct dentry *dentry, int mode, return 0; } -static struct dentry *bfs_lookup(struct inode *dir, struct dentry *dentry, - struct nameidata *nd) +static struct dentry * bfs_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd) { - struct inode *inode = NULL; - struct buffer_head *bh; - struct bfs_dirent *de; + struct inode * inode = NULL; + struct buffer_head * bh; + struct bfs_dirent * de; if (dentry->d_name.len > BFS_NAMELEN) return ERR_PTR(-ENAMETOOLONG); @@ -159,15 +152,13 @@ static struct dentry *bfs_lookup(struct inode *dir, struct dentry *dentry, return NULL; } -static int bfs_link(struct dentry *old, struct inode *dir, - struct dentry *new) +static int bfs_link(struct dentry * old, struct inode * dir, struct dentry * new) { - struct inode *inode = old->d_inode; + struct inode * inode = old->d_inode; int err; lock_kernel(); - err = bfs_add_entry(dir, new->d_name.name, new->d_name.len, - inode->i_ino); + err = bfs_add_entry(dir, new->d_name.name, new->d_name.len, inode->i_ino); if (err) { unlock_kernel(); return err; @@ -181,23 +172,23 @@ static int bfs_link(struct dentry *old, struct inode *dir, return 0; } -static int bfs_unlink(struct inode *dir, struct dentry *dentry) + +static int bfs_unlink(struct inode * dir, struct dentry * dentry) { int error = -ENOENT; - struct inode *inode; - struct buffer_head *bh; - struct bfs_dirent *de; + struct inode * inode; + struct buffer_head * bh; + struct bfs_dirent * de; inode = dentry->d_inode; lock_kernel(); bh = bfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de); - if (!bh || (le16_to_cpu(de->ino) != inode->i_ino)) + if (!bh || le16_to_cpu(de->ino) != inode->i_ino) goto out_brelse; if (!inode->i_nlink) { - printf("unlinking non-existent file %s:%lu (nlink=%d)\n", - inode->i_sb->s_id, inode->i_ino, - inode->i_nlink); + printf("unlinking non-existent file %s:%lu (nlink=%d)\n", inode->i_sb->s_id, + inode->i_ino, inode->i_nlink); inode->i_nlink = 1; } de->ino = 0; @@ -214,12 +205,12 @@ static int bfs_unlink(struct inode *dir, struct dentry *dentry) return error; } -static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry) +static int bfs_rename(struct inode * old_dir, struct dentry * old_dentry, + struct inode * new_dir, struct dentry * new_dentry) { - struct inode *old_inode, *new_inode; - struct buffer_head *old_bh, *new_bh; - struct bfs_dirent *old_de, *new_de; + struct inode * old_inode, * new_inode; + struct buffer_head * old_bh, * new_bh; + struct bfs_dirent * old_de, * new_de; int error = -ENOENT; old_bh = new_bh = NULL; @@ -232,7 +223,7 @@ static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry, old_dentry->d_name.name, old_dentry->d_name.len, &old_de); - if (!old_bh || (le16_to_cpu(old_de->ino) != old_inode->i_ino)) + if (!old_bh || le16_to_cpu(old_de->ino) != old_inode->i_ino) goto end_rename; error = -EPERM; @@ -248,8 +239,7 @@ static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (!new_bh) { error = bfs_add_entry(new_dir, new_dentry->d_name.name, - new_dentry->d_name.len, - old_inode->i_ino); + new_dentry->d_name.len, old_inode->i_ino); if (error) goto end_rename; } @@ -278,12 +268,11 @@ const struct inode_operations bfs_dir_inops = { .rename = bfs_rename, }; -static int bfs_add_entry(struct inode *dir, const unsigned char *name, - int namelen, int ino) +static int bfs_add_entry(struct inode * dir, const unsigned char * name, int namelen, int ino) { - struct buffer_head *bh; - struct bfs_dirent *de; - int block, sblock, eblock, off, pos; + struct buffer_head * bh; + struct bfs_dirent * de; + int block, sblock, eblock, off, eoff; int i; dprintf("name=%s, namelen=%d\n", name, namelen); @@ -295,24 +284,27 @@ static int bfs_add_entry(struct inode *dir, const unsigned char *name, sblock = BFS_I(dir)->i_sblock; eblock = BFS_I(dir)->i_eblock; - for (block = sblock; block <= eblock; block++) { + eoff = dir->i_size % BFS_BSIZE; + for (block=sblock; block<=eblock; block++) { bh = sb_bread(dir->i_sb, block); - if (!bh) + if(!bh) return -ENOSPC; - for (off = 0; off < BFS_BSIZE; off += BFS_DIRENT_SIZE) { + for (off=0; offb_data + off); + if (block==eblock && off>=eoff) { + /* Do not read/interpret the garbage in the end of eblock. */ + de->ino = 0; + } if (!de->ino) { - pos = (block - sblock) * BFS_BSIZE + off; - if (pos >= dir->i_size) { + if ((block-sblock)*BFS_BSIZE + off >= dir->i_size) { dir->i_size += BFS_DIRENT_SIZE; dir->i_ctime = CURRENT_TIME_SEC; } dir->i_mtime = CURRENT_TIME_SEC; mark_inode_dirty(dir); de->ino = cpu_to_le16((u16)ino); - for (i = 0; i < BFS_NAMELEN; i++) - de->name[i] = - (i < namelen) ? name[i] : 0; + for (i=0; iname[i] = (i < namelen) ? name[i] : 0; mark_buffer_dirty(bh); brelse(bh); return 0; @@ -323,26 +315,25 @@ static int bfs_add_entry(struct inode *dir, const unsigned char *name, return -ENOSPC; } -static inline int bfs_namecmp(int len, const unsigned char *name, - const char *buffer) +static inline int bfs_namecmp(int len, const unsigned char * name, const char * buffer) { - if ((len < BFS_NAMELEN) && buffer[len]) + if (len < BFS_NAMELEN && buffer[len]) return 0; return !memcmp(name, buffer, len); } -static struct buffer_head *bfs_find_entry(struct inode *dir, - const unsigned char *name, int namelen, - struct bfs_dirent **res_dir) +static struct buffer_head * bfs_find_entry(struct inode * dir, + const unsigned char * name, int namelen, struct bfs_dirent ** res_dir) { - unsigned long block = 0, offset = 0; - struct buffer_head *bh = NULL; - struct bfs_dirent *de; + unsigned long block, offset; + struct buffer_head * bh; + struct bfs_dirent * de; *res_dir = NULL; if (namelen > BFS_NAMELEN) return NULL; - + bh = NULL; + block = offset = 0; while (block * BFS_BSIZE + offset < dir->i_size) { if (!bh) { bh = sb_bread(dir->i_sb, BFS_I(dir)->i_sblock + block); @@ -353,8 +344,7 @@ static struct buffer_head *bfs_find_entry(struct inode *dir, } de = (struct bfs_dirent *)(bh->b_data + offset); offset += BFS_DIRENT_SIZE; - if (le16_to_cpu(de->ino) && - bfs_namecmp(namelen, name, de->name)) { + if (le16_to_cpu(de->ino) && bfs_namecmp(namelen, name, de->name)) { *res_dir = de; return bh; } diff --git a/trunk/fs/bfs/file.c b/trunk/fs/bfs/file.c index b11e63e8fbcd..911b4ccf470f 100644 --- a/trunk/fs/bfs/file.c +++ b/trunk/fs/bfs/file.c @@ -2,11 +2,6 @@ * fs/bfs/file.c * BFS file operations. * Copyright (C) 1999,2000 Tigran Aivazian - * - * Make the file block allocation algorithm understand the size - * of the underlying block device. - * Copyright (C) 2007 Dmitri Vorobiev - * */ #include @@ -32,8 +27,7 @@ const struct file_operations bfs_file_operations = { .splice_read = generic_file_splice_read, }; -static int bfs_move_block(unsigned long from, unsigned long to, - struct super_block *sb) +static int bfs_move_block(unsigned long from, unsigned long to, struct super_block *sb) { struct buffer_head *bh, *new; @@ -49,22 +43,21 @@ static int bfs_move_block(unsigned long from, unsigned long to, } static int bfs_move_blocks(struct super_block *sb, unsigned long start, - unsigned long end, unsigned long where) + unsigned long end, unsigned long where) { unsigned long i; dprintf("%08lx-%08lx->%08lx\n", start, end, where); for (i = start; i <= end; i++) if(bfs_move_block(i, where + i, sb)) { - dprintf("failed to move block %08lx -> %08lx\n", i, - where + i); + dprintf("failed to move block %08lx -> %08lx\n", i, where + i); return -EIO; } return 0; } -static int bfs_get_block(struct inode *inode, sector_t block, - struct buffer_head *bh_result, int create) +static int bfs_get_block(struct inode * inode, sector_t block, + struct buffer_head * bh_result, int create) { unsigned long phys; int err; @@ -73,6 +66,9 @@ static int bfs_get_block(struct inode *inode, sector_t block, struct bfs_inode_info *bi = BFS_I(inode); struct buffer_head *sbh = info->si_sbh; + if (block > info->si_blocks) + return -EIO; + phys = bi->i_sblock + block; if (!create) { if (phys <= bi->i_eblock) { @@ -83,29 +79,21 @@ static int bfs_get_block(struct inode *inode, sector_t block, return 0; } - /* - * If the file is not empty and the requested block is within the - * range of blocks allocated for this file, we can grant it. - */ - if (bi->i_sblock && (phys <= bi->i_eblock)) { + /* if the file is not empty and the requested block is within the range + of blocks allocated for this file, we can grant it */ + if (inode->i_size && phys <= bi->i_eblock) { dprintf("c=%d, b=%08lx, phys=%08lx (interim block granted)\n", create, (unsigned long)block, phys); map_bh(bh_result, sb, phys); return 0; } - /* The file will be extended, so let's see if there is enough space. */ - if (phys >= info->si_blocks) - return -ENOSPC; - - /* The rest has to be protected against itself. */ + /* the rest has to be protected against itself */ lock_kernel(); - /* - * If the last data block for this file is the last allocated - * block, we can extend the file trivially, without moving it - * anywhere. - */ + /* if the last data block for this file is the last allocated + block, we can extend the file trivially, without moving it + anywhere */ if (bi->i_eblock == info->si_lf_eblk) { dprintf("c=%d, b=%08lx, phys=%08lx (simple extension)\n", create, (unsigned long)block, phys); @@ -118,19 +106,13 @@ static int bfs_get_block(struct inode *inode, sector_t block, goto out; } - /* Ok, we have to move this entire file to the next free block. */ + /* Ok, we have to move this entire file to the next free block */ phys = info->si_lf_eblk + 1; - if (phys + block >= info->si_blocks) { - err = -ENOSPC; - goto out; - } - - if (bi->i_sblock) { + if (bi->i_sblock) { /* if data starts on block 0 then there is no data */ err = bfs_move_blocks(inode->i_sb, bi->i_sblock, - bi->i_eblock, phys); + bi->i_eblock, phys); if (err) { - dprintf("failed to move ino=%08lx -> fs corruption\n", - inode->i_ino); + dprintf("failed to move ino=%08lx -> fs corruption\n", inode->i_ino); goto out; } } else @@ -142,10 +124,8 @@ static int bfs_get_block(struct inode *inode, sector_t block, phys += block; info->si_lf_eblk = bi->i_eblock = phys; - /* - * This assumes nothing can write the inode back while we are here - * and thus update inode->i_blocks! (XXX) - */ + /* this assumes nothing can write the inode back while we are here + * and thus update inode->i_blocks! (XXX)*/ info->si_freeb -= bi->i_eblock - bi->i_sblock + 1 - inode->i_blocks; mark_inode_dirty(inode); mark_buffer_dirty(sbh); diff --git a/trunk/fs/bfs/inode.c b/trunk/fs/bfs/inode.c index 294c41baef6e..7bd9c2bbe6ee 100644 --- a/trunk/fs/bfs/inode.c +++ b/trunk/fs/bfs/inode.c @@ -30,26 +30,25 @@ MODULE_LICENSE("GPL"); #define dprintf(x...) #endif -void dump_imap(const char *prefix, struct super_block *s); +void dump_imap(const char *prefix, struct super_block * s); -static void bfs_read_inode(struct inode *inode) +static void bfs_read_inode(struct inode * inode) { unsigned long ino = inode->i_ino; - struct bfs_inode *di; - struct buffer_head *bh; + struct bfs_inode * di; + struct buffer_head * bh; int block, off; - if ((ino < BFS_ROOT_INO) || (ino > BFS_SB(inode->i_sb)->si_lasti)) { + if (ino < BFS_ROOT_INO || ino > BFS_SB(inode->i_sb)->si_lasti) { printf("Bad inode number %s:%08lx\n", inode->i_sb->s_id, ino); make_bad_inode(inode); return; } - block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1; + block = (ino - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1; bh = sb_bread(inode->i_sb, block); if (!bh) { - printf("Unable to read inode %s:%08lx\n", inode->i_sb->s_id, - ino); + printf("Unable to read inode %s:%08lx\n", inode->i_sb->s_id, ino); make_bad_inode(inode); return; } @@ -57,7 +56,7 @@ static void bfs_read_inode(struct inode *inode) off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK; di = (struct bfs_inode *)bh->b_data + off; - inode->i_mode = 0x0000FFFF & le32_to_cpu(di->i_mode); + inode->i_mode = 0x0000FFFF & le32_to_cpu(di->i_mode); if (le32_to_cpu(di->i_vtype) == BFS_VDIR) { inode->i_mode |= S_IFDIR; inode->i_op = &bfs_dir_inops; @@ -71,48 +70,48 @@ static void bfs_read_inode(struct inode *inode) BFS_I(inode)->i_sblock = le32_to_cpu(di->i_sblock); BFS_I(inode)->i_eblock = le32_to_cpu(di->i_eblock); - BFS_I(inode)->i_dsk_ino = le16_to_cpu(di->i_ino); inode->i_uid = le32_to_cpu(di->i_uid); inode->i_gid = le32_to_cpu(di->i_gid); inode->i_nlink = le32_to_cpu(di->i_nlink); inode->i_size = BFS_FILESIZE(di); inode->i_blocks = BFS_FILEBLOCKS(di); + if (inode->i_size || inode->i_blocks) dprintf("Registered inode with %lld size, %ld blocks\n", inode->i_size, inode->i_blocks); inode->i_atime.tv_sec = le32_to_cpu(di->i_atime); inode->i_mtime.tv_sec = le32_to_cpu(di->i_mtime); inode->i_ctime.tv_sec = le32_to_cpu(di->i_ctime); inode->i_atime.tv_nsec = 0; inode->i_mtime.tv_nsec = 0; inode->i_ctime.tv_nsec = 0; + BFS_I(inode)->i_dsk_ino = le16_to_cpu(di->i_ino); /* can be 0 so we store a copy */ brelse(bh); } -static int bfs_write_inode(struct inode *inode, int unused) +static int bfs_write_inode(struct inode * inode, int unused) { unsigned int ino = (u16)inode->i_ino; unsigned long i_sblock; - struct bfs_inode *di; - struct buffer_head *bh; + struct bfs_inode * di; + struct buffer_head * bh; int block, off; dprintf("ino=%08x\n", ino); - if ((ino < BFS_ROOT_INO) || (ino > BFS_SB(inode->i_sb)->si_lasti)) { + if (ino < BFS_ROOT_INO || ino > BFS_SB(inode->i_sb)->si_lasti) { printf("Bad inode number %s:%08x\n", inode->i_sb->s_id, ino); return -EIO; } lock_kernel(); - block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1; + block = (ino - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1; bh = sb_bread(inode->i_sb, block); if (!bh) { - printf("Unable to read inode %s:%08x\n", - inode->i_sb->s_id, ino); + printf("Unable to read inode %s:%08x\n", inode->i_sb->s_id, ino); unlock_kernel(); return -EIO; } - off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK; + off = (ino - BFS_ROOT_INO)%BFS_INODES_PER_BLOCK; di = (struct bfs_inode *)bh->b_data + off; if (ino == BFS_ROOT_INO) @@ -134,26 +133,27 @@ static int bfs_write_inode(struct inode *inode, int unused) di->i_eoffset = cpu_to_le32(i_sblock * BFS_BSIZE + inode->i_size - 1); mark_buffer_dirty(bh); + dprintf("Written ino=%d into %d:%d\n",le16_to_cpu(di->i_ino),block,off); brelse(bh); unlock_kernel(); return 0; } -static void bfs_delete_inode(struct inode *inode) +static void bfs_delete_inode(struct inode * inode) { unsigned long ino = inode->i_ino; - struct bfs_inode *di; - struct buffer_head *bh; + struct bfs_inode * di; + struct buffer_head * bh; int block, off; - struct super_block *s = inode->i_sb; - struct bfs_sb_info *info = BFS_SB(s); - struct bfs_inode_info *bi = BFS_I(inode); + struct super_block * s = inode->i_sb; + struct bfs_sb_info * info = BFS_SB(s); + struct bfs_inode_info * bi = BFS_I(inode); dprintf("ino=%08lx\n", ino); truncate_inode_pages(&inode->i_data, 0); - if ((ino < BFS_ROOT_INO) || (ino > info->si_lasti)) { + if (ino < BFS_ROOT_INO || ino > info->si_lasti) { printf("invalid ino=%08lx\n", ino); return; } @@ -162,35 +162,31 @@ static void bfs_delete_inode(struct inode *inode) inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; lock_kernel(); mark_inode_dirty(inode); - - block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1; + block = (ino - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1; bh = sb_bread(s, block); if (!bh) { - printf("Unable to read inode %s:%08lx\n", - inode->i_sb->s_id, ino); + printf("Unable to read inode %s:%08lx\n", inode->i_sb->s_id, ino); unlock_kernel(); return; } - off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK; - di = (struct bfs_inode *)bh->b_data + off; - memset((void *)di, 0, sizeof(struct bfs_inode)); - mark_buffer_dirty(bh); - brelse(bh); - + off = (ino - BFS_ROOT_INO)%BFS_INODES_PER_BLOCK; + di = (struct bfs_inode *) bh->b_data + off; if (bi->i_dsk_ino) { - info->si_freeb += BFS_FILEBLOCKS(bi); + info->si_freeb += 1 + bi->i_eblock - bi->i_sblock; info->si_freei++; clear_bit(ino, info->si_imap); dump_imap("delete_inode", s); } + di->i_ino = 0; + di->i_sblock = 0; + mark_buffer_dirty(bh); + brelse(bh); - /* - * If this was the last file, make the previous block - * "last block of the last file" even if there is no - * real file there, saves us 1 gap. - */ - if (info->si_lf_eblk == bi->i_eblock) { - info->si_lf_eblk = bi->i_sblock - 1; + /* if this was the last file, make the previous + block "last files last block" even if there is no real file there, + saves us 1 gap */ + if (info->si_lf_eblk == BFS_I(inode)->i_eblock) { + info->si_lf_eblk = BFS_I(inode)->i_sblock - 1; mark_buffer_dirty(info->si_sbh); } unlock_kernel(); @@ -232,7 +228,7 @@ static void bfs_write_super(struct super_block *s) unlock_kernel(); } -static struct kmem_cache *bfs_inode_cachep; +static struct kmem_cache * bfs_inode_cachep; static struct inode *bfs_alloc_inode(struct super_block *sb) { @@ -283,7 +279,7 @@ static const struct super_operations bfs_sops = { .statfs = bfs_statfs, }; -void dump_imap(const char *prefix, struct super_block *s) +void dump_imap(const char *prefix, struct super_block * s) { #ifdef DEBUG int i; @@ -291,26 +287,25 @@ void dump_imap(const char *prefix, struct super_block *s) if (!tmpbuf) return; - for (i = BFS_SB(s)->si_lasti; i >= 0; i--) { - if (i > PAGE_SIZE - 100) break; + for (i=BFS_SB(s)->si_lasti; i>=0; i--) { + if (i > PAGE_SIZE-100) break; if (test_bit(i, BFS_SB(s)->si_imap)) strcat(tmpbuf, "1"); else strcat(tmpbuf, "0"); } - printf("BFS-fs: %s: lasti=%08lx <%s>\n", - prefix, BFS_SB(s)->si_lasti, tmpbuf); + printk(KERN_ERR "BFS-fs: %s: lasti=%08lx <%s>\n", prefix, BFS_SB(s)->si_lasti, tmpbuf); free_page((unsigned long)tmpbuf); #endif } static int bfs_fill_super(struct super_block *s, void *data, int silent) { - struct buffer_head *bh; - struct bfs_super_block *bfs_sb; - struct inode *inode; + struct buffer_head * bh; + struct bfs_super_block * bfs_sb; + struct inode * inode; unsigned i, imap_len; - struct bfs_sb_info *info; + struct bfs_sb_info * info; info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) @@ -334,14 +329,14 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent) s->s_magic = BFS_MAGIC; info->si_sbh = bh; - info->si_lasti = (le32_to_cpu(bfs_sb->s_start) - BFS_BSIZE) / - sizeof(struct bfs_inode) - + BFS_ROOT_INO - 1; - imap_len = (info->si_lasti / 8) + 1; + info->si_lasti = (le32_to_cpu(bfs_sb->s_start) - BFS_BSIZE)/sizeof(struct bfs_inode) + + BFS_ROOT_INO - 1; + + imap_len = info->si_lasti/8 + 1; info->si_imap = kzalloc(imap_len, GFP_KERNEL); if (!info->si_imap) goto out; - for (i = 0; i < BFS_ROOT_INO; i++) + for (i=0; isi_imap); s->s_op = &bfs_sops; @@ -357,15 +352,16 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent) goto out; } - info->si_blocks = (le32_to_cpu(bfs_sb->s_end) + 1) >> BFS_BSIZE_BITS; - info->si_freeb = (le32_to_cpu(bfs_sb->s_end) + 1 - - le32_to_cpu(bfs_sb->s_start)) >> BFS_BSIZE_BITS; + info->si_blocks = (le32_to_cpu(bfs_sb->s_end) + 1)>>BFS_BSIZE_BITS; /* for statfs(2) */ + info->si_freeb = (le32_to_cpu(bfs_sb->s_end) + 1 - le32_to_cpu(bfs_sb->s_start))>>BFS_BSIZE_BITS; info->si_freei = 0; info->si_lf_eblk = 0; + info->si_lf_sblk = 0; + info->si_lf_ioff = 0; bh = NULL; - for (i = BFS_ROOT_INO; i <= info->si_lasti; i++) { + for (i=BFS_ROOT_INO; i<=info->si_lasti; i++) { struct bfs_inode *di; - int block = (i - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1; + int block = (i - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1; int off = (i - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK; unsigned long sblock, eblock; @@ -388,8 +384,11 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent) sblock = le32_to_cpu(di->i_sblock); eblock = le32_to_cpu(di->i_eblock); - if (eblock > info->si_lf_eblk) + if (eblock > info->si_lf_eblk) { info->si_lf_eblk = eblock; + info->si_lf_sblk = sblock; + info->si_lf_ioff = BFS_INO2OFF(i); + } } brelse(bh); if (!(s->s_flags & MS_RDONLY)) { diff --git a/trunk/fs/ecryptfs/read_write.c b/trunk/fs/ecryptfs/read_write.c index 6b7474a4336a..2150edf9a58e 100644 --- a/trunk/fs/ecryptfs/read_write.c +++ b/trunk/fs/ecryptfs/read_write.c @@ -87,7 +87,7 @@ int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode, loff_t offset; int rc; - offset = ((((loff_t)page_for_lower->index) << PAGE_CACHE_SHIFT) + offset = ((((off_t)page_for_lower->index) << PAGE_CACHE_SHIFT) + offset_in_page); virt = kmap(page_for_lower); rc = ecryptfs_write_lower(ecryptfs_inode, virt, offset, size); diff --git a/trunk/fs/ext2/ioctl.c b/trunk/fs/ext2/ioctl.c index 320b2cb3d4d2..c2324d5fe4ac 100644 --- a/trunk/fs/ext2/ioctl.c +++ b/trunk/fs/ext2/ioctl.c @@ -47,11 +47,6 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, flags &= ~EXT2_DIRSYNC_FL; mutex_lock(&inode->i_mutex); - /* Is it quota file? Do not allow user to mess with it */ - if (IS_NOQUOTA(inode)) { - mutex_unlock(&inode->i_mutex); - return -EPERM; - } oldflags = ei->i_flags; /* diff --git a/trunk/fs/ext3/dir.c b/trunk/fs/ext3/dir.c index 8ca3bfd72427..c8e4ee3af1d0 100644 --- a/trunk/fs/ext3/dir.c +++ b/trunk/fs/ext3/dir.c @@ -67,7 +67,7 @@ int ext3_check_dir_entry (const char * function, struct inode * dir, unsigned long offset) { const char * error_msg = NULL; - const int rlen = ext3_rec_len_from_disk(de->rec_len); + const int rlen = le16_to_cpu(de->rec_len); if (rlen < EXT3_DIR_REC_LEN(1)) error_msg = "rec_len is smaller than minimal"; @@ -173,10 +173,10 @@ static int ext3_readdir(struct file * filp, * least that it is non-zero. A * failure will be detected in the * dirent test below. */ - if (ext3_rec_len_from_disk(de->rec_len) < + if (le16_to_cpu(de->rec_len) < EXT3_DIR_REC_LEN(1)) break; - i += ext3_rec_len_from_disk(de->rec_len); + i += le16_to_cpu(de->rec_len); } offset = i; filp->f_pos = (filp->f_pos & ~(sb->s_blocksize - 1)) @@ -197,7 +197,7 @@ static int ext3_readdir(struct file * filp, ret = stored; goto out; } - offset += ext3_rec_len_from_disk(de->rec_len); + offset += le16_to_cpu(de->rec_len); if (le32_to_cpu(de->inode)) { /* We might block in the next section * if the data destination is @@ -219,7 +219,7 @@ static int ext3_readdir(struct file * filp, goto revalidate; stored ++; } - filp->f_pos += ext3_rec_len_from_disk(de->rec_len); + filp->f_pos += le16_to_cpu(de->rec_len); } offset = 0; brelse (bh); diff --git a/trunk/fs/ext3/ioctl.c b/trunk/fs/ext3/ioctl.c index 023a070f55f1..4a2a02c95bf9 100644 --- a/trunk/fs/ext3/ioctl.c +++ b/trunk/fs/ext3/ioctl.c @@ -51,11 +51,6 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, flags &= ~EXT3_DIRSYNC_FL; mutex_lock(&inode->i_mutex); - /* Is it quota file? Do not allow user to mess with it */ - if (IS_NOQUOTA(inode)) { - mutex_unlock(&inode->i_mutex); - return -EPERM; - } oldflags = ei->i_flags; /* The JOURNAL_DATA flag is modifiable only by root */ diff --git a/trunk/fs/ext3/namei.c b/trunk/fs/ext3/namei.c index 4ab6f76e63d0..ec8170adac53 100644 --- a/trunk/fs/ext3/namei.c +++ b/trunk/fs/ext3/namei.c @@ -176,16 +176,6 @@ static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry, static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry, struct inode *inode); -/* - * p is at least 6 bytes before the end of page - */ -static inline struct ext3_dir_entry_2 * -ext3_next_entry(struct ext3_dir_entry_2 *p) -{ - return (struct ext3_dir_entry_2 *)((char *)p + - ext3_rec_len_from_disk(p->rec_len)); -} - /* * Future: use high four bits of block for coalesce-on-delete flags * Mask them off for now. @@ -290,7 +280,7 @@ static struct stats dx_show_leaf(struct dx_hash_info *hinfo, struct ext3_dir_ent space += EXT3_DIR_REC_LEN(de->name_len); names++; } - de = ext3_next_entry(de); + de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len)); } printk("(%i)\n", names); return (struct stats) { names, space, 1 }; @@ -556,6 +546,14 @@ static int ext3_htree_next_block(struct inode *dir, __u32 hash, } +/* + * p is at least 6 bytes before the end of page + */ +static inline struct ext3_dir_entry_2 *ext3_next_entry(struct ext3_dir_entry_2 *p) +{ + return (struct ext3_dir_entry_2 *)((char*)p + le16_to_cpu(p->rec_len)); +} + /* * This function fills a red-black tree with information from a * directory block. It returns the number directory entries loaded @@ -722,7 +720,7 @@ static int dx_make_map (struct ext3_dir_entry_2 *de, int size, cond_resched(); } /* XXX: do we need to check rec_len == 0 case? -Chris */ - de = ext3_next_entry(de); + de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len)); } return count; } @@ -824,7 +822,7 @@ static inline int search_dirblock(struct buffer_head * bh, return 1; } /* prevent looping on a bad block */ - de_len = ext3_rec_len_from_disk(de->rec_len); + de_len = le16_to_cpu(de->rec_len); if (de_len <= 0) return -1; offset += de_len; @@ -1132,7 +1130,7 @@ dx_move_dirents(char *from, char *to, struct dx_map_entry *map, int count) rec_len = EXT3_DIR_REC_LEN(de->name_len); memcpy (to, de, rec_len); ((struct ext3_dir_entry_2 *) to)->rec_len = - ext3_rec_len_to_disk(rec_len); + cpu_to_le16(rec_len); de->inode = 0; map++; to += rec_len; @@ -1151,12 +1149,13 @@ static struct ext3_dir_entry_2* dx_pack_dirents(char *base, int size) prev = to = de; while ((char*)de < base + size) { - next = ext3_next_entry(de); + next = (struct ext3_dir_entry_2 *) ((char *) de + + le16_to_cpu(de->rec_len)); if (de->inode && de->name_len) { rec_len = EXT3_DIR_REC_LEN(de->name_len); if (de > to) memmove(to, de, rec_len); - to->rec_len = ext3_rec_len_to_disk(rec_len); + to->rec_len = cpu_to_le16(rec_len); prev = to; to = (struct ext3_dir_entry_2 *) (((char *) to) + rec_len); } @@ -1230,8 +1229,8 @@ static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir, /* Fancy dance to stay within two buffers */ de2 = dx_move_dirents(data1, data2, map + split, count - split); de = dx_pack_dirents(data1,blocksize); - de->rec_len = ext3_rec_len_to_disk(data1 + blocksize - (char *) de); - de2->rec_len = ext3_rec_len_to_disk(data2 + blocksize - (char *) de2); + de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de); + de2->rec_len = cpu_to_le16(data2 + blocksize - (char *) de2); dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data1, blocksize, 1)); dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data2, blocksize, 1)); @@ -1301,7 +1300,7 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry, return -EEXIST; } nlen = EXT3_DIR_REC_LEN(de->name_len); - rlen = ext3_rec_len_from_disk(de->rec_len); + rlen = le16_to_cpu(de->rec_len); if ((de->inode? rlen - nlen: rlen) >= reclen) break; de = (struct ext3_dir_entry_2 *)((char *)de + rlen); @@ -1320,11 +1319,11 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry, /* By now the buffer is marked for journaling */ nlen = EXT3_DIR_REC_LEN(de->name_len); - rlen = ext3_rec_len_from_disk(de->rec_len); + rlen = le16_to_cpu(de->rec_len); if (de->inode) { struct ext3_dir_entry_2 *de1 = (struct ext3_dir_entry_2 *)((char *)de + nlen); - de1->rec_len = ext3_rec_len_to_disk(rlen - nlen); - de->rec_len = ext3_rec_len_to_disk(nlen); + de1->rec_len = cpu_to_le16(rlen - nlen); + de->rec_len = cpu_to_le16(nlen); de = de1; } de->file_type = EXT3_FT_UNKNOWN; @@ -1401,18 +1400,17 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry, /* The 0th block becomes the root, move the dirents out */ fde = &root->dotdot; - de = (struct ext3_dir_entry_2 *)((char *)fde + - ext3_rec_len_from_disk(fde->rec_len)); + de = (struct ext3_dir_entry_2 *)((char *)fde + le16_to_cpu(fde->rec_len)); len = ((char *) root) + blocksize - (char *) de; memcpy (data1, de, len); de = (struct ext3_dir_entry_2 *) data1; top = data1 + len; - while ((char *)(de2 = ext3_next_entry(de)) < top) + while ((char *)(de2=(void*)de+le16_to_cpu(de->rec_len)) < top) de = de2; - de->rec_len = ext3_rec_len_to_disk(data1 + blocksize - (char *) de); + de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de); /* Initialize the root; the dot dirents already exist */ de = (struct ext3_dir_entry_2 *) (&root->dotdot); - de->rec_len = ext3_rec_len_to_disk(blocksize - EXT3_DIR_REC_LEN(2)); + de->rec_len = cpu_to_le16(blocksize - EXT3_DIR_REC_LEN(2)); memset (&root->info, 0, sizeof(root->info)); root->info.info_length = sizeof(root->info); root->info.hash_version = EXT3_SB(dir->i_sb)->s_def_hash_version; @@ -1492,7 +1490,7 @@ static int ext3_add_entry (handle_t *handle, struct dentry *dentry, return retval; de = (struct ext3_dir_entry_2 *) bh->b_data; de->inode = 0; - de->rec_len = ext3_rec_len_to_disk(blocksize); + de->rec_len = cpu_to_le16(blocksize); return add_dirent_to_buf(handle, dentry, inode, de, bh); } @@ -1555,7 +1553,7 @@ static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry, goto cleanup; node2 = (struct dx_node *)(bh2->b_data); entries2 = node2->entries; - node2->fake.rec_len = ext3_rec_len_to_disk(sb->s_blocksize); + node2->fake.rec_len = cpu_to_le16(sb->s_blocksize); node2->fake.inode = 0; BUFFER_TRACE(frame->bh, "get_write_access"); err = ext3_journal_get_write_access(handle, frame->bh); @@ -1653,9 +1651,9 @@ static int ext3_delete_entry (handle_t *handle, BUFFER_TRACE(bh, "get_write_access"); ext3_journal_get_write_access(handle, bh); if (pde) - pde->rec_len = ext3_rec_len_to_disk( - ext3_rec_len_from_disk(pde->rec_len) + - ext3_rec_len_from_disk(de->rec_len)); + pde->rec_len = + cpu_to_le16(le16_to_cpu(pde->rec_len) + + le16_to_cpu(de->rec_len)); else de->inode = 0; dir->i_version++; @@ -1663,9 +1661,10 @@ static int ext3_delete_entry (handle_t *handle, ext3_journal_dirty_metadata(handle, bh); return 0; } - i += ext3_rec_len_from_disk(de->rec_len); + i += le16_to_cpu(de->rec_len); pde = de; - de = ext3_next_entry(de); + de = (struct ext3_dir_entry_2 *) + ((char *) de + le16_to_cpu(de->rec_len)); } return -ENOENT; } @@ -1799,13 +1798,13 @@ static int ext3_mkdir(struct inode * dir, struct dentry * dentry, int mode) de = (struct ext3_dir_entry_2 *) dir_block->b_data; de->inode = cpu_to_le32(inode->i_ino); de->name_len = 1; - de->rec_len = ext3_rec_len_to_disk(EXT3_DIR_REC_LEN(de->name_len)); + de->rec_len = cpu_to_le16(EXT3_DIR_REC_LEN(de->name_len)); strcpy (de->name, "."); ext3_set_de_type(dir->i_sb, de, S_IFDIR); - de = ext3_next_entry(de); + de = (struct ext3_dir_entry_2 *) + ((char *) de + le16_to_cpu(de->rec_len)); de->inode = cpu_to_le32(dir->i_ino); - de->rec_len = ext3_rec_len_to_disk(inode->i_sb->s_blocksize - - EXT3_DIR_REC_LEN(1)); + de->rec_len = cpu_to_le16(inode->i_sb->s_blocksize-EXT3_DIR_REC_LEN(1)); de->name_len = 2; strcpy (de->name, ".."); ext3_set_de_type(dir->i_sb, de, S_IFDIR); @@ -1857,7 +1856,8 @@ static int empty_dir (struct inode * inode) return 1; } de = (struct ext3_dir_entry_2 *) bh->b_data; - de1 = ext3_next_entry(de); + de1 = (struct ext3_dir_entry_2 *) + ((char *) de + le16_to_cpu(de->rec_len)); if (le32_to_cpu(de->inode) != inode->i_ino || !le32_to_cpu(de1->inode) || strcmp (".", de->name) || @@ -1868,9 +1868,9 @@ static int empty_dir (struct inode * inode) brelse (bh); return 1; } - offset = ext3_rec_len_from_disk(de->rec_len) + - ext3_rec_len_from_disk(de1->rec_len); - de = ext3_next_entry(de1); + offset = le16_to_cpu(de->rec_len) + le16_to_cpu(de1->rec_len); + de = (struct ext3_dir_entry_2 *) + ((char *) de1 + le16_to_cpu(de1->rec_len)); while (offset < inode->i_size ) { if (!bh || (void *) de >= (void *) (bh->b_data+sb->s_blocksize)) { @@ -1899,8 +1899,9 @@ static int empty_dir (struct inode * inode) brelse (bh); return 0; } - offset += ext3_rec_len_from_disk(de->rec_len); - de = ext3_next_entry(de); + offset += le16_to_cpu(de->rec_len); + de = (struct ext3_dir_entry_2 *) + ((char *) de + le16_to_cpu(de->rec_len)); } brelse (bh); return 1; @@ -2254,7 +2255,8 @@ static int ext3_link (struct dentry * old_dentry, } #define PARENT_INO(buffer) \ - (ext3_next_entry((struct ext3_dir_entry_2 *)(buffer))->inode) + ((struct ext3_dir_entry_2 *) ((char *) buffer + \ + le16_to_cpu(((struct ext3_dir_entry_2 *) buffer)->rec_len)))->inode /* * Anybody can rename anything with this: the permission checks are left to the diff --git a/trunk/fs/ext4/ioctl.c b/trunk/fs/ext4/ioctl.c index e7f894bdb420..c04c7ccba9e3 100644 --- a/trunk/fs/ext4/ioctl.c +++ b/trunk/fs/ext4/ioctl.c @@ -51,11 +51,6 @@ int ext4_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, flags &= ~EXT4_DIRSYNC_FL; mutex_lock(&inode->i_mutex); - /* Is it quota file? Do not allow user to mess with it */ - if (IS_NOQUOTA(inode)) { - mutex_unlock(&inode->i_mutex); - return -EPERM; - } oldflags = ei->i_flags; /* The JOURNAL_DATA flag is modifiable only by root */ diff --git a/trunk/fs/fuse/file.c b/trunk/fs/fuse/file.c index 535b37399009..0fcdba9d47c0 100644 --- a/trunk/fs/fuse/file.c +++ b/trunk/fs/fuse/file.c @@ -55,10 +55,9 @@ struct fuse_file *fuse_file_alloc(void) if (!ff->reserved_req) { kfree(ff); ff = NULL; - } else { - INIT_LIST_HEAD(&ff->write_entry); - atomic_set(&ff->count, 0); } + INIT_LIST_HEAD(&ff->write_entry); + atomic_set(&ff->count, 0); } return ff; } diff --git a/trunk/fs/hugetlbfs/inode.c b/trunk/fs/hugetlbfs/inode.c index 09ee07f02663..12aca8ed605f 100644 --- a/trunk/fs/hugetlbfs/inode.c +++ b/trunk/fs/hugetlbfs/inode.c @@ -364,6 +364,7 @@ static void truncate_hugepages(struct inode *inode, loff_t lstart) ++next; truncate_huge_page(page); unlock_page(page); + hugetlb_put_quota(mapping); freed++; } huge_pagevec_release(&pvec); @@ -858,15 +859,15 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent) return -ENOMEM; } -int hugetlb_get_quota(struct address_space *mapping, long delta) +int hugetlb_get_quota(struct address_space *mapping) { int ret = 0; struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(mapping->host->i_sb); if (sbinfo->free_blocks > -1) { spin_lock(&sbinfo->stat_lock); - if (sbinfo->free_blocks - delta >= 0) - sbinfo->free_blocks -= delta; + if (sbinfo->free_blocks > 0) + sbinfo->free_blocks--; else ret = -ENOMEM; spin_unlock(&sbinfo->stat_lock); @@ -875,13 +876,13 @@ int hugetlb_get_quota(struct address_space *mapping, long delta) return ret; } -void hugetlb_put_quota(struct address_space *mapping, long delta) +void hugetlb_put_quota(struct address_space *mapping) { struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(mapping->host->i_sb); if (sbinfo->free_blocks > -1) { spin_lock(&sbinfo->stat_lock); - sbinfo->free_blocks += delta; + sbinfo->free_blocks++; spin_unlock(&sbinfo->stat_lock); } } diff --git a/trunk/fs/jfs/ioctl.c b/trunk/fs/jfs/ioctl.c index dfda12a073e1..3c8663bea98c 100644 --- a/trunk/fs/jfs/ioctl.c +++ b/trunk/fs/jfs/ioctl.c @@ -79,9 +79,6 @@ int jfs_ioctl(struct inode * inode, struct file * filp, unsigned int cmd, if (!S_ISDIR(inode->i_mode)) flags &= ~JFS_DIRSYNC_FL; - /* Is it quota file? Do not allow user to mess with it */ - if (IS_NOQUOTA(inode)) - return -EPERM; jfs_get_inode_flags(jfs_inode); oldflags = jfs_inode->mode2; diff --git a/trunk/fs/open.c b/trunk/fs/open.c index 4932b4d1da05..3b69c53e1837 100644 --- a/trunk/fs/open.c +++ b/trunk/fs/open.c @@ -1061,7 +1061,7 @@ asmlinkage long sys_open(const char __user *filename, int flags, int mode) prevent_tail_call(ret); return ret; } -EXPORT_UNUSED_SYMBOL_GPL(sys_open); /* To be deleted for 2.6.25 */ +EXPORT_SYMBOL_GPL(sys_open); asmlinkage long sys_openat(int dfd, const char __user *filename, int flags, int mode) diff --git a/trunk/fs/proc/base.c b/trunk/fs/proc/base.c index a17c26859074..aeaf0d0f2f51 100644 --- a/trunk/fs/proc/base.c +++ b/trunk/fs/proc/base.c @@ -2328,18 +2328,21 @@ static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid) void proc_flush_task(struct task_struct *task) { - int i; - struct pid *pid, *tgid = NULL; + int i, leader; + struct pid *pid, *tgid; struct upid *upid; + leader = thread_group_leader(task); + proc_flush_task_mnt(proc_mnt, task->pid, leader ? task->tgid : 0); pid = task_pid(task); - if (thread_group_leader(task)) - tgid = task_tgid(task); + if (pid->level == 0) + return; - for (i = 0; i <= pid->level; i++) { + tgid = task_tgid(task); + for (i = 1; i <= pid->level; i++) { upid = &pid->numbers[i]; proc_flush_task_mnt(upid->ns->proc_mnt, upid->nr, - tgid ? tgid->numbers[i].nr : 0); + leader ? 0 : tgid->numbers[i].nr); } upid = &pid->numbers[pid->level]; diff --git a/trunk/fs/proc/generic.c b/trunk/fs/proc/generic.c index a9806bc21ec3..1bdb62435758 100644 --- a/trunk/fs/proc/generic.c +++ b/trunk/fs/proc/generic.c @@ -561,33 +561,28 @@ static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp static void proc_kill_inodes(struct proc_dir_entry *de) { struct list_head *p; - struct super_block *sb; + struct super_block *sb = proc_mnt->mnt_sb; /* * Actually it's a partial revoke(). */ - spin_lock(&sb_lock); - list_for_each_entry(sb, &proc_fs_type.fs_supers, s_instances) { - file_list_lock(); - list_for_each(p, &sb->s_files) { - struct file *filp = list_entry(p, struct file, - f_u.fu_list); - struct dentry *dentry = filp->f_path.dentry; - struct inode *inode; - const struct file_operations *fops; - - if (dentry->d_op != &proc_dentry_operations) - continue; - inode = dentry->d_inode; - if (PDE(inode) != de) - continue; - fops = filp->f_op; - filp->f_op = NULL; - fops_put(fops); - } - file_list_unlock(); + file_list_lock(); + list_for_each(p, &sb->s_files) { + struct file * filp = list_entry(p, struct file, f_u.fu_list); + struct dentry * dentry = filp->f_path.dentry; + struct inode * inode; + const struct file_operations *fops; + + if (dentry->d_op != &proc_dentry_operations) + continue; + inode = dentry->d_inode; + if (PDE(inode) != de) + continue; + fops = filp->f_op; + filp->f_op = NULL; + fops_put(fops); } - spin_unlock(&sb_lock); + file_list_unlock(); } static struct proc_dir_entry *proc_create(struct proc_dir_entry **parent, diff --git a/trunk/fs/proc/internal.h b/trunk/fs/proc/internal.h index 1b2b6c6bb475..1820eb2ef762 100644 --- a/trunk/fs/proc/internal.h +++ b/trunk/fs/proc/internal.h @@ -78,5 +78,3 @@ static inline int proc_fd(struct inode *inode) { return PROC_I(inode)->fd; } - -extern struct file_system_type proc_fs_type; diff --git a/trunk/fs/proc/root.c b/trunk/fs/proc/root.c index 1f86bb860e04..ec9cb3b6c93b 100644 --- a/trunk/fs/proc/root.c +++ b/trunk/fs/proc/root.c @@ -98,7 +98,7 @@ static void proc_kill_sb(struct super_block *sb) put_pid_ns(ns); } -struct file_system_type proc_fs_type = { +static struct file_system_type proc_fs_type = { .name = "proc", .get_sb = proc_get_sb, .kill_sb = proc_kill_sb, diff --git a/trunk/fs/read_write.c b/trunk/fs/read_write.c index ea1f94cc722e..124693e8d3fa 100644 --- a/trunk/fs/read_write.c +++ b/trunk/fs/read_write.c @@ -370,7 +370,7 @@ asmlinkage ssize_t sys_read(unsigned int fd, char __user * buf, size_t count) return ret; } -EXPORT_UNUSED_SYMBOL_GPL(sys_read); /* to be deleted for 2.6.25 */ +EXPORT_SYMBOL_GPL(sys_read); asmlinkage ssize_t sys_write(unsigned int fd, const char __user * buf, size_t count) { diff --git a/trunk/fs/reiserfs/ioctl.c b/trunk/fs/reiserfs/ioctl.c index e0f0f098a523..c438a8f83f26 100644 --- a/trunk/fs/reiserfs/ioctl.c +++ b/trunk/fs/reiserfs/ioctl.c @@ -57,9 +57,6 @@ int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, if (get_user(flags, (int __user *)arg)) return -EFAULT; - /* Is it quota file? Do not allow user to mess with it. */ - if (IS_NOQUOTA(inode)) - return -EPERM; if (((flags ^ REISERFS_I(inode)-> i_attrs) & (REISERFS_IMMUTABLE_FL | REISERFS_APPEND_FL)) diff --git a/trunk/fs/reiserfs/stree.c b/trunk/fs/reiserfs/stree.c index d2db2417b2bd..ca41567d7890 100644 --- a/trunk/fs/reiserfs/stree.c +++ b/trunk/fs/reiserfs/stree.c @@ -1458,6 +1458,9 @@ static void unmap_buffers(struct page *page, loff_t pos) } bh = next; } while (bh != head); + if (PAGE_SIZE == bh->b_size) { + cancel_dirty_page(page, PAGE_CACHE_SIZE); + } } } } diff --git a/trunk/fs/smbfs/file.c b/trunk/fs/smbfs/file.c index efbe29af3d7a..f5d14cebc75a 100644 --- a/trunk/fs/smbfs/file.c +++ b/trunk/fs/smbfs/file.c @@ -234,7 +234,7 @@ smb_file_aio_read(struct kiocb *iocb, const struct iovec *iov, VERBOSE("before read, size=%ld, flags=%x, atime=%ld\n", (long)dentry->d_inode->i_size, - dentry->d_inode->i_flags, dentry->d_inode->i_atime.tv_sec); + dentry->d_inode->i_flags, dentry->d_inode->i_atime); status = generic_file_aio_read(iocb, iov, nr_segs, pos); out: @@ -269,7 +269,7 @@ smb_file_splice_read(struct file *file, loff_t *ppos, struct dentry *dentry = file->f_path.dentry; ssize_t status; - VERBOSE("file %s/%s, pos=%Ld, count=%lu\n", + VERBOSE("file %s/%s, pos=%Ld, count=%d\n", DENTRY_PATH(dentry), *ppos, count); status = smb_revalidate_inode(dentry); @@ -363,8 +363,7 @@ smb_file_aio_write(struct kiocb *iocb, const struct iovec *iov, result = generic_file_aio_write(iocb, iov, nr_segs, pos); VERBOSE("pos=%ld, size=%ld, mtime=%ld, atime=%ld\n", (long) file->f_pos, (long) dentry->d_inode->i_size, - dentry->d_inode->i_mtime.tv_sec, - dentry->d_inode->i_atime.tv_sec); + dentry->d_inode->i_mtime, dentry->d_inode->i_atime); } out: return result; diff --git a/trunk/fs/smbfs/inode.c b/trunk/fs/smbfs/inode.c index 9416ead0c7aa..ab517755ece0 100644 --- a/trunk/fs/smbfs/inode.c +++ b/trunk/fs/smbfs/inode.c @@ -536,7 +536,7 @@ static int smb_fill_super(struct super_block *sb, void *raw_data, int silent) /* Allocate the global temp buffer and some superblock helper structs */ /* FIXME: move these to the smb_sb_info struct */ - VERBOSE("alloc chunk = %lu\n", sizeof(struct smb_ops) + + VERBOSE("alloc chunk = %d\n", sizeof(struct smb_ops) + sizeof(struct smb_mount_data_kernel)); mem = kmalloc(sizeof(struct smb_ops) + sizeof(struct smb_mount_data_kernel), GFP_KERNEL); diff --git a/trunk/fs/smbfs/proc.c b/trunk/fs/smbfs/proc.c index d517a27b7f4b..feac46050619 100644 --- a/trunk/fs/smbfs/proc.c +++ b/trunk/fs/smbfs/proc.c @@ -2593,7 +2593,7 @@ smb_proc_getattr_ff(struct smb_sb_info *server, struct dentry *dentry, fattr->f_mtime.tv_sec = date_dos2unix(server, date, time); fattr->f_mtime.tv_nsec = 0; VERBOSE("name=%s, date=%x, time=%x, mtime=%ld\n", - mask, date, time, fattr->f_mtime.tv_sec); + mask, date, time, fattr->f_mtime); fattr->f_size = DVAL(req->rq_data, 12); /* ULONG allocation size */ fattr->attr = WVAL(req->rq_data, 20); diff --git a/trunk/fs/smbfs/smbiod.c b/trunk/fs/smbfs/smbiod.c index fae8e85af0ed..283c5720c9de 100644 --- a/trunk/fs/smbfs/smbiod.c +++ b/trunk/fs/smbfs/smbiod.c @@ -227,7 +227,7 @@ int smbiod_retry(struct smb_sb_info *server) printk(KERN_ERR "smb_retry: signal failed [%d]\n", result); goto out; } - VERBOSE("signalled pid %d\n", pid_nr(pid)); + VERBOSE("signalled pid %d\n", pid); /* FIXME: The retried requests should perhaps get a "time boost". */ diff --git a/trunk/include/asm-cris/atomic.h b/trunk/include/asm-cris/atomic.h index 2949a945876a..0b51a87e5532 100644 --- a/trunk/include/asm-cris/atomic.h +++ b/trunk/include/asm-cris/atomic.h @@ -3,8 +3,6 @@ #ifndef __ASM_CRIS_ATOMIC__ #define __ASM_CRIS_ATOMIC__ -#include - #include #include diff --git a/trunk/include/asm-cris/checksum.h b/trunk/include/asm-cris/checksum.h index c6c5be62c698..180dbf2757b0 100644 --- a/trunk/include/asm-cris/checksum.h +++ b/trunk/include/asm-cris/checksum.h @@ -62,7 +62,7 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) * returns a 16-bit checksum, already complemented */ -static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, +static inline __sum16 int csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, unsigned short proto, __wsum sum) diff --git a/trunk/include/asm-cris/ethernet.h b/trunk/include/asm-cris/ethernet.h index 4d58652c3a49..30da58a7d00d 100644 --- a/trunk/include/asm-cris/ethernet.h +++ b/trunk/include/asm-cris/ethernet.h @@ -15,7 +15,4 @@ #define SET_ETH_DUPLEX_AUTO SIOCDEVPRIVATE+3 /* Auto neg duplex */ #define SET_ETH_DUPLEX_HALF SIOCDEVPRIVATE+4 /* Full duplex */ #define SET_ETH_DUPLEX_FULL SIOCDEVPRIVATE+5 /* Half duplex */ -#define SET_ETH_ENABLE_LEDS SIOCDEVPRIVATE+6 /* Enable net LEDs */ -#define SET_ETH_DISABLE_LEDS SIOCDEVPRIVATE+7 /* Disable net LEDs */ -#define SET_ETH_AUTONEG SIOCDEVPRIVATE+8 #endif /* _CRIS_ETHERNET_H */ diff --git a/trunk/include/asm-cris/fasttimer.h b/trunk/include/asm-cris/fasttimer.h index 8f8a8d6c9653..a3a77132ce32 100644 --- a/trunk/include/asm-cris/fasttimer.h +++ b/trunk/include/asm-cris/fasttimer.h @@ -1,8 +1,9 @@ -/* +/* $Id: fasttimer.h,v 1.3 2004/05/14 10:19:19 starvik Exp $ * linux/include/asm-cris/fasttimer.h * * Fast timers for ETRAX100LX - * Copyright (C) 2000-2007 Axis Communications AB + * This may be useful in other OS than Linux so use 2 space indentation... + * Copyright (C) 2000, 2002 Axis Communications AB */ #include /* struct timeval */ #include @@ -11,16 +12,11 @@ typedef void fast_timer_function_type(unsigned long); -struct fasttime_t { - unsigned long tv_jiff; /* jiffies */ - unsigned long tv_usec; /* microseconds */ -}; - struct fast_timer{ /* Close to timer_list */ struct fast_timer *next; struct fast_timer *prev; - struct fasttime_t tv_set; - struct fasttime_t tv_expires; + struct timeval tv_set; + struct timeval tv_expires; unsigned long delay_us; fast_timer_function_type *function; unsigned long data; @@ -42,6 +38,6 @@ int del_fast_timer(struct fast_timer * t); void schedule_usleep(unsigned long us); -int fast_timer_init(void); +void fast_timer_init(void); #endif diff --git a/trunk/include/asm-cris/hardirq.h b/trunk/include/asm-cris/hardirq.h index 74178adeb1cd..1c13dd3faac3 100644 --- a/trunk/include/asm-cris/hardirq.h +++ b/trunk/include/asm-cris/hardirq.h @@ -1,7 +1,6 @@ #ifndef __ASM_HARDIRQ_H #define __ASM_HARDIRQ_H -#include #include #include diff --git a/trunk/include/asm-cris/posix_types.h b/trunk/include/asm-cris/posix_types.h index 3a5e4c43eae7..92000d0c3f97 100644 --- a/trunk/include/asm-cris/posix_types.h +++ b/trunk/include/asm-cris/posix_types.h @@ -52,6 +52,7 @@ typedef struct { } __kernel_fsid_t; #ifdef __KERNEL__ +#include #undef __FD_SET #define __FD_SET(fd,fdsetp) set_bit(fd, (void *)(fdsetp)) diff --git a/trunk/include/asm-cris/termbits.h b/trunk/include/asm-cris/termbits.h index 66e1a7492a0c..71c1b36269b8 100644 --- a/trunk/include/asm-cris/termbits.h +++ b/trunk/include/asm-cris/termbits.h @@ -171,19 +171,6 @@ struct ktermios { #define B115200 0010002 #define B230400 0010003 #define B460800 0010004 - -/* Unsupported rates, but needed to avoid compile error. */ -#define B500000 0010005 -#define B576000 0010006 -#define B1000000 0010010 -#define B1152000 0010011 -#define B1500000 0010012 -#define B2000000 0010013 -#define B2500000 0010014 -#define B3000000 0010015 -#define B3500000 0010016 -#define B4000000 0010017 - /* etrax supports these additional three baud rates */ #define B921600 0010005 #define B1843200 0010006 diff --git a/trunk/include/asm-cris/thread_info.h b/trunk/include/asm-cris/thread_info.h index 784668ab0fa2..fde39f6c49c7 100644 --- a/trunk/include/asm-cris/thread_info.h +++ b/trunk/include/asm-cris/thread_info.h @@ -32,7 +32,6 @@ struct thread_info { unsigned long flags; /* low level flags */ __u32 cpu; /* current CPU */ int preempt_count; /* 0 => preemptable, <0 => BUG */ - __u32 tls; /* TLS for this thread */ mm_segment_t addr_limit; /* thread address space: 0-0xBFFFFFFF for user-thead @@ -80,18 +79,14 @@ struct thread_info { * - other flags in MSW */ #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ -#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */ -#define TIF_SIGPENDING 2 /* signal pending */ -#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ -#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */ +#define TIF_SIGPENDING 1 /* signal pending */ +#define TIF_NEED_RESCHED 2 /* rescheduling necessary */ #define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_MEMDIE 17 #define _TIF_SYSCALL_TRACE (1< - #include /* diff --git a/trunk/include/asm-cris/unistd.h b/trunk/include/asm-cris/unistd.h index 6f2d924f4fd6..7c90fa970c38 100644 --- a/trunk/include/asm-cris/unistd.h +++ b/trunk/include/asm-cris/unistd.h @@ -255,7 +255,6 @@ #define __NR_io_submit 248 #define __NR_io_cancel 249 #define __NR_fadvise64 250 -/* 251 is available for reuse (was briefly sys_set_zone_reclaim) */ #define __NR_exit_group 252 #define __NR_lookup_dcookie 253 #define __NR_epoll_create 254 @@ -293,46 +292,10 @@ #define __NR_add_key 286 #define __NR_request_key 287 #define __NR_keyctl 288 -#define __NR_ioprio_set 289 -#define __NR_ioprio_get 290 -#define __NR_inotify_init 291 -#define __NR_inotify_add_watch 292 -#define __NR_inotify_rm_watch 293 -#define __NR_migrate_pages 294 -#define __NR_openat 295 -#define __NR_mkdirat 296 -#define __NR_mknodat 297 -#define __NR_fchownat 298 -#define __NR_futimesat 299 -#define __NR_fstatat64 300 -#define __NR_unlinkat 301 -#define __NR_renameat 302 -#define __NR_linkat 303 -#define __NR_symlinkat 304 -#define __NR_readlinkat 305 -#define __NR_fchmodat 306 -#define __NR_faccessat 307 -#define __NR_pselect6 308 -#define __NR_ppoll 309 -#define __NR_unshare 310 -#define __NR_set_robust_list 311 -#define __NR_get_robust_list 312 -#define __NR_splice 313 -#define __NR_sync_file_range 314 -#define __NR_tee 315 -#define __NR_vmsplice 316 -#define __NR_move_pages 317 -#define __NR_getcpu 318 -#define __NR_epoll_pwait 319 -#define __NR_utimensat 320 -#define __NR_signalfd 321 -#define __NR_timerfd 322 -#define __NR_eventfd 323 -#define __NR_fallocate 324 #ifdef __KERNEL__ -#define NR_syscalls 325 +#define NR_syscalls 289 #include diff --git a/trunk/include/asm-um/pgtable-3level.h b/trunk/include/asm-um/pgtable-3level.h index 3ebafbaacb24..aa82b88db805 100644 --- a/trunk/include/asm-um/pgtable-3level.h +++ b/trunk/include/asm-um/pgtable-3level.h @@ -71,7 +71,7 @@ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) static inline void pud_clear (pud_t *pud) { - set_pud(pud, __pud(_PAGE_NEWPAGE)); + set_pud(pud, __pud(0)); } #define pud_page(pud) phys_to_page(pud_val(pud) & PAGE_MASK) diff --git a/trunk/include/asm-x86/ptrace.h b/trunk/include/asm-x86/ptrace.h index 51ddb2590870..213c97300cb3 100644 --- a/trunk/include/asm-x86/ptrace.h +++ b/trunk/include/asm-x86/ptrace.h @@ -60,7 +60,7 @@ static inline int v8086_mode(struct pt_regs *regs) #define instruction_pointer(regs) ((regs)->eip) #define frame_pointer(regs) ((regs)->ebp) -#define stack_pointer(regs) ((unsigned long)(regs)) +#define stack_pointer(regs) ((regs)->esp) #define regs_return_value(regs) ((regs)->eax) extern unsigned long profile_pc(struct pt_regs *regs); diff --git a/trunk/include/linux/cgroup_subsys.h b/trunk/include/linux/cgroup_subsys.h index d62fcee9a08a..0b9bfbde8168 100644 --- a/trunk/include/linux/cgroup_subsys.h +++ b/trunk/include/linux/cgroup_subsys.h @@ -13,6 +13,12 @@ SUBSYS(cpuset) /* */ +#ifdef CONFIG_CGROUP_CPUACCT +SUBSYS(cpuacct) +#endif + +/* */ + #ifdef CONFIG_CGROUP_DEBUG SUBSYS(debug) #endif diff --git a/trunk/include/linux/cpu_acct.h b/trunk/include/linux/cpu_acct.h new file mode 100644 index 000000000000..6b5fd8a66c8d --- /dev/null +++ b/trunk/include/linux/cpu_acct.h @@ -0,0 +1,14 @@ + +#ifndef _LINUX_CPU_ACCT_H +#define _LINUX_CPU_ACCT_H + +#include +#include + +#ifdef CONFIG_CGROUP_CPUACCT +extern void cpuacct_charge(struct task_struct *, cputime_t cputime); +#else +static void inline cpuacct_charge(struct task_struct *p, cputime_t cputime) {} +#endif + +#endif diff --git a/trunk/include/linux/ext3_fs.h b/trunk/include/linux/ext3_fs.h index 241c01cb92b2..64134456ed8c 100644 --- a/trunk/include/linux/ext3_fs.h +++ b/trunk/include/linux/ext3_fs.h @@ -656,26 +656,6 @@ struct ext3_dir_entry_2 { #define EXT3_DIR_ROUND (EXT3_DIR_PAD - 1) #define EXT3_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT3_DIR_ROUND) & \ ~EXT3_DIR_ROUND) -#define EXT3_MAX_REC_LEN ((1<<16)-1) - -static inline unsigned ext3_rec_len_from_disk(__le16 dlen) -{ - unsigned len = le16_to_cpu(dlen); - - if (len == EXT3_MAX_REC_LEN) - return 1 << 16; - return len; -} - -static inline __le16 ext3_rec_len_to_disk(unsigned len) -{ - if (len == (1 << 16)) - return cpu_to_le16(EXT3_MAX_REC_LEN); - else if (len > (1 << 16)) - BUG(); - return cpu_to_le16(len); -} - /* * Hash Tree Directory indexing * (c) Daniel Phillips, 2001 diff --git a/trunk/include/linux/hugetlb.h b/trunk/include/linux/hugetlb.h index 24968790bc3e..ea0f50bfbe03 100644 --- a/trunk/include/linux/hugetlb.h +++ b/trunk/include/linux/hugetlb.h @@ -19,7 +19,7 @@ static inline int is_vm_hugetlb_page(struct vm_area_struct *vma) int hugetlb_sysctl_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); int hugetlb_treat_movable_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct vm_area_struct *); -int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, struct page **, struct vm_area_struct **, unsigned long *, int *, int, int); +int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, struct page **, struct vm_area_struct **, unsigned long *, int *, int); void unmap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long); void __unmap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long); int hugetlb_prefault(struct address_space *, struct vm_area_struct *); @@ -106,7 +106,7 @@ static inline unsigned long hugetlb_total_pages(void) return 0; } -#define follow_hugetlb_page(m,v,p,vs,a,b,i,w) ({ BUG(); 0; }) +#define follow_hugetlb_page(m,v,p,vs,a,b,i) ({ BUG(); 0; }) #define follow_huge_addr(mm, addr, write) ERR_PTR(-EINVAL) #define copy_hugetlb_page_range(src, dst, vma) ({ BUG(); 0; }) #define hugetlb_prefault(mapping, vma) ({ BUG(); 0; }) @@ -165,10 +165,8 @@ static inline struct hugetlbfs_sb_info *HUGETLBFS_SB(struct super_block *sb) extern const struct file_operations hugetlbfs_file_operations; extern struct vm_operations_struct hugetlb_vm_ops; struct file *hugetlb_file_setup(const char *name, size_t); -int hugetlb_get_quota(struct address_space *mapping, long delta); -void hugetlb_put_quota(struct address_space *mapping, long delta); - -#define BLOCKS_PER_HUGEPAGE (HPAGE_SIZE / 512) +int hugetlb_get_quota(struct address_space *mapping); +void hugetlb_put_quota(struct address_space *mapping); static inline int is_file_hugepages(struct file *file) { diff --git a/trunk/include/linux/mc146818rtc.h b/trunk/include/linux/mc146818rtc.h index 2f4e957af656..580b3f4956ee 100644 --- a/trunk/include/linux/mc146818rtc.h +++ b/trunk/include/linux/mc146818rtc.h @@ -109,11 +109,8 @@ struct cmos_rtc_board_info { #ifndef ARCH_RTC_LOCATION /* Override by ? */ #define RTC_IO_EXTENT 0x8 -#define RTC_IO_EXTENT_USED 0x2 #define RTC_IOMAPPED 1 /* Default to I/O mapping. */ -#else -#define RTC_IO_EXTENT_USED RTC_IO_EXTENT #endif /* ARCH_RTC_LOCATION */ #endif /* _MC146818RTC_H */ diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index 1ee009e8fec8..cd6cdb3cd7a5 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -2332,7 +2332,6 @@ #define PCI_DEVICE_ID_INTEL_MCH_PC1 0x359a #define PCI_DEVICE_ID_INTEL_E7525_MCH 0x359e #define PCI_DEVICE_ID_INTEL_IOAT_CNB 0x360b -#define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f #define PCI_DEVICE_ID_INTEL_IOAT_SCNB 0x65ff #define PCI_DEVICE_ID_INTEL_TOLAPAI_0 0x5031 #define PCI_DEVICE_ID_INTEL_TOLAPAI_1 0x5032 diff --git a/trunk/include/linux/pid_namespace.h b/trunk/include/linux/pid_namespace.h index 1689e28483e4..0135c76c76c6 100644 --- a/trunk/include/linux/pid_namespace.h +++ b/trunk/include/linux/pid_namespace.h @@ -29,7 +29,6 @@ struct pid_namespace { extern struct pid_namespace init_pid_ns; -#ifdef CONFIG_PID_NS static inline struct pid_namespace *get_pid_ns(struct pid_namespace *ns) { if (ns != &init_pid_ns) @@ -46,28 +45,6 @@ static inline void put_pid_ns(struct pid_namespace *ns) kref_put(&ns->kref, free_pid_ns); } -#else /* !CONFIG_PID_NS */ -#include - -static inline struct pid_namespace *get_pid_ns(struct pid_namespace *ns) -{ - return ns; -} - -static inline struct pid_namespace * -copy_pid_ns(unsigned long flags, struct pid_namespace *ns) -{ - if (flags & CLONE_NEWPID) - ns = ERR_PTR(-EINVAL); - return ns; -} - -static inline void put_pid_ns(struct pid_namespace *ns) -{ -} - -#endif /* CONFIG_PID_NS */ - static inline struct pid_namespace *task_active_pid_ns(struct task_struct *tsk) { return tsk->nsproxy->pid_ns; diff --git a/trunk/include/net/sock.h b/trunk/include/net/sock.h index 567e468d7492..5504fb9fa88a 100644 --- a/trunk/include/net/sock.h +++ b/trunk/include/net/sock.h @@ -1235,16 +1235,14 @@ static inline struct sk_buff *sk_stream_alloc_pskb(struct sock *sk, gfp_t gfp) { struct sk_buff *skb; + int hdr_len; - skb = alloc_skb_fclone(size + sk->sk_prot->max_header, gfp); + hdr_len = SKB_DATA_ALIGN(sk->sk_prot->max_header); + skb = alloc_skb_fclone(size + hdr_len, gfp); if (skb) { skb->truesize += mem; if (sk_stream_wmem_schedule(sk, skb->truesize)) { - /* - * Make sure that we have exactly size bytes - * available to the caller, no more, no less. - */ - skb_reserve(skb, skb_tailroom(skb) - size); + skb_reserve(skb, hdr_len); return skb; } __kfree_skb(skb); diff --git a/trunk/init/Kconfig b/trunk/init/Kconfig index c5b354b1409e..8b88d0bedcbd 100644 --- a/trunk/init/Kconfig +++ b/trunk/init/Kconfig @@ -215,18 +215,6 @@ config USER_NS vservers, to use user namespaces to provide different user info for different servers. If unsure, say N. -config PID_NS - bool "PID Namespaces (EXPERIMENTAL)" - default n - depends on EXPERIMENTAL - help - Suport process id namespaces. This allows having multiple - process with the same pid as long as they are in different - pid namespaces. This is a building block of containers. - - Unless you want to work with an experimental feature - say N here. - config AUDIT bool "Auditing support" depends on NET @@ -313,6 +301,13 @@ config CGROUP_NS for instance virtual servers and checkpoint/restart jobs. +config CGROUP_CPUACCT + bool "Simple CPU accounting cgroup subsystem" + depends on CGROUPS + help + Provides a simple Resource Controller for monitoring the + total CPU consumed by the tasks in a cgroup + config CPUSETS bool "Cpuset support" depends on SMP && CGROUPS diff --git a/trunk/kernel/Makefile b/trunk/kernel/Makefile index dfa96956dae0..f60afe742599 100644 --- a/trunk/kernel/Makefile +++ b/trunk/kernel/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_COMPAT) += compat.o obj-$(CONFIG_CGROUPS) += cgroup.o obj-$(CONFIG_CGROUP_DEBUG) += cgroup_debug.o obj-$(CONFIG_CPUSETS) += cpuset.o +obj-$(CONFIG_CGROUP_CPUACCT) += cpu_acct.o obj-$(CONFIG_CGROUP_NS) += ns_cgroup.o obj-$(CONFIG_IKCONFIG) += configs.o obj-$(CONFIG_STOP_MACHINE) += stop_machine.o diff --git a/trunk/kernel/cgroup.c b/trunk/kernel/cgroup.c index 1a3c23936d43..3fe21e19c96e 100644 --- a/trunk/kernel/cgroup.c +++ b/trunk/kernel/cgroup.c @@ -1,4 +1,6 @@ /* + * kernel/cgroup.c + * * Generic process-grouping system. * * Based originally on the cpuset system, extracted by Paul Menage @@ -2198,8 +2200,7 @@ static void cgroup_init_subsys(struct cgroup_subsys *ss) { struct cgroup_subsys_state *css; struct list_head *l; - - printk(KERN_INFO "Initializing cgroup subsys %s\n", ss->name); + printk(KERN_ERR "Initializing cgroup subsys %s\n", ss->name); /* Create the top cgroup state for this subsystem */ ss->root = &rootnode; @@ -2272,7 +2273,7 @@ int __init cgroup_init_early(void) BUG_ON(!ss->create); BUG_ON(!ss->destroy); if (ss->subsys_id != i) { - printk(KERN_ERR "cgroup: Subsys %s id == %d\n", + printk(KERN_ERR "Subsys %s id == %d\n", ss->name, ss->subsys_id); BUG(); } @@ -2604,7 +2605,7 @@ int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *subsys) dentry = lookup_one_len(nodename, parent->dentry, strlen(nodename)); if (IS_ERR(dentry)) { printk(KERN_INFO - "cgroup: Couldn't allocate dentry for %s: %ld\n", nodename, + "Couldn't allocate dentry for %s: %ld\n", nodename, PTR_ERR(dentry)); ret = PTR_ERR(dentry); goto out_release; diff --git a/trunk/kernel/cpu_acct.c b/trunk/kernel/cpu_acct.c new file mode 100644 index 000000000000..731e47e7f164 --- /dev/null +++ b/trunk/kernel/cpu_acct.c @@ -0,0 +1,186 @@ +/* + * kernel/cpu_acct.c - CPU accounting cgroup subsystem + * + * Copyright (C) Google Inc, 2006 + * + * Developed by Paul Menage (menage@google.com) and Balbir Singh + * (balbir@in.ibm.com) + * + */ + +/* + * Example cgroup subsystem for reporting total CPU usage of tasks in a + * cgroup, along with percentage load over a time interval + */ + +#include +#include +#include +#include + +#include + +struct cpuacct { + struct cgroup_subsys_state css; + spinlock_t lock; + /* total time used by this class */ + cputime64_t time; + + /* time when next load calculation occurs */ + u64 next_interval_check; + + /* time used in current period */ + cputime64_t current_interval_time; + + /* time used in last period */ + cputime64_t last_interval_time; +}; + +struct cgroup_subsys cpuacct_subsys; + +static inline struct cpuacct *cgroup_ca(struct cgroup *cont) +{ + return container_of(cgroup_subsys_state(cont, cpuacct_subsys_id), + struct cpuacct, css); +} + +static inline struct cpuacct *task_ca(struct task_struct *task) +{ + return container_of(task_subsys_state(task, cpuacct_subsys_id), + struct cpuacct, css); +} + +#define INTERVAL (HZ * 10) + +static inline u64 next_interval_boundary(u64 now) +{ + /* calculate the next interval boundary beyond the + * current time */ + do_div(now, INTERVAL); + return (now + 1) * INTERVAL; +} + +static struct cgroup_subsys_state *cpuacct_create( + struct cgroup_subsys *ss, struct cgroup *cont) +{ + struct cpuacct *ca = kzalloc(sizeof(*ca), GFP_KERNEL); + + if (!ca) + return ERR_PTR(-ENOMEM); + spin_lock_init(&ca->lock); + ca->next_interval_check = next_interval_boundary(get_jiffies_64()); + return &ca->css; +} + +static void cpuacct_destroy(struct cgroup_subsys *ss, + struct cgroup *cont) +{ + kfree(cgroup_ca(cont)); +} + +/* Lazily update the load calculation if necessary. Called with ca locked */ +static void cpuusage_update(struct cpuacct *ca) +{ + u64 now = get_jiffies_64(); + + /* If we're not due for an update, return */ + if (ca->next_interval_check > now) + return; + + if (ca->next_interval_check <= (now - INTERVAL)) { + /* If it's been more than an interval since the last + * check, then catch up - the last interval must have + * been zero load */ + ca->last_interval_time = 0; + ca->next_interval_check = next_interval_boundary(now); + } else { + /* If a steal takes the last interval time negative, + * then we just ignore it */ + if ((s64)ca->current_interval_time > 0) + ca->last_interval_time = ca->current_interval_time; + else + ca->last_interval_time = 0; + ca->next_interval_check += INTERVAL; + } + ca->current_interval_time = 0; +} + +static u64 cpuusage_read(struct cgroup *cont, struct cftype *cft) +{ + struct cpuacct *ca = cgroup_ca(cont); + u64 time; + + spin_lock_irq(&ca->lock); + cpuusage_update(ca); + time = cputime64_to_jiffies64(ca->time); + spin_unlock_irq(&ca->lock); + + /* Convert 64-bit jiffies to seconds */ + time *= 1000; + do_div(time, HZ); + return time; +} + +static u64 load_read(struct cgroup *cont, struct cftype *cft) +{ + struct cpuacct *ca = cgroup_ca(cont); + u64 time; + + /* Find the time used in the previous interval */ + spin_lock_irq(&ca->lock); + cpuusage_update(ca); + time = cputime64_to_jiffies64(ca->last_interval_time); + spin_unlock_irq(&ca->lock); + + /* Convert time to a percentage, to give the load in the + * previous period */ + time *= 100; + do_div(time, INTERVAL); + + return time; +} + +static struct cftype files[] = { + { + .name = "usage", + .read_uint = cpuusage_read, + }, + { + .name = "load", + .read_uint = load_read, + } +}; + +static int cpuacct_populate(struct cgroup_subsys *ss, struct cgroup *cont) +{ + return cgroup_add_files(cont, ss, files, ARRAY_SIZE(files)); +} + +void cpuacct_charge(struct task_struct *task, cputime_t cputime) +{ + + struct cpuacct *ca; + unsigned long flags; + + if (!cpuacct_subsys.active) + return; + rcu_read_lock(); + ca = task_ca(task); + if (ca) { + spin_lock_irqsave(&ca->lock, flags); + cpuusage_update(ca); + ca->time = cputime64_add(ca->time, cputime); + ca->current_interval_time = + cputime64_add(ca->current_interval_time, cputime); + spin_unlock_irqrestore(&ca->lock, flags); + } + rcu_read_unlock(); +} + +struct cgroup_subsys cpuacct_subsys = { + .name = "cpuacct", + .create = cpuacct_create, + .destroy = cpuacct_destroy, + .populate = cpuacct_populate, + .subsys_id = cpuacct_subsys_id, +}; diff --git a/trunk/kernel/irq/handle.c b/trunk/kernel/irq/handle.c index dc335ad27525..e391cbb1f566 100644 --- a/trunk/kernel/irq/handle.c +++ b/trunk/kernel/irq/handle.c @@ -178,11 +178,9 @@ fastcall unsigned int __do_IRQ(unsigned int irq) */ if (desc->chip->ack) desc->chip->ack(irq); - if (likely(!(desc->status & IRQ_DISABLED))) { - action_ret = handle_IRQ_event(irq, desc->action); - if (!noirqdebug) - note_interrupt(irq, desc, action_ret); - } + action_ret = handle_IRQ_event(irq, desc->action); + if (!noirqdebug) + note_interrupt(irq, desc, action_ret); desc->chip->end(irq); return 1; } diff --git a/trunk/kernel/marker.c b/trunk/kernel/marker.c index 5323cfaedbce..ccb48d9a3657 100644 --- a/trunk/kernel/marker.c +++ b/trunk/kernel/marker.c @@ -28,7 +28,7 @@ extern struct marker __start___markers[]; extern struct marker __stop___markers[]; /* - * markers_mutex nests inside module_mutex. Markers mutex protects the builtin + * module_mutex nests inside markers_mutex. Markers mutex protects the builtin * and module markers, the hash table and deferred_sync. */ static DEFINE_MUTEX(markers_mutex); @@ -257,6 +257,7 @@ static void disable_marker(struct marker *elem) * @refcount: number of references left to the given probe_module (out) * * Updates the probe callback corresponding to a range of markers. + * Must be called with markers_mutex held. */ void marker_update_probe_range(struct marker *begin, struct marker *end, struct module *probe_module, @@ -265,7 +266,6 @@ void marker_update_probe_range(struct marker *begin, struct marker *iter; struct marker_entry *mark_entry; - mutex_lock(&markers_mutex); for (iter = begin; iter < end; iter++) { mark_entry = get_marker(iter->name); if (mark_entry && mark_entry->refcount) { @@ -281,7 +281,6 @@ void marker_update_probe_range(struct marker *begin, disable_marker(iter); } } - mutex_unlock(&markers_mutex); } /* @@ -294,6 +293,7 @@ static void marker_update_probes(struct module *probe_module) { int refcount = 0; + mutex_lock(&markers_mutex); /* Core kernel markers */ marker_update_probe_range(__start___markers, __stop___markers, probe_module, &refcount); @@ -303,6 +303,7 @@ static void marker_update_probes(struct module *probe_module) synchronize_sched(); deferred_sync = 0; } + mutex_unlock(&markers_mutex); } /** @@ -319,7 +320,7 @@ int marker_probe_register(const char *name, const char *format, marker_probe_func *probe, void *private) { struct marker_entry *entry; - int ret = 0; + int ret = 0, need_update = 0; mutex_lock(&markers_mutex); entry = get_marker(name); @@ -334,11 +335,11 @@ int marker_probe_register(const char *name, const char *format, ret = add_marker(name, format, probe, private); if (ret) goto end; - mutex_unlock(&markers_mutex); - marker_update_probes(NULL); - return ret; + need_update = 1; end: mutex_unlock(&markers_mutex); + if (need_update) + marker_update_probes(NULL); return ret; } EXPORT_SYMBOL_GPL(marker_probe_register); @@ -354,6 +355,7 @@ void *marker_probe_unregister(const char *name) struct module *probe_module; struct marker_entry *entry; void *private; + int need_update = 0; mutex_lock(&markers_mutex); entry = get_marker(name); @@ -366,11 +368,11 @@ void *marker_probe_unregister(const char *name) probe_module = __module_text_address((unsigned long)entry->probe); private = remove_marker(name); deferred_sync = 1; - mutex_unlock(&markers_mutex); - marker_update_probes(probe_module); - return private; + need_update = 1; end: mutex_unlock(&markers_mutex); + if (need_update) + marker_update_probes(probe_module); return private; } EXPORT_SYMBOL_GPL(marker_probe_unregister); @@ -390,6 +392,7 @@ void *marker_probe_unregister_private_data(void *private) struct marker_entry *entry; int found = 0; unsigned int i; + int need_update = 0; mutex_lock(&markers_mutex); for (i = 0; i < MARKER_TABLE_SIZE; i++) { @@ -411,11 +414,11 @@ void *marker_probe_unregister_private_data(void *private) probe_module = __module_text_address((unsigned long)entry->probe); private = remove_marker(entry->name); deferred_sync = 1; - mutex_unlock(&markers_mutex); - marker_update_probes(probe_module); - return private; + need_update = 1; end: mutex_unlock(&markers_mutex); + if (need_update) + marker_update_probes(probe_module); return private; } EXPORT_SYMBOL_GPL(marker_probe_unregister_private_data); @@ -431,7 +434,7 @@ EXPORT_SYMBOL_GPL(marker_probe_unregister_private_data); int marker_arm(const char *name) { struct marker_entry *entry; - int ret = 0; + int ret = 0, need_update = 0; mutex_lock(&markers_mutex); entry = get_marker(name); @@ -444,9 +447,11 @@ int marker_arm(const char *name) */ if (entry->refcount++) goto end; + need_update = 1; end: mutex_unlock(&markers_mutex); - marker_update_probes(NULL); + if (need_update) + marker_update_probes(NULL); return ret; } EXPORT_SYMBOL_GPL(marker_arm); @@ -462,7 +467,7 @@ EXPORT_SYMBOL_GPL(marker_arm); int marker_disarm(const char *name) { struct marker_entry *entry; - int ret = 0; + int ret = 0, need_update = 0; mutex_lock(&markers_mutex); entry = get_marker(name); @@ -481,9 +486,11 @@ int marker_disarm(const char *name) ret = -EPERM; goto end; } + need_update = 1; end: mutex_unlock(&markers_mutex); - marker_update_probes(NULL); + if (need_update) + marker_update_probes(NULL); return ret; } EXPORT_SYMBOL_GPL(marker_disarm); diff --git a/trunk/kernel/params.c b/trunk/kernel/params.c index 2a4c51487e72..16f269e9ddc9 100644 --- a/trunk/kernel/params.c +++ b/trunk/kernel/params.c @@ -592,16 +592,19 @@ static void __init param_sysfs_builtin(void) for (i=0; i < __stop___param - __start___param; i++) { char *dot; - size_t max_name_len; + size_t kplen; kp = &__start___param[i]; - max_name_len = - min_t(size_t, MAX_KBUILD_MODNAME, strlen(kp->name)); + kplen = strlen(kp->name); - dot = memchr(kp->name, '.', max_name_len); + /* We do not handle args without periods. */ + if (kplen > MAX_KBUILD_MODNAME) { + DEBUGP("kernel parameter name is too long: %s\n", kp->name); + continue; + } + dot = memchr(kp->name, '.', kplen); if (!dot) { - DEBUGP("couldn't find period in first %d characters " - "of %s\n", MAX_KBUILD_MODNAME, kp->name); + DEBUGP("couldn't find period in %s\n", kp->name); continue; } name_len = dot - kp->name; diff --git a/trunk/kernel/pid.c b/trunk/kernel/pid.c index f815455431bf..d1db36b94674 100644 --- a/trunk/kernel/pid.c +++ b/trunk/kernel/pid.c @@ -537,7 +537,6 @@ static struct kmem_cache *create_pid_cachep(int nr_ids) return NULL; } -#ifdef CONFIG_PID_NS static struct pid_namespace *create_pid_namespace(int level) { struct pid_namespace *ns; @@ -622,7 +621,6 @@ void free_pid_ns(struct kref *kref) if (parent != NULL) put_pid_ns(parent); } -#endif /* CONFIG_PID_NS */ void zap_pid_ns_processes(struct pid_namespace *pid_ns) { diff --git a/trunk/kernel/power/disk.c b/trunk/kernel/power/disk.c index 05b64790fe83..8b15f777010a 100644 --- a/trunk/kernel/power/disk.c +++ b/trunk/kernel/power/disk.c @@ -456,17 +456,7 @@ static int software_resume(void) int error; unsigned int flags; - /* - * name_to_dev_t() below takes a sysfs buffer mutex when sysfs - * is configured into the kernel. Since the regular hibernate - * trigger path is via sysfs which takes a buffer mutex before - * calling hibernate functions (which take pm_mutex) this can - * cause lockdep to complain about a possible ABBA deadlock - * which cannot happen since we're in the boot code here and - * sysfs can't be invoked yet. Therefore, we use a subclass - * here to avoid lockdep complaining. - */ - mutex_lock_nested(&pm_mutex, SINGLE_DEPTH_NESTING); + mutex_lock(&pm_mutex); if (!swsusp_resume_device) { if (!strlen(resume_file)) { mutex_unlock(&pm_mutex); diff --git a/trunk/kernel/resource.c b/trunk/kernel/resource.c index 2eb553d9b517..a358142ff48f 100644 --- a/trunk/kernel/resource.c +++ b/trunk/kernel/resource.c @@ -277,7 +277,7 @@ walk_memory_resource(unsigned long start_pfn, unsigned long nr_pages, void *arg, int ret = -1; res.start = (u64) start_pfn << PAGE_SHIFT; res.end = ((u64)(start_pfn + nr_pages) << PAGE_SHIFT) - 1; - res.flags = IORESOURCE_MEM | IORESOURCE_BUSY; + res.flags = IORESOURCE_MEM; orig_end = res.end; while ((res.start < res.end) && (find_next_system_ram(&res) >= 0)) { pfn = (unsigned long)(res.start >> PAGE_SHIFT); diff --git a/trunk/kernel/sched.c b/trunk/kernel/sched.c index 4fb3532dd7e8..b18f231a4875 100644 --- a/trunk/kernel/sched.c +++ b/trunk/kernel/sched.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -3337,9 +3338,13 @@ void account_user_time(struct task_struct *p, cputime_t cputime) { struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; cputime64_t tmp; + struct rq *rq = this_rq(); p->utime = cputime_add(p->utime, cputime); + if (p != rq->idle) + cpuacct_charge(p, cputime); + /* Add user time to cpustat. */ tmp = cputime_to_cputime64(cputime); if (TASK_NICE(p) > 0) @@ -3403,9 +3408,10 @@ void account_system_time(struct task_struct *p, int hardirq_offset, cpustat->irq = cputime64_add(cpustat->irq, tmp); else if (softirq_count()) cpustat->softirq = cputime64_add(cpustat->softirq, tmp); - else if (p != rq->idle) + else if (p != rq->idle) { cpustat->system = cputime64_add(cpustat->system, tmp); - else if (atomic_read(&rq->nr_iowait) > 0) + cpuacct_charge(p, cputime); + } else if (atomic_read(&rq->nr_iowait) > 0) cpustat->iowait = cputime64_add(cpustat->iowait, tmp); else cpustat->idle = cputime64_add(cpustat->idle, tmp); @@ -3441,8 +3447,10 @@ void account_steal_time(struct task_struct *p, cputime_t steal) cpustat->iowait = cputime64_add(cpustat->iowait, tmp); else cpustat->idle = cputime64_add(cpustat->idle, tmp); - } else + } else { cpustat->steal = cputime64_add(cpustat->steal, tmp); + cpuacct_charge(p, -tmp); + } } /* diff --git a/trunk/kernel/sysctl.c b/trunk/kernel/sysctl.c index 0deed82a6156..3a1744fed2b6 100644 --- a/trunk/kernel/sysctl.c +++ b/trunk/kernel/sysctl.c @@ -2620,10 +2620,6 @@ static int deprecated_sysctl_warning(struct __sysctl_args *args) int name[CTL_MAXNAME]; int i; - /* Check args->nlen. */ - if (args->nlen < 0 || args->nlen > CTL_MAXNAME) - return -ENOTDIR; - /* Read in the sysctl name for better debug message logging */ for (i = 0; i < args->nlen; i++) if (get_user(name[i], args->name + i)) diff --git a/trunk/kernel/sysctl_check.c b/trunk/kernel/sysctl_check.c index 4abc6d2306f4..5a2f2b2bf888 100644 --- a/trunk/kernel/sysctl_check.c +++ b/trunk/kernel/sysctl_check.c @@ -738,7 +738,7 @@ static struct trans_ctl_table trans_net_table[] = { { NET_ROSE, "rose", trans_net_rose_table }, { NET_IPV6, "ipv6", trans_net_ipv6_table }, { NET_X25, "x25", trans_net_x25_table }, - { NET_TR, "token-ring", trans_net_tr_table }, + { NET_TR, "tr", trans_net_tr_table }, { NET_DECNET, "decnet", trans_net_decnet_table }, /* NET_ECONET not used */ { NET_SCTP, "sctp", trans_net_sctp_table }, diff --git a/trunk/kernel/taskstats.c b/trunk/kernel/taskstats.c index 07e86a828073..354e74bc17c1 100644 --- a/trunk/kernel/taskstats.c +++ b/trunk/kernel/taskstats.c @@ -398,31 +398,31 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info) fd = nla_get_u32(info->attrs[CGROUPSTATS_CMD_ATTR_FD]); file = fget_light(fd, &fput_needed); - if (!file) - return 0; + if (file) { + size = nla_total_size(sizeof(struct cgroupstats)); - size = nla_total_size(sizeof(struct cgroupstats)); + rc = prepare_reply(info, CGROUPSTATS_CMD_NEW, &rep_skb, + size); + if (rc < 0) + goto err; - rc = prepare_reply(info, CGROUPSTATS_CMD_NEW, &rep_skb, - size); - if (rc < 0) - goto err; + na = nla_reserve(rep_skb, CGROUPSTATS_TYPE_CGROUP_STATS, + sizeof(struct cgroupstats)); + stats = nla_data(na); + memset(stats, 0, sizeof(*stats)); - na = nla_reserve(rep_skb, CGROUPSTATS_TYPE_CGROUP_STATS, - sizeof(struct cgroupstats)); - stats = nla_data(na); - memset(stats, 0, sizeof(*stats)); + rc = cgroupstats_build(stats, file->f_dentry); + if (rc < 0) + goto err; - rc = cgroupstats_build(stats, file->f_dentry); - if (rc < 0) { - nlmsg_free(rep_skb); - goto err; + fput_light(file, fput_needed); + return send_reply(rep_skb, info->snd_pid); } - rc = send_reply(rep_skb, info->snd_pid); - err: - fput_light(file, fput_needed); + if (file) + fput_light(file, fput_needed); + nlmsg_free(rep_skb); return rc; } diff --git a/trunk/lib/Makefile b/trunk/lib/Makefile index b6793ed28d84..3a0983b77412 100644 --- a/trunk/lib/Makefile +++ b/trunk/lib/Makefile @@ -4,7 +4,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \ rbtree.o radix-tree.o dump_stack.o \ - idr.o int_sqrt.o extable.o prio_tree.o \ + idr.o int_sqrt.o bitmap.o extable.o prio_tree.o \ sha1.o irq_regs.o reciprocal_div.o argv_split.o \ proportions.o prio_heap.o @@ -14,7 +14,7 @@ lib-$(CONFIG_SMP) += cpumask.o lib-y += kobject.o kref.o klist.o obj-y += div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ - bust_spinlocks.o hexdump.o kasprintf.o bitmap.o + bust_spinlocks.o hexdump.o kasprintf.o ifeq ($(CONFIG_DEBUG_KOBJECT),y) CFLAGS_kobject.o += -DDEBUG diff --git a/trunk/mm/hugetlb.c b/trunk/mm/hugetlb.c index 6121b57bbe96..8b809ecefa39 100644 --- a/trunk/mm/hugetlb.c +++ b/trunk/mm/hugetlb.c @@ -116,9 +116,7 @@ static void update_and_free_page(struct page *page) static void free_huge_page(struct page *page) { int nid = page_to_nid(page); - struct address_space *mapping; - mapping = (struct address_space *) page_private(page); BUG_ON(page_count(page)); INIT_LIST_HEAD(&page->lru); @@ -131,9 +129,6 @@ static void free_huge_page(struct page *page) enqueue_huge_page(page); } spin_unlock(&hugetlb_lock); - if (mapping) - hugetlb_put_quota(mapping, 1); - set_page_private(page, 0); } /* @@ -328,7 +323,7 @@ static int gather_surplus_pages(int delta) * allocated to satisfy the reservation must be explicitly freed if they were * never used. */ -static void return_unused_surplus_pages(unsigned long unused_resv_pages) +void return_unused_surplus_pages(unsigned long unused_resv_pages) { static int nid = -1; struct page *page; @@ -358,50 +353,35 @@ static void return_unused_surplus_pages(unsigned long unused_resv_pages) } } - -static struct page *alloc_huge_page_shared(struct vm_area_struct *vma, - unsigned long addr) +static struct page *alloc_huge_page(struct vm_area_struct *vma, + unsigned long addr) { - struct page *page; + struct page *page = NULL; + int use_reserved_page = vma->vm_flags & VM_MAYSHARE; spin_lock(&hugetlb_lock); - page = dequeue_huge_page(vma, addr); - spin_unlock(&hugetlb_lock); - return page ? page : ERR_PTR(-VM_FAULT_OOM); -} + if (!use_reserved_page && (free_huge_pages <= resv_huge_pages)) + goto fail; -static struct page *alloc_huge_page_private(struct vm_area_struct *vma, - unsigned long addr) -{ - struct page *page = NULL; - - if (hugetlb_get_quota(vma->vm_file->f_mapping, 1)) - return ERR_PTR(-VM_FAULT_SIGBUS); + page = dequeue_huge_page(vma, addr); + if (!page) + goto fail; - spin_lock(&hugetlb_lock); - if (free_huge_pages > resv_huge_pages) - page = dequeue_huge_page(vma, addr); spin_unlock(&hugetlb_lock); - if (!page) - page = alloc_buddy_huge_page(vma, addr); - return page ? page : ERR_PTR(-VM_FAULT_OOM); -} + set_page_refcounted(page); + return page; -static struct page *alloc_huge_page(struct vm_area_struct *vma, - unsigned long addr) -{ - struct page *page; - struct address_space *mapping = vma->vm_file->f_mapping; +fail: + spin_unlock(&hugetlb_lock); - if (vma->vm_flags & VM_MAYSHARE) - page = alloc_huge_page_shared(vma, addr); - else - page = alloc_huge_page_private(vma, addr); + /* + * Private mappings do not use reserved huge pages so the allocation + * may have failed due to an undersized hugetlb pool. Try to grab a + * surplus huge page from the buddy allocator. + */ + if (!use_reserved_page) + page = alloc_buddy_huge_page(vma, addr); - if (!IS_ERR(page)) { - set_page_refcounted(page); - set_page_private(page, (unsigned long) mapping); - } return page; } @@ -746,9 +726,9 @@ static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma, page_cache_get(old_page); new_page = alloc_huge_page(vma, address); - if (IS_ERR(new_page)) { + if (!new_page) { page_cache_release(old_page); - return -PTR_ERR(new_page); + return VM_FAULT_OOM; } spin_unlock(&mm->page_table_lock); @@ -792,28 +772,27 @@ static int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma, size = i_size_read(mapping->host) >> HPAGE_SHIFT; if (idx >= size) goto out; + if (hugetlb_get_quota(mapping)) + goto out; page = alloc_huge_page(vma, address); - if (IS_ERR(page)) { - ret = -PTR_ERR(page); + if (!page) { + hugetlb_put_quota(mapping); + ret = VM_FAULT_OOM; goto out; } clear_huge_page(page, address); if (vma->vm_flags & VM_SHARED) { int err; - struct inode *inode = mapping->host; err = add_to_page_cache(page, mapping, idx, GFP_KERNEL); if (err) { put_page(page); + hugetlb_put_quota(mapping); if (err == -EEXIST) goto retry; goto out; } - - spin_lock(&inode->i_lock); - inode->i_blocks += BLOCKS_PER_HUGEPAGE; - spin_unlock(&inode->i_lock); } else lock_page(page); } @@ -843,6 +822,7 @@ static int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma, backout: spin_unlock(&mm->page_table_lock); + hugetlb_put_quota(mapping); unlock_page(page); put_page(page); goto out; @@ -888,8 +868,7 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, struct page **pages, struct vm_area_struct **vmas, - unsigned long *position, int *length, int i, - int write) + unsigned long *position, int *length, int i) { unsigned long pfn_offset; unsigned long vaddr = *position; @@ -911,7 +890,7 @@ int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, int ret; spin_unlock(&mm->page_table_lock); - ret = hugetlb_fault(mm, vma, vaddr, write); + ret = hugetlb_fault(mm, vma, vaddr, 0); spin_lock(&mm->page_table_lock); if (!(ret & VM_FAULT_ERROR)) continue; @@ -1153,8 +1132,6 @@ int hugetlb_reserve_pages(struct inode *inode, long from, long to) if (chg < 0) return chg; - if (hugetlb_get_quota(inode->i_mapping, chg)) - return -ENOSPC; ret = hugetlb_acct_memory(chg); if (ret < 0) return ret; @@ -1165,11 +1142,5 @@ int hugetlb_reserve_pages(struct inode *inode, long from, long to) void hugetlb_unreserve_pages(struct inode *inode, long offset, long freed) { long chg = region_truncate(&inode->i_mapping->private_list, offset); - - spin_lock(&inode->i_lock); - inode->i_blocks -= BLOCKS_PER_HUGEPAGE * freed; - spin_unlock(&inode->i_lock); - - hugetlb_put_quota(inode->i_mapping, (chg - freed)); - hugetlb_acct_memory(-(chg - freed)); + hugetlb_acct_memory(freed - chg); } diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c index 4bf0b6d0eb2a..9791e4786843 100644 --- a/trunk/mm/memory.c +++ b/trunk/mm/memory.c @@ -1036,7 +1036,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, if (is_vm_hugetlb_page(vma)) { i = follow_hugetlb_page(mm, vma, pages, vmas, - &start, &len, i, write); + &start, &len, i); continue; } @@ -2084,9 +2084,9 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, count_vm_event(PGMAJFAULT); } + delayacct_clear_flag(DELAYACCT_PF_SWAPIN); mark_page_accessed(page); lock_page(page); - delayacct_clear_flag(DELAYACCT_PF_SWAPIN); /* * Back out if somebody else already faulted in this pte. diff --git a/trunk/mm/memory_hotplug.c b/trunk/mm/memory_hotplug.c index 9512a544d044..3a47871a29d9 100644 --- a/trunk/mm/memory_hotplug.c +++ b/trunk/mm/memory_hotplug.c @@ -39,7 +39,7 @@ static struct resource *register_memory_resource(u64 start, u64 size) res->name = "System RAM"; res->start = start; res->end = start + size - 1; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + res->flags = IORESOURCE_MEM; if (request_resource(&iomem_resource, res) < 0) { printk("System RAM resource %llx - %llx cannot be added\n", (unsigned long long)res->start, (unsigned long long)res->end); @@ -574,8 +574,8 @@ int offline_pages(unsigned long start_pfn, /* Ok, all of our target is islaoted. We cannot do rollback at this point. */ offline_isolated_pages(start_pfn, end_pfn); - /* reset pagetype flags and makes migrate type to be MOVABLE */ - undo_isolate_page_range(start_pfn, end_pfn); + /* reset pagetype flags */ + start_isolate_page_range(start_pfn, end_pfn); /* removal success */ zone->present_pages -= offlined_pages; zone->zone_pgdat->node_present_pages -= offlined_pages; diff --git a/trunk/mm/mempolicy.c b/trunk/mm/mempolicy.c index 83c69f8a64c2..c1592a94582f 100644 --- a/trunk/mm/mempolicy.c +++ b/trunk/mm/mempolicy.c @@ -722,29 +722,12 @@ int do_migrate_pages(struct mm_struct *mm, } -/* - * Allocate a new page for page migration based on vma policy. - * Start assuming that page is mapped by vma pointed to by @private. - * Search forward from there, if not. N.B., this assumes that the - * list of pages handed to migrate_pages()--which is how we get here-- - * is in virtual address order. - */ static struct page *new_vma_page(struct page *page, unsigned long private, int **x) { struct vm_area_struct *vma = (struct vm_area_struct *)private; - unsigned long uninitialized_var(address); - while (vma) { - address = page_address_in_vma(page, vma); - if (address != -EFAULT) - break; - vma = vma->vm_next; - } - - /* - * if !vma, alloc_page_vma() will use task or system default policy - */ - return alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, address); + return alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, + page_address_in_vma(page, vma)); } #else diff --git a/trunk/mm/page-writeback.c b/trunk/mm/page-writeback.c index 81a91e6f1f99..838a5e31394c 100644 --- a/trunk/mm/page-writeback.c +++ b/trunk/mm/page-writeback.c @@ -355,8 +355,8 @@ get_dirty_limits(long *pbackground, long *pdirty, long *pbdi_dirty, */ static void balance_dirty_pages(struct address_space *mapping) { - long nr_reclaimable, bdi_nr_reclaimable; - long nr_writeback, bdi_nr_writeback; + long bdi_nr_reclaimable; + long bdi_nr_writeback; long background_thresh; long dirty_thresh; long bdi_thresh; @@ -376,26 +376,11 @@ static void balance_dirty_pages(struct address_space *mapping) get_dirty_limits(&background_thresh, &dirty_thresh, &bdi_thresh, bdi); - - nr_reclaimable = global_page_state(NR_FILE_DIRTY) + - global_page_state(NR_UNSTABLE_NFS); - nr_writeback = global_page_state(NR_WRITEBACK); - bdi_nr_reclaimable = bdi_stat(bdi, BDI_RECLAIMABLE); bdi_nr_writeback = bdi_stat(bdi, BDI_WRITEBACK); - if (bdi_nr_reclaimable + bdi_nr_writeback <= bdi_thresh) break; - /* - * Throttle it only when the background writeback cannot - * catch-up. This avoids (excessively) small writeouts - * when the bdi limits are ramping up. - */ - if (nr_reclaimable + nr_writeback < - (background_thresh + dirty_thresh) / 2) - break; - if (!bdi->dirty_exceeded) bdi->dirty_exceeded = 1; diff --git a/trunk/mm/page_isolation.c b/trunk/mm/page_isolation.c index 3444b58033c8..8f92a29695cc 100644 --- a/trunk/mm/page_isolation.c +++ b/trunk/mm/page_isolation.c @@ -55,7 +55,7 @@ start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn) return 0; undo: for (pfn = start_pfn; - pfn < undo_pfn; + pfn <= undo_pfn; pfn += pageblock_nr_pages) unset_migratetype_isolate(pfn_to_page(pfn)); @@ -76,7 +76,7 @@ undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn) pfn < end_pfn; pfn += pageblock_nr_pages) { page = __first_valid_page(pfn, pageblock_nr_pages); - if (!page || get_pageblock_migratetype(page) != MIGRATE_ISOLATE) + if (!page || get_pageblock_flags(page) != MIGRATE_ISOLATE) continue; unset_migratetype_isolate(page); } @@ -126,7 +126,7 @@ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn) */ for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) { page = __first_valid_page(pfn, pageblock_nr_pages); - if (page && get_pageblock_migratetype(page) != MIGRATE_ISOLATE) + if (page && get_pageblock_flags(page) != MIGRATE_ISOLATE) break; } if (pfn < end_pfn) diff --git a/trunk/mm/rmap.c b/trunk/mm/rmap.c index dc3be5f5b0da..8990f909492f 100644 --- a/trunk/mm/rmap.c +++ b/trunk/mm/rmap.c @@ -183,9 +183,7 @@ static void page_unlock_anon_vma(struct anon_vma *anon_vma) } /* - * At what user virtual address is page expected in @vma? - * Returns virtual address or -EFAULT if page's index/offset is not - * within the range mapped the @vma. + * At what user virtual address is page expected in vma? */ static inline unsigned long vma_address(struct page *page, struct vm_area_struct *vma) @@ -195,7 +193,8 @@ vma_address(struct page *page, struct vm_area_struct *vma) address = vma->vm_start + ((pgoff - vma->vm_pgoff) << PAGE_SHIFT); if (unlikely(address < vma->vm_start || address >= vma->vm_end)) { - /* page should be within @vma mapping range */ + /* page should be within any vma from prio_tree_next */ + BUG_ON(!PageAnon(page)); return -EFAULT; } return address; diff --git a/trunk/mm/slab.c b/trunk/mm/slab.c index c31cd3682a0b..cfa6be4e378e 100644 --- a/trunk/mm/slab.c +++ b/trunk/mm/slab.c @@ -1043,7 +1043,7 @@ static struct array_cache **alloc_alien_cache(int node, int limit) } ac_ptr[i] = alloc_arraycache(node, limit, 0xbaadf00d); if (!ac_ptr[i]) { - for (i--; i >= 0; i--) + for (i--; i <= 0; i--) kfree(ac_ptr[i]); kfree(ac_ptr); return NULL; diff --git a/trunk/mm/util.c b/trunk/mm/util.c index 8f18683825bc..5f64026cbb4d 100644 --- a/trunk/mm/util.c +++ b/trunk/mm/util.c @@ -95,8 +95,8 @@ void *krealloc(const void *p, size_t new_size, gfp_t flags) return (void *)p; ret = kmalloc_track_caller(new_size, flags); - if (ret && p) { - memcpy(ret, p, ks); + if (ret) { + memcpy(ret, p, min(new_size, ks)); kfree(p); } return ret; diff --git a/trunk/mm/vmstat.c b/trunk/mm/vmstat.c index e8d846f57774..4651bf153f35 100644 --- a/trunk/mm/vmstat.c +++ b/trunk/mm/vmstat.c @@ -803,7 +803,7 @@ static void vmstat_update(struct work_struct *w) sysctl_stat_interval); } -static void __cpuinit start_cpu_timer(int cpu) +static void __devinit start_cpu_timer(int cpu) { struct delayed_work *vmstat_work = &per_cpu(vmstat_work, cpu); diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 86d62611f2fc..dd40b35bb006 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -1171,8 +1171,6 @@ int register_netdevice_notifier(struct notifier_block *nb) nb->notifier_call(nb, NETDEV_UNREGISTER, dev); } } - - raw_notifier_chain_unregister(&netdev_chain, nb); goto unlock; } diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c index 1bff9ed349ff..45651834e1e2 100644 --- a/trunk/net/ipv4/route.c +++ b/trunk/net/ipv4/route.c @@ -578,9 +578,6 @@ static void rt_check_expire(struct work_struct *work) i = (i + 1) & rt_hash_mask; rthp = &rt_hash_table[i].chain; - if (need_resched()) - cond_resched(); - if (*rthp == NULL) continue; spin_lock_bh(rt_hash_lock_addr(i)); diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index 0f0c1c9829a1..20c9440ab85e 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -1269,9 +1269,6 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ if (before(TCP_SKB_CB(ack_skb)->ack_seq, prior_snd_una - tp->max_window)) return 0; - if (!tp->packets_out) - goto out; - /* SACK fastpath: * if the only SACK change is the increase of the end_seq of * the first block then only apply that SACK block @@ -1518,8 +1515,6 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ (!tp->frto_highmark || after(tp->snd_una, tp->frto_highmark))) tcp_update_reordering(sk, tp->fackets_out - reord, 0); -out: - #if FASTRETRANS_DEBUG > 0 BUG_TRAP((int)tp->sacked_out >= 0); BUG_TRAP((int)tp->lost_out >= 0); @@ -1674,9 +1669,6 @@ void tcp_enter_frto(struct sock *sk) } tcp_verify_left_out(tp); - /* Too bad if TCP was application limited */ - tp->snd_cwnd = min(tp->snd_cwnd, tcp_packets_in_flight(tp) + 1); - /* Earlier loss recovery underway (see RFC4138; Appendix B). * The last condition is necessary at least in tp->frto_counter case. */ @@ -1709,8 +1701,6 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag) tcp_for_write_queue(skb, sk) { if (skb == tcp_send_head(sk)) break; - - TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST; /* * Count the retransmission made on RTO correctly (only when * waiting for the first ACK and did not get it)... @@ -1724,7 +1714,7 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag) } else { if (TCP_SKB_CB(skb)->sacked & TCPCB_RETRANS) tp->undo_marker = 0; - TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS; + TCP_SKB_CB(skb)->sacked &= ~(TCPCB_LOST|TCPCB_SACKED_RETRANS); } /* Don't lost mark skbs that were fwd transmitted after RTO */ @@ -3113,11 +3103,11 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) /* See if we can take anything off of the retransmit queue. */ flag |= tcp_clean_rtx_queue(sk, &seq_rtt, prior_fackets); - if (tp->frto_counter) - frto_cwnd = tcp_process_frto(sk, flag); /* Guarantee sacktag reordering detection against wrap-arounds */ if (before(tp->frto_highmark, tp->snd_una)) tp->frto_highmark = 0; + if (tp->frto_counter) + frto_cwnd = tcp_process_frto(sk, flag); if (tcp_ack_is_dubious(sk, flag)) { /* Advance CWND, if state allows this. */ diff --git a/trunk/net/sched/sch_generic.c b/trunk/net/sched/sch_generic.c index e595e6570ce0..fa1a6f45dc41 100644 --- a/trunk/net/sched/sch_generic.c +++ b/trunk/net/sched/sch_generic.c @@ -134,7 +134,7 @@ static inline int qdisc_restart(struct net_device *dev) { struct Qdisc *q = dev->qdisc; struct sk_buff *skb; - int ret = NETDEV_TX_BUSY; + int ret; /* Dequeue packet */ if (unlikely((skb = dev_dequeue_skb(dev, q)) == NULL)) @@ -145,8 +145,7 @@ static inline int qdisc_restart(struct net_device *dev) spin_unlock(&dev->queue_lock); HARD_TX_LOCK(dev, smp_processor_id()); - if (!netif_subqueue_stopped(dev, skb)) - ret = dev_hard_start_xmit(skb, dev); + ret = dev_hard_start_xmit(skb, dev); HARD_TX_UNLOCK(dev); spin_lock(&dev->queue_lock); diff --git a/trunk/net/sunrpc/xprtrdma/transport.c b/trunk/net/sunrpc/xprtrdma/transport.c index 1afeb3eb8e4c..dc55cc974c90 100644 --- a/trunk/net/sunrpc/xprtrdma/transport.c +++ b/trunk/net/sunrpc/xprtrdma/transport.c @@ -320,9 +320,9 @@ xprt_setup_rdma(struct xprt_create *args) xprt->slot = kcalloc(xprt->max_reqs, sizeof(struct rpc_rqst), GFP_KERNEL); if (xprt->slot == NULL) { + kfree(xprt); dprintk("RPC: %s: couldn't allocate %d slots\n", __func__, xprt->max_reqs); - kfree(xprt); return ERR_PTR(-ENOMEM); } diff --git a/trunk/samples/markers/marker-example.c b/trunk/samples/markers/marker-example.c index 05e438f8b4e2..e787c6d16dd7 100644 --- a/trunk/samples/markers/marker-example.c +++ b/trunk/samples/markers/marker-example.c @@ -19,8 +19,7 @@ static int my_open(struct inode *inode, struct file *file) { int i; - trace_mark(subsystem_event, "integer %d string %s", 123, - "example string"); + trace_mark(subsystem_event, "%d %s", 123, "example string"); for (i = 0; i < 10; i++) trace_mark(subsystem_eventb, MARK_NOARGS); return -EPERM; diff --git a/trunk/samples/markers/probe-example.c b/trunk/samples/markers/probe-example.c index a36797535615..238b2e384fc8 100644 --- a/trunk/samples/markers/probe-example.c +++ b/trunk/samples/markers/probe-example.c @@ -53,7 +53,7 @@ void probe_subsystem_eventb(const struct marker *mdata, void *private, static struct probe_data probe_array[] = { { .name = "subsystem_event", - .format = "integer %d string %s", + .format = "%d %s", .probe_func = probe_subsystem_event }, { .name = "subsystem_eventb", .format = MARK_NOARGS, diff --git a/trunk/scripts/kconfig/Makefile b/trunk/scripts/kconfig/Makefile index 1ad6f7fc490a..59594126e8b6 100644 --- a/trunk/scripts/kconfig/Makefile +++ b/trunk/scripts/kconfig/Makefile @@ -4,7 +4,12 @@ PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config -Kconfig := arch/$(SRCARCH)/Kconfig +# If a arch/$(SRCARCH)/Kconfig.$(ARCH) file exist use it +ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/Kconfig.$(ARCH)),) + Kconfig := arch/$(SRCARCH)/Kconfig.$(ARCH) +else + Kconfig := arch/$(SRCARCH)/Kconfig +endif xconfig: $(obj)/qconf $< $(Kconfig) diff --git a/trunk/scripts/kconfig/conf.c b/trunk/scripts/kconfig/conf.c index c6bee85c3962..a38787a881ea 100644 --- a/trunk/scripts/kconfig/conf.c +++ b/trunk/scripts/kconfig/conf.c @@ -591,7 +591,6 @@ int main(int ac, char **av) conf_read_simple(name, S_DEF_USER); else if (!stat("all.config", &tmpstat)) conf_read_simple("all.config", S_DEF_USER); - conf_set_env_sym("K64BIT", "64BIT", S_DEF_USER); break; default: break; diff --git a/trunk/scripts/kconfig/confdata.c b/trunk/scripts/kconfig/confdata.c index e4fa3f302541..b2913e9da495 100644 --- a/trunk/scripts/kconfig/confdata.c +++ b/trunk/scripts/kconfig/confdata.c @@ -83,95 +83,6 @@ char *conf_get_default_confname(void) return name; } -static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) -{ - char *p2; - - switch (sym->type) { - case S_TRISTATE: - if (p[0] == 'm') { - sym->def[def].tri = mod; - sym->flags |= def_flags; - break; - } - case S_BOOLEAN: - if (p[0] == 'y') { - sym->def[def].tri = yes; - sym->flags |= def_flags; - break; - } - if (p[0] == 'n') { - sym->def[def].tri = no; - sym->flags |= def_flags; - break; - } - conf_warning("symbol value '%s' invalid for %s", p, sym->name); - break; - case S_OTHER: - if (*p != '"') { - for (p2 = p; *p2 && !isspace(*p2); p2++) - ; - sym->type = S_STRING; - goto done; - } - case S_STRING: - if (*p++ != '"') - break; - for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) { - if (*p2 == '"') { - *p2 = 0; - break; - } - memmove(p2, p2 + 1, strlen(p2)); - } - if (!p2) { - conf_warning("invalid string found"); - return 1; - } - case S_INT: - case S_HEX: - done: - if (sym_string_valid(sym, p)) { - sym->def[def].val = strdup(p); - sym->flags |= def_flags; - } else { - conf_warning("symbol value '%s' invalid for %s", p, sym->name); - return 1; - } - break; - default: - ; - } - return 0; -} - -/* Read an environment variable and assign the value to the symbol */ -int conf_set_env_sym(const char *env, const char *symname, int def) -{ - struct symbol *sym; - char *p; - int def_flags; - - p = getenv(env); - if (p) { - char warning[200]; - sprintf(warning, "Environment variable (%s = \"%s\")", env, p); - conf_filename = warning; - def_flags = SYMBOL_DEF << def; - if (def == S_DEF_USER) { - sym = sym_find(symname); - if (!sym) - return 1; - } else { - sym = sym_lookup(symname, 0); - if (sym->type == S_UNKNOWN) - sym->type = S_OTHER; - } - conf_set_sym_val(sym, def, def_flags, p); - } - return 0; -} - int conf_read_simple(const char *name, int def) { FILE *in = NULL; @@ -302,8 +213,61 @@ int conf_read_simple(const char *name, int def) conf_warning("trying to reassign symbol %s", sym->name); break; } - if (conf_set_sym_val(sym, def, def_flags, p)) - continue; + switch (sym->type) { + case S_TRISTATE: + if (p[0] == 'm') { + sym->def[def].tri = mod; + sym->flags |= def_flags; + break; + } + case S_BOOLEAN: + if (p[0] == 'y') { + sym->def[def].tri = yes; + sym->flags |= def_flags; + break; + } + if (p[0] == 'n') { + sym->def[def].tri = no; + sym->flags |= def_flags; + break; + } + conf_warning("symbol value '%s' invalid for %s", p, sym->name); + break; + case S_OTHER: + if (*p != '"') { + for (p2 = p; *p2 && !isspace(*p2); p2++) + ; + sym->type = S_STRING; + goto done; + } + case S_STRING: + if (*p++ != '"') + break; + for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) { + if (*p2 == '"') { + *p2 = 0; + break; + } + memmove(p2, p2 + 1, strlen(p2)); + } + if (!p2) { + conf_warning("invalid string found"); + continue; + } + case S_INT: + case S_HEX: + done: + if (sym_string_valid(sym, p)) { + sym->def[def].val = strdup(p); + sym->flags |= def_flags; + } else { + conf_warning("symbol value '%s' invalid for %s", p, sym->name); + continue; + } + break; + default: + ; + } break; case '\r': case '\n': diff --git a/trunk/scripts/kconfig/lkc_proto.h b/trunk/scripts/kconfig/lkc_proto.h index dca294e90cc3..4d09f6ddefe3 100644 --- a/trunk/scripts/kconfig/lkc_proto.h +++ b/trunk/scripts/kconfig/lkc_proto.h @@ -1,7 +1,6 @@ /* confdata.c */ P(conf_parse,void,(const char *name)); -P(conf_set_env_sym,int,(const char *envname, const char *symname, int def)); P(conf_read,int,(const char *name)); P(conf_read_simple,int,(const char *name, int)); P(conf_write,int,(const char *name)); diff --git a/trunk/security/commoncap.c b/trunk/security/commoncap.c index 302e8d0839a9..bf67871173ef 100644 --- a/trunk/security/commoncap.c +++ b/trunk/security/commoncap.c @@ -526,10 +526,6 @@ int cap_task_kill(struct task_struct *p, struct siginfo *info, if (info != SEND_SIG_NOINFO && (is_si_special(info) || SI_FROMKERNEL(info))) return 0; - /* sigcont is permitted within same session */ - if (sig == SIGCONT && (task_session_nr(current) == task_session_nr(p))) - return 0; - if (secid) /* * Signal sent as a particular user.