--- linux-2.6.24.orig/Makefile +++ linux-2.6.24/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 24 -EXTRAVERSION = .2 +EXTRAVERSION = .6 NAME = Err Metey! A Heury Beelge-a Ret! # *DOCUMENTATION* @@ -189,7 +189,7 @@ # Alternatively CROSS_COMPILE can be set in the environment. # Default value for CROSS_COMPILE is not to prefix executables # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile - +export KBUILD_BUILDHOST := $(SUBARCH) ARCH ?= $(SUBARCH) CROSS_COMPILE ?= @@ -297,9 +297,17 @@ # Make variables (CC, etc...) +CC = $(CROSS_COMPILE)gcc + +# +# gcc-4.2 won't build powerpc64-smp or ia64. +# +ifneq (,$(findstring $(ARCH), powerpc ia64)) +CC = gcc-4.1 +endif + AS = $(CROSS_COMPILE)as LD = $(CROSS_COMPILE)ld -CC = $(CROSS_COMPILE)gcc CPP = $(CC) -E AR = $(CROSS_COMPILE)ar NM = $(CROSS_COMPILE)nm @@ -313,6 +321,7 @@ PERL = perl CHECK = sparse + CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ -Wbitwise $(CF) MODFLAGS = -DMODULE CFLAGS_MODULE = $(MODFLAGS) @@ -321,10 +330,17 @@ CFLAGS_KERNEL = AFLAGS_KERNEL = +# Prefer linux-ubuntu-modules and linux-backports-modules +ifneq ($(KBUILD_SRC),) +ifneq ($(shell if test -e $(KBUILD_OUTPUT)/ubuntu-build; then echo yes; fi),yes) +UBUNTUINCLUDE := -I/usr/src/linux-headers-lum-$(KERNELRELEASE) \ + -I/usr/src/linux-headers-lbm-$(KERNELRELEASE) +endif +endif # Use LINUXINCLUDE when you must reference the include/ directory. # Needed to be compatible with the O= option -LINUXINCLUDE := -Iinclude \ +LINUXINCLUDE := $(UBUNTUINCLUDE) -Iinclude \ $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \ -include include/linux/autoconf.h --- linux-2.6.24.orig/Documentation/kernel-parameters.txt +++ linux-2.6.24/Documentation/kernel-parameters.txt @@ -545,6 +545,10 @@ This is a 16-member array composed of values ranging from 0-255. + default_relatime= + [FS] mount all filesystems with relative atime + updates by default. + vt.default_utf8= [VT] Format=<0|1> @@ -588,8 +592,7 @@ eata= [HW,SCSI] edd= [EDD] - Format: {"of[f]" | "sk[ipmbr]"} - See comment in arch/i386/boot/edd.S + Format: {"off" | "on" | "sk[ipmbr]"} eisa_irq_edge= [PARISC,HW] See header of drivers/parisc/eisa.c. @@ -786,6 +789,16 @@ for translation below 32 bit and if not available then look in the higher range. + io_delay= [X86-32,X86-64] I/O delay method + 0x80 + Standard port 0x80 based delay + 0xed + Alternate port 0xed based delay (needed on some systems) + udelay + Simple two microseconds delay + none + No delay + io7= [HW] IO7 for Marvel based alpha systems See comment before marvel_specify_io7 in arch/alpha/kernel/core_marvel.c. @@ -1320,6 +1333,8 @@ disable the use of PCIE advanced error reporting. nodomains [PCI] Disable support for multiple PCI root domains (aka PCI segments, in ACPI-speak). + mmconf [X86-32,X86_64] Enable use of MMCONFIG for PCI + Configuration nommconf [X86-32,X86_64] Disable use of MMCONFIG for PCI Configuration nomsi [MSI] If the PCI_MSI kernel config parameter is @@ -1519,6 +1534,10 @@ Format: [,[,...]] See arch/*/kernel/reboot.c or arch/*/kernel/process.c + relatime_interval= + [FS] relative atime update frequency, in seconds. + (default: 1 day: 86400 seconds) + reserve= [KNL,BUGS] Force the kernel to ignore some iomem area reservetop= [X86-32] --- linux-2.6.24.orig/Documentation/dsdt-initrd.txt +++ linux-2.6.24/Documentation/dsdt-initrd.txt @@ -0,0 +1,98 @@ +ACPI Custom DSDT read from initramfs + +2003 by Markuss Gaugusch < dsdt at gaugusch dot org > +Special thanks go to Thomas Renninger from SuSE, who updated the patch for +2.6.0 and later modified it to read inside initramfs +2004 - 2007 maintained by Eric Piel < eric dot piel at tremplin-utc dot net > + +This option is intended for people who would like to hack their DSDT and don't want +to recompile their kernel after every change. It can also be useful to distros +which offers pre-compiled kernels and want to allow their users to use a +modified DSDT. In the Kernel config, enable the initial RAM filesystem support +(in Device Drivers|Block Devices) and enable ACPI_CUSTOM_DSDT_INITRD at the ACPI +options (General Setup|ACPI Support|Read custom DSDT from initrd). + +A custom DSDT (Differentiated System Description Table) is useful when your +computer uses ACPI but problems occur due to broken implementation. Typically, +your computer works but there are some troubles with the hardware detection or +the power management. You can check that troubles come from errors in the DSDT by +activating the ACPI debug option and reading the logs. This table is provided +by the BIOS, therefore it might be a good idea to check for BIOS update on your +vendor website before going any further. Errors are often caused by vendors +testing their hardware only with Windows or because there is code which is +executed only on a specific OS with a specific version and Linux hasn't been +considered during the development. + +Before you run away from customising your DSDT, you should note that already +corrected tables are available for a fair amount of computers on this web-page: +http://acpi.sf.net/dsdt . If you are part of the unluckies who cannot find +their hardware in this database, you can modify your DSDT by yourself. This +process is less painful than it sounds. Download the Intel ASL +compiler/decompiler at http://www.intel.com/technology/IAPC/acpi/downloads.htm . +As root, you then have to dump your DSDT and decompile it. By using the +compiler messages as well as the kernel ACPI debug messages and the reference book +(available at the Intel website and also at http://www.acpi.info), it is quite +easy to obtain a fully working table. + +Once your new DSDT is ready you'll have to add it to an initrd so that the +kernel can read the table at the very beginning of the boot. As the file has +to be accessed very early during the boot process the initrd has to be an +initramfs. The file is contained into the initramfs under the name /DSDT.aml . +To obtain such an initrd, you might have to modify your mkinitrd script or you +can add it later to the initrd with the script appended to this document. The +command will look like: +initrd-add-dsdt initrd.img my-dsdt.aml + +In case you don't use any initrd, the possibilities you have are to either start +using one (try mkinitrd or yaird), or use the "Include Custom DSDT" configure +option to directly include your DSDT inside the kernel. + +The message "Looking for DSDT in initramfs..." will tell you if the DSDT was +found or not. If you need to update your DSDT, generate a new initrd and +perform the steps above. Don't forget that with Lilo, you'll have to re-run it. + + +======================= Here starts initrd-add-dsdt =============================== +#!/bin/bash +# Adds a DSDT file to the initrd (if it's an initramfs) +# first argument is the name of archive +# second argurment is the name of the file to add +# The file will be copied as /DSDT.aml + +# 20060126: fix "Premature end of file" with some old cpio (Roland Robic) +# 20060205: this time it should really work + +# check the arguments +if [ $# -ne 2 ]; then + program_name=$(basename $0) + echo "\ +$program_name: too few arguments +Usage: $program_name initrd-name.img DSDT-to-add.aml +Adds a DSDT file to an initrd (in initramfs format) + + initrd-name.img: filename of the initrd in initramfs format + DSDT-to-add.aml: filename of the DSDT file to add + " 1>&2 + exit 1 +fi + +# we should check it's an initramfs + +tempcpio=$(mktemp -d) +# cleanup on exit, hangup, interrupt, quit, termination +trap 'rm -rf $tempcpio' 0 1 2 3 15 + +# extract the archive +gunzip -c "$1" > "$tempcpio"/initramfs.cpio || exit 1 + +# copy the DSDT file at the root of the directory so that we can call it "/DSDT.aml" +cp -f "$2" "$tempcpio"/DSDT.aml + +# add the file +cd "$tempcpio" +(echo DSDT.aml | cpio --quiet -H newc -o -A -O "$tempcpio"/initramfs.cpio) || exit 1 +cd "$OLDPWD" + +# re-compress the archive +gzip -c "$tempcpio"/initramfs.cpio > "$1" + --- linux-2.6.24.orig/Documentation/hwmon/coretemp +++ linux-2.6.24/Documentation/hwmon/coretemp @@ -4,9 +4,10 @@ Supported chips: * All Intel Core family Prefix: 'coretemp' - CPUID: family 0x6, models 0xe, 0xf, 0x16 + CPUID: family 0x6, models 0xe, 0xf, 0x16, 0x17 Datasheet: Intel 64 and IA-32 Architectures Software Developer's Manual Volume 3A: System Programming Guide + http://softwarecommunity.intel.com/Wiki/Mobility/720.htm Author: Rudolf Marek --- linux-2.6.24.orig/Documentation/lguest/lguest.c +++ linux-2.6.24/Documentation/lguest/lguest.c @@ -34,6 +34,8 @@ #include #include #include +#include +#include #include "linux/lguest_launcher.h" #include "linux/virtio_config.h" #include "linux/virtio_net.h" @@ -79,6 +81,9 @@ /* The maximum guest physical address allowed, and maximum possible. */ static unsigned long guest_limit, guest_max; +/* a per-cpu variable indicating whose vcpu is currently running */ +static unsigned int __thread cpu_id; + /* This is our list of devices. */ struct device_list { @@ -96,13 +101,11 @@ /* The descriptor page for the devices. */ u8 *descpage; - /* The tail of the last descriptor. */ - unsigned int desc_used; - /* A single linked list of devices. */ struct device *dev; - /* ... And an end pointer so we can easily append new devices */ - struct device **lastdev; + /* And a pointer to the last device for easy append and also for + * configuration appending. */ + struct device *lastdev; }; /* The list of Guest devices, based on command line arguments. */ @@ -153,6 +156,9 @@ void (*handle_output)(int fd, struct virtqueue *me); }; +/* Remember the arguments to the program so we can "reboot" */ +static char **main_args; + /* Since guest is UP and we don't run at the same time, we don't need barriers. * But I include them in the code in case others copy it. */ #define wmb() @@ -185,7 +191,14 @@ #define cpu_to_le64(v64) (v64) #define le16_to_cpu(v16) (v16) #define le32_to_cpu(v32) (v32) -#define le64_to_cpu(v32) (v64) +#define le64_to_cpu(v64) (v64) + +/* The device virtqueue descriptors are followed by feature bitmasks. */ +static u8 *get_feature_bits(struct device *dev) +{ + return (u8 *)(dev->desc + 1) + + dev->desc->num_vq * sizeof(struct lguest_vqconfig); +} /*L:100 The Launcher code itself takes us out into userspace, that scary place * where pointers run wild and free! Unfortunately, like most userspace @@ -473,9 +486,12 @@ unsigned int i, len = 0; for (i = 0; args[i]; i++) { + if (i) { + strcat(dst+len, " "); + len++; + } strcpy(dst+len, args[i]); - strcat(dst+len, " "); - len += strlen(args[i]) + 1; + len += strlen(args[i]); } /* In case it's empty. */ dst[len] = '\0'; @@ -554,7 +570,7 @@ else FD_CLR(-fd - 1, &devices.infds); } else /* Send LHREQ_BREAK command. */ - write(lguest_fd, args, sizeof(args)); + pwrite(lguest_fd, args, sizeof(args), cpu_id); } } @@ -908,21 +924,58 @@ write(waker_fd, &vq->dev->fd, sizeof(vq->dev->fd)); } +/* Resetting a device is fairly easy. */ +static void reset_device(struct device *dev) +{ + struct virtqueue *vq; + + verbose("Resetting device %s\n", dev->name); + /* Clear the status. */ + dev->desc->status = 0; + + /* Clear any features they've acked. */ + memset(get_feature_bits(dev) + dev->desc->feature_len, 0, + dev->desc->feature_len); + + /* Zero out the virtqueues. */ + for (vq = dev->vq; vq; vq = vq->next) { + memset(vq->vring.desc, 0, + vring_size(vq->config.num, getpagesize())); + vq->last_avail_idx = 0; + } +} + /* This is the generic routine we call when the Guest uses LHCALL_NOTIFY. */ static void handle_output(int fd, unsigned long addr) { struct device *i; struct virtqueue *vq; - /* Check each virtqueue. */ + /* Check each device and virtqueue. */ for (i = devices.dev; i; i = i->next) { + /* Notifications to device descriptors reset the device. */ + if (from_guest_phys(addr) == i->desc) { + reset_device(i); + return; + } + + /* Notifications to virtqueues mean output has occurred. */ for (vq = i->vq; vq; vq = vq->next) { - if (vq->config.pfn == addr/getpagesize() - && vq->handle_output) { - verbose("Output to %s\n", vq->dev->name); - vq->handle_output(fd, vq); + if (vq->config.pfn != addr/getpagesize()) + continue; + + /* Guest should acknowledge (and set features!) before + * using the device. */ + if (i->desc->status == 0) { + warnx("%s gave early output", i->name); return; } + + if (strcmp(vq->dev->name, "console") != 0) + verbose("Output to %s\n", vq->dev->name); + if (vq->handle_output) + vq->handle_output(fd, vq); + return; } } @@ -980,54 +1033,44 @@ * * All devices need a descriptor so the Guest knows it exists, and a "struct * device" so the Launcher can keep track of it. We have common helper - * routines to allocate them. - * - * This routine allocates a new "struct lguest_device_desc" from descriptor - * table just above the Guest's normal memory. It returns a pointer to that - * descriptor. */ -static struct lguest_device_desc *new_dev_desc(u16 type) -{ - struct lguest_device_desc *d; + * routines to allocate and manage them. */ - /* We only have one page for all the descriptors. */ - if (devices.desc_used + sizeof(*d) > getpagesize()) - errx(1, "Too many devices"); - - /* We don't need to set config_len or status: page is 0 already. */ - d = (void *)devices.descpage + devices.desc_used; - d->type = type; - devices.desc_used += sizeof(*d); - - return d; +/* The layout of the device page is a "struct lguest_device_desc" followed by a + * number of virtqueue descriptors, then two sets of feature bits, then an + * array of configuration bytes. This routine returns the configuration + * pointer. */ +static u8 *device_config(const struct device *dev) +{ + return (void *)(dev->desc + 1) + + dev->desc->num_vq * sizeof(struct lguest_vqconfig) + + dev->desc->feature_len * 2; } -/* Each device descriptor is followed by some configuration information. - * Each configuration field looks like: u8 type, u8 len, [... len bytes...]. - * - * This routine adds a new field to an existing device's descriptor. It only - * works for the last device, but that's OK because that's how we use it. */ -static void add_desc_field(struct device *dev, u8 type, u8 len, const void *c) +/* This routine allocates a new "struct lguest_device_desc" from descriptor + * table page just above the Guest's normal memory. It returns a pointer to + * that descriptor. */ +static struct lguest_device_desc *new_dev_desc(u16 type) { - /* This is the last descriptor, right? */ - assert(devices.descpage + devices.desc_used - == (u8 *)(dev->desc + 1) + dev->desc->config_len); + struct lguest_device_desc d = { .type = type }; + void *p; - /* We only have one page of device descriptions. */ - if (devices.desc_used + 2 + len > getpagesize()) - errx(1, "Too many devices"); + /* Figure out where the next device config is, based on the last one. */ + if (devices.lastdev) + p = device_config(devices.lastdev) + + devices.lastdev->desc->config_len; + else + p = devices.descpage; - /* Copy in the new config header: type then length. */ - devices.descpage[devices.desc_used++] = type; - devices.descpage[devices.desc_used++] = len; - memcpy(devices.descpage + devices.desc_used, c, len); - devices.desc_used += len; + /* We only have one page for all the descriptors. */ + if (p + sizeof(d) > (void *)devices.descpage + getpagesize()) + errx(1, "Too many devices"); - /* Update the device descriptor length: two byte head then data. */ - dev->desc->config_len += 2 + len; + /* p might not be aligned, so we memcpy in. */ + return memcpy(p, &d, sizeof(d)); } -/* This routine adds a virtqueue to a device. We specify how many descriptors - * the virtqueue is to have. */ +/* Each device descriptor is followed by the description of its virtqueues. We + * specify how many descriptors the virtqueue is to have. */ static void add_virtqueue(struct device *dev, unsigned int num_descs, void (*handle_output)(int fd, struct virtqueue *me)) { @@ -1053,9 +1096,15 @@ /* Initialize the vring. */ vring_init(&vq->vring, num_descs, p, getpagesize()); - /* Add the configuration information to this device's descriptor. */ - add_desc_field(dev, VIRTIO_CONFIG_F_VIRTQUEUE, - sizeof(vq->config), &vq->config); + /* Append virtqueue to this device's descriptor. We use + * device_config() to get the end of the device's current virtqueues; + * we check that we haven't added any config or feature information + * yet, otherwise we'd be overwriting them. */ + assert(dev->desc->config_len == 0 && dev->desc->feature_len == 0); + memcpy(device_config(dev), &vq->config, sizeof(vq->config)); + dev->desc->num_vq++; + + verbose("Virtqueue page %#lx\n", to_guest_phys(p)); /* Add to tail of list, so dev->vq is first vq, dev->vq->next is * second. */ @@ -1066,11 +1115,41 @@ * virtqueue. */ vq->handle_output = handle_output; - /* Set the "Don't Notify Me" flag if we don't have a handler */ + /* As an optimization, set the advisory "Don't Notify Me" flag if we + * don't have a handler */ if (!handle_output) vq->vring.used->flags = VRING_USED_F_NO_NOTIFY; } +/* The first half of the feature bitmask is for us to advertise features. The + * second half if for the Guest to accept features. */ +static void add_feature(struct device *dev, unsigned bit) +{ + u8 *features = get_feature_bits(dev); + + /* We can't extend the feature bits once we've added config bytes */ + if (dev->desc->feature_len <= bit / CHAR_BIT) { + assert(dev->desc->config_len == 0); + dev->desc->feature_len = (bit / CHAR_BIT) + 1; + } + + features[bit / CHAR_BIT] |= (1 << (bit % CHAR_BIT)); +} + +/* This routine sets the configuration fields for an existing device's + * descriptor. It only works for the last device, but that's OK because that's + * how we use it. */ +static void set_config(struct device *dev, unsigned len, const void *conf) +{ + /* Check we haven't overflowed our single page. */ + if (device_config(dev) + len > devices.descpage + getpagesize()) + errx(1, "Too many devices"); + + /* Copy in the config information, and store the length. */ + memcpy(device_config(dev), conf, len); + dev->desc->config_len = len; +} + /* This routine does all the creation and setup of a new device, including * calling new_dev_desc() to allocate the descriptor and device memory. */ static struct device *new_device(const char *name, u16 type, int fd, @@ -1078,14 +1157,6 @@ { struct device *dev = malloc(sizeof(*dev)); - /* Append to device list. Prepending to a single-linked list is - * easier, but the user expects the devices to be arranged on the bus - * in command-line order. The first network device on the command line - * is eth0, the first block device /dev/vda, etc. */ - *devices.lastdev = dev; - dev->next = NULL; - devices.lastdev = &dev->next; - /* Now we populate the fields one at a time. */ dev->fd = fd; /* If we have an input handler for this file descriptor, then we add it @@ -1096,6 +1167,17 @@ dev->handle_input = handle_input; dev->name = name; dev->vq = NULL; + + /* Append to device list. Prepending to a single-linked list is + * easier, but the user expects the devices to be arranged on the bus + * in command-line order. The first network device on the command line + * is eth0, the first block device /dev/vda, etc. */ + if (devices.lastdev) + devices.lastdev->next = dev; + else + devices.dev = dev; + devices.lastdev = dev; + return dev; } @@ -1220,7 +1302,7 @@ int netfd, ipfd; u32 ip; const char *br_name = NULL; - u8 hwaddr[6]; + struct virtio_net_config conf; /* We open the /dev/net/tun device and tell it we want a tap device. A * tap device is like a tun device, only somehow different. To tell @@ -1259,12 +1341,13 @@ ip = str2ip(arg); /* Set up the tun device, and get the mac address for the interface. */ - configure_device(ipfd, ifr.ifr_name, ip, hwaddr); + configure_device(ipfd, ifr.ifr_name, ip, conf.mac); /* Tell Guest what MAC address to use. */ - add_desc_field(dev, VIRTIO_CONFIG_NET_MAC_F, sizeof(hwaddr), hwaddr); + add_feature(dev, VIRTIO_NET_F_MAC); + set_config(dev, sizeof(conf), &conf); - /* We don't seed the socket any more; setup is done. */ + /* We don't need the socket any more; setup is done. */ close(ipfd); verbose("device %u: tun net %u.%u.%u.%u\n", @@ -1300,7 +1383,6 @@ * Launcher triggers interrupt to Guest. */ int done_fd; }; -/*:*/ /*L:210 * The Disk @@ -1452,8 +1534,7 @@ struct device *dev; struct vblk_info *vblk; void *stack; - u64 cap; - unsigned int val; + struct virtio_blk_config conf; /* This is the pipe the I/O thread will use to tell us I/O is done. */ pipe(p); @@ -1471,14 +1552,18 @@ vblk->fd = open_or_die(filename, O_RDWR|O_LARGEFILE); vblk->len = lseek64(vblk->fd, 0, SEEK_END); + /* We support barriers. */ + add_feature(dev, VIRTIO_BLK_F_BARRIER); + /* Tell Guest how many sectors this device has. */ - cap = cpu_to_le64(vblk->len / 512); - add_desc_field(dev, VIRTIO_CONFIG_BLK_F_CAPACITY, sizeof(cap), &cap); + conf.capacity = cpu_to_le64(vblk->len / 512); /* Tell Guest not to put in too many descriptors at once: two are used * for the in and out elements. */ - val = cpu_to_le32(VIRTQUEUE_NUM - 2); - add_desc_field(dev, VIRTIO_CONFIG_BLK_F_SEG_MAX, sizeof(val), &val); + add_feature(dev, VIRTIO_BLK_F_SEG_MAX); + conf.seg_max = cpu_to_le32(VIRTQUEUE_NUM - 2); + + set_config(dev, sizeof(conf), &conf); /* The I/O thread writes to this end of the pipe when done. */ vblk->done_fd = p[1]; @@ -1489,7 +1574,9 @@ /* Create stack for thread and run it */ stack = malloc(32768); - if (clone(io_thread, stack + 32768, CLONE_VM, dev) == -1) + /* SIGCHLD - We dont "wait" for our cloned thread, so prevent it from + * becoming a zombie. */ + if (clone(io_thread, stack + 32768, CLONE_VM | SIGCHLD, dev) == -1) err(1, "Creating clone"); /* We don't need to keep the I/O thread's end of the pipes open. */ @@ -1497,9 +1584,23 @@ close(vblk->workpipe[0]); verbose("device %u: virtblock %llu sectors\n", - devices.device_num, cap); + devices.device_num, le64_to_cpu(conf.capacity)); +} +/* That's the end of device setup. :*/ + +/* Reboot */ +static void __attribute__((noreturn)) restart_guest(void) +{ + unsigned int i; + + /* Closing pipes causes the waker thread and io_threads to die, and + * closing /dev/lguest cleans up the Guest. Since we don't track all + * open fds, we simply close everything beyond stderr. */ + for (i = 3; i < FD_SETSIZE; i++) + close(i); + execv(main_args[0], main_args); + err(1, "Could not exec %s", main_args[0]); } -/* That's the end of device setup. */ /*L:220 Finally we reach the core of the Launcher, which runs the Guest, serves * its input and output, and finally, lays it to rest. */ @@ -1511,7 +1612,8 @@ int readval; /* We read from the /dev/lguest device to run the Guest. */ - readval = read(lguest_fd, ¬ify_addr, sizeof(notify_addr)); + readval = pread(lguest_fd, ¬ify_addr, + sizeof(notify_addr), cpu_id); /* One unsigned long means the Guest did HCALL_NOTIFY */ if (readval == sizeof(notify_addr)) { @@ -1521,16 +1623,23 @@ /* ENOENT means the Guest died. Reading tells us why. */ } else if (errno == ENOENT) { char reason[1024] = { 0 }; - read(lguest_fd, reason, sizeof(reason)-1); + pread(lguest_fd, reason, sizeof(reason)-1, cpu_id); errx(1, "%s", reason); + /* ERESTART means that we need to reboot the guest */ + } else if (errno == ERESTART) { + restart_guest(); /* EAGAIN means the Waker wanted us to look at some input. * Anything else means a bug or incompatible change. */ } else if (errno != EAGAIN) err(1, "Running guest failed"); + /* Only service input on thread for CPU 0. */ + if (cpu_id != 0) + continue; + /* Service input, then unset the BREAK to release the Waker. */ handle_input(lguest_fd); - if (write(lguest_fd, args, sizeof(args)) < 0) + if (pwrite(lguest_fd, args, sizeof(args), cpu_id) < 0) err(1, "Resetting break"); } } @@ -1571,17 +1680,24 @@ /* If they specify an initrd file to load. */ const char *initrd_name = NULL; + /* Save the args: we "reboot" by execing ourselves again. */ + main_args = argv; + /* We don't "wait" for the children, so prevent them from becoming + * zombies. */ + signal(SIGCHLD, SIG_IGN); + /* First we initialize the device list. Since console and network * device receive input from a file descriptor, we keep an fdset * (infds) and the maximum fd number (max_infd) with the head of the - * list. We also keep a pointer to the last device, for easy appending - * to the list. Finally, we keep the next interrupt number to hand out - * (1: remember that 0 is used by the timer). */ + * list. We also keep a pointer to the last device. Finally, we keep + * the next interrupt number to hand out (1: remember that 0 is used by + * the timer). */ FD_ZERO(&devices.infds); devices.max_infd = -1; - devices.lastdev = &devices.dev; + devices.lastdev = NULL; devices.next_irq = 1; + cpu_id = 0; /* We need to know how much memory so we can set up the device * descriptor and memory pages for the devices as we parse the command * line. So we quickly look through the arguments to find the amount --- linux-2.6.24.orig/Documentation/lguest/lguest.txt +++ linux-2.6.24/Documentation/lguest/lguest.txt @@ -1,6 +1,7 @@ -Rusty's Remarkably Unreliable Guide to Lguest - - or, A Young Coder's Illustrated Hypervisor -http://lguest.ozlabs.org + __ + (___()'`; Rusty's Remarkably Unreliable Guide to Lguest + /, /` - or, A Young Coder's Illustrated Hypervisor + \\"--\\ http://lguest.ozlabs.org Lguest is designed to be a minimal hypervisor for the Linux kernel, for Linux developers and users to experiment with virtualization with the @@ -41,12 +42,16 @@ CONFIG_PHYSICAL_ALIGN=0x100000) "Device Drivers": + "Block devices" + "Virtio block driver (EXPERIMENTAL)" = M/Y "Network device support" "Universal TUN/TAP device driver support" = M/Y - (CONFIG_TUN=m) - "Virtualization" - "Linux hypervisor example code" = M/Y - (CONFIG_LGUEST=m) + "Virtio network driver (EXPERIMENTAL)" = M/Y + (CONFIG_VIRTIO_BLK=m, CONFIG_VIRTIO_NET=m and CONFIG_TUN=m) + + "Virtualization" + "Linux hypervisor example code" = M/Y + (CONFIG_LGUEST=m) - A tool called "lguest" is available in this directory: type "make" to build it. If you didn't build your kernel in-tree, use "make --- linux-2.6.24.orig/Documentation/video4linux/CARDLIST.em28xx +++ linux-2.6.24/Documentation/video4linux/CARDLIST.em28xx @@ -8,7 +8,7 @@ 7 -> Leadtek Winfast USB II (em2800) 8 -> Kworld USB2800 (em2800) 9 -> Pinnacle Dazzle DVC 90 (em2820/em2840) [2304:0207] - 10 -> Hauppauge WinTV HVR 900 (em2880) + 10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500,2040:6502] 11 -> Terratec Hybrid XS (em2880) 12 -> Kworld PVR TV 2800 RF (em2820/em2840) 13 -> Terratec Prodigy XS (em2880) --- linux-2.6.24.orig/Documentation/lsm/AppArmor-Security-Goal.txt +++ linux-2.6.24/Documentation/lsm/AppArmor-Security-Goal.txt @@ -0,0 +1,134 @@ +AppArmor Security Goal +Crispin Cowan, PhD +MercenaryLinux.com + +This document specifies the security goal that AppArmor is intended to +achieve, so that users can evaluate whether AppArmor will meet their +needs, and kernel developers can evaluate whether AppArmor is living up +to its claims. This document is *not* a general purpose explanation of +how AppArmor works, nor is it an explanation for why one might want to +use AppArmor rather than some other system. + +AppArmor is intended to limit system damage from attackers exploiting +vulnerabilities in applications that the system hosts. The threat is +that an attacker can cause a vulnerable application to do something +unexpected and undesirable. AppArmor addresses this threat by confining +the application to access only the resources it needs to access to +execute properly, effectively imposing "least privilege" execution on +the application. + +Applications interact with the rest of the system via resources +including files, interprocess communication, networking, capabilities, +and execution of other applications. The purpose of least privilege is +to bound the damage that a malicious user or code can do by removing +access to resources that the application does not need for its intended +function. This is true for all access control systems, including AppArmor. + +The "attacker" is someone trying to gain the privileges of a process for +themselves. For instance, a policy for a web server might grant read +only access to most web documents, preventing an attacker who can +corrupt the web server from defacing the web pages. A web server has +access to the web server's local file system, and a network attacker +trying to hack the web server does not have such file access. An e-mail +attacker attempting to infect the recipient of the e-mail does not have +access to the files that the victim user's mail client does. By limiting +the scope of access for an application, AppArmor can limit the damage an +attacker can do by exploiting vulnerabilities in applications. + +An "application" is one or more related processes performing a function, +e.g. the gang of processes that constitute an Apache web server, or a +Postfix mail server. AppArmor *only* confines processes that the +AppArmor policy says it should confine, and other processes are +permitted to do anything that DAC permits. This is sometimes known as a +targeted security policy. + +AppArmor does not provide a "default" policy that applies to all +processes. So to defend an entire host, you have to piece-wise confine +each process that is exposed to potential attack. For instance, to +defend a system against network attack, place AppArmor profiles around +every application that accesses the network. This limits the damage a +network attacker can do to the file system to only those files granted +by the profiles for the network-available applications. Similarly, to +defend a system against attack from the console, place AppArmor profiles +around every application that accessed the keyboard and mouse. The +system is "defended" in that the worst the attacker can do to corrupt +the system is limited to the transitive closure of what the confined +processes are allowed to access. + +AppArmor currently mediates access to files, ability to use POSIX.1e +Capabilities, and coarse-grained control on network access. This is +sufficient to prevent a confined process from *directly* corrupting the +file system. It is not sufficient to prevent a confined process from +*indirectly* corrupting the system by influencing some other process to +do the dirty deed. But to do so requires a complicit process that can be +manipulated through another channel such as IPC. A "complicit" process +is either a malicious process the attacker somehow got control of, or is +a process that is actively listening to IPC of some kind and can be +corrupted via IPC. + +The only IPC that AppArmor mediates is access to named sockets, FIFOs, +etc. that appear in the file system name space, a side effect of +AppArmor's file access mediation. Future versions of AppArmor will +mediate more resources, including finer grained network access controls, +and controls on various forms of IPC. + +AppArmor specifies the programs to be confined and the resources they +can access in a syntax similar to how users are accustomed to accessing +those resources. So file access controls are specified using absolute +paths with respect to the name space the process is in. POSIX.1e +capabilities are specified by name. Network access controls currently +are specified by simply naming the protocol that can be used e.g. tcp, +udp, and in the future will be more general, resembling firewall rules. + +Thus the AppArmor security goal should be considered piecewise from the +point of view of a single confined process: that process should only be +able to access the resources specified in its profile: + + * can only access files that are reachable in its name space by path + names matching its profile, and only with the permitted modes: + read, append, write, memory map, execute, and link + * can only use the POSIX.1e capabilities listed in the profile + * can only perform the network operations listed in the profile + +Security issues that AppArmor explicitly does *not* address: + + * Processes that are not confined by AppArmor are not restricted in + any way by AppArmor. If an unconfined process is considered an + unacceptable threat, then confine additional applications until + adequate security is achieved. + * A process that is not permitted to directly access a resource can + influence some other process that does have access to the resource + may do so, if the "influence" is a permitted action. + * A confined process may only access a file if it has at least one + of the files aliases specified in its profile. If a file alias is + not specified in the profile then it can not be accessed by that + path. The creation of aliases needs to be tightly controlled in + confined applications, hard links creation should be limited to + provide adequate security. + * A confined process can operate on a file descriptor passed to it + by an unconfined process, even if it manipulates a file not in the + confined process's profile. To block this attack, confine the + process that passed the file descriptor. + * Process activities not currently mediated by AppArmor are + permitted, e.g. confined processes can perform any IPC that DAC + permits, other than signals as mediated by CAP_KILL. + * Manipulating AppArmor policy requires being both root privileged + and not being confined by AppArmor, thus there is explicitly no + capability for non-privileged users to change AppArmor policy. + * AppArmor confines processes if they are children of a confined + process, or if the name of the exec'd child matches the name of an + AppArmor profile. Another process could copy a program to a + different path name and then execute it without confinement, but + the other process would have to have permission to do so in the + first place. To prevent this, confine the other process and + additional applications until adequate security is achieved. + * Mount and namespace manipulations can be used to arbitrarily + change the pathnames that files appear at, and thus completely + bypass AppArmor policy. To prevent this, processes confined by + AppArmor are currently not permitted to call mount or manipulate + name spaces at all. A future development may provide more granular + controls on mount and namespace manipulations. + * AppArmor does not slice bread, cure cancer, bring world peace, or + provide perfect security. This list may be expanded :-) + + --- linux-2.6.24.orig/Documentation/power/devices.txt +++ linux-2.6.24/Documentation/power/devices.txt @@ -310,9 +310,12 @@ PM_EVENT_SUSPEND -- quiesce the driver and put hardware into a low-power state. When used with system sleep states like "suspend-to-RAM" or "standby", the upcoming resume() call will often be able to rely on - state kept in hardware, or issue system wakeup events. When used - instead with suspend-to-disk, few devices support this capability; - most are completely powered off. + state kept in hardware, or issue system wakeup events. + + PM_EVENT_HIBERNATE -- Put hardware into a low-power state and enable wakeup + events as appropriate. It is only used with hibernation + (suspend-to-disk) and few devices are able to wake up the system from + this state; most are completely powered off. PM_EVENT_FREEZE -- quiesce the driver, but don't necessarily change into any low power mode. A system snapshot is about to be taken, often @@ -329,8 +332,8 @@ wakeup events nor DMA are allowed. To enter "standby" (ACPI S1) or "Suspend to RAM" (STR, ACPI S3) states, or -the similarly named APM states, only PM_EVENT_SUSPEND is used; for "Suspend -to Disk" (STD, hibernate, ACPI S4), all of those event codes are used. +the similarly named APM states, only PM_EVENT_SUSPEND is used; the other event +codes are used for hibernation ("Suspend to Disk", STD, ACPI S4). There's also PM_EVENT_ON, a value which never appears as a suspend event but is sometimes used to record the "not suspended" device state. --- linux-2.6.24.orig/scripts/Makefile.modpost +++ linux-2.6.24/scripts/Makefile.modpost @@ -53,6 +53,9 @@ # Stop after building .o files if NOFINAL is set. Makes compile tests quicker _modpost: $(if $(KBUILD_MODPOST_NOFINAL), $(modules:.ko:.o),$(modules)) +ifneq ($(KBUILD_BUILDHOST),$(ARCH)) + cross_build := 1 +endif # Step 2), invoke modpost # Includes step 3,4 @@ -62,7 +65,8 @@ $(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \ $(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \ $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ - $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) + $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) \ + $(if $(cross_build),-c) quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules cmd_modpost = $(modpost) -s --- linux-2.6.24.orig/scripts/mod/modpost.c +++ linux-2.6.24/scripts/mod/modpost.c @@ -1659,7 +1659,7 @@ int opt; int err; - while ((opt = getopt(argc, argv, "i:I:mso:aw")) != -1) { + while ((opt = getopt(argc, argv, "i:I:cmso:aw")) != -1) { switch(opt) { case 'i': kernel_read = optarg; @@ -1668,6 +1668,9 @@ module_read = optarg; external_module = 1; break; + case 'c': + cross_build = 1; + break; case 'm': modversions = 1; break; --- linux-2.6.24.orig/scripts/mod/file2alias.c +++ linux-2.6.24/scripts/mod/file2alias.c @@ -51,11 +51,13 @@ sprintf(str + strlen(str), "*"); \ } while(0) +unsigned int cross_build = 0; /** * Check that sizeof(device_id type) are consistent with size of section * in .o file. If in-consistent then userspace and kernel does not agree * on actual size which is a bug. * Also verify that the final entry in the table is all zeros. + * Ignore both checks if build host differ from target host and size differs. **/ static void device_id_check(const char *modname, const char *device_id, unsigned long size, unsigned long id_size, @@ -64,6 +66,8 @@ int i; if (size % id_size || size < id_size) { + if (cross_build != 0) + return; fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo " "of the size of section __mod_%s_device_table=%lu.\n" "Fix definition of struct %s_device_id " --- linux-2.6.24.orig/scripts/mod/modpost.h +++ linux-2.6.24/scripts/mod/modpost.h @@ -130,6 +130,7 @@ }; /* file2alias.c */ +extern unsigned int cross_build; void handle_moddevtable(struct module *mod, struct elf_info *info, Elf_Sym *sym, const char *symname); void add_moddevtable(struct buffer *buf, struct module *mod); --- linux-2.6.24.orig/arch/powerpc/kernel/ppc_ksyms.c +++ linux-2.6.24/arch/powerpc/kernel/ppc_ksyms.c @@ -145,9 +145,11 @@ long long __ashrdi3(long long, int); long long __ashldi3(long long, int); long long __lshrdi3(long long, int); +int __ucmpdi2(uint64_t, uint64_t); EXPORT_SYMBOL(__ashrdi3); EXPORT_SYMBOL(__ashldi3); EXPORT_SYMBOL(__lshrdi3); +EXPORT_SYMBOL(__ucmpdi2); #endif EXPORT_SYMBOL(memcpy); --- linux-2.6.24.orig/arch/powerpc/kernel/misc_32.S +++ linux-2.6.24/arch/powerpc/kernel/misc_32.S @@ -756,6 +756,27 @@ or r4,r4,r7 # LSW |= t2 blr +/* + * __ucmpdi2: 64-bit comparison + * + * R3/R4 has 64 bit value A + * R5/R6 has 64 bit value B + * result in R3: 0 for A < B + * 1 for A == B + * 2 for A > B + */ +_GLOBAL(__ucmpdi2) + cmplw r7,r3,r5 # compare high words + li r3,0 + blt r7,2f # a < b ... return 0 + bgt r7,1f # a > b ... return 2 + cmplw r6,r4,r6 # compare low words + blt r6,2f # a < b ... return 0 + li r3,1 + ble r6,2f # a = b ... return 1 +1: li r3,2 +2: blr + _GLOBAL(abs) srawi r4,r3,31 xor r3,r3,r4 --- linux-2.6.24.orig/arch/powerpc/kernel/vdso.c +++ linux-2.6.24/arch/powerpc/kernel/vdso.c @@ -141,7 +141,7 @@ printk("kpg: %p (c:%d,f:%08lx)", __va(page_to_pfn(pg) << PAGE_SHIFT), page_count(pg), pg->flags); - if (upg/* && pg != upg*/) { + if (upg && !IS_ERR(upg) /* && pg != upg*/) { printk(" upg: %p (c:%d,f:%08lx)", __va(page_to_pfn(upg) << PAGE_SHIFT), page_count(upg), --- linux-2.6.24.orig/arch/powerpc/platforms/chrp/pci.c +++ linux-2.6.24/arch/powerpc/platforms/chrp/pci.c @@ -354,7 +354,7 @@ * mode as well. The same fixup must be done to the class-code property in * the IDE node /pci@80000000/ide@C,1 */ -static void __devinit chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide) +static void chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide) { u8 progif; struct pci_dev *viaisa; @@ -375,4 +375,4 @@ pci_dev_put(viaisa); } -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata); --- linux-2.6.24.orig/arch/powerpc/platforms/chrp/setup.c +++ linux-2.6.24/arch/powerpc/platforms/chrp/setup.c @@ -115,7 +115,7 @@ seq_printf(m, "machine\t\t: CHRP %s\n", model); /* longtrail (goldengate) stuff */ - if (!strncmp(model, "IBM,LongTrail", 13)) { + if (model && !strncmp(model, "IBM,LongTrail", 13)) { /* VLSI VAS96011/12 `Golden Gate 2' */ /* Memory banks */ sdramen = (in_le32(gg2_pci_config_base + GG2_PCI_DRAM_CTRL) @@ -203,15 +203,20 @@ static void __init sio_init(void) { struct device_node *root; + const char *model; - if ((root = of_find_node_by_path("/")) && - !strncmp(of_get_property(root, "model", NULL), - "IBM,LongTrail", 13)) { + root = of_find_node_by_path("/"); + if (!root) + return; + + model = of_get_property(root, "model", NULL); + if (model && !strncmp(model, "IBM,LongTrail", 13)) { /* logical device 0 (KBC/Keyboard) */ sio_fixup_irq("keyboard", 0, 1, 2); /* select logical device 1 (KBC/Mouse) */ sio_fixup_irq("mouse", 1, 12, 2); } + of_node_put(root); } --- linux-2.6.24.orig/arch/powerpc/platforms/powermac/feature.c +++ linux-2.6.24/arch/powerpc/platforms/powermac/feature.c @@ -2565,6 +2565,8 @@ /* Locate core99 Uni-N */ uninorth_node = of_find_node_by_name(NULL, "uni-n"); + uninorth_maj = 1; + /* Locate G5 u3 */ if (uninorth_node == NULL) { uninorth_node = of_find_node_by_name(NULL, "u3"); @@ -2575,8 +2577,10 @@ uninorth_node = of_find_node_by_name(NULL, "u4"); uninorth_maj = 4; } - if (uninorth_node == NULL) + if (uninorth_node == NULL) { + uninorth_maj = 0; return; + } addrp = of_get_property(uninorth_node, "reg", NULL); if (addrp == NULL) @@ -3029,3 +3033,8 @@ pmac_agp_resume(pmac_agp_bridge); } EXPORT_SYMBOL(pmac_resume_agp_for_card); + +int pmac_get_uninorth_variant(void) +{ + return uninorth_maj; +} --- linux-2.6.24.orig/arch/powerpc/platforms/powermac/setup.c +++ linux-2.6.24/arch/powerpc/platforms/powermac/setup.c @@ -584,12 +584,10 @@ DMA_MODE_READ = 1; DMA_MODE_WRITE = 2; -#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) -#ifdef CONFIG_BLK_DEV_IDE_PMAC +#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports; ppc_ide_md.default_io_base = pmac_ide_get_base; -#endif /* CONFIG_BLK_DEV_IDE_PMAC */ -#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */ +#endif #endif /* CONFIG_PPC32 */ --- linux-2.6.24.orig/arch/ia64/pci/pci.c +++ linux-2.6.24/arch/ia64/pci/pci.c @@ -371,7 +371,12 @@ info.name = name; acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window, &info); - + /* + * See arch/x86/pci/acpi.c. + * The desired pci bus might already be scanned in a quirk. We + * should handle the case here, but it appears that IA64 hasn't + * such quirk. So we just ignore the case now. + */ pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller); if (pbus) pcibios_setup_root_windows(pbus, controller); --- linux-2.6.24.orig/arch/ia64/ia32/binfmt_elf32.c +++ linux-2.6.24/arch/ia64/ia32/binfmt_elf32.c @@ -222,7 +222,7 @@ } static unsigned long -elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type) +elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type, unsigned long unused) { unsigned long pgoff = (eppnt->p_vaddr) & ~IA32_PAGE_MASK; --- linux-2.6.24.orig/arch/sparc/kernel/sys_sparc.c +++ linux-2.6.24/arch/sparc/kernel/sys_sparc.c @@ -224,8 +224,7 @@ { if (ARCH_SUN4C_SUN4 && (len > 0x20000000 || - ((flags & MAP_FIXED) && - addr < 0xe0000000 && addr + len > 0x20000000))) + (addr < 0xe0000000 && addr + len > 0x20000000))) return -EINVAL; /* See asm-sparc/uaccess.h */ --- linux-2.6.24.orig/arch/sparc/lib/rwsem.S +++ linux-2.6.24/arch/sparc/lib/rwsem.S @@ -7,7 +7,7 @@ #include #include - .section .sched.text + .section .sched.text, "ax" .align 4 .globl ___down_read --- linux-2.6.24.orig/arch/mips/kernel/i8259.c +++ linux-2.6.24/arch/mips/kernel/i8259.c @@ -338,8 +338,10 @@ init_8259A(0); - for (i = I8259A_IRQ_BASE; i < I8259A_IRQ_BASE + 16; i++) + for (i = I8259A_IRQ_BASE; i < I8259A_IRQ_BASE + 16; i++) { set_irq_chip_and_handler(i, &i8259A_chip, handle_level_irq); + set_irq_probe(i); + } setup_irq(I8259A_IRQ_BASE + PIC_CASCADE_IR, &irq2); } --- linux-2.6.24.orig/arch/mips/kernel/irq.c +++ linux-2.6.24/arch/mips/kernel/irq.c @@ -145,6 +145,11 @@ void __init init_IRQ(void) { + int i; + + for (i = 0; i < NR_IRQS; i++) + set_irq_noprobe(i); + arch_init_irq(); #ifdef CONFIG_KGDB --- linux-2.6.24.orig/arch/x86/Kconfig.debug +++ linux-2.6.24/arch/x86/Kconfig.debug @@ -5,6 +5,18 @@ source "lib/Kconfig.debug" +config NONPROMISC_DEVMEM + bool "Disable promiscuous /dev/mem" + default y + help + The /dev/mem file by default only allows userspace access to PCI + space and the BIOS code and data regions. This is sufficient for + dosemu and X and all common users of /dev/mem. With this config + option, you allow userspace access to all of memory, including + kernel and userspace memory. Accidental access to this is + obviously disasterous, but specific access can be used by people + debugging the kernel. + config EARLY_PRINTK bool "Early printk" if EMBEDDED && DEBUG_KERNEL && X86_32 default y @@ -18,6 +30,12 @@ with klogd/syslogd or the X server. You should normally N here, unless you want to debug such a crash. +config WRAPPER_PRINT + bool "Boot wrapper print" if EMBEDDED + default y + help + Enable informational output from the bootwrapper (bzImage and zImage). + config DEBUG_STACKOVERFLOW bool "Check for stack overflows" depends on DEBUG_KERNEL @@ -112,4 +130,78 @@ Add a simple leak tracer to the IOMMU code. This is useful when you are debugging a buggy device driver that leaks IOMMU mappings. +# +# IO delay types: +# + +config IO_DELAY_TYPE_0X80 + int + default "0" + +config IO_DELAY_TYPE_0XED + int + default "1" + +config IO_DELAY_TYPE_UDELAY + int + default "2" + +config IO_DELAY_TYPE_NONE + int + default "3" + +choice + prompt "IO delay type" + default IO_DELAY_0XED + +config IO_DELAY_0X80 + bool "port 0x80 based port-IO delay [recommended]" + help + This is the traditional Linux IO delay used for in/out_p. + It is the most tested hence safest selection here. + +config IO_DELAY_0XED + bool "port 0xed based port-IO delay" + help + Use port 0xed as the IO delay. This frees up port 0x80 which is + often used as a hardware-debug port. + +config IO_DELAY_UDELAY + bool "udelay based port-IO delay" + help + Use udelay(2) as the IO delay method. This provides the delay + while not having any side-effect on the IO port space. + +config IO_DELAY_NONE + bool "no port-IO delay" + help + No port-IO delay. Will break on old boxes that require port-IO + delay for certain operations. Should work on most new machines. + +endchoice + +if IO_DELAY_0X80 +config DEFAULT_IO_DELAY_TYPE + int + default IO_DELAY_TYPE_0X80 +endif + +if IO_DELAY_0XED +config DEFAULT_IO_DELAY_TYPE + int + default IO_DELAY_TYPE_0XED +endif + +if IO_DELAY_UDELAY +config DEFAULT_IO_DELAY_TYPE + int + default IO_DELAY_TYPE_UDELAY +endif + +if IO_DELAY_NONE +config DEFAULT_IO_DELAY_TYPE + int + default IO_DELAY_TYPE_NONE +endif + endmenu --- linux-2.6.24.orig/arch/x86/Kconfig +++ linux-2.6.24/arch/x86/Kconfig @@ -116,6 +116,7 @@ bool default y +select HAVE_KVM config ZONE_DMA32 bool @@ -1619,4 +1620,6 @@ source "crypto/Kconfig" +source "arch/x86/kvm/Kconfig" + source "lib/Kconfig" --- linux-2.6.24.orig/arch/x86/Makefile +++ linux-2.6.24/arch/x86/Makefile @@ -17,3 +17,5 @@ UTS_MACHINE := x86_64 include $(srctree)/arch/x86/Makefile_64 endif + +core-$(CONFIG_KVM) += arch/x86/kvm/ --- linux-2.6.24.orig/arch/x86/kvm/svm.h +++ linux-2.6.24/arch/x86/kvm/svm.h @@ -0,0 +1,325 @@ +#ifndef __SVM_H +#define __SVM_H + +enum { + INTERCEPT_INTR, + INTERCEPT_NMI, + INTERCEPT_SMI, + INTERCEPT_INIT, + INTERCEPT_VINTR, + INTERCEPT_SELECTIVE_CR0, + INTERCEPT_STORE_IDTR, + INTERCEPT_STORE_GDTR, + INTERCEPT_STORE_LDTR, + INTERCEPT_STORE_TR, + INTERCEPT_LOAD_IDTR, + INTERCEPT_LOAD_GDTR, + INTERCEPT_LOAD_LDTR, + INTERCEPT_LOAD_TR, + INTERCEPT_RDTSC, + INTERCEPT_RDPMC, + INTERCEPT_PUSHF, + INTERCEPT_POPF, + INTERCEPT_CPUID, + INTERCEPT_RSM, + INTERCEPT_IRET, + INTERCEPT_INTn, + INTERCEPT_INVD, + INTERCEPT_PAUSE, + INTERCEPT_HLT, + INTERCEPT_INVLPG, + INTERCEPT_INVLPGA, + INTERCEPT_IOIO_PROT, + INTERCEPT_MSR_PROT, + INTERCEPT_TASK_SWITCH, + INTERCEPT_FERR_FREEZE, + INTERCEPT_SHUTDOWN, + INTERCEPT_VMRUN, + INTERCEPT_VMMCALL, + INTERCEPT_VMLOAD, + INTERCEPT_VMSAVE, + INTERCEPT_STGI, + INTERCEPT_CLGI, + INTERCEPT_SKINIT, + INTERCEPT_RDTSCP, + INTERCEPT_ICEBP, + INTERCEPT_WBINVD, + INTERCEPT_MONITOR, + INTERCEPT_MWAIT, + INTERCEPT_MWAIT_COND, +}; + + +struct __attribute__ ((__packed__)) vmcb_control_area { + u16 intercept_cr_read; + u16 intercept_cr_write; + u16 intercept_dr_read; + u16 intercept_dr_write; + u32 intercept_exceptions; + u64 intercept; + u8 reserved_1[44]; + u64 iopm_base_pa; + u64 msrpm_base_pa; + u64 tsc_offset; + u32 asid; + u8 tlb_ctl; + u8 reserved_2[3]; + u32 int_ctl; + u32 int_vector; + u32 int_state; + u8 reserved_3[4]; + u32 exit_code; + u32 exit_code_hi; + u64 exit_info_1; + u64 exit_info_2; + u32 exit_int_info; + u32 exit_int_info_err; + u64 nested_ctl; + u8 reserved_4[16]; + u32 event_inj; + u32 event_inj_err; + u64 nested_cr3; + u64 lbr_ctl; + u8 reserved_5[832]; +}; + + +#define TLB_CONTROL_DO_NOTHING 0 +#define TLB_CONTROL_FLUSH_ALL_ASID 1 + +#define V_TPR_MASK 0x0f + +#define V_IRQ_SHIFT 8 +#define V_IRQ_MASK (1 << V_IRQ_SHIFT) + +#define V_INTR_PRIO_SHIFT 16 +#define V_INTR_PRIO_MASK (0x0f << V_INTR_PRIO_SHIFT) + +#define V_IGN_TPR_SHIFT 20 +#define V_IGN_TPR_MASK (1 << V_IGN_TPR_SHIFT) + +#define V_INTR_MASKING_SHIFT 24 +#define V_INTR_MASKING_MASK (1 << V_INTR_MASKING_SHIFT) + +#define SVM_INTERRUPT_SHADOW_MASK 1 + +#define SVM_IOIO_STR_SHIFT 2 +#define SVM_IOIO_REP_SHIFT 3 +#define SVM_IOIO_SIZE_SHIFT 4 +#define SVM_IOIO_ASIZE_SHIFT 7 + +#define SVM_IOIO_TYPE_MASK 1 +#define SVM_IOIO_STR_MASK (1 << SVM_IOIO_STR_SHIFT) +#define SVM_IOIO_REP_MASK (1 << SVM_IOIO_REP_SHIFT) +#define SVM_IOIO_SIZE_MASK (7 << SVM_IOIO_SIZE_SHIFT) +#define SVM_IOIO_ASIZE_MASK (7 << SVM_IOIO_ASIZE_SHIFT) + +struct __attribute__ ((__packed__)) vmcb_seg { + u16 selector; + u16 attrib; + u32 limit; + u64 base; +}; + +struct __attribute__ ((__packed__)) vmcb_save_area { + struct vmcb_seg es; + struct vmcb_seg cs; + struct vmcb_seg ss; + struct vmcb_seg ds; + struct vmcb_seg fs; + struct vmcb_seg gs; + struct vmcb_seg gdtr; + struct vmcb_seg ldtr; + struct vmcb_seg idtr; + struct vmcb_seg tr; + u8 reserved_1[43]; + u8 cpl; + u8 reserved_2[4]; + u64 efer; + u8 reserved_3[112]; + u64 cr4; + u64 cr3; + u64 cr0; + u64 dr7; + u64 dr6; + u64 rflags; + u64 rip; + u8 reserved_4[88]; + u64 rsp; + u8 reserved_5[24]; + u64 rax; + u64 star; + u64 lstar; + u64 cstar; + u64 sfmask; + u64 kernel_gs_base; + u64 sysenter_cs; + u64 sysenter_esp; + u64 sysenter_eip; + u64 cr2; + u8 reserved_6[32]; + u64 g_pat; + u64 dbgctl; + u64 br_from; + u64 br_to; + u64 last_excp_from; + u64 last_excp_to; +}; + +struct __attribute__ ((__packed__)) vmcb { + struct vmcb_control_area control; + struct vmcb_save_area save; +}; + +#define SVM_CPUID_FEATURE_SHIFT 2 +#define SVM_CPUID_FUNC 0x8000000a + +#define MSR_EFER_SVME_MASK (1ULL << 12) +#define MSR_VM_CR 0xc0010114 +#define MSR_VM_HSAVE_PA 0xc0010117ULL + +#define SVM_VM_CR_SVM_DISABLE 4 + +#define SVM_SELECTOR_S_SHIFT 4 +#define SVM_SELECTOR_DPL_SHIFT 5 +#define SVM_SELECTOR_P_SHIFT 7 +#define SVM_SELECTOR_AVL_SHIFT 8 +#define SVM_SELECTOR_L_SHIFT 9 +#define SVM_SELECTOR_DB_SHIFT 10 +#define SVM_SELECTOR_G_SHIFT 11 + +#define SVM_SELECTOR_TYPE_MASK (0xf) +#define SVM_SELECTOR_S_MASK (1 << SVM_SELECTOR_S_SHIFT) +#define SVM_SELECTOR_DPL_MASK (3 << SVM_SELECTOR_DPL_SHIFT) +#define SVM_SELECTOR_P_MASK (1 << SVM_SELECTOR_P_SHIFT) +#define SVM_SELECTOR_AVL_MASK (1 << SVM_SELECTOR_AVL_SHIFT) +#define SVM_SELECTOR_L_MASK (1 << SVM_SELECTOR_L_SHIFT) +#define SVM_SELECTOR_DB_MASK (1 << SVM_SELECTOR_DB_SHIFT) +#define SVM_SELECTOR_G_MASK (1 << SVM_SELECTOR_G_SHIFT) + +#define SVM_SELECTOR_WRITE_MASK (1 << 1) +#define SVM_SELECTOR_READ_MASK SVM_SELECTOR_WRITE_MASK +#define SVM_SELECTOR_CODE_MASK (1 << 3) + +#define INTERCEPT_CR0_MASK 1 +#define INTERCEPT_CR3_MASK (1 << 3) +#define INTERCEPT_CR4_MASK (1 << 4) +#define INTERCEPT_CR8_MASK (1 << 8) + +#define INTERCEPT_DR0_MASK 1 +#define INTERCEPT_DR1_MASK (1 << 1) +#define INTERCEPT_DR2_MASK (1 << 2) +#define INTERCEPT_DR3_MASK (1 << 3) +#define INTERCEPT_DR4_MASK (1 << 4) +#define INTERCEPT_DR5_MASK (1 << 5) +#define INTERCEPT_DR6_MASK (1 << 6) +#define INTERCEPT_DR7_MASK (1 << 7) + +#define SVM_EVTINJ_VEC_MASK 0xff + +#define SVM_EVTINJ_TYPE_SHIFT 8 +#define SVM_EVTINJ_TYPE_MASK (7 << SVM_EVTINJ_TYPE_SHIFT) + +#define SVM_EVTINJ_TYPE_INTR (0 << SVM_EVTINJ_TYPE_SHIFT) +#define SVM_EVTINJ_TYPE_NMI (2 << SVM_EVTINJ_TYPE_SHIFT) +#define SVM_EVTINJ_TYPE_EXEPT (3 << SVM_EVTINJ_TYPE_SHIFT) +#define SVM_EVTINJ_TYPE_SOFT (4 << SVM_EVTINJ_TYPE_SHIFT) + +#define SVM_EVTINJ_VALID (1 << 31) +#define SVM_EVTINJ_VALID_ERR (1 << 11) + +#define SVM_EXITINTINFO_VEC_MASK SVM_EVTINJ_VEC_MASK + +#define SVM_EXITINTINFO_TYPE_INTR SVM_EVTINJ_TYPE_INTR +#define SVM_EXITINTINFO_TYPE_NMI SVM_EVTINJ_TYPE_NMI +#define SVM_EXITINTINFO_TYPE_EXEPT SVM_EVTINJ_TYPE_EXEPT +#define SVM_EXITINTINFO_TYPE_SOFT SVM_EVTINJ_TYPE_SOFT + +#define SVM_EXITINTINFO_VALID SVM_EVTINJ_VALID +#define SVM_EXITINTINFO_VALID_ERR SVM_EVTINJ_VALID_ERR + +#define SVM_EXIT_READ_CR0 0x000 +#define SVM_EXIT_READ_CR3 0x003 +#define SVM_EXIT_READ_CR4 0x004 +#define SVM_EXIT_READ_CR8 0x008 +#define SVM_EXIT_WRITE_CR0 0x010 +#define SVM_EXIT_WRITE_CR3 0x013 +#define SVM_EXIT_WRITE_CR4 0x014 +#define SVM_EXIT_WRITE_CR8 0x018 +#define SVM_EXIT_READ_DR0 0x020 +#define SVM_EXIT_READ_DR1 0x021 +#define SVM_EXIT_READ_DR2 0x022 +#define SVM_EXIT_READ_DR3 0x023 +#define SVM_EXIT_READ_DR4 0x024 +#define SVM_EXIT_READ_DR5 0x025 +#define SVM_EXIT_READ_DR6 0x026 +#define SVM_EXIT_READ_DR7 0x027 +#define SVM_EXIT_WRITE_DR0 0x030 +#define SVM_EXIT_WRITE_DR1 0x031 +#define SVM_EXIT_WRITE_DR2 0x032 +#define SVM_EXIT_WRITE_DR3 0x033 +#define SVM_EXIT_WRITE_DR4 0x034 +#define SVM_EXIT_WRITE_DR5 0x035 +#define SVM_EXIT_WRITE_DR6 0x036 +#define SVM_EXIT_WRITE_DR7 0x037 +#define SVM_EXIT_EXCP_BASE 0x040 +#define SVM_EXIT_INTR 0x060 +#define SVM_EXIT_NMI 0x061 +#define SVM_EXIT_SMI 0x062 +#define SVM_EXIT_INIT 0x063 +#define SVM_EXIT_VINTR 0x064 +#define SVM_EXIT_CR0_SEL_WRITE 0x065 +#define SVM_EXIT_IDTR_READ 0x066 +#define SVM_EXIT_GDTR_READ 0x067 +#define SVM_EXIT_LDTR_READ 0x068 +#define SVM_EXIT_TR_READ 0x069 +#define SVM_EXIT_IDTR_WRITE 0x06a +#define SVM_EXIT_GDTR_WRITE 0x06b +#define SVM_EXIT_LDTR_WRITE 0x06c +#define SVM_EXIT_TR_WRITE 0x06d +#define SVM_EXIT_RDTSC 0x06e +#define SVM_EXIT_RDPMC 0x06f +#define SVM_EXIT_PUSHF 0x070 +#define SVM_EXIT_POPF 0x071 +#define SVM_EXIT_CPUID 0x072 +#define SVM_EXIT_RSM 0x073 +#define SVM_EXIT_IRET 0x074 +#define SVM_EXIT_SWINT 0x075 +#define SVM_EXIT_INVD 0x076 +#define SVM_EXIT_PAUSE 0x077 +#define SVM_EXIT_HLT 0x078 +#define SVM_EXIT_INVLPG 0x079 +#define SVM_EXIT_INVLPGA 0x07a +#define SVM_EXIT_IOIO 0x07b +#define SVM_EXIT_MSR 0x07c +#define SVM_EXIT_TASK_SWITCH 0x07d +#define SVM_EXIT_FERR_FREEZE 0x07e +#define SVM_EXIT_SHUTDOWN 0x07f +#define SVM_EXIT_VMRUN 0x080 +#define SVM_EXIT_VMMCALL 0x081 +#define SVM_EXIT_VMLOAD 0x082 +#define SVM_EXIT_VMSAVE 0x083 +#define SVM_EXIT_STGI 0x084 +#define SVM_EXIT_CLGI 0x085 +#define SVM_EXIT_SKINIT 0x086 +#define SVM_EXIT_RDTSCP 0x087 +#define SVM_EXIT_ICEBP 0x088 +#define SVM_EXIT_WBINVD 0x089 +#define SVM_EXIT_MONITOR 0x08a +#define SVM_EXIT_MWAIT 0x08b +#define SVM_EXIT_MWAIT_COND 0x08c +#define SVM_EXIT_NPF 0x400 + +#define SVM_EXIT_ERR -1 + +#define SVM_CR0_SELECTIVE_MASK (1 << 3 | 1) /* TS and MP */ + +#define SVM_VMLOAD ".byte 0x0f, 0x01, 0xda" +#define SVM_VMRUN ".byte 0x0f, 0x01, 0xd8" +#define SVM_VMSAVE ".byte 0x0f, 0x01, 0xdb" +#define SVM_CLGI ".byte 0x0f, 0x01, 0xdd" +#define SVM_STGI ".byte 0x0f, 0x01, 0xdc" +#define SVM_INVLPGA ".byte 0x0f, 0x01, 0xdf" + +#endif + --- linux-2.6.24.orig/arch/x86/kvm/lapic.h +++ linux-2.6.24/arch/x86/kvm/lapic.h @@ -0,0 +1,50 @@ +#ifndef __KVM_X86_LAPIC_H +#define __KVM_X86_LAPIC_H + +#include "iodev.h" + +#include + +struct kvm_lapic { + unsigned long base_address; + struct kvm_io_device dev; + struct { + atomic_t pending; + s64 period; /* unit: ns */ + u32 divide_count; + ktime_t last_update; + struct hrtimer dev; + } timer; + struct kvm_vcpu *vcpu; + struct page *regs_page; + void *regs; + gpa_t vapic_addr; + struct page *vapic_page; +}; +int kvm_create_lapic(struct kvm_vcpu *vcpu); +void kvm_free_lapic(struct kvm_vcpu *vcpu); + +int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu); +int kvm_apic_accept_pic_intr(struct kvm_vcpu *vcpu); +int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu); +void kvm_lapic_reset(struct kvm_vcpu *vcpu); +u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu); +void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8); +void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value); + +int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest); +int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda); +int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 trig); + +u64 kvm_get_apic_base(struct kvm_vcpu *vcpu); +void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data); +void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu); +int kvm_lapic_enabled(struct kvm_vcpu *vcpu); +int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu); +void kvm_apic_timer_intr_post(struct kvm_vcpu *vcpu, int vec); + +void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr); +void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu); +void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu); + +#endif --- linux-2.6.24.orig/arch/x86/kvm/x86.c +++ linux-2.6.24/arch/x86/kvm/x86.c @@ -0,0 +1,3432 @@ +/* + * Kernel-based Virtual Machine driver for Linux + * + * derived from drivers/kvm/kvm_main.c + * + * Copyright (C) 2006 Qumranet, Inc. + * + * Authors: + * Avi Kivity + * Yaniv Kamay + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#include +#include "segment_descriptor.h" +#include "irq.h" +#include "mmu.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define MAX_IO_MSRS 256 +#define CR0_RESERVED_BITS \ + (~(unsigned long)(X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS \ + | X86_CR0_ET | X86_CR0_NE | X86_CR0_WP | X86_CR0_AM \ + | X86_CR0_NW | X86_CR0_CD | X86_CR0_PG)) +#define CR4_RESERVED_BITS \ + (~(unsigned long)(X86_CR4_VME | X86_CR4_PVI | X86_CR4_TSD | X86_CR4_DE\ + | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_MCE \ + | X86_CR4_PGE | X86_CR4_PCE | X86_CR4_OSFXSR \ + | X86_CR4_OSXMMEXCPT | X86_CR4_VMXE)) + +#define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR) +/* EFER defaults: + * - enable syscall per default because its emulated by KVM + * - enable LME and LMA per default on 64 bit KVM + */ +#ifdef CONFIG_X86_64 +static u64 __read_mostly efer_reserved_bits = 0xfffffffffffffafeULL; +#else +static u64 __read_mostly efer_reserved_bits = 0xfffffffffffffffeULL; +#endif + +#define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM +#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU + +static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid, + struct kvm_cpuid_entry2 __user *entries); + +struct kvm_x86_ops *kvm_x86_ops; + +struct kvm_stats_debugfs_item debugfs_entries[] = { + { "pf_fixed", VCPU_STAT(pf_fixed) }, + { "pf_guest", VCPU_STAT(pf_guest) }, + { "tlb_flush", VCPU_STAT(tlb_flush) }, + { "invlpg", VCPU_STAT(invlpg) }, + { "exits", VCPU_STAT(exits) }, + { "io_exits", VCPU_STAT(io_exits) }, + { "mmio_exits", VCPU_STAT(mmio_exits) }, + { "signal_exits", VCPU_STAT(signal_exits) }, + { "irq_window", VCPU_STAT(irq_window_exits) }, + { "halt_exits", VCPU_STAT(halt_exits) }, + { "halt_wakeup", VCPU_STAT(halt_wakeup) }, + { "hypercalls", VCPU_STAT(hypercalls) }, + { "request_irq", VCPU_STAT(request_irq_exits) }, + { "irq_exits", VCPU_STAT(irq_exits) }, + { "host_state_reload", VCPU_STAT(host_state_reload) }, + { "efer_reload", VCPU_STAT(efer_reload) }, + { "fpu_reload", VCPU_STAT(fpu_reload) }, + { "insn_emulation", VCPU_STAT(insn_emulation) }, + { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail) }, + { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped) }, + { "mmu_pte_write", VM_STAT(mmu_pte_write) }, + { "mmu_pte_updated", VM_STAT(mmu_pte_updated) }, + { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped) }, + { "mmu_flooded", VM_STAT(mmu_flooded) }, + { "mmu_recycled", VM_STAT(mmu_recycled) }, + { "mmu_cache_miss", VM_STAT(mmu_cache_miss) }, + { "remote_tlb_flush", VM_STAT(remote_tlb_flush) }, + { "largepages", VM_STAT(lpages) }, + { NULL } +}; + + +unsigned long segment_base(u16 selector) +{ + struct descriptor_table gdt; + struct segment_descriptor *d; + unsigned long table_base; + unsigned long v; + + if (selector == 0) + return 0; + + asm("sgdt %0" : "=m"(gdt)); + table_base = gdt.base; + + if (selector & 4) { /* from ldt */ + u16 ldt_selector; + + asm("sldt %0" : "=g"(ldt_selector)); + table_base = segment_base(ldt_selector); + } + d = (struct segment_descriptor *)(table_base + (selector & ~7)); + v = d->base_low | ((unsigned long)d->base_mid << 16) | + ((unsigned long)d->base_high << 24); +#ifdef CONFIG_X86_64 + if (d->system == 0 && (d->type == 2 || d->type == 9 || d->type == 11)) + v |= ((unsigned long) \ + ((struct segment_descriptor_64 *)d)->base_higher) << 32; +#endif + return v; +} +EXPORT_SYMBOL_GPL(segment_base); + +u64 kvm_get_apic_base(struct kvm_vcpu *vcpu) +{ + if (irqchip_in_kernel(vcpu->kvm)) + return vcpu->arch.apic_base; + else + return vcpu->arch.apic_base; +} +EXPORT_SYMBOL_GPL(kvm_get_apic_base); + +void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data) +{ + /* TODO: reserve bits check */ + if (irqchip_in_kernel(vcpu->kvm)) + kvm_lapic_set_base(vcpu, data); + else + vcpu->arch.apic_base = data; +} +EXPORT_SYMBOL_GPL(kvm_set_apic_base); + +void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr) +{ + WARN_ON(vcpu->arch.exception.pending); + vcpu->arch.exception.pending = true; + vcpu->arch.exception.has_error_code = false; + vcpu->arch.exception.nr = nr; +} +EXPORT_SYMBOL_GPL(kvm_queue_exception); + +void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long addr, + u32 error_code) +{ + ++vcpu->stat.pf_guest; + if (vcpu->arch.exception.pending && vcpu->arch.exception.nr == PF_VECTOR) { + printk(KERN_DEBUG "kvm: inject_page_fault:" + " double fault 0x%lx\n", addr); + vcpu->arch.exception.nr = DF_VECTOR; + vcpu->arch.exception.error_code = 0; + return; + } + vcpu->arch.cr2 = addr; + kvm_queue_exception_e(vcpu, PF_VECTOR, error_code); +} + +void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code) +{ + WARN_ON(vcpu->arch.exception.pending); + vcpu->arch.exception.pending = true; + vcpu->arch.exception.has_error_code = true; + vcpu->arch.exception.nr = nr; + vcpu->arch.exception.error_code = error_code; +} +EXPORT_SYMBOL_GPL(kvm_queue_exception_e); + +static void __queue_exception(struct kvm_vcpu *vcpu) +{ + kvm_x86_ops->queue_exception(vcpu, vcpu->arch.exception.nr, + vcpu->arch.exception.has_error_code, + vcpu->arch.exception.error_code); +} + +/* + * Load the pae pdptrs. Return true is they are all valid. + */ +int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3) +{ + gfn_t pdpt_gfn = cr3 >> PAGE_SHIFT; + unsigned offset = ((cr3 & (PAGE_SIZE-1)) >> 5) << 2; + int i; + int ret; + u64 pdpte[ARRAY_SIZE(vcpu->arch.pdptrs)]; + + down_read(&vcpu->kvm->slots_lock); + ret = kvm_read_guest_page(vcpu->kvm, pdpt_gfn, pdpte, + offset * sizeof(u64), sizeof(pdpte)); + if (ret < 0) { + ret = 0; + goto out; + } + for (i = 0; i < ARRAY_SIZE(pdpte); ++i) { + if ((pdpte[i] & 1) && (pdpte[i] & 0xfffffff0000001e6ull)) { + ret = 0; + goto out; + } + } + ret = 1; + + memcpy(vcpu->arch.pdptrs, pdpte, sizeof(vcpu->arch.pdptrs)); +out: + up_read(&vcpu->kvm->slots_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(load_pdptrs); + +static bool pdptrs_changed(struct kvm_vcpu *vcpu) +{ + u64 pdpte[ARRAY_SIZE(vcpu->arch.pdptrs)]; + bool changed = true; + int r; + + if (is_long_mode(vcpu) || !is_pae(vcpu)) + return false; + + down_read(&vcpu->kvm->slots_lock); + r = kvm_read_guest(vcpu->kvm, vcpu->arch.cr3 & ~31u, pdpte, sizeof(pdpte)); + if (r < 0) + goto out; + changed = memcmp(pdpte, vcpu->arch.pdptrs, sizeof(pdpte)) != 0; +out: + up_read(&vcpu->kvm->slots_lock); + + return changed; +} + +void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) +{ + if (cr0 & CR0_RESERVED_BITS) { + printk(KERN_DEBUG "set_cr0: 0x%lx #GP, reserved bits 0x%lx\n", + cr0, vcpu->arch.cr0); + kvm_inject_gp(vcpu, 0); + return; + } + + if ((cr0 & X86_CR0_NW) && !(cr0 & X86_CR0_CD)) { + printk(KERN_DEBUG "set_cr0: #GP, CD == 0 && NW == 1\n"); + kvm_inject_gp(vcpu, 0); + return; + } + + if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE)) { + printk(KERN_DEBUG "set_cr0: #GP, set PG flag " + "and a clear PE flag\n"); + kvm_inject_gp(vcpu, 0); + return; + } + + if (!is_paging(vcpu) && (cr0 & X86_CR0_PG)) { +#ifdef CONFIG_X86_64 + if ((vcpu->arch.shadow_efer & EFER_LME)) { + int cs_db, cs_l; + + if (!is_pae(vcpu)) { + printk(KERN_DEBUG "set_cr0: #GP, start paging " + "in long mode while PAE is disabled\n"); + kvm_inject_gp(vcpu, 0); + return; + } + kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l); + if (cs_l) { + printk(KERN_DEBUG "set_cr0: #GP, start paging " + "in long mode while CS.L == 1\n"); + kvm_inject_gp(vcpu, 0); + return; + + } + } else +#endif + if (is_pae(vcpu) && !load_pdptrs(vcpu, vcpu->arch.cr3)) { + printk(KERN_DEBUG "set_cr0: #GP, pdptrs " + "reserved bits\n"); + kvm_inject_gp(vcpu, 0); + return; + } + + } + + kvm_x86_ops->set_cr0(vcpu, cr0); + vcpu->arch.cr0 = cr0; + + kvm_mmu_reset_context(vcpu); + return; +} +EXPORT_SYMBOL_GPL(kvm_set_cr0); + +void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw) +{ + kvm_set_cr0(vcpu, (vcpu->arch.cr0 & ~0x0ful) | (msw & 0x0f)); +} +EXPORT_SYMBOL_GPL(kvm_lmsw); + +void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) +{ + if (cr4 & CR4_RESERVED_BITS) { + printk(KERN_DEBUG "set_cr4: #GP, reserved bits\n"); + kvm_inject_gp(vcpu, 0); + return; + } + + if (is_long_mode(vcpu)) { + if (!(cr4 & X86_CR4_PAE)) { + printk(KERN_DEBUG "set_cr4: #GP, clearing PAE while " + "in long mode\n"); + kvm_inject_gp(vcpu, 0); + return; + } + } else if (is_paging(vcpu) && !is_pae(vcpu) && (cr4 & X86_CR4_PAE) + && !load_pdptrs(vcpu, vcpu->arch.cr3)) { + printk(KERN_DEBUG "set_cr4: #GP, pdptrs reserved bits\n"); + kvm_inject_gp(vcpu, 0); + return; + } + + if (cr4 & X86_CR4_VMXE) { + printk(KERN_DEBUG "set_cr4: #GP, setting VMXE\n"); + kvm_inject_gp(vcpu, 0); + return; + } + kvm_x86_ops->set_cr4(vcpu, cr4); + vcpu->arch.cr4 = cr4; + kvm_mmu_reset_context(vcpu); +} +EXPORT_SYMBOL_GPL(kvm_set_cr4); + +void kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) +{ + if (cr3 == vcpu->arch.cr3 && !pdptrs_changed(vcpu)) { + kvm_mmu_flush_tlb(vcpu); + return; + } + + if (is_long_mode(vcpu)) { + if (cr3 & CR3_L_MODE_RESERVED_BITS) { + printk(KERN_DEBUG "set_cr3: #GP, reserved bits\n"); + kvm_inject_gp(vcpu, 0); + return; + } + } else { + if (is_pae(vcpu)) { + if (cr3 & CR3_PAE_RESERVED_BITS) { + printk(KERN_DEBUG + "set_cr3: #GP, reserved bits\n"); + kvm_inject_gp(vcpu, 0); + return; + } + if (is_paging(vcpu) && !load_pdptrs(vcpu, cr3)) { + printk(KERN_DEBUG "set_cr3: #GP, pdptrs " + "reserved bits\n"); + kvm_inject_gp(vcpu, 0); + return; + } + } + /* + * We don't check reserved bits in nonpae mode, because + * this isn't enforced, and VMware depends on this. + */ + } + + down_read(&vcpu->kvm->slots_lock); + /* + * Does the new cr3 value map to physical memory? (Note, we + * catch an invalid cr3 even in real-mode, because it would + * cause trouble later on when we turn on paging anyway.) + * + * A real CPU would silently accept an invalid cr3 and would + * attempt to use it - with largely undefined (and often hard + * to debug) behavior on the guest side. + */ + if (unlikely(!gfn_to_memslot(vcpu->kvm, cr3 >> PAGE_SHIFT))) + kvm_inject_gp(vcpu, 0); + else { + vcpu->arch.cr3 = cr3; + vcpu->arch.mmu.new_cr3(vcpu); + } + up_read(&vcpu->kvm->slots_lock); +} +EXPORT_SYMBOL_GPL(kvm_set_cr3); + +void kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8) +{ + if (cr8 & CR8_RESERVED_BITS) { + printk(KERN_DEBUG "set_cr8: #GP, reserved bits 0x%lx\n", cr8); + kvm_inject_gp(vcpu, 0); + return; + } + if (irqchip_in_kernel(vcpu->kvm)) + kvm_lapic_set_tpr(vcpu, cr8); + else + vcpu->arch.cr8 = cr8; +} +EXPORT_SYMBOL_GPL(kvm_set_cr8); + +unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu) +{ + if (irqchip_in_kernel(vcpu->kvm)) + return kvm_lapic_get_cr8(vcpu); + else + return vcpu->arch.cr8; +} +EXPORT_SYMBOL_GPL(kvm_get_cr8); + +/* + * List of msr numbers which we expose to userspace through KVM_GET_MSRS + * and KVM_SET_MSRS, and KVM_GET_MSR_INDEX_LIST. + * + * This list is modified at module load time to reflect the + * capabilities of the host cpu. + */ +static u32 msrs_to_save[] = { + MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP, + MSR_K6_STAR, +#ifdef CONFIG_X86_64 + MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR, +#endif + MSR_IA32_TIME_STAMP_COUNTER, MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK, + MSR_IA32_PERF_STATUS, +}; + +static unsigned num_msrs_to_save; + +static u32 emulated_msrs[] = { + MSR_IA32_MISC_ENABLE, +}; + +static void set_efer(struct kvm_vcpu *vcpu, u64 efer) +{ + if (efer & efer_reserved_bits) { + printk(KERN_DEBUG "set_efer: 0x%llx #GP, reserved bits\n", + efer); + kvm_inject_gp(vcpu, 0); + return; + } + + if (is_paging(vcpu) + && (vcpu->arch.shadow_efer & EFER_LME) != (efer & EFER_LME)) { + printk(KERN_DEBUG "set_efer: #GP, change LME while paging\n"); + kvm_inject_gp(vcpu, 0); + return; + } + + kvm_x86_ops->set_efer(vcpu, efer); + + efer &= ~EFER_LMA; + efer |= vcpu->arch.shadow_efer & EFER_LMA; + + vcpu->arch.shadow_efer = efer; +} + +void kvm_enable_efer_bits(u64 mask) +{ + efer_reserved_bits &= ~mask; +} +EXPORT_SYMBOL_GPL(kvm_enable_efer_bits); + + +/* + * Writes msr value into into the appropriate "register". + * Returns 0 on success, non-0 otherwise. + * Assumes vcpu_load() was already called. + */ +int kvm_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) +{ + return kvm_x86_ops->set_msr(vcpu, msr_index, data); +} + +/* + * Adapt set_msr() to msr_io()'s calling convention + */ +static int do_set_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *data) +{ + return kvm_set_msr(vcpu, index, *data); +} + +static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock) +{ + static int version; + struct kvm_wall_clock wc; + struct timespec wc_ts; + + if (!wall_clock) + return; + + mutex_lock(&kvm->lock); + + version++; + kvm_write_guest(kvm, wall_clock, &version, sizeof(version)); + + wc_ts = current_kernel_time(); + wc.wc_sec = wc_ts.tv_sec; + wc.wc_nsec = wc_ts.tv_nsec; + wc.wc_version = version; + kvm_write_guest(kvm, wall_clock, &wc, sizeof(wc)); + + version++; + kvm_write_guest(kvm, wall_clock, &version, sizeof(version)); + + mutex_unlock(&kvm->lock); +} + +static void kvm_write_guest_time(struct kvm_vcpu *v) +{ + struct timespec ts; + unsigned long flags; + struct kvm_vcpu_arch *vcpu = &v->arch; + void *shared_kaddr; + + if ((!vcpu->time_page)) + return; + + /* Keep irq disabled to prevent changes to the clock */ + local_irq_save(flags); + kvm_get_msr(v, MSR_IA32_TIME_STAMP_COUNTER, + &vcpu->hv_clock.tsc_timestamp); + ktime_get_ts(&ts); + local_irq_restore(flags); + + /* With all the info we got, fill in the values */ + + vcpu->hv_clock.system_time = ts.tv_nsec + + (NSEC_PER_SEC * (u64)ts.tv_sec); + /* + * The interface expects us to write an even number signaling that the + * update is finished. Since the guest won't see the intermediate + * state, we just write "2" at the end + */ + vcpu->hv_clock.version = 2; + + shared_kaddr = kmap_atomic(vcpu->time_page, KM_USER0); + + memcpy(shared_kaddr + vcpu->time_offset, &vcpu->hv_clock, + sizeof(vcpu->hv_clock)); + + kunmap_atomic(shared_kaddr, KM_USER0); + + mark_page_dirty(v->kvm, vcpu->time >> PAGE_SHIFT); +} + + +int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) +{ + switch (msr) { + case MSR_EFER: + set_efer(vcpu, data); + break; + case MSR_IA32_MC0_STATUS: + pr_unimpl(vcpu, "%s: MSR_IA32_MC0_STATUS 0x%llx, nop\n", + __FUNCTION__, data); + break; + case MSR_IA32_MCG_STATUS: + pr_unimpl(vcpu, "%s: MSR_IA32_MCG_STATUS 0x%llx, nop\n", + __FUNCTION__, data); + break; + case MSR_IA32_MCG_CTL: + pr_unimpl(vcpu, "%s: MSR_IA32_MCG_CTL 0x%llx, nop\n", + __FUNCTION__, data); + break; + case MSR_IA32_UCODE_REV: + case MSR_IA32_UCODE_WRITE: + case 0x200 ... 0x2ff: /* MTRRs */ + break; + case MSR_IA32_APICBASE: + kvm_set_apic_base(vcpu, data); + break; + case MSR_IA32_MISC_ENABLE: + vcpu->arch.ia32_misc_enable_msr = data; + break; + case MSR_KVM_WALL_CLOCK: + vcpu->kvm->arch.wall_clock = data; + kvm_write_wall_clock(vcpu->kvm, data); + break; + case MSR_KVM_SYSTEM_TIME: { + vcpu->arch.time = data & PAGE_MASK; + vcpu->arch.time_offset = data & ~PAGE_MASK; + + vcpu->arch.hv_clock.tsc_to_system_mul = + clocksource_khz2mult(tsc_khz, 22); + vcpu->arch.hv_clock.tsc_shift = 22; + + down_read(¤t->mm->mmap_sem); + vcpu->arch.time_page = + gfn_to_page(vcpu->kvm, data >> PAGE_SHIFT); + up_read(¤t->mm->mmap_sem); + + if (is_error_page(vcpu->arch.time_page)) + vcpu->arch.time_page = NULL; + + kvm_write_guest_time(vcpu); + break; + } + default: + pr_unimpl(vcpu, "unhandled wrmsr: 0x%x data %llx\n", msr, data); + return 1; + } + return 0; +} +EXPORT_SYMBOL_GPL(kvm_set_msr_common); + + +/* + * Reads an msr value (of 'msr_index') into 'pdata'. + * Returns 0 on success, non-0 otherwise. + * Assumes vcpu_load() was already called. + */ +int kvm_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) +{ + return kvm_x86_ops->get_msr(vcpu, msr_index, pdata); +} + +int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) +{ + u64 data; + + switch (msr) { + case 0xc0010010: /* SYSCFG */ + case 0xc0010015: /* HWCR */ + case MSR_IA32_PLATFORM_ID: + case MSR_IA32_P5_MC_ADDR: + case MSR_IA32_P5_MC_TYPE: + case MSR_IA32_MC0_CTL: + case MSR_IA32_MCG_STATUS: + case MSR_IA32_MCG_CAP: + case MSR_IA32_MCG_CTL: + case MSR_IA32_MC0_MISC: + case MSR_IA32_MC0_MISC+4: + case MSR_IA32_MC0_MISC+8: + case MSR_IA32_MC0_MISC+12: + case MSR_IA32_MC0_MISC+16: + case MSR_IA32_UCODE_REV: + case MSR_IA32_EBL_CR_POWERON: + /* MTRR registers */ + case 0xfe: + case 0x200 ... 0x2ff: + data = 0; + break; + case 0xcd: /* fsb frequency */ + data = 3; + break; + case MSR_IA32_APICBASE: + data = kvm_get_apic_base(vcpu); + break; + case MSR_IA32_MISC_ENABLE: + data = vcpu->arch.ia32_misc_enable_msr; + break; + case MSR_IA32_PERF_STATUS: + /* TSC increment by tick */ + data = 1000ULL; + /* CPU multiplier */ + data |= (((uint64_t)4ULL) << 40); + break; + case MSR_EFER: + data = vcpu->arch.shadow_efer; + break; + case MSR_KVM_WALL_CLOCK: + data = vcpu->kvm->arch.wall_clock; + break; + case MSR_KVM_SYSTEM_TIME: + data = vcpu->arch.time; + break; + default: + pr_unimpl(vcpu, "unhandled rdmsr: 0x%x\n", msr); + return 1; + } + *pdata = data; + return 0; +} +EXPORT_SYMBOL_GPL(kvm_get_msr_common); + +/* + * Read or write a bunch of msrs. All parameters are kernel addresses. + * + * @return number of msrs set successfully. + */ +static int __msr_io(struct kvm_vcpu *vcpu, struct kvm_msrs *msrs, + struct kvm_msr_entry *entries, + int (*do_msr)(struct kvm_vcpu *vcpu, + unsigned index, u64 *data)) +{ + int i; + + vcpu_load(vcpu); + + for (i = 0; i < msrs->nmsrs; ++i) + if (do_msr(vcpu, entries[i].index, &entries[i].data)) + break; + + vcpu_put(vcpu); + + return i; +} + +/* + * Read or write a bunch of msrs. Parameters are user addresses. + * + * @return number of msrs set successfully. + */ +static int msr_io(struct kvm_vcpu *vcpu, struct kvm_msrs __user *user_msrs, + int (*do_msr)(struct kvm_vcpu *vcpu, + unsigned index, u64 *data), + int writeback) +{ + struct kvm_msrs msrs; + struct kvm_msr_entry *entries; + int r, n; + unsigned size; + + r = -EFAULT; + if (copy_from_user(&msrs, user_msrs, sizeof msrs)) + goto out; + + r = -E2BIG; + if (msrs.nmsrs >= MAX_IO_MSRS) + goto out; + + r = -ENOMEM; + size = sizeof(struct kvm_msr_entry) * msrs.nmsrs; + entries = vmalloc(size); + if (!entries) + goto out; + + r = -EFAULT; + if (copy_from_user(entries, user_msrs->entries, size)) + goto out_free; + + r = n = __msr_io(vcpu, &msrs, entries, do_msr); + if (r < 0) + goto out_free; + + r = -EFAULT; + if (writeback && copy_to_user(user_msrs->entries, entries, size)) + goto out_free; + + r = n; + +out_free: + vfree(entries); +out: + return r; +} + +/* + * Make sure that a cpu that is being hot-unplugged does not have any vcpus + * cached on it. + */ +void decache_vcpus_on_cpu(int cpu) +{ + struct kvm *vm; + struct kvm_vcpu *vcpu; + int i; + + spin_lock(&kvm_lock); + list_for_each_entry(vm, &vm_list, vm_list) + for (i = 0; i < KVM_MAX_VCPUS; ++i) { + vcpu = vm->vcpus[i]; + if (!vcpu) + continue; + /* + * If the vcpu is locked, then it is running on some + * other cpu and therefore it is not cached on the + * cpu in question. + * + * If it's not locked, check the last cpu it executed + * on. + */ + if (mutex_trylock(&vcpu->mutex)) { + if (vcpu->cpu == cpu) { + kvm_x86_ops->vcpu_decache(vcpu); + vcpu->cpu = -1; + } + mutex_unlock(&vcpu->mutex); + } + } + spin_unlock(&kvm_lock); +} + +int kvm_dev_ioctl_check_extension(long ext) +{ + int r; + + switch (ext) { + case KVM_CAP_IRQCHIP: + case KVM_CAP_HLT: + case KVM_CAP_MMU_SHADOW_CACHE_CONTROL: + case KVM_CAP_USER_MEMORY: + case KVM_CAP_SET_TSS_ADDR: + case KVM_CAP_EXT_CPUID: + case KVM_CAP_CLOCKSOURCE: + r = 1; + break; + case KVM_CAP_VAPIC: + r = !kvm_x86_ops->cpu_has_accelerated_tpr(); + break; + case KVM_CAP_NR_VCPUS: + r = KVM_MAX_VCPUS; + break; + case KVM_CAP_NR_MEMSLOTS: + r = KVM_MEMORY_SLOTS; + break; + default: + r = 0; + break; + } + return r; + +} + +long kvm_arch_dev_ioctl(struct file *filp, + unsigned int ioctl, unsigned long arg) +{ + void __user *argp = (void __user *)arg; + long r; + + switch (ioctl) { + case KVM_GET_MSR_INDEX_LIST: { + struct kvm_msr_list __user *user_msr_list = argp; + struct kvm_msr_list msr_list; + unsigned n; + + r = -EFAULT; + if (copy_from_user(&msr_list, user_msr_list, sizeof msr_list)) + goto out; + n = msr_list.nmsrs; + msr_list.nmsrs = num_msrs_to_save + ARRAY_SIZE(emulated_msrs); + if (copy_to_user(user_msr_list, &msr_list, sizeof msr_list)) + goto out; + r = -E2BIG; + if (n < num_msrs_to_save) + goto out; + r = -EFAULT; + if (copy_to_user(user_msr_list->indices, &msrs_to_save, + num_msrs_to_save * sizeof(u32))) + goto out; + if (copy_to_user(user_msr_list->indices + + num_msrs_to_save * sizeof(u32), + &emulated_msrs, + ARRAY_SIZE(emulated_msrs) * sizeof(u32))) + goto out; + r = 0; + break; + } + case KVM_GET_SUPPORTED_CPUID: { + struct kvm_cpuid2 __user *cpuid_arg = argp; + struct kvm_cpuid2 cpuid; + + r = -EFAULT; + if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid)) + goto out; + r = kvm_dev_ioctl_get_supported_cpuid(&cpuid, + cpuid_arg->entries); + if (r) + goto out; + + r = -EFAULT; + if (copy_to_user(cpuid_arg, &cpuid, sizeof cpuid)) + goto out; + r = 0; + break; + } + default: + r = -EINVAL; + } +out: + return r; +} + +void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +{ + kvm_x86_ops->vcpu_load(vcpu, cpu); + kvm_write_guest_time(vcpu); +} + +void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) +{ + kvm_x86_ops->vcpu_put(vcpu); + kvm_put_guest_fpu(vcpu); +} + +static int is_efer_nx(void) +{ + u64 efer; + + rdmsrl(MSR_EFER, efer); + return efer & EFER_NX; +} + +static void cpuid_fix_nx_cap(struct kvm_vcpu *vcpu) +{ + int i; + struct kvm_cpuid_entry2 *e, *entry; + + entry = NULL; + for (i = 0; i < vcpu->arch.cpuid_nent; ++i) { + e = &vcpu->arch.cpuid_entries[i]; + if (e->function == 0x80000001) { + entry = e; + break; + } + } + if (entry && (entry->edx & (1 << 20)) && !is_efer_nx()) { + entry->edx &= ~(1 << 20); + printk(KERN_INFO "kvm: guest NX capability removed\n"); + } +} + +/* when an old userspace process fills a new kernel module */ +static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu, + struct kvm_cpuid *cpuid, + struct kvm_cpuid_entry __user *entries) +{ + int r, i; + struct kvm_cpuid_entry *cpuid_entries; + + r = -E2BIG; + if (cpuid->nent > KVM_MAX_CPUID_ENTRIES) + goto out; + r = -ENOMEM; + cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry) * cpuid->nent); + if (!cpuid_entries) + goto out; + r = -EFAULT; + if (copy_from_user(cpuid_entries, entries, + cpuid->nent * sizeof(struct kvm_cpuid_entry))) + goto out_free; + for (i = 0; i < cpuid->nent; i++) { + vcpu->arch.cpuid_entries[i].function = cpuid_entries[i].function; + vcpu->arch.cpuid_entries[i].eax = cpuid_entries[i].eax; + vcpu->arch.cpuid_entries[i].ebx = cpuid_entries[i].ebx; + vcpu->arch.cpuid_entries[i].ecx = cpuid_entries[i].ecx; + vcpu->arch.cpuid_entries[i].edx = cpuid_entries[i].edx; + vcpu->arch.cpuid_entries[i].index = 0; + vcpu->arch.cpuid_entries[i].flags = 0; + vcpu->arch.cpuid_entries[i].padding[0] = 0; + vcpu->arch.cpuid_entries[i].padding[1] = 0; + vcpu->arch.cpuid_entries[i].padding[2] = 0; + } + vcpu->arch.cpuid_nent = cpuid->nent; + cpuid_fix_nx_cap(vcpu); + r = 0; + +out_free: + vfree(cpuid_entries); +out: + return r; +} + +static int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu, + struct kvm_cpuid2 *cpuid, + struct kvm_cpuid_entry2 __user *entries) +{ + int r; + + r = -E2BIG; + if (cpuid->nent > KVM_MAX_CPUID_ENTRIES) + goto out; + r = -EFAULT; + if (copy_from_user(&vcpu->arch.cpuid_entries, entries, + cpuid->nent * sizeof(struct kvm_cpuid_entry2))) + goto out; + vcpu->arch.cpuid_nent = cpuid->nent; + return 0; + +out: + return r; +} + +static int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu, + struct kvm_cpuid2 *cpuid, + struct kvm_cpuid_entry2 __user *entries) +{ + int r; + + r = -E2BIG; + if (cpuid->nent < vcpu->arch.cpuid_nent) + goto out; + r = -EFAULT; + if (copy_to_user(entries, &vcpu->arch.cpuid_entries, + vcpu->arch.cpuid_nent * sizeof(struct kvm_cpuid_entry2))) + goto out; + return 0; + +out: + cpuid->nent = vcpu->arch.cpuid_nent; + return r; +} + +static inline u32 bit(int bitno) +{ + return 1 << (bitno & 31); +} + +static void do_cpuid_1_ent(struct kvm_cpuid_entry2 *entry, u32 function, + u32 index) +{ + entry->function = function; + entry->index = index; + cpuid_count(entry->function, entry->index, + &entry->eax, &entry->ebx, &entry->ecx, &entry->edx); + entry->flags = 0; +} + +static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, + u32 index, int *nent, int maxnent) +{ + const u32 kvm_supported_word0_x86_features = bit(X86_FEATURE_FPU) | + bit(X86_FEATURE_VME) | bit(X86_FEATURE_DE) | + bit(X86_FEATURE_PSE) | bit(X86_FEATURE_TSC) | + bit(X86_FEATURE_MSR) | bit(X86_FEATURE_PAE) | + bit(X86_FEATURE_CX8) | bit(X86_FEATURE_APIC) | + bit(X86_FEATURE_SEP) | bit(X86_FEATURE_PGE) | + bit(X86_FEATURE_CMOV) | bit(X86_FEATURE_PSE36) | + bit(X86_FEATURE_CLFLSH) | bit(X86_FEATURE_MMX) | + bit(X86_FEATURE_FXSR) | bit(X86_FEATURE_XMM) | + bit(X86_FEATURE_XMM2) | bit(X86_FEATURE_SELFSNOOP); + const u32 kvm_supported_word1_x86_features = bit(X86_FEATURE_FPU) | + bit(X86_FEATURE_VME) | bit(X86_FEATURE_DE) | + bit(X86_FEATURE_PSE) | bit(X86_FEATURE_TSC) | + bit(X86_FEATURE_MSR) | bit(X86_FEATURE_PAE) | + bit(X86_FEATURE_CX8) | bit(X86_FEATURE_APIC) | + bit(X86_FEATURE_PGE) | + bit(X86_FEATURE_CMOV) | bit(X86_FEATURE_PSE36) | + bit(X86_FEATURE_MMX) | bit(X86_FEATURE_FXSR) | + bit(X86_FEATURE_SYSCALL) | + (bit(X86_FEATURE_NX) && is_efer_nx()) | +#ifdef CONFIG_X86_64 + bit(X86_FEATURE_LM) | +#endif + bit(X86_FEATURE_MMXEXT) | + bit(X86_FEATURE_3DNOWEXT) | + bit(X86_FEATURE_3DNOW); + const u32 kvm_supported_word3_x86_features = + bit(X86_FEATURE_XMM3) | bit(X86_FEATURE_CX16); + const u32 kvm_supported_word6_x86_features = + bit(X86_FEATURE_LAHF_LM) | bit(X86_FEATURE_CMP_LEGACY); + + /* all func 2 cpuid_count() should be called on the same cpu */ + get_cpu(); + do_cpuid_1_ent(entry, function, index); + ++*nent; + + switch (function) { + case 0: + entry->eax = min(entry->eax, (u32)0xb); + break; + case 1: + entry->edx &= kvm_supported_word0_x86_features; + entry->ecx &= kvm_supported_word3_x86_features; + break; + /* function 2 entries are STATEFUL. That is, repeated cpuid commands + * may return different values. This forces us to get_cpu() before + * issuing the first command, and also to emulate this annoying behavior + * in kvm_emulate_cpuid() using KVM_CPUID_FLAG_STATE_READ_NEXT */ + case 2: { + int t, times = entry->eax & 0xff; + + entry->flags |= KVM_CPUID_FLAG_STATEFUL_FUNC; + for (t = 1; t < times && *nent < maxnent; ++t) { + do_cpuid_1_ent(&entry[t], function, 0); + entry[t].flags |= KVM_CPUID_FLAG_STATEFUL_FUNC; + ++*nent; + } + break; + } + /* function 4 and 0xb have additional index. */ + case 4: { + int i, cache_type; + + entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX; + /* read more entries until cache_type is zero */ + for (i = 1; *nent < maxnent; ++i) { + cache_type = entry[i - 1].eax & 0x1f; + if (!cache_type) + break; + do_cpuid_1_ent(&entry[i], function, i); + entry[i].flags |= + KVM_CPUID_FLAG_SIGNIFCANT_INDEX; + ++*nent; + } + break; + } + case 0xb: { + int i, level_type; + + entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX; + /* read more entries until level_type is zero */ + for (i = 1; *nent < maxnent; ++i) { + level_type = entry[i - 1].ecx & 0xff; + if (!level_type) + break; + do_cpuid_1_ent(&entry[i], function, i); + entry[i].flags |= + KVM_CPUID_FLAG_SIGNIFCANT_INDEX; + ++*nent; + } + break; + } + case 0x80000000: + entry->eax = min(entry->eax, 0x8000001a); + break; + case 0x80000001: + entry->edx &= kvm_supported_word1_x86_features; + entry->ecx &= kvm_supported_word6_x86_features; + break; + } + put_cpu(); +} + +static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid, + struct kvm_cpuid_entry2 __user *entries) +{ + struct kvm_cpuid_entry2 *cpuid_entries; + int limit, nent = 0, r = -E2BIG; + u32 func; + + if (cpuid->nent < 1) + goto out; + r = -ENOMEM; + cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry2) * cpuid->nent); + if (!cpuid_entries) + goto out; + + do_cpuid_ent(&cpuid_entries[0], 0, 0, &nent, cpuid->nent); + limit = cpuid_entries[0].eax; + for (func = 1; func <= limit && nent < cpuid->nent; ++func) + do_cpuid_ent(&cpuid_entries[nent], func, 0, + &nent, cpuid->nent); + r = -E2BIG; + if (nent >= cpuid->nent) + goto out_free; + + do_cpuid_ent(&cpuid_entries[nent], 0x80000000, 0, &nent, cpuid->nent); + limit = cpuid_entries[nent - 1].eax; + for (func = 0x80000001; func <= limit && nent < cpuid->nent; ++func) + do_cpuid_ent(&cpuid_entries[nent], func, 0, + &nent, cpuid->nent); + r = -EFAULT; + if (copy_to_user(entries, cpuid_entries, + nent * sizeof(struct kvm_cpuid_entry2))) + goto out_free; + cpuid->nent = nent; + r = 0; + +out_free: + vfree(cpuid_entries); +out: + return r; +} + +static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu, + struct kvm_lapic_state *s) +{ + vcpu_load(vcpu); + memcpy(s->regs, vcpu->arch.apic->regs, sizeof *s); + vcpu_put(vcpu); + + return 0; +} + +static int kvm_vcpu_ioctl_set_lapic(struct kvm_vcpu *vcpu, + struct kvm_lapic_state *s) +{ + vcpu_load(vcpu); + memcpy(vcpu->arch.apic->regs, s->regs, sizeof *s); + kvm_apic_post_state_restore(vcpu); + vcpu_put(vcpu); + + return 0; +} + +static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, + struct kvm_interrupt *irq) +{ + if (irq->irq < 0 || irq->irq >= 256) + return -EINVAL; + if (irqchip_in_kernel(vcpu->kvm)) + return -ENXIO; + vcpu_load(vcpu); + + set_bit(irq->irq, vcpu->arch.irq_pending); + set_bit(irq->irq / BITS_PER_LONG, &vcpu->arch.irq_summary); + + vcpu_put(vcpu); + + return 0; +} + +static int vcpu_ioctl_tpr_access_reporting(struct kvm_vcpu *vcpu, + struct kvm_tpr_access_ctl *tac) +{ + if (tac->flags) + return -EINVAL; + vcpu->arch.tpr_access_reporting = !!tac->enabled; + return 0; +} + +long kvm_arch_vcpu_ioctl(struct file *filp, + unsigned int ioctl, unsigned long arg) +{ + struct kvm_vcpu *vcpu = filp->private_data; + void __user *argp = (void __user *)arg; + int r; + + switch (ioctl) { + case KVM_GET_LAPIC: { + struct kvm_lapic_state lapic; + + memset(&lapic, 0, sizeof lapic); + r = kvm_vcpu_ioctl_get_lapic(vcpu, &lapic); + if (r) + goto out; + r = -EFAULT; + if (copy_to_user(argp, &lapic, sizeof lapic)) + goto out; + r = 0; + break; + } + case KVM_SET_LAPIC: { + struct kvm_lapic_state lapic; + + r = -EFAULT; + if (copy_from_user(&lapic, argp, sizeof lapic)) + goto out; + r = kvm_vcpu_ioctl_set_lapic(vcpu, &lapic);; + if (r) + goto out; + r = 0; + break; + } + case KVM_INTERRUPT: { + struct kvm_interrupt irq; + + r = -EFAULT; + if (copy_from_user(&irq, argp, sizeof irq)) + goto out; + r = kvm_vcpu_ioctl_interrupt(vcpu, &irq); + if (r) + goto out; + r = 0; + break; + } + case KVM_SET_CPUID: { + struct kvm_cpuid __user *cpuid_arg = argp; + struct kvm_cpuid cpuid; + + r = -EFAULT; + if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid)) + goto out; + r = kvm_vcpu_ioctl_set_cpuid(vcpu, &cpuid, cpuid_arg->entries); + if (r) + goto out; + break; + } + case KVM_SET_CPUID2: { + struct kvm_cpuid2 __user *cpuid_arg = argp; + struct kvm_cpuid2 cpuid; + + r = -EFAULT; + if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid)) + goto out; + r = kvm_vcpu_ioctl_set_cpuid2(vcpu, &cpuid, + cpuid_arg->entries); + if (r) + goto out; + break; + } + case KVM_GET_CPUID2: { + struct kvm_cpuid2 __user *cpuid_arg = argp; + struct kvm_cpuid2 cpuid; + + r = -EFAULT; + if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid)) + goto out; + r = kvm_vcpu_ioctl_get_cpuid2(vcpu, &cpuid, + cpuid_arg->entries); + if (r) + goto out; + r = -EFAULT; + if (copy_to_user(cpuid_arg, &cpuid, sizeof cpuid)) + goto out; + r = 0; + break; + } + case KVM_GET_MSRS: + r = msr_io(vcpu, argp, kvm_get_msr, 1); + break; + case KVM_SET_MSRS: + r = msr_io(vcpu, argp, do_set_msr, 0); + break; + case KVM_TPR_ACCESS_REPORTING: { + struct kvm_tpr_access_ctl tac; + + r = -EFAULT; + if (copy_from_user(&tac, argp, sizeof tac)) + goto out; + r = vcpu_ioctl_tpr_access_reporting(vcpu, &tac); + if (r) + goto out; + r = -EFAULT; + if (copy_to_user(argp, &tac, sizeof tac)) + goto out; + r = 0; + break; + }; + case KVM_SET_VAPIC_ADDR: { + struct kvm_vapic_addr va; + + r = -EINVAL; + if (!irqchip_in_kernel(vcpu->kvm)) + goto out; + r = -EFAULT; + if (copy_from_user(&va, argp, sizeof va)) + goto out; + r = 0; + kvm_lapic_set_vapic_addr(vcpu, va.vapic_addr); + break; + } + default: + r = -EINVAL; + } +out: + return r; +} + +static int kvm_vm_ioctl_set_tss_addr(struct kvm *kvm, unsigned long addr) +{ + int ret; + + if (addr > (unsigned int)(-3 * PAGE_SIZE)) + return -1; + ret = kvm_x86_ops->set_tss_addr(kvm, addr); + return ret; +} + +static int kvm_vm_ioctl_set_nr_mmu_pages(struct kvm *kvm, + u32 kvm_nr_mmu_pages) +{ + if (kvm_nr_mmu_pages < KVM_MIN_ALLOC_MMU_PAGES) + return -EINVAL; + + down_write(&kvm->slots_lock); + + kvm_mmu_change_mmu_pages(kvm, kvm_nr_mmu_pages); + kvm->arch.n_requested_mmu_pages = kvm_nr_mmu_pages; + + up_write(&kvm->slots_lock); + return 0; +} + +static int kvm_vm_ioctl_get_nr_mmu_pages(struct kvm *kvm) +{ + return kvm->arch.n_alloc_mmu_pages; +} + +gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) +{ + int i; + struct kvm_mem_alias *alias; + + for (i = 0; i < kvm->arch.naliases; ++i) { + alias = &kvm->arch.aliases[i]; + if (gfn >= alias->base_gfn + && gfn < alias->base_gfn + alias->npages) + return alias->target_gfn + gfn - alias->base_gfn; + } + return gfn; +} + +/* + * Set a new alias region. Aliases map a portion of physical memory into + * another portion. This is useful for memory windows, for example the PC + * VGA region. + */ +static int kvm_vm_ioctl_set_memory_alias(struct kvm *kvm, + struct kvm_memory_alias *alias) +{ + int r, n; + struct kvm_mem_alias *p; + + r = -EINVAL; + /* General sanity checks */ + if (alias->memory_size & (PAGE_SIZE - 1)) + goto out; + if (alias->guest_phys_addr & (PAGE_SIZE - 1)) + goto out; + if (alias->slot >= KVM_ALIAS_SLOTS) + goto out; + if (alias->guest_phys_addr + alias->memory_size + < alias->guest_phys_addr) + goto out; + if (alias->target_phys_addr + alias->memory_size + < alias->target_phys_addr) + goto out; + + down_write(&kvm->slots_lock); + + p = &kvm->arch.aliases[alias->slot]; + p->base_gfn = alias->guest_phys_addr >> PAGE_SHIFT; + p->npages = alias->memory_size >> PAGE_SHIFT; + p->target_gfn = alias->target_phys_addr >> PAGE_SHIFT; + + for (n = KVM_ALIAS_SLOTS; n > 0; --n) + if (kvm->arch.aliases[n - 1].npages) + break; + kvm->arch.naliases = n; + + kvm_mmu_zap_all(kvm); + + up_write(&kvm->slots_lock); + + return 0; + +out: + return r; +} + +static int kvm_vm_ioctl_get_irqchip(struct kvm *kvm, struct kvm_irqchip *chip) +{ + int r; + + r = 0; + switch (chip->chip_id) { + case KVM_IRQCHIP_PIC_MASTER: + memcpy(&chip->chip.pic, + &pic_irqchip(kvm)->pics[0], + sizeof(struct kvm_pic_state)); + break; + case KVM_IRQCHIP_PIC_SLAVE: + memcpy(&chip->chip.pic, + &pic_irqchip(kvm)->pics[1], + sizeof(struct kvm_pic_state)); + break; + case KVM_IRQCHIP_IOAPIC: + memcpy(&chip->chip.ioapic, + ioapic_irqchip(kvm), + sizeof(struct kvm_ioapic_state)); + break; + default: + r = -EINVAL; + break; + } + return r; +} + +static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip *chip) +{ + int r; + + r = 0; + switch (chip->chip_id) { + case KVM_IRQCHIP_PIC_MASTER: + memcpy(&pic_irqchip(kvm)->pics[0], + &chip->chip.pic, + sizeof(struct kvm_pic_state)); + break; + case KVM_IRQCHIP_PIC_SLAVE: + memcpy(&pic_irqchip(kvm)->pics[1], + &chip->chip.pic, + sizeof(struct kvm_pic_state)); + break; + case KVM_IRQCHIP_IOAPIC: + memcpy(ioapic_irqchip(kvm), + &chip->chip.ioapic, + sizeof(struct kvm_ioapic_state)); + break; + default: + r = -EINVAL; + break; + } + kvm_pic_update_irq(pic_irqchip(kvm)); + return r; +} + +/* + * Get (and clear) the dirty memory log for a memory slot. + */ +int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, + struct kvm_dirty_log *log) +{ + int r; + int n; + struct kvm_memory_slot *memslot; + int is_dirty = 0; + + down_write(&kvm->slots_lock); + + r = kvm_get_dirty_log(kvm, log, &is_dirty); + if (r) + goto out; + + /* If nothing is dirty, don't bother messing with page tables. */ + if (is_dirty) { + kvm_mmu_slot_remove_write_access(kvm, log->slot); + kvm_flush_remote_tlbs(kvm); + memslot = &kvm->memslots[log->slot]; + n = ALIGN(memslot->npages, BITS_PER_LONG) / 8; + memset(memslot->dirty_bitmap, 0, n); + } + r = 0; +out: + up_write(&kvm->slots_lock); + return r; +} + +long kvm_arch_vm_ioctl(struct file *filp, + unsigned int ioctl, unsigned long arg) +{ + struct kvm *kvm = filp->private_data; + void __user *argp = (void __user *)arg; + int r = -EINVAL; + + switch (ioctl) { + case KVM_SET_TSS_ADDR: + r = kvm_vm_ioctl_set_tss_addr(kvm, arg); + if (r < 0) + goto out; + break; + case KVM_SET_MEMORY_REGION: { + struct kvm_memory_region kvm_mem; + struct kvm_userspace_memory_region kvm_userspace_mem; + + r = -EFAULT; + if (copy_from_user(&kvm_mem, argp, sizeof kvm_mem)) + goto out; + kvm_userspace_mem.slot = kvm_mem.slot; + kvm_userspace_mem.flags = kvm_mem.flags; + kvm_userspace_mem.guest_phys_addr = kvm_mem.guest_phys_addr; + kvm_userspace_mem.memory_size = kvm_mem.memory_size; + r = kvm_vm_ioctl_set_memory_region(kvm, &kvm_userspace_mem, 0); + if (r) + goto out; + break; + } + case KVM_SET_NR_MMU_PAGES: + r = kvm_vm_ioctl_set_nr_mmu_pages(kvm, arg); + if (r) + goto out; + break; + case KVM_GET_NR_MMU_PAGES: + r = kvm_vm_ioctl_get_nr_mmu_pages(kvm); + break; + case KVM_SET_MEMORY_ALIAS: { + struct kvm_memory_alias alias; + + r = -EFAULT; + if (copy_from_user(&alias, argp, sizeof alias)) + goto out; + r = kvm_vm_ioctl_set_memory_alias(kvm, &alias); + if (r) + goto out; + break; + } + case KVM_CREATE_IRQCHIP: + r = -ENOMEM; + kvm->arch.vpic = kvm_create_pic(kvm); + if (kvm->arch.vpic) { + r = kvm_ioapic_init(kvm); + if (r) { + kfree(kvm->arch.vpic); + kvm->arch.vpic = NULL; + goto out; + } + } else + goto out; + break; + case KVM_IRQ_LINE: { + struct kvm_irq_level irq_event; + + r = -EFAULT; + if (copy_from_user(&irq_event, argp, sizeof irq_event)) + goto out; + if (irqchip_in_kernel(kvm)) { + mutex_lock(&kvm->lock); + if (irq_event.irq < 16) + kvm_pic_set_irq(pic_irqchip(kvm), + irq_event.irq, + irq_event.level); + kvm_ioapic_set_irq(kvm->arch.vioapic, + irq_event.irq, + irq_event.level); + mutex_unlock(&kvm->lock); + r = 0; + } + break; + } + case KVM_GET_IRQCHIP: { + /* 0: PIC master, 1: PIC slave, 2: IOAPIC */ + struct kvm_irqchip chip; + + r = -EFAULT; + if (copy_from_user(&chip, argp, sizeof chip)) + goto out; + r = -ENXIO; + if (!irqchip_in_kernel(kvm)) + goto out; + r = kvm_vm_ioctl_get_irqchip(kvm, &chip); + if (r) + goto out; + r = -EFAULT; + if (copy_to_user(argp, &chip, sizeof chip)) + goto out; + r = 0; + break; + } + case KVM_SET_IRQCHIP: { + /* 0: PIC master, 1: PIC slave, 2: IOAPIC */ + struct kvm_irqchip chip; + + r = -EFAULT; + if (copy_from_user(&chip, argp, sizeof chip)) + goto out; + r = -ENXIO; + if (!irqchip_in_kernel(kvm)) + goto out; + r = kvm_vm_ioctl_set_irqchip(kvm, &chip); + if (r) + goto out; + r = 0; + break; + } + default: + ; + } +out: + return r; +} + +static void kvm_init_msr_list(void) +{ + u32 dummy[2]; + unsigned i, j; + + for (i = j = 0; i < ARRAY_SIZE(msrs_to_save); i++) { + if (rdmsr_safe(msrs_to_save[i], &dummy[0], &dummy[1]) < 0) + continue; + if (j < i) + msrs_to_save[j] = msrs_to_save[i]; + j++; + } + num_msrs_to_save = j; +} + +/* + * Only apic need an MMIO device hook, so shortcut now.. + */ +static struct kvm_io_device *vcpu_find_pervcpu_dev(struct kvm_vcpu *vcpu, + gpa_t addr) +{ + struct kvm_io_device *dev; + + if (vcpu->arch.apic) { + dev = &vcpu->arch.apic->dev; + if (dev->in_range(dev, addr)) + return dev; + } + return NULL; +} + + +static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu, + gpa_t addr) +{ + struct kvm_io_device *dev; + + dev = vcpu_find_pervcpu_dev(vcpu, addr); + if (dev == NULL) + dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr); + return dev; +} + +int emulator_read_std(unsigned long addr, + void *val, + unsigned int bytes, + struct kvm_vcpu *vcpu) +{ + void *data = val; + int r = X86EMUL_CONTINUE; + + down_read(&vcpu->kvm->slots_lock); + while (bytes) { + gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr); + unsigned offset = addr & (PAGE_SIZE-1); + unsigned tocopy = min(bytes, (unsigned)PAGE_SIZE - offset); + int ret; + + if (gpa == UNMAPPED_GVA) { + r = X86EMUL_PROPAGATE_FAULT; + goto out; + } + ret = kvm_read_guest(vcpu->kvm, gpa, data, tocopy); + if (ret < 0) { + r = X86EMUL_UNHANDLEABLE; + goto out; + } + + bytes -= tocopy; + data += tocopy; + addr += tocopy; + } +out: + up_read(&vcpu->kvm->slots_lock); + return r; +} +EXPORT_SYMBOL_GPL(emulator_read_std); + +static int emulator_read_emulated(unsigned long addr, + void *val, + unsigned int bytes, + struct kvm_vcpu *vcpu) +{ + struct kvm_io_device *mmio_dev; + gpa_t gpa; + + if (vcpu->mmio_read_completed) { + memcpy(val, vcpu->mmio_data, bytes); + vcpu->mmio_read_completed = 0; + return X86EMUL_CONTINUE; + } + + down_read(&vcpu->kvm->slots_lock); + gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr); + up_read(&vcpu->kvm->slots_lock); + + /* For APIC access vmexit */ + if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) + goto mmio; + + if (emulator_read_std(addr, val, bytes, vcpu) + == X86EMUL_CONTINUE) + return X86EMUL_CONTINUE; + if (gpa == UNMAPPED_GVA) + return X86EMUL_PROPAGATE_FAULT; + +mmio: + /* + * Is this MMIO handled locally? + */ + mutex_lock(&vcpu->kvm->lock); + mmio_dev = vcpu_find_mmio_dev(vcpu, gpa); + if (mmio_dev) { + kvm_iodevice_read(mmio_dev, gpa, bytes, val); + mutex_unlock(&vcpu->kvm->lock); + return X86EMUL_CONTINUE; + } + mutex_unlock(&vcpu->kvm->lock); + + vcpu->mmio_needed = 1; + vcpu->mmio_phys_addr = gpa; + vcpu->mmio_size = bytes; + vcpu->mmio_is_write = 0; + + return X86EMUL_UNHANDLEABLE; +} + +static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, + const void *val, int bytes) +{ + int ret; + + down_read(&vcpu->kvm->slots_lock); + ret = kvm_write_guest(vcpu->kvm, gpa, val, bytes); + if (ret < 0) { + up_read(&vcpu->kvm->slots_lock); + return 0; + } + kvm_mmu_pte_write(vcpu, gpa, val, bytes); + up_read(&vcpu->kvm->slots_lock); + return 1; +} + +static int emulator_write_emulated_onepage(unsigned long addr, + const void *val, + unsigned int bytes, + struct kvm_vcpu *vcpu) +{ + struct kvm_io_device *mmio_dev; + gpa_t gpa; + + down_read(&vcpu->kvm->slots_lock); + gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr); + up_read(&vcpu->kvm->slots_lock); + + if (gpa == UNMAPPED_GVA) { + kvm_inject_page_fault(vcpu, addr, 2); + return X86EMUL_PROPAGATE_FAULT; + } + + /* For APIC access vmexit */ + if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) + goto mmio; + + if (emulator_write_phys(vcpu, gpa, val, bytes)) + return X86EMUL_CONTINUE; + +mmio: + /* + * Is this MMIO handled locally? + */ + mutex_lock(&vcpu->kvm->lock); + mmio_dev = vcpu_find_mmio_dev(vcpu, gpa); + if (mmio_dev) { + kvm_iodevice_write(mmio_dev, gpa, bytes, val); + mutex_unlock(&vcpu->kvm->lock); + return X86EMUL_CONTINUE; + } + mutex_unlock(&vcpu->kvm->lock); + + vcpu->mmio_needed = 1; + vcpu->mmio_phys_addr = gpa; + vcpu->mmio_size = bytes; + vcpu->mmio_is_write = 1; + memcpy(vcpu->mmio_data, val, bytes); + + return X86EMUL_CONTINUE; +} + +int emulator_write_emulated(unsigned long addr, + const void *val, + unsigned int bytes, + struct kvm_vcpu *vcpu) +{ + /* Crossing a page boundary? */ + if (((addr + bytes - 1) ^ addr) & PAGE_MASK) { + int rc, now; + + now = -addr & ~PAGE_MASK; + rc = emulator_write_emulated_onepage(addr, val, now, vcpu); + if (rc != X86EMUL_CONTINUE) + return rc; + addr += now; + val += now; + bytes -= now; + } + return emulator_write_emulated_onepage(addr, val, bytes, vcpu); +} +EXPORT_SYMBOL_GPL(emulator_write_emulated); + +static int emulator_cmpxchg_emulated(unsigned long addr, + const void *old, + const void *new, + unsigned int bytes, + struct kvm_vcpu *vcpu) +{ + static int reported; + + if (!reported) { + reported = 1; + printk(KERN_WARNING "kvm: emulating exchange as write\n"); + } +#ifndef CONFIG_X86_64 + /* guests cmpxchg8b have to be emulated atomically */ + if (bytes == 8) { + gpa_t gpa; + struct page *page; + char *kaddr; + u64 val; + + down_read(&vcpu->kvm->slots_lock); + gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr); + + if (gpa == UNMAPPED_GVA || + (gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) + goto emul_write; + + if (((gpa + bytes - 1) & PAGE_MASK) != (gpa & PAGE_MASK)) + goto emul_write; + + val = *(u64 *)new; + + down_read(¤t->mm->mmap_sem); + page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT); + up_read(¤t->mm->mmap_sem); + + kaddr = kmap_atomic(page, KM_USER0); + set_64bit((u64 *)(kaddr + offset_in_page(gpa)), val); + kunmap_atomic(kaddr, KM_USER0); + kvm_release_page_dirty(page); + emul_write: + up_read(&vcpu->kvm->slots_lock); + } +#endif + + return emulator_write_emulated(addr, new, bytes, vcpu); +} + +static unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg) +{ + return kvm_x86_ops->get_segment_base(vcpu, seg); +} + +int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address) +{ + return X86EMUL_CONTINUE; +} + +int emulate_clts(struct kvm_vcpu *vcpu) +{ + kvm_x86_ops->set_cr0(vcpu, vcpu->arch.cr0 & ~X86_CR0_TS); + return X86EMUL_CONTINUE; +} + +int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long *dest) +{ + struct kvm_vcpu *vcpu = ctxt->vcpu; + + switch (dr) { + case 0 ... 3: + *dest = kvm_x86_ops->get_dr(vcpu, dr); + return X86EMUL_CONTINUE; + default: + pr_unimpl(vcpu, "%s: unexpected dr %u\n", __FUNCTION__, dr); + return X86EMUL_UNHANDLEABLE; + } +} + +int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value) +{ + unsigned long mask = (ctxt->mode == X86EMUL_MODE_PROT64) ? ~0ULL : ~0U; + int exception; + + kvm_x86_ops->set_dr(ctxt->vcpu, dr, value & mask, &exception); + if (exception) { + /* FIXME: better handling */ + return X86EMUL_UNHANDLEABLE; + } + return X86EMUL_CONTINUE; +} + +void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context) +{ + static int reported; + u8 opcodes[4]; + unsigned long rip = vcpu->arch.rip; + unsigned long rip_linear; + + rip_linear = rip + get_segment_base(vcpu, VCPU_SREG_CS); + + if (reported) + return; + + emulator_read_std(rip_linear, (void *)opcodes, 4, vcpu); + + printk(KERN_ERR "emulation failed (%s) rip %lx %02x %02x %02x %02x\n", + context, rip, opcodes[0], opcodes[1], opcodes[2], opcodes[3]); + reported = 1; +} +EXPORT_SYMBOL_GPL(kvm_report_emulation_failure); + +static struct x86_emulate_ops emulate_ops = { + .read_std = emulator_read_std, + .read_emulated = emulator_read_emulated, + .write_emulated = emulator_write_emulated, + .cmpxchg_emulated = emulator_cmpxchg_emulated, +}; + +int emulate_instruction(struct kvm_vcpu *vcpu, + struct kvm_run *run, + unsigned long cr2, + u16 error_code, + int emulation_type) +{ + int r; + struct decode_cache *c; + + vcpu->arch.mmio_fault_cr2 = cr2; + kvm_x86_ops->cache_regs(vcpu); + + vcpu->mmio_is_write = 0; + vcpu->arch.pio.string = 0; + + if (!(emulation_type & EMULTYPE_NO_DECODE)) { + int cs_db, cs_l; + kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l); + + vcpu->arch.emulate_ctxt.vcpu = vcpu; + vcpu->arch.emulate_ctxt.eflags = kvm_x86_ops->get_rflags(vcpu); + vcpu->arch.emulate_ctxt.mode = + (vcpu->arch.emulate_ctxt.eflags & X86_EFLAGS_VM) + ? X86EMUL_MODE_REAL : cs_l + ? X86EMUL_MODE_PROT64 : cs_db + ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16; + + if (vcpu->arch.emulate_ctxt.mode == X86EMUL_MODE_PROT64) { + vcpu->arch.emulate_ctxt.cs_base = 0; + vcpu->arch.emulate_ctxt.ds_base = 0; + vcpu->arch.emulate_ctxt.es_base = 0; + vcpu->arch.emulate_ctxt.ss_base = 0; + } else { + vcpu->arch.emulate_ctxt.cs_base = + get_segment_base(vcpu, VCPU_SREG_CS); + vcpu->arch.emulate_ctxt.ds_base = + get_segment_base(vcpu, VCPU_SREG_DS); + vcpu->arch.emulate_ctxt.es_base = + get_segment_base(vcpu, VCPU_SREG_ES); + vcpu->arch.emulate_ctxt.ss_base = + get_segment_base(vcpu, VCPU_SREG_SS); + } + + vcpu->arch.emulate_ctxt.gs_base = + get_segment_base(vcpu, VCPU_SREG_GS); + vcpu->arch.emulate_ctxt.fs_base = + get_segment_base(vcpu, VCPU_SREG_FS); + + r = x86_decode_insn(&vcpu->arch.emulate_ctxt, &emulate_ops); + + /* Reject the instructions other than VMCALL/VMMCALL when + * try to emulate invalid opcode */ + c = &vcpu->arch.emulate_ctxt.decode; + if ((emulation_type & EMULTYPE_TRAP_UD) && + (!(c->twobyte && c->b == 0x01 && + (c->modrm_reg == 0 || c->modrm_reg == 3) && + c->modrm_mod == 3 && c->modrm_rm == 1))) + return EMULATE_FAIL; + + ++vcpu->stat.insn_emulation; + if (r) { + ++vcpu->stat.insn_emulation_fail; + if (kvm_mmu_unprotect_page_virt(vcpu, cr2)) + return EMULATE_DONE; + return EMULATE_FAIL; + } + } + + r = x86_emulate_insn(&vcpu->arch.emulate_ctxt, &emulate_ops); + + if (vcpu->arch.pio.string) + return EMULATE_DO_MMIO; + + if ((r || vcpu->mmio_is_write) && run) { + run->exit_reason = KVM_EXIT_MMIO; + run->mmio.phys_addr = vcpu->mmio_phys_addr; + memcpy(run->mmio.data, vcpu->mmio_data, 8); + run->mmio.len = vcpu->mmio_size; + run->mmio.is_write = vcpu->mmio_is_write; + } + + if (r) { + if (kvm_mmu_unprotect_page_virt(vcpu, cr2)) + return EMULATE_DONE; + if (!vcpu->mmio_needed) { + kvm_report_emulation_failure(vcpu, "mmio"); + return EMULATE_FAIL; + } + return EMULATE_DO_MMIO; + } + + kvm_x86_ops->decache_regs(vcpu); + kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags); + + if (vcpu->mmio_is_write) { + vcpu->mmio_needed = 0; + return EMULATE_DO_MMIO; + } + + return EMULATE_DONE; +} +EXPORT_SYMBOL_GPL(emulate_instruction); + +static void free_pio_guest_pages(struct kvm_vcpu *vcpu) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(vcpu->arch.pio.guest_pages); ++i) + if (vcpu->arch.pio.guest_pages[i]) { + kvm_release_page_dirty(vcpu->arch.pio.guest_pages[i]); + vcpu->arch.pio.guest_pages[i] = NULL; + } +} + +static int pio_copy_data(struct kvm_vcpu *vcpu) +{ + void *p = vcpu->arch.pio_data; + void *q; + unsigned bytes; + int nr_pages = vcpu->arch.pio.guest_pages[1] ? 2 : 1; + + q = vmap(vcpu->arch.pio.guest_pages, nr_pages, VM_READ|VM_WRITE, + PAGE_KERNEL); + if (!q) { + free_pio_guest_pages(vcpu); + return -ENOMEM; + } + q += vcpu->arch.pio.guest_page_offset; + bytes = vcpu->arch.pio.size * vcpu->arch.pio.cur_count; + if (vcpu->arch.pio.in) + memcpy(q, p, bytes); + else + memcpy(p, q, bytes); + q -= vcpu->arch.pio.guest_page_offset; + vunmap(q); + free_pio_guest_pages(vcpu); + return 0; +} + +int complete_pio(struct kvm_vcpu *vcpu) +{ + struct kvm_pio_request *io = &vcpu->arch.pio; + long delta; + int r; + + kvm_x86_ops->cache_regs(vcpu); + + if (!io->string) { + if (io->in) + memcpy(&vcpu->arch.regs[VCPU_REGS_RAX], vcpu->arch.pio_data, + io->size); + } else { + if (io->in) { + r = pio_copy_data(vcpu); + if (r) { + kvm_x86_ops->cache_regs(vcpu); + return r; + } + } + + delta = 1; + if (io->rep) { + delta *= io->cur_count; + /* + * The size of the register should really depend on + * current address size. + */ + vcpu->arch.regs[VCPU_REGS_RCX] -= delta; + } + if (io->down) + delta = -delta; + delta *= io->size; + if (io->in) + vcpu->arch.regs[VCPU_REGS_RDI] += delta; + else + vcpu->arch.regs[VCPU_REGS_RSI] += delta; + } + + kvm_x86_ops->decache_regs(vcpu); + + io->count -= io->cur_count; + io->cur_count = 0; + + return 0; +} + +static void kernel_pio(struct kvm_io_device *pio_dev, + struct kvm_vcpu *vcpu, + void *pd) +{ + /* TODO: String I/O for in kernel device */ + + mutex_lock(&vcpu->kvm->lock); + if (vcpu->arch.pio.in) + kvm_iodevice_read(pio_dev, vcpu->arch.pio.port, + vcpu->arch.pio.size, + pd); + else + kvm_iodevice_write(pio_dev, vcpu->arch.pio.port, + vcpu->arch.pio.size, + pd); + mutex_unlock(&vcpu->kvm->lock); +} + +static void pio_string_write(struct kvm_io_device *pio_dev, + struct kvm_vcpu *vcpu) +{ + struct kvm_pio_request *io = &vcpu->arch.pio; + void *pd = vcpu->arch.pio_data; + int i; + + mutex_lock(&vcpu->kvm->lock); + for (i = 0; i < io->cur_count; i++) { + kvm_iodevice_write(pio_dev, io->port, + io->size, + pd); + pd += io->size; + } + mutex_unlock(&vcpu->kvm->lock); +} + +static struct kvm_io_device *vcpu_find_pio_dev(struct kvm_vcpu *vcpu, + gpa_t addr) +{ + return kvm_io_bus_find_dev(&vcpu->kvm->pio_bus, addr); +} + +int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, + int size, unsigned port) +{ + struct kvm_io_device *pio_dev; + + vcpu->run->exit_reason = KVM_EXIT_IO; + vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT; + vcpu->run->io.size = vcpu->arch.pio.size = size; + vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE; + vcpu->run->io.count = vcpu->arch.pio.count = vcpu->arch.pio.cur_count = 1; + vcpu->run->io.port = vcpu->arch.pio.port = port; + vcpu->arch.pio.in = in; + vcpu->arch.pio.string = 0; + vcpu->arch.pio.down = 0; + vcpu->arch.pio.guest_page_offset = 0; + vcpu->arch.pio.rep = 0; + + kvm_x86_ops->cache_regs(vcpu); + memcpy(vcpu->arch.pio_data, &vcpu->arch.regs[VCPU_REGS_RAX], 4); + kvm_x86_ops->decache_regs(vcpu); + + kvm_x86_ops->skip_emulated_instruction(vcpu); + + pio_dev = vcpu_find_pio_dev(vcpu, port); + if (pio_dev) { + kernel_pio(pio_dev, vcpu, vcpu->arch.pio_data); + complete_pio(vcpu); + return 1; + } + return 0; +} +EXPORT_SYMBOL_GPL(kvm_emulate_pio); + +int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, + int size, unsigned long count, int down, + gva_t address, int rep, unsigned port) +{ + unsigned now, in_page; + int i, ret = 0; + int nr_pages = 1; + struct page *page; + struct kvm_io_device *pio_dev; + + vcpu->run->exit_reason = KVM_EXIT_IO; + vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT; + vcpu->run->io.size = vcpu->arch.pio.size = size; + vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE; + vcpu->run->io.count = vcpu->arch.pio.count = vcpu->arch.pio.cur_count = count; + vcpu->run->io.port = vcpu->arch.pio.port = port; + vcpu->arch.pio.in = in; + vcpu->arch.pio.string = 1; + vcpu->arch.pio.down = down; + vcpu->arch.pio.guest_page_offset = offset_in_page(address); + vcpu->arch.pio.rep = rep; + + if (!count) { + kvm_x86_ops->skip_emulated_instruction(vcpu); + return 1; + } + + if (!down) + in_page = PAGE_SIZE - offset_in_page(address); + else + in_page = offset_in_page(address) + size; + now = min(count, (unsigned long)in_page / size); + if (!now) { + /* + * String I/O straddles page boundary. Pin two guest pages + * so that we satisfy atomicity constraints. Do just one + * transaction to avoid complexity. + */ + nr_pages = 2; + now = 1; + } + if (down) { + /* + * String I/O in reverse. Yuck. Kill the guest, fix later. + */ + pr_unimpl(vcpu, "guest string pio down\n"); + kvm_inject_gp(vcpu, 0); + return 1; + } + vcpu->run->io.count = now; + vcpu->arch.pio.cur_count = now; + + if (vcpu->arch.pio.cur_count == vcpu->arch.pio.count) + kvm_x86_ops->skip_emulated_instruction(vcpu); + + for (i = 0; i < nr_pages; ++i) { + down_read(&vcpu->kvm->slots_lock); + page = gva_to_page(vcpu, address + i * PAGE_SIZE); + vcpu->arch.pio.guest_pages[i] = page; + up_read(&vcpu->kvm->slots_lock); + if (!page) { + kvm_inject_gp(vcpu, 0); + free_pio_guest_pages(vcpu); + return 1; + } + } + + pio_dev = vcpu_find_pio_dev(vcpu, port); + if (!vcpu->arch.pio.in) { + /* string PIO write */ + ret = pio_copy_data(vcpu); + if (ret >= 0 && pio_dev) { + pio_string_write(pio_dev, vcpu); + complete_pio(vcpu); + if (vcpu->arch.pio.count == 0) + ret = 1; + } + } else if (pio_dev) + pr_unimpl(vcpu, "no string pio read support yet, " + "port %x size %d count %ld\n", + port, size, count); + + return ret; +} +EXPORT_SYMBOL_GPL(kvm_emulate_pio_string); + +int kvm_arch_init(void *opaque) +{ + int r; + struct kvm_x86_ops *ops = (struct kvm_x86_ops *)opaque; + + if (kvm_x86_ops) { + printk(KERN_ERR "kvm: already loaded the other module\n"); + r = -EEXIST; + goto out; + } + + if (!ops->cpu_has_kvm_support()) { + printk(KERN_ERR "kvm: no hardware support\n"); + r = -EOPNOTSUPP; + goto out; + } + if (ops->disabled_by_bios()) { + printk(KERN_ERR "kvm: disabled by bios\n"); + r = -EOPNOTSUPP; + goto out; + } + + r = kvm_mmu_module_init(); + if (r) + goto out; + + kvm_init_msr_list(); + + kvm_x86_ops = ops; + kvm_mmu_set_nonpresent_ptes(0ull, 0ull); + return 0; + +out: + return r; +} + +void kvm_arch_exit(void) +{ + kvm_x86_ops = NULL; + kvm_mmu_module_exit(); +} + +int kvm_emulate_halt(struct kvm_vcpu *vcpu) +{ + ++vcpu->stat.halt_exits; + if (irqchip_in_kernel(vcpu->kvm)) { + vcpu->arch.mp_state = VCPU_MP_STATE_HALTED; + kvm_vcpu_block(vcpu); + if (vcpu->arch.mp_state != VCPU_MP_STATE_RUNNABLE) + return -EINTR; + return 1; + } else { + vcpu->run->exit_reason = KVM_EXIT_HLT; + return 0; + } +} +EXPORT_SYMBOL_GPL(kvm_emulate_halt); + +int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) +{ + unsigned long nr, a0, a1, a2, a3, ret; + + kvm_x86_ops->cache_regs(vcpu); + + nr = vcpu->arch.regs[VCPU_REGS_RAX]; + a0 = vcpu->arch.regs[VCPU_REGS_RBX]; + a1 = vcpu->arch.regs[VCPU_REGS_RCX]; + a2 = vcpu->arch.regs[VCPU_REGS_RDX]; + a3 = vcpu->arch.regs[VCPU_REGS_RSI]; + + if (!is_long_mode(vcpu)) { + nr &= 0xFFFFFFFF; + a0 &= 0xFFFFFFFF; + a1 &= 0xFFFFFFFF; + a2 &= 0xFFFFFFFF; + a3 &= 0xFFFFFFFF; + } + + switch (nr) { + case KVM_HC_VAPIC_POLL_IRQ: + ret = 0; + break; + default: + ret = -KVM_ENOSYS; + break; + } + vcpu->arch.regs[VCPU_REGS_RAX] = ret; + kvm_x86_ops->decache_regs(vcpu); + ++vcpu->stat.hypercalls; + return 0; +} +EXPORT_SYMBOL_GPL(kvm_emulate_hypercall); + +int kvm_fix_hypercall(struct kvm_vcpu *vcpu) +{ + char instruction[3]; + int ret = 0; + + + /* + * Blow out the MMU to ensure that no other VCPU has an active mapping + * to ensure that the updated hypercall appears atomically across all + * VCPUs. + */ + kvm_mmu_zap_all(vcpu->kvm); + + kvm_x86_ops->cache_regs(vcpu); + kvm_x86_ops->patch_hypercall(vcpu, instruction); + if (emulator_write_emulated(vcpu->arch.rip, instruction, 3, vcpu) + != X86EMUL_CONTINUE) + ret = -EFAULT; + + return ret; +} + +static u64 mk_cr_64(u64 curr_cr, u32 new_val) +{ + return (curr_cr & ~((1ULL << 32) - 1)) | new_val; +} + +void realmode_lgdt(struct kvm_vcpu *vcpu, u16 limit, unsigned long base) +{ + struct descriptor_table dt = { limit, base }; + + kvm_x86_ops->set_gdt(vcpu, &dt); +} + +void realmode_lidt(struct kvm_vcpu *vcpu, u16 limit, unsigned long base) +{ + struct descriptor_table dt = { limit, base }; + + kvm_x86_ops->set_idt(vcpu, &dt); +} + +void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw, + unsigned long *rflags) +{ + kvm_lmsw(vcpu, msw); + *rflags = kvm_x86_ops->get_rflags(vcpu); +} + +unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr) +{ + kvm_x86_ops->decache_cr4_guest_bits(vcpu); + switch (cr) { + case 0: + return vcpu->arch.cr0; + case 2: + return vcpu->arch.cr2; + case 3: + return vcpu->arch.cr3; + case 4: + return vcpu->arch.cr4; + case 8: + return kvm_get_cr8(vcpu); + default: + vcpu_printf(vcpu, "%s: unexpected cr %u\n", __FUNCTION__, cr); + return 0; + } +} + +void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long val, + unsigned long *rflags) +{ + switch (cr) { + case 0: + kvm_set_cr0(vcpu, mk_cr_64(vcpu->arch.cr0, val)); + *rflags = kvm_x86_ops->get_rflags(vcpu); + break; + case 2: + vcpu->arch.cr2 = val; + break; + case 3: + kvm_set_cr3(vcpu, val); + break; + case 4: + kvm_set_cr4(vcpu, mk_cr_64(vcpu->arch.cr4, val)); + break; + case 8: + kvm_set_cr8(vcpu, val & 0xfUL); + break; + default: + vcpu_printf(vcpu, "%s: unexpected cr %u\n", __FUNCTION__, cr); + } +} + +static int move_to_next_stateful_cpuid_entry(struct kvm_vcpu *vcpu, int i) +{ + struct kvm_cpuid_entry2 *e = &vcpu->arch.cpuid_entries[i]; + int j, nent = vcpu->arch.cpuid_nent; + + e->flags &= ~KVM_CPUID_FLAG_STATE_READ_NEXT; + /* when no next entry is found, the current entry[i] is reselected */ + for (j = i + 1; j == i; j = (j + 1) % nent) { + struct kvm_cpuid_entry2 *ej = &vcpu->arch.cpuid_entries[j]; + if (ej->function == e->function) { + ej->flags |= KVM_CPUID_FLAG_STATE_READ_NEXT; + return j; + } + } + return 0; /* silence gcc, even though control never reaches here */ +} + +/* find an entry with matching function, matching index (if needed), and that + * should be read next (if it's stateful) */ +static int is_matching_cpuid_entry(struct kvm_cpuid_entry2 *e, + u32 function, u32 index) +{ + if (e->function != function) + return 0; + if ((e->flags & KVM_CPUID_FLAG_SIGNIFCANT_INDEX) && e->index != index) + return 0; + if ((e->flags & KVM_CPUID_FLAG_STATEFUL_FUNC) && + !(e->flags & KVM_CPUID_FLAG_STATE_READ_NEXT)) + return 0; + return 1; +} + +void kvm_emulate_cpuid(struct kvm_vcpu *vcpu) +{ + int i; + u32 function, index; + struct kvm_cpuid_entry2 *e, *best; + + kvm_x86_ops->cache_regs(vcpu); + function = vcpu->arch.regs[VCPU_REGS_RAX]; + index = vcpu->arch.regs[VCPU_REGS_RCX]; + vcpu->arch.regs[VCPU_REGS_RAX] = 0; + vcpu->arch.regs[VCPU_REGS_RBX] = 0; + vcpu->arch.regs[VCPU_REGS_RCX] = 0; + vcpu->arch.regs[VCPU_REGS_RDX] = 0; + best = NULL; + for (i = 0; i < vcpu->arch.cpuid_nent; ++i) { + e = &vcpu->arch.cpuid_entries[i]; + if (is_matching_cpuid_entry(e, function, index)) { + if (e->flags & KVM_CPUID_FLAG_STATEFUL_FUNC) + move_to_next_stateful_cpuid_entry(vcpu, i); + best = e; + break; + } + /* + * Both basic or both extended? + */ + if (((e->function ^ function) & 0x80000000) == 0) + if (!best || e->function > best->function) + best = e; + } + if (best) { + vcpu->arch.regs[VCPU_REGS_RAX] = best->eax; + vcpu->arch.regs[VCPU_REGS_RBX] = best->ebx; + vcpu->arch.regs[VCPU_REGS_RCX] = best->ecx; + vcpu->arch.regs[VCPU_REGS_RDX] = best->edx; + } + kvm_x86_ops->decache_regs(vcpu); + kvm_x86_ops->skip_emulated_instruction(vcpu); +} +EXPORT_SYMBOL_GPL(kvm_emulate_cpuid); + +/* + * Check if userspace requested an interrupt window, and that the + * interrupt window is open. + * + * No need to exit to userspace if we already have an interrupt queued. + */ +static int dm_request_for_irq_injection(struct kvm_vcpu *vcpu, + struct kvm_run *kvm_run) +{ + return (!vcpu->arch.irq_summary && + kvm_run->request_interrupt_window && + vcpu->arch.interrupt_window_open && + (kvm_x86_ops->get_rflags(vcpu) & X86_EFLAGS_IF)); +} + +static void post_kvm_run_save(struct kvm_vcpu *vcpu, + struct kvm_run *kvm_run) +{ + kvm_run->if_flag = (kvm_x86_ops->get_rflags(vcpu) & X86_EFLAGS_IF) != 0; + kvm_run->cr8 = kvm_get_cr8(vcpu); + kvm_run->apic_base = kvm_get_apic_base(vcpu); + if (irqchip_in_kernel(vcpu->kvm)) + kvm_run->ready_for_interrupt_injection = 1; + else + kvm_run->ready_for_interrupt_injection = + (vcpu->arch.interrupt_window_open && + vcpu->arch.irq_summary == 0); +} + +static void vapic_enter(struct kvm_vcpu *vcpu) +{ + struct kvm_lapic *apic = vcpu->arch.apic; + struct page *page; + + if (!apic || !apic->vapic_addr) + return; + + down_read(¤t->mm->mmap_sem); + page = gfn_to_page(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT); + up_read(¤t->mm->mmap_sem); + + vcpu->arch.apic->vapic_page = page; +} + +static void vapic_exit(struct kvm_vcpu *vcpu) +{ + struct kvm_lapic *apic = vcpu->arch.apic; + + if (!apic || !apic->vapic_addr) + return; + + kvm_release_page_dirty(apic->vapic_page); + mark_page_dirty(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT); +} + +static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + int r; + + if (unlikely(vcpu->arch.mp_state == VCPU_MP_STATE_SIPI_RECEIVED)) { + pr_debug("vcpu %d received sipi with vector # %x\n", + vcpu->vcpu_id, vcpu->arch.sipi_vector); + kvm_lapic_reset(vcpu); + r = kvm_x86_ops->vcpu_reset(vcpu); + if (r) + return r; + vcpu->arch.mp_state = VCPU_MP_STATE_RUNNABLE; + } + + vapic_enter(vcpu); + +preempted: + if (vcpu->guest_debug.enabled) + kvm_x86_ops->guest_debug_pre(vcpu); + +again: + if (vcpu->requests) + if (test_and_clear_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests)) + kvm_mmu_unload(vcpu); + + r = kvm_mmu_reload(vcpu); + if (unlikely(r)) + goto out; + + if (vcpu->requests) { + if (test_and_clear_bit(KVM_REQ_MIGRATE_TIMER, &vcpu->requests)) + __kvm_migrate_apic_timer(vcpu); + if (test_and_clear_bit(KVM_REQ_REPORT_TPR_ACCESS, + &vcpu->requests)) { + kvm_run->exit_reason = KVM_EXIT_TPR_ACCESS; + r = 0; + goto out; + } + } + + kvm_inject_pending_timer_irqs(vcpu); + + preempt_disable(); + + kvm_x86_ops->prepare_guest_switch(vcpu); + kvm_load_guest_fpu(vcpu); + + local_irq_disable(); + + if (need_resched()) { + local_irq_enable(); + preempt_enable(); + r = 1; + goto out; + } + + if (vcpu->requests) + if (test_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests)) { + local_irq_enable(); + preempt_enable(); + r = 1; + goto out; + } + + if (signal_pending(current)) { + local_irq_enable(); + preempt_enable(); + r = -EINTR; + kvm_run->exit_reason = KVM_EXIT_INTR; + ++vcpu->stat.signal_exits; + goto out; + } + + if (vcpu->arch.exception.pending) + __queue_exception(vcpu); + else if (irqchip_in_kernel(vcpu->kvm)) + kvm_x86_ops->inject_pending_irq(vcpu); + else + kvm_x86_ops->inject_pending_vectors(vcpu, kvm_run); + + kvm_lapic_sync_to_vapic(vcpu); + + vcpu->guest_mode = 1; + kvm_guest_enter(); + + if (vcpu->requests) + if (test_and_clear_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests)) + kvm_x86_ops->tlb_flush(vcpu); + + kvm_x86_ops->run(vcpu, kvm_run); + + vcpu->guest_mode = 0; + local_irq_enable(); + + ++vcpu->stat.exits; + + /* + * We must have an instruction between local_irq_enable() and + * kvm_guest_exit(), so the timer interrupt isn't delayed by + * the interrupt shadow. The stat.exits increment will do nicely. + * But we need to prevent reordering, hence this barrier(): + */ + barrier(); + + kvm_guest_exit(); + + preempt_enable(); + + /* + * Profile KVM exit RIPs: + */ + if (unlikely(prof_on == KVM_PROFILING)) { + kvm_x86_ops->cache_regs(vcpu); + profile_hit(KVM_PROFILING, (void *)vcpu->arch.rip); + } + + if (vcpu->arch.exception.pending && kvm_x86_ops->exception_injected(vcpu)) + vcpu->arch.exception.pending = false; + + kvm_lapic_sync_from_vapic(vcpu); + + r = kvm_x86_ops->handle_exit(kvm_run, vcpu); + + if (r > 0) { + if (dm_request_for_irq_injection(vcpu, kvm_run)) { + r = -EINTR; + kvm_run->exit_reason = KVM_EXIT_INTR; + ++vcpu->stat.request_irq_exits; + goto out; + } + if (!need_resched()) + goto again; + } + +out: + if (r > 0) { + kvm_resched(vcpu); + goto preempted; + } + + post_kvm_run_save(vcpu, kvm_run); + + vapic_exit(vcpu); + + return r; +} + +int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + int r; + sigset_t sigsaved; + + vcpu_load(vcpu); + + if (unlikely(vcpu->arch.mp_state == VCPU_MP_STATE_UNINITIALIZED)) { + kvm_vcpu_block(vcpu); + vcpu_put(vcpu); + return -EAGAIN; + } + + if (vcpu->sigset_active) + sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved); + + /* re-sync apic's tpr */ + if (!irqchip_in_kernel(vcpu->kvm)) + kvm_set_cr8(vcpu, kvm_run->cr8); + + if (vcpu->arch.pio.cur_count) { + r = complete_pio(vcpu); + if (r) + goto out; + } +#if CONFIG_HAS_IOMEM + if (vcpu->mmio_needed) { + memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8); + vcpu->mmio_read_completed = 1; + vcpu->mmio_needed = 0; + r = emulate_instruction(vcpu, kvm_run, + vcpu->arch.mmio_fault_cr2, 0, + EMULTYPE_NO_DECODE); + if (r == EMULATE_DO_MMIO) { + /* + * Read-modify-write. Back to userspace. + */ + r = 0; + goto out; + } + } +#endif + if (kvm_run->exit_reason == KVM_EXIT_HYPERCALL) { + kvm_x86_ops->cache_regs(vcpu); + vcpu->arch.regs[VCPU_REGS_RAX] = kvm_run->hypercall.ret; + kvm_x86_ops->decache_regs(vcpu); + } + + r = __vcpu_run(vcpu, kvm_run); + +out: + if (vcpu->sigset_active) + sigprocmask(SIG_SETMASK, &sigsaved, NULL); + + vcpu_put(vcpu); + return r; +} + +int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) +{ + vcpu_load(vcpu); + + kvm_x86_ops->cache_regs(vcpu); + + regs->rax = vcpu->arch.regs[VCPU_REGS_RAX]; + regs->rbx = vcpu->arch.regs[VCPU_REGS_RBX]; + regs->rcx = vcpu->arch.regs[VCPU_REGS_RCX]; + regs->rdx = vcpu->arch.regs[VCPU_REGS_RDX]; + regs->rsi = vcpu->arch.regs[VCPU_REGS_RSI]; + regs->rdi = vcpu->arch.regs[VCPU_REGS_RDI]; + regs->rsp = vcpu->arch.regs[VCPU_REGS_RSP]; + regs->rbp = vcpu->arch.regs[VCPU_REGS_RBP]; +#ifdef CONFIG_X86_64 + regs->r8 = vcpu->arch.regs[VCPU_REGS_R8]; + regs->r9 = vcpu->arch.regs[VCPU_REGS_R9]; + regs->r10 = vcpu->arch.regs[VCPU_REGS_R10]; + regs->r11 = vcpu->arch.regs[VCPU_REGS_R11]; + regs->r12 = vcpu->arch.regs[VCPU_REGS_R12]; + regs->r13 = vcpu->arch.regs[VCPU_REGS_R13]; + regs->r14 = vcpu->arch.regs[VCPU_REGS_R14]; + regs->r15 = vcpu->arch.regs[VCPU_REGS_R15]; +#endif + + regs->rip = vcpu->arch.rip; + regs->rflags = kvm_x86_ops->get_rflags(vcpu); + + /* + * Don't leak debug flags in case they were set for guest debugging + */ + if (vcpu->guest_debug.enabled && vcpu->guest_debug.singlestep) + regs->rflags &= ~(X86_EFLAGS_TF | X86_EFLAGS_RF); + + vcpu_put(vcpu); + + return 0; +} + +int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) +{ + vcpu_load(vcpu); + + vcpu->arch.regs[VCPU_REGS_RAX] = regs->rax; + vcpu->arch.regs[VCPU_REGS_RBX] = regs->rbx; + vcpu->arch.regs[VCPU_REGS_RCX] = regs->rcx; + vcpu->arch.regs[VCPU_REGS_RDX] = regs->rdx; + vcpu->arch.regs[VCPU_REGS_RSI] = regs->rsi; + vcpu->arch.regs[VCPU_REGS_RDI] = regs->rdi; + vcpu->arch.regs[VCPU_REGS_RSP] = regs->rsp; + vcpu->arch.regs[VCPU_REGS_RBP] = regs->rbp; +#ifdef CONFIG_X86_64 + vcpu->arch.regs[VCPU_REGS_R8] = regs->r8; + vcpu->arch.regs[VCPU_REGS_R9] = regs->r9; + vcpu->arch.regs[VCPU_REGS_R10] = regs->r10; + vcpu->arch.regs[VCPU_REGS_R11] = regs->r11; + vcpu->arch.regs[VCPU_REGS_R12] = regs->r12; + vcpu->arch.regs[VCPU_REGS_R13] = regs->r13; + vcpu->arch.regs[VCPU_REGS_R14] = regs->r14; + vcpu->arch.regs[VCPU_REGS_R15] = regs->r15; +#endif + + vcpu->arch.rip = regs->rip; + kvm_x86_ops->set_rflags(vcpu, regs->rflags); + + kvm_x86_ops->decache_regs(vcpu); + + vcpu_put(vcpu); + + return 0; +} + +static void get_segment(struct kvm_vcpu *vcpu, + struct kvm_segment *var, int seg) +{ + kvm_x86_ops->get_segment(vcpu, var, seg); +} + +void kvm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l) +{ + struct kvm_segment cs; + + get_segment(vcpu, &cs, VCPU_SREG_CS); + *db = cs.db; + *l = cs.l; +} +EXPORT_SYMBOL_GPL(kvm_get_cs_db_l_bits); + +int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, + struct kvm_sregs *sregs) +{ + struct descriptor_table dt; + int pending_vec; + + vcpu_load(vcpu); + + get_segment(vcpu, &sregs->cs, VCPU_SREG_CS); + get_segment(vcpu, &sregs->ds, VCPU_SREG_DS); + get_segment(vcpu, &sregs->es, VCPU_SREG_ES); + get_segment(vcpu, &sregs->fs, VCPU_SREG_FS); + get_segment(vcpu, &sregs->gs, VCPU_SREG_GS); + get_segment(vcpu, &sregs->ss, VCPU_SREG_SS); + + get_segment(vcpu, &sregs->tr, VCPU_SREG_TR); + get_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR); + + kvm_x86_ops->get_idt(vcpu, &dt); + sregs->idt.limit = dt.limit; + sregs->idt.base = dt.base; + kvm_x86_ops->get_gdt(vcpu, &dt); + sregs->gdt.limit = dt.limit; + sregs->gdt.base = dt.base; + + kvm_x86_ops->decache_cr4_guest_bits(vcpu); + sregs->cr0 = vcpu->arch.cr0; + sregs->cr2 = vcpu->arch.cr2; + sregs->cr3 = vcpu->arch.cr3; + sregs->cr4 = vcpu->arch.cr4; + sregs->cr8 = kvm_get_cr8(vcpu); + sregs->efer = vcpu->arch.shadow_efer; + sregs->apic_base = kvm_get_apic_base(vcpu); + + if (irqchip_in_kernel(vcpu->kvm)) { + memset(sregs->interrupt_bitmap, 0, + sizeof sregs->interrupt_bitmap); + pending_vec = kvm_x86_ops->get_irq(vcpu); + if (pending_vec >= 0) + set_bit(pending_vec, + (unsigned long *)sregs->interrupt_bitmap); + } else + memcpy(sregs->interrupt_bitmap, vcpu->arch.irq_pending, + sizeof sregs->interrupt_bitmap); + + vcpu_put(vcpu); + + return 0; +} + +static void set_segment(struct kvm_vcpu *vcpu, + struct kvm_segment *var, int seg) +{ + kvm_x86_ops->set_segment(vcpu, var, seg); +} + +int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, + struct kvm_sregs *sregs) +{ + int mmu_reset_needed = 0; + int i, pending_vec, max_bits; + struct descriptor_table dt; + + vcpu_load(vcpu); + + dt.limit = sregs->idt.limit; + dt.base = sregs->idt.base; + kvm_x86_ops->set_idt(vcpu, &dt); + dt.limit = sregs->gdt.limit; + dt.base = sregs->gdt.base; + kvm_x86_ops->set_gdt(vcpu, &dt); + + vcpu->arch.cr2 = sregs->cr2; + mmu_reset_needed |= vcpu->arch.cr3 != sregs->cr3; + vcpu->arch.cr3 = sregs->cr3; + + kvm_set_cr8(vcpu, sregs->cr8); + + mmu_reset_needed |= vcpu->arch.shadow_efer != sregs->efer; + kvm_x86_ops->set_efer(vcpu, sregs->efer); + kvm_set_apic_base(vcpu, sregs->apic_base); + + kvm_x86_ops->decache_cr4_guest_bits(vcpu); + + mmu_reset_needed |= vcpu->arch.cr0 != sregs->cr0; + kvm_x86_ops->set_cr0(vcpu, sregs->cr0); + vcpu->arch.cr0 = sregs->cr0; + + mmu_reset_needed |= vcpu->arch.cr4 != sregs->cr4; + kvm_x86_ops->set_cr4(vcpu, sregs->cr4); + if (!is_long_mode(vcpu) && is_pae(vcpu)) + load_pdptrs(vcpu, vcpu->arch.cr3); + + if (mmu_reset_needed) + kvm_mmu_reset_context(vcpu); + + if (!irqchip_in_kernel(vcpu->kvm)) { + memcpy(vcpu->arch.irq_pending, sregs->interrupt_bitmap, + sizeof vcpu->arch.irq_pending); + vcpu->arch.irq_summary = 0; + for (i = 0; i < ARRAY_SIZE(vcpu->arch.irq_pending); ++i) + if (vcpu->arch.irq_pending[i]) + __set_bit(i, &vcpu->arch.irq_summary); + } else { + max_bits = (sizeof sregs->interrupt_bitmap) << 3; + pending_vec = find_first_bit( + (const unsigned long *)sregs->interrupt_bitmap, + max_bits); + /* Only pending external irq is handled here */ + if (pending_vec < max_bits) { + kvm_x86_ops->set_irq(vcpu, pending_vec); + pr_debug("Set back pending irq %d\n", + pending_vec); + } + } + + set_segment(vcpu, &sregs->cs, VCPU_SREG_CS); + set_segment(vcpu, &sregs->ds, VCPU_SREG_DS); + set_segment(vcpu, &sregs->es, VCPU_SREG_ES); + set_segment(vcpu, &sregs->fs, VCPU_SREG_FS); + set_segment(vcpu, &sregs->gs, VCPU_SREG_GS); + set_segment(vcpu, &sregs->ss, VCPU_SREG_SS); + + set_segment(vcpu, &sregs->tr, VCPU_SREG_TR); + set_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR); + + vcpu_put(vcpu); + + return 0; +} + +int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu, + struct kvm_debug_guest *dbg) +{ + int r; + + vcpu_load(vcpu); + + r = kvm_x86_ops->set_guest_debug(vcpu, dbg); + + vcpu_put(vcpu); + + return r; +} + +/* + * fxsave fpu state. Taken from x86_64/processor.h. To be killed when + * we have asm/x86/processor.h + */ +struct fxsave { + u16 cwd; + u16 swd; + u16 twd; + u16 fop; + u64 rip; + u64 rdp; + u32 mxcsr; + u32 mxcsr_mask; + u32 st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ +#ifdef CONFIG_X86_64 + u32 xmm_space[64]; /* 16*16 bytes for each XMM-reg = 256 bytes */ +#else + u32 xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */ +#endif +}; + +/* + * Translate a guest virtual address to a guest physical address. + */ +int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, + struct kvm_translation *tr) +{ + unsigned long vaddr = tr->linear_address; + gpa_t gpa; + + vcpu_load(vcpu); + down_read(&vcpu->kvm->slots_lock); + gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, vaddr); + up_read(&vcpu->kvm->slots_lock); + tr->physical_address = gpa; + tr->valid = gpa != UNMAPPED_GVA; + tr->writeable = 1; + tr->usermode = 0; + vcpu_put(vcpu); + + return 0; +} + +int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) +{ + struct fxsave *fxsave = (struct fxsave *)&vcpu->arch.guest_fx_image; + + vcpu_load(vcpu); + + memcpy(fpu->fpr, fxsave->st_space, 128); + fpu->fcw = fxsave->cwd; + fpu->fsw = fxsave->swd; + fpu->ftwx = fxsave->twd; + fpu->last_opcode = fxsave->fop; + fpu->last_ip = fxsave->rip; + fpu->last_dp = fxsave->rdp; + memcpy(fpu->xmm, fxsave->xmm_space, sizeof fxsave->xmm_space); + + vcpu_put(vcpu); + + return 0; +} + +int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) +{ + struct fxsave *fxsave = (struct fxsave *)&vcpu->arch.guest_fx_image; + + vcpu_load(vcpu); + + memcpy(fxsave->st_space, fpu->fpr, 128); + fxsave->cwd = fpu->fcw; + fxsave->swd = fpu->fsw; + fxsave->twd = fpu->ftwx; + fxsave->fop = fpu->last_opcode; + fxsave->rip = fpu->last_ip; + fxsave->rdp = fpu->last_dp; + memcpy(fxsave->xmm_space, fpu->xmm, sizeof fxsave->xmm_space); + + vcpu_put(vcpu); + + return 0; +} + +void fx_init(struct kvm_vcpu *vcpu) +{ + unsigned after_mxcsr_mask; + + /* Initialize guest FPU by resetting ours and saving into guest's */ + preempt_disable(); + fx_save(&vcpu->arch.host_fx_image); + fpu_init(); + fx_save(&vcpu->arch.guest_fx_image); + fx_restore(&vcpu->arch.host_fx_image); + preempt_enable(); + + vcpu->arch.cr0 |= X86_CR0_ET; + after_mxcsr_mask = offsetof(struct i387_fxsave_struct, st_space); + vcpu->arch.guest_fx_image.mxcsr = 0x1f80; + memset((void *)&vcpu->arch.guest_fx_image + after_mxcsr_mask, + 0, sizeof(struct i387_fxsave_struct) - after_mxcsr_mask); +} +EXPORT_SYMBOL_GPL(fx_init); + +void kvm_load_guest_fpu(struct kvm_vcpu *vcpu) +{ + if (!vcpu->fpu_active || vcpu->guest_fpu_loaded) + return; + + vcpu->guest_fpu_loaded = 1; + fx_save(&vcpu->arch.host_fx_image); + fx_restore(&vcpu->arch.guest_fx_image); +} +EXPORT_SYMBOL_GPL(kvm_load_guest_fpu); + +void kvm_put_guest_fpu(struct kvm_vcpu *vcpu) +{ + if (!vcpu->guest_fpu_loaded) + return; + + vcpu->guest_fpu_loaded = 0; + fx_save(&vcpu->arch.guest_fx_image); + fx_restore(&vcpu->arch.host_fx_image); + ++vcpu->stat.fpu_reload; +} +EXPORT_SYMBOL_GPL(kvm_put_guest_fpu); + +void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu) +{ + kvm_x86_ops->vcpu_free(vcpu); +} + +struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, + unsigned int id) +{ + return kvm_x86_ops->vcpu_create(kvm, id); +} + +int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) +{ + int r; + + /* We do fxsave: this must be aligned. */ + BUG_ON((unsigned long)&vcpu->arch.host_fx_image & 0xF); + + vcpu_load(vcpu); + r = kvm_arch_vcpu_reset(vcpu); + if (r == 0) + r = kvm_mmu_setup(vcpu); + vcpu_put(vcpu); + if (r < 0) + goto free_vcpu; + + return 0; +free_vcpu: + kvm_x86_ops->vcpu_free(vcpu); + return r; +} + +void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) +{ + vcpu_load(vcpu); + kvm_mmu_unload(vcpu); + vcpu_put(vcpu); + + kvm_x86_ops->vcpu_free(vcpu); +} + +int kvm_arch_vcpu_reset(struct kvm_vcpu *vcpu) +{ + return kvm_x86_ops->vcpu_reset(vcpu); +} + +void kvm_arch_hardware_enable(void *garbage) +{ + kvm_x86_ops->hardware_enable(garbage); +} + +void kvm_arch_hardware_disable(void *garbage) +{ + kvm_x86_ops->hardware_disable(garbage); +} + +int kvm_arch_hardware_setup(void) +{ + return kvm_x86_ops->hardware_setup(); +} + +void kvm_arch_hardware_unsetup(void) +{ + kvm_x86_ops->hardware_unsetup(); +} + +void kvm_arch_check_processor_compat(void *rtn) +{ + kvm_x86_ops->check_processor_compatibility(rtn); +} + +int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) +{ + struct page *page; + struct kvm *kvm; + int r; + + BUG_ON(vcpu->kvm == NULL); + kvm = vcpu->kvm; + + vcpu->arch.mmu.root_hpa = INVALID_PAGE; + if (!irqchip_in_kernel(kvm) || vcpu->vcpu_id == 0) + vcpu->arch.mp_state = VCPU_MP_STATE_RUNNABLE; + else + vcpu->arch.mp_state = VCPU_MP_STATE_UNINITIALIZED; + + page = alloc_page(GFP_KERNEL | __GFP_ZERO); + if (!page) { + r = -ENOMEM; + goto fail; + } + vcpu->arch.pio_data = page_address(page); + + r = kvm_mmu_create(vcpu); + if (r < 0) + goto fail_free_pio_data; + + if (irqchip_in_kernel(kvm)) { + r = kvm_create_lapic(vcpu); + if (r < 0) + goto fail_mmu_destroy; + } + + return 0; + +fail_mmu_destroy: + kvm_mmu_destroy(vcpu); +fail_free_pio_data: + free_page((unsigned long)vcpu->arch.pio_data); +fail: + return r; +} + +void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) +{ + kvm_free_lapic(vcpu); + kvm_mmu_destroy(vcpu); + free_page((unsigned long)vcpu->arch.pio_data); +} + +struct kvm *kvm_arch_create_vm(void) +{ + struct kvm *kvm = kzalloc(sizeof(struct kvm), GFP_KERNEL); + + if (!kvm) + return ERR_PTR(-ENOMEM); + + INIT_LIST_HEAD(&kvm->arch.active_mmu_pages); + + return kvm; +} + +static void kvm_unload_vcpu_mmu(struct kvm_vcpu *vcpu) +{ + vcpu_load(vcpu); + kvm_mmu_unload(vcpu); + vcpu_put(vcpu); +} + +static void kvm_free_vcpus(struct kvm *kvm) +{ + unsigned int i; + + /* + * Unpin any mmu pages first. + */ + for (i = 0; i < KVM_MAX_VCPUS; ++i) + if (kvm->vcpus[i]) + kvm_unload_vcpu_mmu(kvm->vcpus[i]); + for (i = 0; i < KVM_MAX_VCPUS; ++i) { + if (kvm->vcpus[i]) { + kvm_arch_vcpu_free(kvm->vcpus[i]); + kvm->vcpus[i] = NULL; + } + } + +} + +void kvm_arch_destroy_vm(struct kvm *kvm) +{ + kfree(kvm->arch.vpic); + kfree(kvm->arch.vioapic); + kvm_free_vcpus(kvm); + kvm_free_physmem(kvm); + kfree(kvm); +} + +int kvm_arch_set_memory_region(struct kvm *kvm, + struct kvm_userspace_memory_region *mem, + struct kvm_memory_slot old, + int user_alloc) +{ + int npages = mem->memory_size >> PAGE_SHIFT; + struct kvm_memory_slot *memslot = &kvm->memslots[mem->slot]; + + /*To keep backward compatibility with older userspace, + *x86 needs to hanlde !user_alloc case. + */ + if (!user_alloc) { + if (npages && !old.rmap) { + down_write(¤t->mm->mmap_sem); + memslot->userspace_addr = do_mmap(NULL, 0, + npages * PAGE_SIZE, + PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, + 0); + up_write(¤t->mm->mmap_sem); + + if (IS_ERR((void *)memslot->userspace_addr)) + return PTR_ERR((void *)memslot->userspace_addr); + } else { + if (!old.user_alloc && old.rmap) { + int ret; + + down_write(¤t->mm->mmap_sem); + ret = do_munmap(current->mm, old.userspace_addr, + old.npages * PAGE_SIZE); + up_write(¤t->mm->mmap_sem); + if (ret < 0) + printk(KERN_WARNING + "kvm_vm_ioctl_set_memory_region: " + "failed to munmap memory\n"); + } + } + } + + if (!kvm->arch.n_requested_mmu_pages) { + unsigned int nr_mmu_pages = kvm_mmu_calculate_mmu_pages(kvm); + kvm_mmu_change_mmu_pages(kvm, nr_mmu_pages); + } + + kvm_mmu_slot_remove_write_access(kvm, mem->slot); + kvm_flush_remote_tlbs(kvm); + + return 0; +} + +int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.mp_state == VCPU_MP_STATE_RUNNABLE + || vcpu->arch.mp_state == VCPU_MP_STATE_SIPI_RECEIVED; +} + +static void vcpu_kick_intr(void *info) +{ +#ifdef DEBUG + struct kvm_vcpu *vcpu = (struct kvm_vcpu *)info; + printk(KERN_DEBUG "vcpu_kick_intr %p \n", vcpu); +#endif +} + +void kvm_vcpu_kick(struct kvm_vcpu *vcpu) +{ + int ipi_pcpu = vcpu->cpu; + + if (waitqueue_active(&vcpu->wq)) { + wake_up_interruptible(&vcpu->wq); + ++vcpu->stat.halt_wakeup; + } + if (vcpu->guest_mode) + smp_call_function_single(ipi_pcpu, vcpu_kick_intr, vcpu, 0, 0); +} --- linux-2.6.24.orig/arch/x86/kvm/segment_descriptor.h +++ linux-2.6.24/arch/x86/kvm/segment_descriptor.h @@ -0,0 +1,29 @@ +#ifndef __SEGMENT_DESCRIPTOR_H +#define __SEGMENT_DESCRIPTOR_H + +struct segment_descriptor { + u16 limit_low; + u16 base_low; + u8 base_mid; + u8 type : 4; + u8 system : 1; + u8 dpl : 2; + u8 present : 1; + u8 limit_high : 4; + u8 avl : 1; + u8 long_mode : 1; + u8 default_op : 1; + u8 granularity : 1; + u8 base_high; +} __attribute__((packed)); + +#ifdef CONFIG_X86_64 +/* LDT or TSS descriptor in the GDT. 16 bytes. */ +struct segment_descriptor_64 { + struct segment_descriptor s; + u32 base_higher; + u32 pad_zero; +}; + +#endif +#endif --- linux-2.6.24.orig/arch/x86/kvm/x86_emulate.c +++ linux-2.6.24/arch/x86/kvm/x86_emulate.c @@ -0,0 +1,1942 @@ +/****************************************************************************** + * x86_emulate.c + * + * Generic x86 (32-bit and 64-bit) instruction decoder and emulator. + * + * Copyright (c) 2005 Keir Fraser + * + * Linux coding style, mod r/m decoder, segment base fixes, real-mode + * privileged instructions: + * + * Copyright (C) 2006 Qumranet + * + * Avi Kivity + * Yaniv Kamay + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + * From: xen-unstable 10676:af9809f51f81a3c43f276f00c81a52ef558afda4 + */ + +#ifndef __KERNEL__ +#include +#include +#include +#define DPRINTF(_f, _a ...) printf(_f , ## _a) +#else +#include +#define DPRINTF(x...) do {} while (0) +#endif +#include +#include + +/* + * Opcode effective-address decode tables. + * Note that we only emulate instructions that have at least one memory + * operand (excluding implicit stack references). We assume that stack + * references and instruction fetches will never occur in special memory + * areas that require emulation. So, for example, 'mov ,' need + * not be handled. + */ + +/* Operand sizes: 8-bit operands or specified/overridden size. */ +#define ByteOp (1<<0) /* 8-bit operands. */ +/* Destination operand type. */ +#define ImplicitOps (1<<1) /* Implicit in opcode. No generic decode. */ +#define DstReg (2<<1) /* Register operand. */ +#define DstMem (3<<1) /* Memory operand. */ +#define DstMask (3<<1) +/* Source operand type. */ +#define SrcNone (0<<3) /* No source operand. */ +#define SrcImplicit (0<<3) /* Source operand is implicit in the opcode. */ +#define SrcReg (1<<3) /* Register operand. */ +#define SrcMem (2<<3) /* Memory operand. */ +#define SrcMem16 (3<<3) /* Memory operand (16-bit). */ +#define SrcMem32 (4<<3) /* Memory operand (32-bit). */ +#define SrcImm (5<<3) /* Immediate operand. */ +#define SrcImmByte (6<<3) /* 8-bit sign-extended immediate operand. */ +#define SrcMask (7<<3) +/* Generic ModRM decode. */ +#define ModRM (1<<6) +/* Destination is only written; never read. */ +#define Mov (1<<7) +#define BitOp (1<<8) +#define MemAbs (1<<9) /* Memory operand is absolute displacement */ +#define String (1<<10) /* String instruction (rep capable) */ +#define Stack (1<<11) /* Stack instruction (push/pop) */ +#define Group (1<<14) /* Bits 3:5 of modrm byte extend opcode */ +#define GroupDual (1<<15) /* Alternate decoding of mod == 3 */ +#define GroupMask 0xff /* Group number stored in bits 0:7 */ + +enum { + Group1_80, Group1_81, Group1_82, Group1_83, + Group1A, Group3_Byte, Group3, Group4, Group5, Group7, +}; + +static u16 opcode_table[256] = { + /* 0x00 - 0x07 */ + ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, + ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, + 0, 0, 0, 0, + /* 0x08 - 0x0F */ + ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, + ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, + 0, 0, 0, 0, + /* 0x10 - 0x17 */ + ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, + ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, + 0, 0, 0, 0, + /* 0x18 - 0x1F */ + ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, + ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, + 0, 0, 0, 0, + /* 0x20 - 0x27 */ + ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, + ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, + SrcImmByte, SrcImm, 0, 0, + /* 0x28 - 0x2F */ + ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, + ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, + 0, 0, 0, 0, + /* 0x30 - 0x37 */ + ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, + ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, + 0, 0, 0, 0, + /* 0x38 - 0x3F */ + ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, + ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, + 0, 0, 0, 0, + /* 0x40 - 0x47 */ + DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, + /* 0x48 - 0x4F */ + DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, + /* 0x50 - 0x57 */ + SrcReg | Stack, SrcReg | Stack, SrcReg | Stack, SrcReg | Stack, + SrcReg | Stack, SrcReg | Stack, SrcReg | Stack, SrcReg | Stack, + /* 0x58 - 0x5F */ + DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack, + DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack, + /* 0x60 - 0x67 */ + 0, 0, 0, DstReg | SrcMem32 | ModRM | Mov /* movsxd (x86/64) */ , + 0, 0, 0, 0, + /* 0x68 - 0x6F */ + 0, 0, ImplicitOps | Mov | Stack, 0, + SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, /* insb, insw/insd */ + SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, /* outsb, outsw/outsd */ + /* 0x70 - 0x77 */ + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, + /* 0x78 - 0x7F */ + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, + /* 0x80 - 0x87 */ + Group | Group1_80, Group | Group1_81, + Group | Group1_82, Group | Group1_83, + ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, + ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, + /* 0x88 - 0x8F */ + ByteOp | DstMem | SrcReg | ModRM | Mov, DstMem | SrcReg | ModRM | Mov, + ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, + 0, ModRM | DstReg, 0, Group | Group1A, + /* 0x90 - 0x9F */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, ImplicitOps | Stack, ImplicitOps | Stack, 0, 0, + /* 0xA0 - 0xA7 */ + ByteOp | DstReg | SrcMem | Mov | MemAbs, DstReg | SrcMem | Mov | MemAbs, + ByteOp | DstMem | SrcReg | Mov | MemAbs, DstMem | SrcReg | Mov | MemAbs, + ByteOp | ImplicitOps | Mov | String, ImplicitOps | Mov | String, + ByteOp | ImplicitOps | String, ImplicitOps | String, + /* 0xA8 - 0xAF */ + 0, 0, ByteOp | ImplicitOps | Mov | String, ImplicitOps | Mov | String, + ByteOp | ImplicitOps | Mov | String, ImplicitOps | Mov | String, + ByteOp | ImplicitOps | String, ImplicitOps | String, + /* 0xB0 - 0xBF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0xC0 - 0xC7 */ + ByteOp | DstMem | SrcImm | ModRM, DstMem | SrcImmByte | ModRM, + 0, ImplicitOps | Stack, 0, 0, + ByteOp | DstMem | SrcImm | ModRM | Mov, DstMem | SrcImm | ModRM | Mov, + /* 0xC8 - 0xCF */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 0xD0 - 0xD7 */ + ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM, + ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM, + 0, 0, 0, 0, + /* 0xD8 - 0xDF */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 0xE0 - 0xE7 */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* 0xE8 - 0xEF */ + ImplicitOps | Stack, SrcImm|ImplicitOps, 0, SrcImmByte|ImplicitOps, + 0, 0, 0, 0, + /* 0xF0 - 0xF7 */ + 0, 0, 0, 0, + ImplicitOps, ImplicitOps, Group | Group3_Byte, Group | Group3, + /* 0xF8 - 0xFF */ + ImplicitOps, 0, ImplicitOps, ImplicitOps, + 0, 0, Group | Group4, Group | Group5, +}; + +static u16 twobyte_table[256] = { + /* 0x00 - 0x0F */ + 0, Group | GroupDual | Group7, 0, 0, 0, 0, ImplicitOps, 0, + ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0, + /* 0x10 - 0x1F */ + 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0, + /* 0x20 - 0x2F */ + ModRM | ImplicitOps, ModRM, ModRM | ImplicitOps, ModRM, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x30 - 0x3F */ + ImplicitOps, 0, ImplicitOps, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x40 - 0x47 */ + DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, + DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, + DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, + DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, + /* 0x48 - 0x4F */ + DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, + DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, + DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, + DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, + /* 0x50 - 0x5F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x60 - 0x6F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x70 - 0x7F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x80 - 0x8F */ + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, + /* 0x90 - 0x9F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0xA0 - 0xA7 */ + 0, 0, 0, DstMem | SrcReg | ModRM | BitOp, 0, 0, 0, 0, + /* 0xA8 - 0xAF */ + 0, 0, 0, DstMem | SrcReg | ModRM | BitOp, 0, 0, 0, 0, + /* 0xB0 - 0xB7 */ + ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 0, + DstMem | SrcReg | ModRM | BitOp, + 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov, + DstReg | SrcMem16 | ModRM | Mov, + /* 0xB8 - 0xBF */ + 0, 0, DstMem | SrcImmByte | ModRM, DstMem | SrcReg | ModRM | BitOp, + 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov, + DstReg | SrcMem16 | ModRM | Mov, + /* 0xC0 - 0xCF */ + 0, 0, 0, DstMem | SrcReg | ModRM | Mov, 0, 0, 0, ImplicitOps | ModRM, + 0, 0, 0, 0, 0, 0, 0, 0, + /* 0xD0 - 0xDF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0xE0 - 0xEF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0xF0 - 0xFF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static u16 group_table[] = { + [Group1_80*8] = + ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, + ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, + ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, + ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, + [Group1_81*8] = + DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM, + DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM, + DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM, + DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM, + [Group1_82*8] = + ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, + ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, + ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, + ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, + [Group1_83*8] = + DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM, + DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM, + DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM, + DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM, + [Group1A*8] = + DstMem | SrcNone | ModRM | Mov | Stack, 0, 0, 0, 0, 0, 0, 0, + [Group3_Byte*8] = + ByteOp | SrcImm | DstMem | ModRM, 0, + ByteOp | DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM, + 0, 0, 0, 0, + [Group3*8] = + DstMem | SrcImm | ModRM | SrcImm, 0, + DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM, + 0, 0, 0, 0, + [Group4*8] = + ByteOp | DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM, + 0, 0, 0, 0, 0, 0, + [Group5*8] = + DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM, 0, 0, + SrcMem | ModRM, 0, SrcMem | ModRM | Stack, 0, + [Group7*8] = + 0, 0, ModRM | SrcMem, ModRM | SrcMem, + SrcNone | ModRM | DstMem, 0, SrcMem | ModRM, SrcMem | ModRM | ByteOp, +}; + +static u16 group2_table[] = { + [Group7*8] = + SrcNone | ModRM, 0, 0, 0, SrcNone | ModRM | DstMem, 0, SrcMem | ModRM, 0, +}; + +/* EFLAGS bit definitions. */ +#define EFLG_OF (1<<11) +#define EFLG_DF (1<<10) +#define EFLG_SF (1<<7) +#define EFLG_ZF (1<<6) +#define EFLG_AF (1<<4) +#define EFLG_PF (1<<2) +#define EFLG_CF (1<<0) + +/* + * Instruction emulation: + * Most instructions are emulated directly via a fragment of inline assembly + * code. This allows us to save/restore EFLAGS and thus very easily pick up + * any modified flags. + */ + +#if defined(CONFIG_X86_64) +#define _LO32 "k" /* force 32-bit operand */ +#define _STK "%%rsp" /* stack pointer */ +#elif defined(__i386__) +#define _LO32 "" /* force 32-bit operand */ +#define _STK "%%esp" /* stack pointer */ +#endif + +/* + * These EFLAGS bits are restored from saved value during emulation, and + * any changes are written back to the saved value after emulation. + */ +#define EFLAGS_MASK (EFLG_OF|EFLG_SF|EFLG_ZF|EFLG_AF|EFLG_PF|EFLG_CF) + +/* Before executing instruction: restore necessary bits in EFLAGS. */ +#define _PRE_EFLAGS(_sav, _msk, _tmp) \ + /* EFLAGS = (_sav & _msk) | (EFLAGS & ~_msk); _sav &= ~_msk; */ \ + "movl %"_sav",%"_LO32 _tmp"; " \ + "push %"_tmp"; " \ + "push %"_tmp"; " \ + "movl %"_msk",%"_LO32 _tmp"; " \ + "andl %"_LO32 _tmp",("_STK"); " \ + "pushf; " \ + "notl %"_LO32 _tmp"; " \ + "andl %"_LO32 _tmp",("_STK"); " \ + "andl %"_LO32 _tmp","__stringify(BITS_PER_LONG/4)"("_STK"); " \ + "pop %"_tmp"; " \ + "orl %"_LO32 _tmp",("_STK"); " \ + "popf; " \ + "pop %"_sav"; " + +/* After executing instruction: write-back necessary bits in EFLAGS. */ +#define _POST_EFLAGS(_sav, _msk, _tmp) \ + /* _sav |= EFLAGS & _msk; */ \ + "pushf; " \ + "pop %"_tmp"; " \ + "andl %"_msk",%"_LO32 _tmp"; " \ + "orl %"_LO32 _tmp",%"_sav"; " + +/* Raw emulation: instruction has two explicit operands. */ +#define __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy) \ + do { \ + unsigned long _tmp; \ + \ + switch ((_dst).bytes) { \ + case 2: \ + __asm__ __volatile__ ( \ + _PRE_EFLAGS("0", "4", "2") \ + _op"w %"_wx"3,%1; " \ + _POST_EFLAGS("0", "4", "2") \ + : "=m" (_eflags), "=m" ((_dst).val), \ + "=&r" (_tmp) \ + : _wy ((_src).val), "i" (EFLAGS_MASK)); \ + break; \ + case 4: \ + __asm__ __volatile__ ( \ + _PRE_EFLAGS("0", "4", "2") \ + _op"l %"_lx"3,%1; " \ + _POST_EFLAGS("0", "4", "2") \ + : "=m" (_eflags), "=m" ((_dst).val), \ + "=&r" (_tmp) \ + : _ly ((_src).val), "i" (EFLAGS_MASK)); \ + break; \ + case 8: \ + __emulate_2op_8byte(_op, _src, _dst, \ + _eflags, _qx, _qy); \ + break; \ + } \ + } while (0) + +#define __emulate_2op(_op,_src,_dst,_eflags,_bx,_by,_wx,_wy,_lx,_ly,_qx,_qy) \ + do { \ + unsigned long __tmp; \ + switch ((_dst).bytes) { \ + case 1: \ + __asm__ __volatile__ ( \ + _PRE_EFLAGS("0", "4", "2") \ + _op"b %"_bx"3,%1; " \ + _POST_EFLAGS("0", "4", "2") \ + : "=m" (_eflags), "=m" ((_dst).val), \ + "=&r" (__tmp) \ + : _by ((_src).val), "i" (EFLAGS_MASK)); \ + break; \ + default: \ + __emulate_2op_nobyte(_op, _src, _dst, _eflags, \ + _wx, _wy, _lx, _ly, _qx, _qy); \ + break; \ + } \ + } while (0) + +/* Source operand is byte-sized and may be restricted to just %cl. */ +#define emulate_2op_SrcB(_op, _src, _dst, _eflags) \ + __emulate_2op(_op, _src, _dst, _eflags, \ + "b", "c", "b", "c", "b", "c", "b", "c") + +/* Source operand is byte, word, long or quad sized. */ +#define emulate_2op_SrcV(_op, _src, _dst, _eflags) \ + __emulate_2op(_op, _src, _dst, _eflags, \ + "b", "q", "w", "r", _LO32, "r", "", "r") + +/* Source operand is word, long or quad sized. */ +#define emulate_2op_SrcV_nobyte(_op, _src, _dst, _eflags) \ + __emulate_2op_nobyte(_op, _src, _dst, _eflags, \ + "w", "r", _LO32, "r", "", "r") + +/* Instruction has only one explicit operand (no source operand). */ +#define emulate_1op(_op, _dst, _eflags) \ + do { \ + unsigned long _tmp; \ + \ + switch ((_dst).bytes) { \ + case 1: \ + __asm__ __volatile__ ( \ + _PRE_EFLAGS("0", "3", "2") \ + _op"b %1; " \ + _POST_EFLAGS("0", "3", "2") \ + : "=m" (_eflags), "=m" ((_dst).val), \ + "=&r" (_tmp) \ + : "i" (EFLAGS_MASK)); \ + break; \ + case 2: \ + __asm__ __volatile__ ( \ + _PRE_EFLAGS("0", "3", "2") \ + _op"w %1; " \ + _POST_EFLAGS("0", "3", "2") \ + : "=m" (_eflags), "=m" ((_dst).val), \ + "=&r" (_tmp) \ + : "i" (EFLAGS_MASK)); \ + break; \ + case 4: \ + __asm__ __volatile__ ( \ + _PRE_EFLAGS("0", "3", "2") \ + _op"l %1; " \ + _POST_EFLAGS("0", "3", "2") \ + : "=m" (_eflags), "=m" ((_dst).val), \ + "=&r" (_tmp) \ + : "i" (EFLAGS_MASK)); \ + break; \ + case 8: \ + __emulate_1op_8byte(_op, _dst, _eflags); \ + break; \ + } \ + } while (0) + +/* Emulate an instruction with quadword operands (x86/64 only). */ +#if defined(CONFIG_X86_64) +#define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy) \ + do { \ + __asm__ __volatile__ ( \ + _PRE_EFLAGS("0", "4", "2") \ + _op"q %"_qx"3,%1; " \ + _POST_EFLAGS("0", "4", "2") \ + : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \ + : _qy ((_src).val), "i" (EFLAGS_MASK)); \ + } while (0) + +#define __emulate_1op_8byte(_op, _dst, _eflags) \ + do { \ + __asm__ __volatile__ ( \ + _PRE_EFLAGS("0", "3", "2") \ + _op"q %1; " \ + _POST_EFLAGS("0", "3", "2") \ + : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \ + : "i" (EFLAGS_MASK)); \ + } while (0) + +#elif defined(__i386__) +#define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy) +#define __emulate_1op_8byte(_op, _dst, _eflags) +#endif /* __i386__ */ + +/* Fetch next part of the instruction being emulated. */ +#define insn_fetch(_type, _size, _eip) \ +({ unsigned long _x; \ + rc = do_insn_fetch(ctxt, ops, (_eip), &_x, (_size)); \ + if (rc != 0) \ + goto done; \ + (_eip) += (_size); \ + (_type)_x; \ +}) + +static inline unsigned long ad_mask(struct decode_cache *c) +{ + return (1UL << (c->ad_bytes << 3)) - 1; +} + +/* Access/update address held in a register, based on addressing mode. */ +static inline unsigned long +address_mask(struct decode_cache *c, unsigned long reg) +{ + if (c->ad_bytes == sizeof(unsigned long)) + return reg; + else + return reg & ad_mask(c); +} + +static inline unsigned long +register_address(struct decode_cache *c, unsigned long base, unsigned long reg) +{ + return base + address_mask(c, reg); +} + +static inline void +register_address_increment(struct decode_cache *c, unsigned long *reg, int inc) +{ + if (c->ad_bytes == sizeof(unsigned long)) + *reg += inc; + else + *reg = (*reg & ~ad_mask(c)) | ((*reg + inc) & ad_mask(c)); +} + +static inline void jmp_rel(struct decode_cache *c, int rel) +{ + register_address_increment(c, &c->eip, rel); +} + +static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, + unsigned long linear, u8 *dest) +{ + struct fetch_cache *fc = &ctxt->decode.fetch; + int rc; + int size; + + if (linear < fc->start || linear >= fc->end) { + size = min(15UL, PAGE_SIZE - offset_in_page(linear)); + rc = ops->read_std(linear, fc->data, size, ctxt->vcpu); + if (rc) + return rc; + fc->start = linear; + fc->end = linear + size; + } + *dest = fc->data[linear - fc->start]; + return 0; +} + +static int do_insn_fetch(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, + unsigned long eip, void *dest, unsigned size) +{ + int rc = 0; + + eip += ctxt->cs_base; + while (size--) { + rc = do_fetch_insn_byte(ctxt, ops, eip++, dest++); + if (rc) + return rc; + } + return 0; +} + +/* + * Given the 'reg' portion of a ModRM byte, and a register block, return a + * pointer into the block that addresses the relevant register. + * @highbyte_regs specifies whether to decode AH,CH,DH,BH. + */ +static void *decode_register(u8 modrm_reg, unsigned long *regs, + int highbyte_regs) +{ + void *p; + + p = ®s[modrm_reg]; + if (highbyte_regs && modrm_reg >= 4 && modrm_reg < 8) + p = (unsigned char *)®s[modrm_reg & 3] + 1; + return p; +} + +static int read_descriptor(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, + void *ptr, + u16 *size, unsigned long *address, int op_bytes) +{ + int rc; + + if (op_bytes == 2) + op_bytes = 3; + *address = 0; + rc = ops->read_std((unsigned long)ptr, (unsigned long *)size, 2, + ctxt->vcpu); + if (rc) + return rc; + rc = ops->read_std((unsigned long)ptr + 2, address, op_bytes, + ctxt->vcpu); + return rc; +} + +static int test_cc(unsigned int condition, unsigned int flags) +{ + int rc = 0; + + switch ((condition & 15) >> 1) { + case 0: /* o */ + rc |= (flags & EFLG_OF); + break; + case 1: /* b/c/nae */ + rc |= (flags & EFLG_CF); + break; + case 2: /* z/e */ + rc |= (flags & EFLG_ZF); + break; + case 3: /* be/na */ + rc |= (flags & (EFLG_CF|EFLG_ZF)); + break; + case 4: /* s */ + rc |= (flags & EFLG_SF); + break; + case 5: /* p/pe */ + rc |= (flags & EFLG_PF); + break; + case 7: /* le/ng */ + rc |= (flags & EFLG_ZF); + /* fall through */ + case 6: /* l/nge */ + rc |= (!(flags & EFLG_SF) != !(flags & EFLG_OF)); + break; + } + + /* Odd condition identifiers (lsb == 1) have inverted sense. */ + return (!!rc ^ (condition & 1)); +} + +static void decode_register_operand(struct operand *op, + struct decode_cache *c, + int inhibit_bytereg) +{ + unsigned reg = c->modrm_reg; + int highbyte_regs = c->rex_prefix == 0; + + if (!(c->d & ModRM)) + reg = (c->b & 7) | ((c->rex_prefix & 1) << 3); + op->type = OP_REG; + if ((c->d & ByteOp) && !inhibit_bytereg) { + op->ptr = decode_register(reg, c->regs, highbyte_regs); + op->val = *(u8 *)op->ptr; + op->bytes = 1; + } else { + op->ptr = decode_register(reg, c->regs, 0); + op->bytes = c->op_bytes; + switch (op->bytes) { + case 2: + op->val = *(u16 *)op->ptr; + break; + case 4: + op->val = *(u32 *)op->ptr; + break; + case 8: + op->val = *(u64 *) op->ptr; + break; + } + } + op->orig_val = op->val; +} + +static int decode_modrm(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops) +{ + struct decode_cache *c = &ctxt->decode; + u8 sib; + int index_reg = 0, base_reg = 0, scale, rip_relative = 0; + int rc = 0; + + if (c->rex_prefix) { + c->modrm_reg = (c->rex_prefix & 4) << 1; /* REX.R */ + index_reg = (c->rex_prefix & 2) << 2; /* REX.X */ + c->modrm_rm = base_reg = (c->rex_prefix & 1) << 3; /* REG.B */ + } + + c->modrm = insn_fetch(u8, 1, c->eip); + c->modrm_mod |= (c->modrm & 0xc0) >> 6; + c->modrm_reg |= (c->modrm & 0x38) >> 3; + c->modrm_rm |= (c->modrm & 0x07); + c->modrm_ea = 0; + c->use_modrm_ea = 1; + + if (c->modrm_mod == 3) { + c->modrm_val = *(unsigned long *) + decode_register(c->modrm_rm, c->regs, c->d & ByteOp); + return rc; + } + + if (c->ad_bytes == 2) { + unsigned bx = c->regs[VCPU_REGS_RBX]; + unsigned bp = c->regs[VCPU_REGS_RBP]; + unsigned si = c->regs[VCPU_REGS_RSI]; + unsigned di = c->regs[VCPU_REGS_RDI]; + + /* 16-bit ModR/M decode. */ + switch (c->modrm_mod) { + case 0: + if (c->modrm_rm == 6) + c->modrm_ea += insn_fetch(u16, 2, c->eip); + break; + case 1: + c->modrm_ea += insn_fetch(s8, 1, c->eip); + break; + case 2: + c->modrm_ea += insn_fetch(u16, 2, c->eip); + break; + } + switch (c->modrm_rm) { + case 0: + c->modrm_ea += bx + si; + break; + case 1: + c->modrm_ea += bx + di; + break; + case 2: + c->modrm_ea += bp + si; + break; + case 3: + c->modrm_ea += bp + di; + break; + case 4: + c->modrm_ea += si; + break; + case 5: + c->modrm_ea += di; + break; + case 6: + if (c->modrm_mod != 0) + c->modrm_ea += bp; + break; + case 7: + c->modrm_ea += bx; + break; + } + if (c->modrm_rm == 2 || c->modrm_rm == 3 || + (c->modrm_rm == 6 && c->modrm_mod != 0)) + if (!c->override_base) + c->override_base = &ctxt->ss_base; + c->modrm_ea = (u16)c->modrm_ea; + } else { + /* 32/64-bit ModR/M decode. */ + switch (c->modrm_rm) { + case 4: + case 12: + sib = insn_fetch(u8, 1, c->eip); + index_reg |= (sib >> 3) & 7; + base_reg |= sib & 7; + scale = sib >> 6; + + switch (base_reg) { + case 5: + if (c->modrm_mod != 0) + c->modrm_ea += c->regs[base_reg]; + else + c->modrm_ea += + insn_fetch(s32, 4, c->eip); + break; + default: + c->modrm_ea += c->regs[base_reg]; + } + switch (index_reg) { + case 4: + break; + default: + c->modrm_ea += c->regs[index_reg] << scale; + } + break; + case 5: + if (c->modrm_mod != 0) + c->modrm_ea += c->regs[c->modrm_rm]; + else if (ctxt->mode == X86EMUL_MODE_PROT64) + rip_relative = 1; + break; + default: + c->modrm_ea += c->regs[c->modrm_rm]; + break; + } + switch (c->modrm_mod) { + case 0: + if (c->modrm_rm == 5) + c->modrm_ea += insn_fetch(s32, 4, c->eip); + break; + case 1: + c->modrm_ea += insn_fetch(s8, 1, c->eip); + break; + case 2: + c->modrm_ea += insn_fetch(s32, 4, c->eip); + break; + } + } + if (rip_relative) { + c->modrm_ea += c->eip; + switch (c->d & SrcMask) { + case SrcImmByte: + c->modrm_ea += 1; + break; + case SrcImm: + if (c->d & ByteOp) + c->modrm_ea += 1; + else + if (c->op_bytes == 8) + c->modrm_ea += 4; + else + c->modrm_ea += c->op_bytes; + } + } +done: + return rc; +} + +static int decode_abs(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops) +{ + struct decode_cache *c = &ctxt->decode; + int rc = 0; + + switch (c->ad_bytes) { + case 2: + c->modrm_ea = insn_fetch(u16, 2, c->eip); + break; + case 4: + c->modrm_ea = insn_fetch(u32, 4, c->eip); + break; + case 8: + c->modrm_ea = insn_fetch(u64, 8, c->eip); + break; + } +done: + return rc; +} + +int +x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) +{ + struct decode_cache *c = &ctxt->decode; + int rc = 0; + int mode = ctxt->mode; + int def_op_bytes, def_ad_bytes, group; + + /* Shadow copy of register state. Committed on successful emulation. */ + + memset(c, 0, sizeof(struct decode_cache)); + c->eip = ctxt->vcpu->arch.rip; + memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); + + switch (mode) { + case X86EMUL_MODE_REAL: + case X86EMUL_MODE_PROT16: + def_op_bytes = def_ad_bytes = 2; + break; + case X86EMUL_MODE_PROT32: + def_op_bytes = def_ad_bytes = 4; + break; +#ifdef CONFIG_X86_64 + case X86EMUL_MODE_PROT64: + def_op_bytes = 4; + def_ad_bytes = 8; + break; +#endif + default: + return -1; + } + + c->op_bytes = def_op_bytes; + c->ad_bytes = def_ad_bytes; + + /* Legacy prefixes. */ + for (;;) { + switch (c->b = insn_fetch(u8, 1, c->eip)) { + case 0x66: /* operand-size override */ + /* switch between 2/4 bytes */ + c->op_bytes = def_op_bytes ^ 6; + break; + case 0x67: /* address-size override */ + if (mode == X86EMUL_MODE_PROT64) + /* switch between 4/8 bytes */ + c->ad_bytes = def_ad_bytes ^ 12; + else + /* switch between 2/4 bytes */ + c->ad_bytes = def_ad_bytes ^ 6; + break; + case 0x2e: /* CS override */ + c->override_base = &ctxt->cs_base; + break; + case 0x3e: /* DS override */ + c->override_base = &ctxt->ds_base; + break; + case 0x26: /* ES override */ + c->override_base = &ctxt->es_base; + break; + case 0x64: /* FS override */ + c->override_base = &ctxt->fs_base; + break; + case 0x65: /* GS override */ + c->override_base = &ctxt->gs_base; + break; + case 0x36: /* SS override */ + c->override_base = &ctxt->ss_base; + break; + case 0x40 ... 0x4f: /* REX */ + if (mode != X86EMUL_MODE_PROT64) + goto done_prefixes; + c->rex_prefix = c->b; + continue; + case 0xf0: /* LOCK */ + c->lock_prefix = 1; + break; + case 0xf2: /* REPNE/REPNZ */ + c->rep_prefix = REPNE_PREFIX; + break; + case 0xf3: /* REP/REPE/REPZ */ + c->rep_prefix = REPE_PREFIX; + break; + default: + goto done_prefixes; + } + + /* Any legacy prefix after a REX prefix nullifies its effect. */ + + c->rex_prefix = 0; + } + +done_prefixes: + + /* REX prefix. */ + if (c->rex_prefix) + if (c->rex_prefix & 8) + c->op_bytes = 8; /* REX.W */ + + /* Opcode byte(s). */ + c->d = opcode_table[c->b]; + if (c->d == 0) { + /* Two-byte opcode? */ + if (c->b == 0x0f) { + c->twobyte = 1; + c->b = insn_fetch(u8, 1, c->eip); + c->d = twobyte_table[c->b]; + } + } + + if (c->d & Group) { + group = c->d & GroupMask; + c->modrm = insn_fetch(u8, 1, c->eip); + --c->eip; + + group = (group << 3) + ((c->modrm >> 3) & 7); + if ((c->d & GroupDual) && (c->modrm >> 6) == 3) + c->d = group2_table[group]; + else + c->d = group_table[group]; + } + + /* Unrecognised? */ + if (c->d == 0) { + DPRINTF("Cannot emulate %02x\n", c->b); + return -1; + } + + if (mode == X86EMUL_MODE_PROT64 && (c->d & Stack)) + c->op_bytes = 8; + + /* ModRM and SIB bytes. */ + if (c->d & ModRM) + rc = decode_modrm(ctxt, ops); + else if (c->d & MemAbs) + rc = decode_abs(ctxt, ops); + if (rc) + goto done; + + if (!c->override_base) + c->override_base = &ctxt->ds_base; + if (mode == X86EMUL_MODE_PROT64 && + c->override_base != &ctxt->fs_base && + c->override_base != &ctxt->gs_base) + c->override_base = NULL; + + if (c->override_base) + c->modrm_ea += *c->override_base; + + if (c->ad_bytes != 8) + c->modrm_ea = (u32)c->modrm_ea; + /* + * Decode and fetch the source operand: register, memory + * or immediate. + */ + switch (c->d & SrcMask) { + case SrcNone: + break; + case SrcReg: + decode_register_operand(&c->src, c, 0); + break; + case SrcMem16: + c->src.bytes = 2; + goto srcmem_common; + case SrcMem32: + c->src.bytes = 4; + goto srcmem_common; + case SrcMem: + c->src.bytes = (c->d & ByteOp) ? 1 : + c->op_bytes; + /* Don't fetch the address for invlpg: it could be unmapped. */ + if (c->twobyte && c->b == 0x01 && c->modrm_reg == 7) + break; + srcmem_common: + /* + * For instructions with a ModR/M byte, switch to register + * access if Mod = 3. + */ + if ((c->d & ModRM) && c->modrm_mod == 3) { + c->src.type = OP_REG; + break; + } + c->src.type = OP_MEM; + break; + case SrcImm: + c->src.type = OP_IMM; + c->src.ptr = (unsigned long *)c->eip; + c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; + if (c->src.bytes == 8) + c->src.bytes = 4; + /* NB. Immediates are sign-extended as necessary. */ + switch (c->src.bytes) { + case 1: + c->src.val = insn_fetch(s8, 1, c->eip); + break; + case 2: + c->src.val = insn_fetch(s16, 2, c->eip); + break; + case 4: + c->src.val = insn_fetch(s32, 4, c->eip); + break; + } + break; + case SrcImmByte: + c->src.type = OP_IMM; + c->src.ptr = (unsigned long *)c->eip; + c->src.bytes = 1; + c->src.val = insn_fetch(s8, 1, c->eip); + break; + } + + /* Decode and fetch the destination operand: register or memory. */ + switch (c->d & DstMask) { + case ImplicitOps: + /* Special instructions do their own operand decoding. */ + return 0; + case DstReg: + decode_register_operand(&c->dst, c, + c->twobyte && (c->b == 0xb6 || c->b == 0xb7)); + break; + case DstMem: + if ((c->d & ModRM) && c->modrm_mod == 3) { + c->dst.type = OP_REG; + break; + } + c->dst.type = OP_MEM; + break; + } + +done: + return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; +} + +static inline void emulate_push(struct x86_emulate_ctxt *ctxt) +{ + struct decode_cache *c = &ctxt->decode; + + c->dst.type = OP_MEM; + c->dst.bytes = c->op_bytes; + c->dst.val = c->src.val; + register_address_increment(c, &c->regs[VCPU_REGS_RSP], -c->op_bytes); + c->dst.ptr = (void *) register_address(c, ctxt->ss_base, + c->regs[VCPU_REGS_RSP]); +} + +static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops) +{ + struct decode_cache *c = &ctxt->decode; + int rc; + + rc = ops->read_std(register_address(c, ctxt->ss_base, + c->regs[VCPU_REGS_RSP]), + &c->dst.val, c->dst.bytes, ctxt->vcpu); + if (rc != 0) + return rc; + + register_address_increment(c, &c->regs[VCPU_REGS_RSP], c->dst.bytes); + + return 0; +} + +static inline void emulate_grp2(struct x86_emulate_ctxt *ctxt) +{ + struct decode_cache *c = &ctxt->decode; + switch (c->modrm_reg) { + case 0: /* rol */ + emulate_2op_SrcB("rol", c->src, c->dst, ctxt->eflags); + break; + case 1: /* ror */ + emulate_2op_SrcB("ror", c->src, c->dst, ctxt->eflags); + break; + case 2: /* rcl */ + emulate_2op_SrcB("rcl", c->src, c->dst, ctxt->eflags); + break; + case 3: /* rcr */ + emulate_2op_SrcB("rcr", c->src, c->dst, ctxt->eflags); + break; + case 4: /* sal/shl */ + case 6: /* sal/shl */ + emulate_2op_SrcB("sal", c->src, c->dst, ctxt->eflags); + break; + case 5: /* shr */ + emulate_2op_SrcB("shr", c->src, c->dst, ctxt->eflags); + break; + case 7: /* sar */ + emulate_2op_SrcB("sar", c->src, c->dst, ctxt->eflags); + break; + } +} + +static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops) +{ + struct decode_cache *c = &ctxt->decode; + int rc = 0; + + switch (c->modrm_reg) { + case 0 ... 1: /* test */ + emulate_2op_SrcV("test", c->src, c->dst, ctxt->eflags); + break; + case 2: /* not */ + c->dst.val = ~c->dst.val; + break; + case 3: /* neg */ + emulate_1op("neg", c->dst, ctxt->eflags); + break; + default: + DPRINTF("Cannot emulate %02x\n", c->b); + rc = X86EMUL_UNHANDLEABLE; + break; + } + return rc; +} + +static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops) +{ + struct decode_cache *c = &ctxt->decode; + + switch (c->modrm_reg) { + case 0: /* inc */ + emulate_1op("inc", c->dst, ctxt->eflags); + break; + case 1: /* dec */ + emulate_1op("dec", c->dst, ctxt->eflags); + break; + case 4: /* jmp abs */ + c->eip = c->src.val; + break; + case 6: /* push */ + emulate_push(ctxt); + break; + } + return 0; +} + +static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, + unsigned long memop) +{ + struct decode_cache *c = &ctxt->decode; + u64 old, new; + int rc; + + rc = ops->read_emulated(memop, &old, 8, ctxt->vcpu); + if (rc != 0) + return rc; + + if (((u32) (old >> 0) != (u32) c->regs[VCPU_REGS_RAX]) || + ((u32) (old >> 32) != (u32) c->regs[VCPU_REGS_RDX])) { + + c->regs[VCPU_REGS_RAX] = (u32) (old >> 0); + c->regs[VCPU_REGS_RDX] = (u32) (old >> 32); + ctxt->eflags &= ~EFLG_ZF; + + } else { + new = ((u64)c->regs[VCPU_REGS_RCX] << 32) | + (u32) c->regs[VCPU_REGS_RBX]; + + rc = ops->cmpxchg_emulated(memop, &old, &new, 8, ctxt->vcpu); + if (rc != 0) + return rc; + ctxt->eflags |= EFLG_ZF; + } + return 0; +} + +static inline int writeback(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops) +{ + int rc; + struct decode_cache *c = &ctxt->decode; + + switch (c->dst.type) { + case OP_REG: + /* The 4-byte case *is* correct: + * in 64-bit mode we zero-extend. + */ + switch (c->dst.bytes) { + case 1: + *(u8 *)c->dst.ptr = (u8)c->dst.val; + break; + case 2: + *(u16 *)c->dst.ptr = (u16)c->dst.val; + break; + case 4: + *c->dst.ptr = (u32)c->dst.val; + break; /* 64b: zero-ext */ + case 8: + *c->dst.ptr = c->dst.val; + break; + } + break; + case OP_MEM: + if (c->lock_prefix) + rc = ops->cmpxchg_emulated( + (unsigned long)c->dst.ptr, + &c->dst.orig_val, + &c->dst.val, + c->dst.bytes, + ctxt->vcpu); + else + rc = ops->write_emulated( + (unsigned long)c->dst.ptr, + &c->dst.val, + c->dst.bytes, + ctxt->vcpu); + if (rc != 0) + return rc; + break; + case OP_NONE: + /* no writeback */ + break; + default: + break; + } + return 0; +} + +int +x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) +{ + unsigned long memop = 0; + u64 msr_data; + unsigned long saved_eip = 0; + struct decode_cache *c = &ctxt->decode; + int rc = 0; + + /* Shadow copy of register state. Committed on successful emulation. + * NOTE: we can copy them from vcpu as x86_decode_insn() doesn't + * modify them. + */ + + memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); + saved_eip = c->eip; + + if (((c->d & ModRM) && (c->modrm_mod != 3)) || (c->d & MemAbs)) + memop = c->modrm_ea; + + if (c->rep_prefix && (c->d & String)) { + /* All REP prefixes have the same first termination condition */ + if (c->regs[VCPU_REGS_RCX] == 0) { + ctxt->vcpu->arch.rip = c->eip; + goto done; + } + /* The second termination condition only applies for REPE + * and REPNE. Test if the repeat string operation prefix is + * REPE/REPZ or REPNE/REPNZ and if it's the case it tests the + * corresponding termination condition according to: + * - if REPE/REPZ and ZF = 0 then done + * - if REPNE/REPNZ and ZF = 1 then done + */ + if ((c->b == 0xa6) || (c->b == 0xa7) || + (c->b == 0xae) || (c->b == 0xaf)) { + if ((c->rep_prefix == REPE_PREFIX) && + ((ctxt->eflags & EFLG_ZF) == 0)) { + ctxt->vcpu->arch.rip = c->eip; + goto done; + } + if ((c->rep_prefix == REPNE_PREFIX) && + ((ctxt->eflags & EFLG_ZF) == EFLG_ZF)) { + ctxt->vcpu->arch.rip = c->eip; + goto done; + } + } + c->regs[VCPU_REGS_RCX]--; + c->eip = ctxt->vcpu->arch.rip; + } + + if (c->src.type == OP_MEM) { + c->src.ptr = (unsigned long *)memop; + c->src.val = 0; + rc = ops->read_emulated((unsigned long)c->src.ptr, + &c->src.val, + c->src.bytes, + ctxt->vcpu); + if (rc != 0) + goto done; + c->src.orig_val = c->src.val; + } + + if ((c->d & DstMask) == ImplicitOps) + goto special_insn; + + + if (c->dst.type == OP_MEM) { + c->dst.ptr = (unsigned long *)memop; + c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; + c->dst.val = 0; + if (c->d & BitOp) { + unsigned long mask = ~(c->dst.bytes * 8 - 1); + + c->dst.ptr = (void *)c->dst.ptr + + (c->src.val & mask) / 8; + } + if (!(c->d & Mov) && + /* optimisation - avoid slow emulated read */ + ((rc = ops->read_emulated((unsigned long)c->dst.ptr, + &c->dst.val, + c->dst.bytes, ctxt->vcpu)) != 0)) + goto done; + } + c->dst.orig_val = c->dst.val; + +special_insn: + + if (c->twobyte) + goto twobyte_insn; + + switch (c->b) { + case 0x00 ... 0x05: + add: /* add */ + emulate_2op_SrcV("add", c->src, c->dst, ctxt->eflags); + break; + case 0x08 ... 0x0d: + or: /* or */ + emulate_2op_SrcV("or", c->src, c->dst, ctxt->eflags); + break; + case 0x10 ... 0x15: + adc: /* adc */ + emulate_2op_SrcV("adc", c->src, c->dst, ctxt->eflags); + break; + case 0x18 ... 0x1d: + sbb: /* sbb */ + emulate_2op_SrcV("sbb", c->src, c->dst, ctxt->eflags); + break; + case 0x20 ... 0x23: + and: /* and */ + emulate_2op_SrcV("and", c->src, c->dst, ctxt->eflags); + break; + case 0x24: /* and al imm8 */ + c->dst.type = OP_REG; + c->dst.ptr = &c->regs[VCPU_REGS_RAX]; + c->dst.val = *(u8 *)c->dst.ptr; + c->dst.bytes = 1; + c->dst.orig_val = c->dst.val; + goto and; + case 0x25: /* and ax imm16, or eax imm32 */ + c->dst.type = OP_REG; + c->dst.bytes = c->op_bytes; + c->dst.ptr = &c->regs[VCPU_REGS_RAX]; + if (c->op_bytes == 2) + c->dst.val = *(u16 *)c->dst.ptr; + else + c->dst.val = *(u32 *)c->dst.ptr; + c->dst.orig_val = c->dst.val; + goto and; + case 0x28 ... 0x2d: + sub: /* sub */ + emulate_2op_SrcV("sub", c->src, c->dst, ctxt->eflags); + break; + case 0x30 ... 0x35: + xor: /* xor */ + emulate_2op_SrcV("xor", c->src, c->dst, ctxt->eflags); + break; + case 0x38 ... 0x3d: + cmp: /* cmp */ + emulate_2op_SrcV("cmp", c->src, c->dst, ctxt->eflags); + break; + case 0x40 ... 0x47: /* inc r16/r32 */ + emulate_1op("inc", c->dst, ctxt->eflags); + break; + case 0x48 ... 0x4f: /* dec r16/r32 */ + emulate_1op("dec", c->dst, ctxt->eflags); + break; + case 0x50 ... 0x57: /* push reg */ + c->dst.type = OP_MEM; + c->dst.bytes = c->op_bytes; + c->dst.val = c->src.val; + register_address_increment(c, &c->regs[VCPU_REGS_RSP], + -c->op_bytes); + c->dst.ptr = (void *) register_address( + c, ctxt->ss_base, c->regs[VCPU_REGS_RSP]); + break; + case 0x58 ... 0x5f: /* pop reg */ + pop_instruction: + if ((rc = ops->read_std(register_address(c, ctxt->ss_base, + c->regs[VCPU_REGS_RSP]), c->dst.ptr, + c->op_bytes, ctxt->vcpu)) != 0) + goto done; + + register_address_increment(c, &c->regs[VCPU_REGS_RSP], + c->op_bytes); + c->dst.type = OP_NONE; /* Disable writeback. */ + break; + case 0x63: /* movsxd */ + if (ctxt->mode != X86EMUL_MODE_PROT64) + goto cannot_emulate; + c->dst.val = (s32) c->src.val; + break; + case 0x6a: /* push imm8 */ + c->src.val = 0L; + c->src.val = insn_fetch(s8, 1, c->eip); + emulate_push(ctxt); + break; + case 0x6c: /* insb */ + case 0x6d: /* insw/insd */ + if (kvm_emulate_pio_string(ctxt->vcpu, NULL, + 1, + (c->d & ByteOp) ? 1 : c->op_bytes, + c->rep_prefix ? + address_mask(c, c->regs[VCPU_REGS_RCX]) : 1, + (ctxt->eflags & EFLG_DF), + register_address(c, ctxt->es_base, + c->regs[VCPU_REGS_RDI]), + c->rep_prefix, + c->regs[VCPU_REGS_RDX]) == 0) { + c->eip = saved_eip; + return -1; + } + return 0; + case 0x6e: /* outsb */ + case 0x6f: /* outsw/outsd */ + if (kvm_emulate_pio_string(ctxt->vcpu, NULL, + 0, + (c->d & ByteOp) ? 1 : c->op_bytes, + c->rep_prefix ? + address_mask(c, c->regs[VCPU_REGS_RCX]) : 1, + (ctxt->eflags & EFLG_DF), + register_address(c, c->override_base ? + *c->override_base : + ctxt->ds_base, + c->regs[VCPU_REGS_RSI]), + c->rep_prefix, + c->regs[VCPU_REGS_RDX]) == 0) { + c->eip = saved_eip; + return -1; + } + return 0; + case 0x70 ... 0x7f: /* jcc (short) */ { + int rel = insn_fetch(s8, 1, c->eip); + + if (test_cc(c->b, ctxt->eflags)) + jmp_rel(c, rel); + break; + } + case 0x80 ... 0x83: /* Grp1 */ + switch (c->modrm_reg) { + case 0: + goto add; + case 1: + goto or; + case 2: + goto adc; + case 3: + goto sbb; + case 4: + goto and; + case 5: + goto sub; + case 6: + goto xor; + case 7: + goto cmp; + } + break; + case 0x84 ... 0x85: + emulate_2op_SrcV("test", c->src, c->dst, ctxt->eflags); + break; + case 0x86 ... 0x87: /* xchg */ + /* Write back the register source. */ + switch (c->dst.bytes) { + case 1: + *(u8 *) c->src.ptr = (u8) c->dst.val; + break; + case 2: + *(u16 *) c->src.ptr = (u16) c->dst.val; + break; + case 4: + *c->src.ptr = (u32) c->dst.val; + break; /* 64b reg: zero-extend */ + case 8: + *c->src.ptr = c->dst.val; + break; + } + /* + * Write back the memory destination with implicit LOCK + * prefix. + */ + c->dst.val = c->src.val; + c->lock_prefix = 1; + break; + case 0x88 ... 0x8b: /* mov */ + goto mov; + case 0x8d: /* lea r16/r32, m */ + c->dst.val = c->modrm_val; + break; + case 0x8f: /* pop (sole member of Grp1a) */ + rc = emulate_grp1a(ctxt, ops); + if (rc != 0) + goto done; + break; + case 0x9c: /* pushf */ + c->src.val = (unsigned long) ctxt->eflags; + emulate_push(ctxt); + break; + case 0x9d: /* popf */ + c->dst.ptr = (unsigned long *) &ctxt->eflags; + goto pop_instruction; + case 0xa0 ... 0xa1: /* mov */ + c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX]; + c->dst.val = c->src.val; + break; + case 0xa2 ... 0xa3: /* mov */ + c->dst.val = (unsigned long)c->regs[VCPU_REGS_RAX]; + break; + case 0xa4 ... 0xa5: /* movs */ + c->dst.type = OP_MEM; + c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; + c->dst.ptr = (unsigned long *)register_address(c, + ctxt->es_base, + c->regs[VCPU_REGS_RDI]); + if ((rc = ops->read_emulated(register_address(c, + c->override_base ? *c->override_base : + ctxt->ds_base, + c->regs[VCPU_REGS_RSI]), + &c->dst.val, + c->dst.bytes, ctxt->vcpu)) != 0) + goto done; + register_address_increment(c, &c->regs[VCPU_REGS_RSI], + (ctxt->eflags & EFLG_DF) ? -c->dst.bytes + : c->dst.bytes); + register_address_increment(c, &c->regs[VCPU_REGS_RDI], + (ctxt->eflags & EFLG_DF) ? -c->dst.bytes + : c->dst.bytes); + break; + case 0xa6 ... 0xa7: /* cmps */ + c->src.type = OP_NONE; /* Disable writeback. */ + c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; + c->src.ptr = (unsigned long *)register_address(c, + c->override_base ? *c->override_base : + ctxt->ds_base, + c->regs[VCPU_REGS_RSI]); + if ((rc = ops->read_emulated((unsigned long)c->src.ptr, + &c->src.val, + c->src.bytes, + ctxt->vcpu)) != 0) + goto done; + + c->dst.type = OP_NONE; /* Disable writeback. */ + c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; + c->dst.ptr = (unsigned long *)register_address(c, + ctxt->es_base, + c->regs[VCPU_REGS_RDI]); + if ((rc = ops->read_emulated((unsigned long)c->dst.ptr, + &c->dst.val, + c->dst.bytes, + ctxt->vcpu)) != 0) + goto done; + + DPRINTF("cmps: mem1=0x%p mem2=0x%p\n", c->src.ptr, c->dst.ptr); + + emulate_2op_SrcV("cmp", c->src, c->dst, ctxt->eflags); + + register_address_increment(c, &c->regs[VCPU_REGS_RSI], + (ctxt->eflags & EFLG_DF) ? -c->src.bytes + : c->src.bytes); + register_address_increment(c, &c->regs[VCPU_REGS_RDI], + (ctxt->eflags & EFLG_DF) ? -c->dst.bytes + : c->dst.bytes); + + break; + case 0xaa ... 0xab: /* stos */ + c->dst.type = OP_MEM; + c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; + c->dst.ptr = (unsigned long *)register_address(c, + ctxt->es_base, + c->regs[VCPU_REGS_RDI]); + c->dst.val = c->regs[VCPU_REGS_RAX]; + register_address_increment(c, &c->regs[VCPU_REGS_RDI], + (ctxt->eflags & EFLG_DF) ? -c->dst.bytes + : c->dst.bytes); + break; + case 0xac ... 0xad: /* lods */ + c->dst.type = OP_REG; + c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; + c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX]; + if ((rc = ops->read_emulated(register_address(c, + c->override_base ? *c->override_base : + ctxt->ds_base, + c->regs[VCPU_REGS_RSI]), + &c->dst.val, + c->dst.bytes, + ctxt->vcpu)) != 0) + goto done; + register_address_increment(c, &c->regs[VCPU_REGS_RSI], + (ctxt->eflags & EFLG_DF) ? -c->dst.bytes + : c->dst.bytes); + break; + case 0xae ... 0xaf: /* scas */ + DPRINTF("Urk! I don't handle SCAS.\n"); + goto cannot_emulate; + case 0xc0 ... 0xc1: + emulate_grp2(ctxt); + break; + case 0xc3: /* ret */ + c->dst.ptr = &c->eip; + goto pop_instruction; + case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */ + mov: + c->dst.val = c->src.val; + break; + case 0xd0 ... 0xd1: /* Grp2 */ + c->src.val = 1; + emulate_grp2(ctxt); + break; + case 0xd2 ... 0xd3: /* Grp2 */ + c->src.val = c->regs[VCPU_REGS_RCX]; + emulate_grp2(ctxt); + break; + case 0xe8: /* call (near) */ { + long int rel; + switch (c->op_bytes) { + case 2: + rel = insn_fetch(s16, 2, c->eip); + break; + case 4: + rel = insn_fetch(s32, 4, c->eip); + break; + default: + DPRINTF("Call: Invalid op_bytes\n"); + goto cannot_emulate; + } + c->src.val = (unsigned long) c->eip; + jmp_rel(c, rel); + c->op_bytes = c->ad_bytes; + emulate_push(ctxt); + break; + } + case 0xe9: /* jmp rel */ + case 0xeb: /* jmp rel short */ + jmp_rel(c, c->src.val); + c->dst.type = OP_NONE; /* Disable writeback. */ + break; + case 0xf4: /* hlt */ + ctxt->vcpu->arch.halt_request = 1; + goto done; + case 0xf5: /* cmc */ + /* complement carry flag from eflags reg */ + ctxt->eflags ^= EFLG_CF; + c->dst.type = OP_NONE; /* Disable writeback. */ + break; + case 0xf6 ... 0xf7: /* Grp3 */ + rc = emulate_grp3(ctxt, ops); + if (rc != 0) + goto done; + break; + case 0xf8: /* clc */ + ctxt->eflags &= ~EFLG_CF; + c->dst.type = OP_NONE; /* Disable writeback. */ + break; + case 0xfa: /* cli */ + ctxt->eflags &= ~X86_EFLAGS_IF; + c->dst.type = OP_NONE; /* Disable writeback. */ + break; + case 0xfb: /* sti */ + ctxt->eflags |= X86_EFLAGS_IF; + c->dst.type = OP_NONE; /* Disable writeback. */ + break; + case 0xfe ... 0xff: /* Grp4/Grp5 */ + rc = emulate_grp45(ctxt, ops); + if (rc != 0) + goto done; + break; + } + +writeback: + rc = writeback(ctxt, ops); + if (rc != 0) + goto done; + + /* Commit shadow register state. */ + memcpy(ctxt->vcpu->arch.regs, c->regs, sizeof c->regs); + ctxt->vcpu->arch.rip = c->eip; + +done: + if (rc == X86EMUL_UNHANDLEABLE) { + c->eip = saved_eip; + return -1; + } + return 0; + +twobyte_insn: + switch (c->b) { + case 0x01: /* lgdt, lidt, lmsw */ + switch (c->modrm_reg) { + u16 size; + unsigned long address; + + case 0: /* vmcall */ + if (c->modrm_mod != 3 || c->modrm_rm != 1) + goto cannot_emulate; + + rc = kvm_fix_hypercall(ctxt->vcpu); + if (rc) + goto done; + + kvm_emulate_hypercall(ctxt->vcpu); + break; + case 2: /* lgdt */ + rc = read_descriptor(ctxt, ops, c->src.ptr, + &size, &address, c->op_bytes); + if (rc) + goto done; + realmode_lgdt(ctxt->vcpu, size, address); + break; + case 3: /* lidt/vmmcall */ + if (c->modrm_mod == 3 && c->modrm_rm == 1) { + rc = kvm_fix_hypercall(ctxt->vcpu); + if (rc) + goto done; + kvm_emulate_hypercall(ctxt->vcpu); + } else { + rc = read_descriptor(ctxt, ops, c->src.ptr, + &size, &address, + c->op_bytes); + if (rc) + goto done; + realmode_lidt(ctxt->vcpu, size, address); + } + break; + case 4: /* smsw */ + if (c->modrm_mod != 3) + goto cannot_emulate; + *(u16 *)&c->regs[c->modrm_rm] + = realmode_get_cr(ctxt->vcpu, 0); + break; + case 6: /* lmsw */ + if (c->modrm_mod != 3) + goto cannot_emulate; + realmode_lmsw(ctxt->vcpu, (u16)c->modrm_val, + &ctxt->eflags); + break; + case 7: /* invlpg*/ + emulate_invlpg(ctxt->vcpu, memop); + break; + default: + goto cannot_emulate; + } + /* Disable writeback. */ + c->dst.type = OP_NONE; + break; + case 0x06: + emulate_clts(ctxt->vcpu); + c->dst.type = OP_NONE; + break; + case 0x08: /* invd */ + case 0x09: /* wbinvd */ + case 0x0d: /* GrpP (prefetch) */ + case 0x18: /* Grp16 (prefetch/nop) */ + c->dst.type = OP_NONE; + break; + case 0x20: /* mov cr, reg */ + if (c->modrm_mod != 3) + goto cannot_emulate; + c->regs[c->modrm_rm] = + realmode_get_cr(ctxt->vcpu, c->modrm_reg); + c->dst.type = OP_NONE; /* no writeback */ + break; + case 0x21: /* mov from dr to reg */ + if (c->modrm_mod != 3) + goto cannot_emulate; + rc = emulator_get_dr(ctxt, c->modrm_reg, &c->regs[c->modrm_rm]); + if (rc) + goto cannot_emulate; + c->dst.type = OP_NONE; /* no writeback */ + break; + case 0x22: /* mov reg, cr */ + if (c->modrm_mod != 3) + goto cannot_emulate; + realmode_set_cr(ctxt->vcpu, + c->modrm_reg, c->modrm_val, &ctxt->eflags); + c->dst.type = OP_NONE; + break; + case 0x23: /* mov from reg to dr */ + if (c->modrm_mod != 3) + goto cannot_emulate; + rc = emulator_set_dr(ctxt, c->modrm_reg, + c->regs[c->modrm_rm]); + if (rc) + goto cannot_emulate; + c->dst.type = OP_NONE; /* no writeback */ + break; + case 0x30: + /* wrmsr */ + msr_data = (u32)c->regs[VCPU_REGS_RAX] + | ((u64)c->regs[VCPU_REGS_RDX] << 32); + rc = kvm_set_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], msr_data); + if (rc) { + kvm_inject_gp(ctxt->vcpu, 0); + c->eip = ctxt->vcpu->arch.rip; + } + rc = X86EMUL_CONTINUE; + c->dst.type = OP_NONE; + break; + case 0x32: + /* rdmsr */ + rc = kvm_get_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], &msr_data); + if (rc) { + kvm_inject_gp(ctxt->vcpu, 0); + c->eip = ctxt->vcpu->arch.rip; + } else { + c->regs[VCPU_REGS_RAX] = (u32)msr_data; + c->regs[VCPU_REGS_RDX] = msr_data >> 32; + } + rc = X86EMUL_CONTINUE; + c->dst.type = OP_NONE; + break; + case 0x40 ... 0x4f: /* cmov */ + c->dst.val = c->dst.orig_val = c->src.val; + if (!test_cc(c->b, ctxt->eflags)) + c->dst.type = OP_NONE; /* no writeback */ + break; + case 0x80 ... 0x8f: /* jnz rel, etc*/ { + long int rel; + + switch (c->op_bytes) { + case 2: + rel = insn_fetch(s16, 2, c->eip); + break; + case 4: + rel = insn_fetch(s32, 4, c->eip); + break; + case 8: + rel = insn_fetch(s64, 8, c->eip); + break; + default: + DPRINTF("jnz: Invalid op_bytes\n"); + goto cannot_emulate; + } + if (test_cc(c->b, ctxt->eflags)) + jmp_rel(c, rel); + c->dst.type = OP_NONE; + break; + } + case 0xa3: + bt: /* bt */ + c->dst.type = OP_NONE; + /* only subword offset */ + c->src.val &= (c->dst.bytes << 3) - 1; + emulate_2op_SrcV_nobyte("bt", c->src, c->dst, ctxt->eflags); + break; + case 0xab: + bts: /* bts */ + /* only subword offset */ + c->src.val &= (c->dst.bytes << 3) - 1; + emulate_2op_SrcV_nobyte("bts", c->src, c->dst, ctxt->eflags); + break; + case 0xb0 ... 0xb1: /* cmpxchg */ + /* + * Save real source value, then compare EAX against + * destination. + */ + c->src.orig_val = c->src.val; + c->src.val = c->regs[VCPU_REGS_RAX]; + emulate_2op_SrcV("cmp", c->src, c->dst, ctxt->eflags); + if (ctxt->eflags & EFLG_ZF) { + /* Success: write back to memory. */ + c->dst.val = c->src.orig_val; + } else { + /* Failure: write the value we saw to EAX. */ + c->dst.type = OP_REG; + c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX]; + } + break; + case 0xb3: + btr: /* btr */ + /* only subword offset */ + c->src.val &= (c->dst.bytes << 3) - 1; + emulate_2op_SrcV_nobyte("btr", c->src, c->dst, ctxt->eflags); + break; + case 0xb6 ... 0xb7: /* movzx */ + c->dst.bytes = c->op_bytes; + c->dst.val = (c->d & ByteOp) ? (u8) c->src.val + : (u16) c->src.val; + break; + case 0xba: /* Grp8 */ + switch (c->modrm_reg & 3) { + case 0: + goto bt; + case 1: + goto bts; + case 2: + goto btr; + case 3: + goto btc; + } + break; + case 0xbb: + btc: /* btc */ + /* only subword offset */ + c->src.val &= (c->dst.bytes << 3) - 1; + emulate_2op_SrcV_nobyte("btc", c->src, c->dst, ctxt->eflags); + break; + case 0xbe ... 0xbf: /* movsx */ + c->dst.bytes = c->op_bytes; + c->dst.val = (c->d & ByteOp) ? (s8) c->src.val : + (s16) c->src.val; + break; + case 0xc3: /* movnti */ + c->dst.bytes = c->op_bytes; + c->dst.val = (c->op_bytes == 4) ? (u32) c->src.val : + (u64) c->src.val; + break; + case 0xc7: /* Grp9 (cmpxchg8b) */ + rc = emulate_grp9(ctxt, ops, memop); + if (rc != 0) + goto done; + c->dst.type = OP_NONE; + break; + } + goto writeback; + +cannot_emulate: + DPRINTF("Cannot emulate %02x\n", c->b); + c->eip = saved_eip; + return -1; +} --- linux-2.6.24.orig/arch/x86/kvm/kvm_svm.h +++ linux-2.6.24/arch/x86/kvm/kvm_svm.h @@ -0,0 +1,47 @@ +#ifndef __KVM_SVM_H +#define __KVM_SVM_H + +#include +#include +#include +#include +#include + +#include "svm.h" + +static const u32 host_save_user_msrs[] = { +#ifdef CONFIG_X86_64 + MSR_STAR, MSR_LSTAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_KERNEL_GS_BASE, + MSR_FS_BASE, +#endif + MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP, +}; + +#define NR_HOST_SAVE_USER_MSRS ARRAY_SIZE(host_save_user_msrs) +#define NUM_DB_REGS 4 + +struct kvm_vcpu; + +struct vcpu_svm { + struct kvm_vcpu vcpu; + struct vmcb *vmcb; + unsigned long vmcb_pa; + struct svm_cpu_data *svm_data; + uint64_t asid_generation; + + unsigned long db_regs[NUM_DB_REGS]; + + u64 next_rip; + + u64 host_user_msrs[NR_HOST_SAVE_USER_MSRS]; + u64 host_gs_base; + unsigned long host_cr2; + unsigned long host_db_regs[NUM_DB_REGS]; + unsigned long host_dr6; + unsigned long host_dr7; + + u32 *msrpm; +}; + +#endif + --- linux-2.6.24.orig/arch/x86/kvm/Kconfig +++ linux-2.6.24/arch/x86/kvm/Kconfig @@ -0,0 +1,58 @@ +# +# KVM configuration +# +config HAVE_KVM + bool + +menuconfig VIRTUALIZATION + bool "Virtualization" + depends on HAVE_KVM || X86 + default y + ---help--- + Say Y here to get to see options for using your Linux host to run other + operating systems inside virtual machines (guests). + This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. + +if VIRTUALIZATION + +config KVM + tristate "Kernel-based Virtual Machine (KVM) support" + depends on HAVE_KVM && EXPERIMENTAL + select PREEMPT_NOTIFIERS + select ANON_INODES + ---help--- + Support hosting fully virtualized guest machines using hardware + virtualization extensions. You will need a fairly recent + processor equipped with virtualization extensions. You will also + need to select one or more of the processor modules below. + + This module provides access to the hardware capabilities through + a character device node named /dev/kvm. + + To compile this as a module, choose M here: the module + will be called kvm. + + If unsure, say N. + +config KVM_INTEL + tristate "KVM for Intel processors support" + depends on KVM + ---help--- + Provides support for KVM on Intel processors equipped with the VT + extensions. + +config KVM_AMD + tristate "KVM for AMD processors support" + depends on KVM + ---help--- + Provides support for KVM on AMD processors equipped with the AMD-V + (SVM) extensions. + +# OK, it's a little counter-intuitive to do this, but it puts it neatly under +# the virtualization menu. +source drivers/lguest/Kconfig +source drivers/virtio/Kconfig + +endif # VIRTUALIZATION --- linux-2.6.24.orig/arch/x86/kvm/mmu.h +++ linux-2.6.24/arch/x86/kvm/mmu.h @@ -0,0 +1,50 @@ +#ifndef __KVM_X86_MMU_H +#define __KVM_X86_MMU_H + +#include + +#ifdef CONFIG_X86_64 +#define TDP_ROOT_LEVEL PT64_ROOT_LEVEL +#else +#define TDP_ROOT_LEVEL PT32E_ROOT_LEVEL +#endif + +static inline void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu) +{ + if (unlikely(vcpu->kvm->arch.n_free_mmu_pages < KVM_MIN_FREE_MMU_PAGES)) + __kvm_mmu_free_some_pages(vcpu); +} + +static inline int kvm_mmu_reload(struct kvm_vcpu *vcpu) +{ + if (likely(vcpu->arch.mmu.root_hpa != INVALID_PAGE)) + return 0; + + return kvm_mmu_load(vcpu); +} + +static inline int is_long_mode(struct kvm_vcpu *vcpu) +{ +#ifdef CONFIG_X86_64 + return vcpu->arch.shadow_efer & EFER_LME; +#else + return 0; +#endif +} + +static inline int is_pae(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.cr4 & X86_CR4_PAE; +} + +static inline int is_pse(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.cr4 & X86_CR4_PSE; +} + +static inline int is_paging(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.cr0 & X86_CR0_PG; +} + +#endif --- linux-2.6.24.orig/arch/x86/kvm/i8259.c +++ linux-2.6.24/arch/x86/kvm/i8259.c @@ -0,0 +1,450 @@ +/* + * 8259 interrupt controller emulation + * + * Copyright (c) 2003-2004 Fabrice Bellard + * Copyright (c) 2007 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * Authors: + * Yaozu (Eddie) Dong + * Port from Qemu. + */ +#include +#include "irq.h" + +#include + +/* + * set irq level. If an edge is detected, then the IRR is set to 1 + */ +static inline void pic_set_irq1(struct kvm_kpic_state *s, int irq, int level) +{ + int mask; + mask = 1 << irq; + if (s->elcr & mask) /* level triggered */ + if (level) { + s->irr |= mask; + s->last_irr |= mask; + } else { + s->irr &= ~mask; + s->last_irr &= ~mask; + } + else /* edge triggered */ + if (level) { + if ((s->last_irr & mask) == 0) + s->irr |= mask; + s->last_irr |= mask; + } else + s->last_irr &= ~mask; +} + +/* + * return the highest priority found in mask (highest = smallest + * number). Return 8 if no irq + */ +static inline int get_priority(struct kvm_kpic_state *s, int mask) +{ + int priority; + if (mask == 0) + return 8; + priority = 0; + while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0) + priority++; + return priority; +} + +/* + * return the pic wanted interrupt. return -1 if none + */ +static int pic_get_irq(struct kvm_kpic_state *s) +{ + int mask, cur_priority, priority; + + mask = s->irr & ~s->imr; + priority = get_priority(s, mask); + if (priority == 8) + return -1; + /* + * compute current priority. If special fully nested mode on the + * master, the IRQ coming from the slave is not taken into account + * for the priority computation. + */ + mask = s->isr; + if (s->special_fully_nested_mode && s == &s->pics_state->pics[0]) + mask &= ~(1 << 2); + cur_priority = get_priority(s, mask); + if (priority < cur_priority) + /* + * higher priority found: an irq should be generated + */ + return (priority + s->priority_add) & 7; + else + return -1; +} + +/* + * raise irq to CPU if necessary. must be called every time the active + * irq may change + */ +static void pic_update_irq(struct kvm_pic *s) +{ + int irq2, irq; + + irq2 = pic_get_irq(&s->pics[1]); + if (irq2 >= 0) { + /* + * if irq request by slave pic, signal master PIC + */ + pic_set_irq1(&s->pics[0], 2, 1); + pic_set_irq1(&s->pics[0], 2, 0); + } + irq = pic_get_irq(&s->pics[0]); + if (irq >= 0) + s->irq_request(s->irq_request_opaque, 1); + else + s->irq_request(s->irq_request_opaque, 0); +} + +void kvm_pic_update_irq(struct kvm_pic *s) +{ + pic_update_irq(s); +} + +void kvm_pic_set_irq(void *opaque, int irq, int level) +{ + struct kvm_pic *s = opaque; + + pic_set_irq1(&s->pics[irq >> 3], irq & 7, level); + pic_update_irq(s); +} + +/* + * acknowledge interrupt 'irq' + */ +static inline void pic_intack(struct kvm_kpic_state *s, int irq) +{ + if (s->auto_eoi) { + if (s->rotate_on_auto_eoi) + s->priority_add = (irq + 1) & 7; + } else + s->isr |= (1 << irq); + /* + * We don't clear a level sensitive interrupt here + */ + if (!(s->elcr & (1 << irq))) + s->irr &= ~(1 << irq); +} + +int kvm_pic_read_irq(struct kvm_pic *s) +{ + int irq, irq2, intno; + + irq = pic_get_irq(&s->pics[0]); + if (irq >= 0) { + pic_intack(&s->pics[0], irq); + if (irq == 2) { + irq2 = pic_get_irq(&s->pics[1]); + if (irq2 >= 0) + pic_intack(&s->pics[1], irq2); + else + /* + * spurious IRQ on slave controller + */ + irq2 = 7; + intno = s->pics[1].irq_base + irq2; + irq = irq2 + 8; + } else + intno = s->pics[0].irq_base + irq; + } else { + /* + * spurious IRQ on host controller + */ + irq = 7; + intno = s->pics[0].irq_base + irq; + } + pic_update_irq(s); + + return intno; +} + +void kvm_pic_reset(struct kvm_kpic_state *s) +{ + s->last_irr = 0; + s->irr = 0; + s->imr = 0; + s->isr = 0; + s->priority_add = 0; + s->irq_base = 0; + s->read_reg_select = 0; + s->poll = 0; + s->special_mask = 0; + s->init_state = 0; + s->auto_eoi = 0; + s->rotate_on_auto_eoi = 0; + s->special_fully_nested_mode = 0; + s->init4 = 0; +} + +static void pic_ioport_write(void *opaque, u32 addr, u32 val) +{ + struct kvm_kpic_state *s = opaque; + int priority, cmd, irq; + + addr &= 1; + if (addr == 0) { + if (val & 0x10) { + kvm_pic_reset(s); /* init */ + /* + * deassert a pending interrupt + */ + s->pics_state->irq_request(s->pics_state-> + irq_request_opaque, 0); + s->init_state = 1; + s->init4 = val & 1; + if (val & 0x02) + printk(KERN_ERR "single mode not supported"); + if (val & 0x08) + printk(KERN_ERR + "level sensitive irq not supported"); + } else if (val & 0x08) { + if (val & 0x04) + s->poll = 1; + if (val & 0x02) + s->read_reg_select = val & 1; + if (val & 0x40) + s->special_mask = (val >> 5) & 1; + } else { + cmd = val >> 5; + switch (cmd) { + case 0: + case 4: + s->rotate_on_auto_eoi = cmd >> 2; + break; + case 1: /* end of interrupt */ + case 5: + priority = get_priority(s, s->isr); + if (priority != 8) { + irq = (priority + s->priority_add) & 7; + s->isr &= ~(1 << irq); + if (cmd == 5) + s->priority_add = (irq + 1) & 7; + pic_update_irq(s->pics_state); + } + break; + case 3: + irq = val & 7; + s->isr &= ~(1 << irq); + pic_update_irq(s->pics_state); + break; + case 6: + s->priority_add = (val + 1) & 7; + pic_update_irq(s->pics_state); + break; + case 7: + irq = val & 7; + s->isr &= ~(1 << irq); + s->priority_add = (irq + 1) & 7; + pic_update_irq(s->pics_state); + break; + default: + break; /* no operation */ + } + } + } else + switch (s->init_state) { + case 0: /* normal mode */ + s->imr = val; + pic_update_irq(s->pics_state); + break; + case 1: + s->irq_base = val & 0xf8; + s->init_state = 2; + break; + case 2: + if (s->init4) + s->init_state = 3; + else + s->init_state = 0; + break; + case 3: + s->special_fully_nested_mode = (val >> 4) & 1; + s->auto_eoi = (val >> 1) & 1; + s->init_state = 0; + break; + } +} + +static u32 pic_poll_read(struct kvm_kpic_state *s, u32 addr1) +{ + int ret; + + ret = pic_get_irq(s); + if (ret >= 0) { + if (addr1 >> 7) { + s->pics_state->pics[0].isr &= ~(1 << 2); + s->pics_state->pics[0].irr &= ~(1 << 2); + } + s->irr &= ~(1 << ret); + s->isr &= ~(1 << ret); + if (addr1 >> 7 || ret != 2) + pic_update_irq(s->pics_state); + } else { + ret = 0x07; + pic_update_irq(s->pics_state); + } + + return ret; +} + +static u32 pic_ioport_read(void *opaque, u32 addr1) +{ + struct kvm_kpic_state *s = opaque; + unsigned int addr; + int ret; + + addr = addr1; + addr &= 1; + if (s->poll) { + ret = pic_poll_read(s, addr1); + s->poll = 0; + } else + if (addr == 0) + if (s->read_reg_select) + ret = s->isr; + else + ret = s->irr; + else + ret = s->imr; + return ret; +} + +static void elcr_ioport_write(void *opaque, u32 addr, u32 val) +{ + struct kvm_kpic_state *s = opaque; + s->elcr = val & s->elcr_mask; +} + +static u32 elcr_ioport_read(void *opaque, u32 addr1) +{ + struct kvm_kpic_state *s = opaque; + return s->elcr; +} + +static int picdev_in_range(struct kvm_io_device *this, gpa_t addr) +{ + switch (addr) { + case 0x20: + case 0x21: + case 0xa0: + case 0xa1: + case 0x4d0: + case 0x4d1: + return 1; + default: + return 0; + } +} + +static void picdev_write(struct kvm_io_device *this, + gpa_t addr, int len, const void *val) +{ + struct kvm_pic *s = this->private; + unsigned char data = *(unsigned char *)val; + + if (len != 1) { + if (printk_ratelimit()) + printk(KERN_ERR "PIC: non byte write\n"); + return; + } + switch (addr) { + case 0x20: + case 0x21: + case 0xa0: + case 0xa1: + pic_ioport_write(&s->pics[addr >> 7], addr, data); + break; + case 0x4d0: + case 0x4d1: + elcr_ioport_write(&s->pics[addr & 1], addr, data); + break; + } +} + +static void picdev_read(struct kvm_io_device *this, + gpa_t addr, int len, void *val) +{ + struct kvm_pic *s = this->private; + unsigned char data = 0; + + if (len != 1) { + if (printk_ratelimit()) + printk(KERN_ERR "PIC: non byte read\n"); + return; + } + switch (addr) { + case 0x20: + case 0x21: + case 0xa0: + case 0xa1: + data = pic_ioport_read(&s->pics[addr >> 7], addr); + break; + case 0x4d0: + case 0x4d1: + data = elcr_ioport_read(&s->pics[addr & 1], addr); + break; + } + *(unsigned char *)val = data; +} + +/* + * callback when PIC0 irq status changed + */ +static void pic_irq_request(void *opaque, int level) +{ + struct kvm *kvm = opaque; + struct kvm_vcpu *vcpu = kvm->vcpus[0]; + + pic_irqchip(kvm)->output = level; + if (vcpu) + kvm_vcpu_kick(vcpu); +} + +struct kvm_pic *kvm_create_pic(struct kvm *kvm) +{ + struct kvm_pic *s; + s = kzalloc(sizeof(struct kvm_pic), GFP_KERNEL); + if (!s) + return NULL; + s->pics[0].elcr_mask = 0xf8; + s->pics[1].elcr_mask = 0xde; + s->irq_request = pic_irq_request; + s->irq_request_opaque = kvm; + s->pics[0].pics_state = s; + s->pics[1].pics_state = s; + + /* + * Initialize PIO device + */ + s->dev.read = picdev_read; + s->dev.write = picdev_write; + s->dev.in_range = picdev_in_range; + s->dev.private = s; + kvm_io_bus_register_dev(&kvm->pio_bus, &s->dev); + return s; +} --- linux-2.6.24.orig/arch/x86/kvm/lapic.c +++ linux-2.6.24/arch/x86/kvm/lapic.c @@ -0,0 +1,1158 @@ + +/* + * Local APIC virtualization + * + * Copyright (C) 2006 Qumranet, Inc. + * Copyright (C) 2007 Novell + * Copyright (C) 2007 Intel + * + * Authors: + * Dor Laor + * Gregory Haskins + * Yaozu (Eddie) Dong + * + * Based on Xen 3.1 code, Copyright (c) 2004, Intel Corporation. + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "irq.h" + +#define PRId64 "d" +#define PRIx64 "llx" +#define PRIu64 "u" +#define PRIo64 "o" + +#define APIC_BUS_CYCLE_NS 1 + +/* #define apic_debug(fmt,arg...) printk(KERN_WARNING fmt,##arg) */ +#define apic_debug(fmt, arg...) + +#define APIC_LVT_NUM 6 +/* 14 is the version for Xeon and Pentium 8.4.8*/ +#define APIC_VERSION (0x14UL | ((APIC_LVT_NUM - 1) << 16)) +#define LAPIC_MMIO_LENGTH (1 << 12) +/* followed define is not in apicdef.h */ +#define APIC_SHORT_MASK 0xc0000 +#define APIC_DEST_NOSHORT 0x0 +#define APIC_DEST_MASK 0x800 +#define MAX_APIC_VECTOR 256 + +#define VEC_POS(v) ((v) & (32 - 1)) +#define REG_POS(v) (((v) >> 5) << 4) + +static inline u32 apic_get_reg(struct kvm_lapic *apic, int reg_off) +{ + return *((u32 *) (apic->regs + reg_off)); +} + +static inline void apic_set_reg(struct kvm_lapic *apic, int reg_off, u32 val) +{ + *((u32 *) (apic->regs + reg_off)) = val; +} + +static inline int apic_test_and_set_vector(int vec, void *bitmap) +{ + return test_and_set_bit(VEC_POS(vec), (bitmap) + REG_POS(vec)); +} + +static inline int apic_test_and_clear_vector(int vec, void *bitmap) +{ + return test_and_clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec)); +} + +static inline void apic_set_vector(int vec, void *bitmap) +{ + set_bit(VEC_POS(vec), (bitmap) + REG_POS(vec)); +} + +static inline void apic_clear_vector(int vec, void *bitmap) +{ + clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec)); +} + +static inline int apic_hw_enabled(struct kvm_lapic *apic) +{ + return (apic)->vcpu->arch.apic_base & MSR_IA32_APICBASE_ENABLE; +} + +static inline int apic_sw_enabled(struct kvm_lapic *apic) +{ + return apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_APIC_ENABLED; +} + +static inline int apic_enabled(struct kvm_lapic *apic) +{ + return apic_sw_enabled(apic) && apic_hw_enabled(apic); +} + +#define LVT_MASK \ + (APIC_LVT_MASKED | APIC_SEND_PENDING | APIC_VECTOR_MASK) + +#define LINT_MASK \ + (LVT_MASK | APIC_MODE_MASK | APIC_INPUT_POLARITY | \ + APIC_LVT_REMOTE_IRR | APIC_LVT_LEVEL_TRIGGER) + +static inline int kvm_apic_id(struct kvm_lapic *apic) +{ + return (apic_get_reg(apic, APIC_ID) >> 24) & 0xff; +} + +static inline int apic_lvt_enabled(struct kvm_lapic *apic, int lvt_type) +{ + return !(apic_get_reg(apic, lvt_type) & APIC_LVT_MASKED); +} + +static inline int apic_lvt_vector(struct kvm_lapic *apic, int lvt_type) +{ + return apic_get_reg(apic, lvt_type) & APIC_VECTOR_MASK; +} + +static inline int apic_lvtt_period(struct kvm_lapic *apic) +{ + return apic_get_reg(apic, APIC_LVTT) & APIC_LVT_TIMER_PERIODIC; +} + +static unsigned int apic_lvt_mask[APIC_LVT_NUM] = { + LVT_MASK | APIC_LVT_TIMER_PERIODIC, /* LVTT */ + LVT_MASK | APIC_MODE_MASK, /* LVTTHMR */ + LVT_MASK | APIC_MODE_MASK, /* LVTPC */ + LINT_MASK, LINT_MASK, /* LVT0-1 */ + LVT_MASK /* LVTERR */ +}; + +static int find_highest_vector(void *bitmap) +{ + u32 *word = bitmap; + int word_offset = MAX_APIC_VECTOR >> 5; + + while ((word_offset != 0) && (word[(--word_offset) << 2] == 0)) + continue; + + if (likely(!word_offset && !word[0])) + return -1; + else + return fls(word[word_offset << 2]) - 1 + (word_offset << 5); +} + +static inline int apic_test_and_set_irr(int vec, struct kvm_lapic *apic) +{ + return apic_test_and_set_vector(vec, apic->regs + APIC_IRR); +} + +static inline void apic_clear_irr(int vec, struct kvm_lapic *apic) +{ + apic_clear_vector(vec, apic->regs + APIC_IRR); +} + +static inline int apic_find_highest_irr(struct kvm_lapic *apic) +{ + int result; + + result = find_highest_vector(apic->regs + APIC_IRR); + ASSERT(result == -1 || result >= 16); + + return result; +} + +int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu) +{ + struct kvm_lapic *apic = vcpu->arch.apic; + int highest_irr; + + if (!apic) + return 0; + highest_irr = apic_find_highest_irr(apic); + + return highest_irr; +} +EXPORT_SYMBOL_GPL(kvm_lapic_find_highest_irr); + +int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 trig) +{ + struct kvm_lapic *apic = vcpu->arch.apic; + + if (!apic_test_and_set_irr(vec, apic)) { + /* a new pending irq is set in IRR */ + if (trig) + apic_set_vector(vec, apic->regs + APIC_TMR); + else + apic_clear_vector(vec, apic->regs + APIC_TMR); + kvm_vcpu_kick(apic->vcpu); + return 1; + } + return 0; +} + +static inline int apic_find_highest_isr(struct kvm_lapic *apic) +{ + int result; + + result = find_highest_vector(apic->regs + APIC_ISR); + ASSERT(result == -1 || result >= 16); + + return result; +} + +static void apic_update_ppr(struct kvm_lapic *apic) +{ + u32 tpr, isrv, ppr; + int isr; + + tpr = apic_get_reg(apic, APIC_TASKPRI); + isr = apic_find_highest_isr(apic); + isrv = (isr != -1) ? isr : 0; + + if ((tpr & 0xf0) >= (isrv & 0xf0)) + ppr = tpr & 0xff; + else + ppr = isrv & 0xf0; + + apic_debug("vlapic %p, ppr 0x%x, isr 0x%x, isrv 0x%x", + apic, ppr, isr, isrv); + + apic_set_reg(apic, APIC_PROCPRI, ppr); +} + +static void apic_set_tpr(struct kvm_lapic *apic, u32 tpr) +{ + apic_set_reg(apic, APIC_TASKPRI, tpr); + apic_update_ppr(apic); +} + +int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest) +{ + return kvm_apic_id(apic) == dest; +} + +int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda) +{ + int result = 0; + u8 logical_id; + + logical_id = GET_APIC_LOGICAL_ID(apic_get_reg(apic, APIC_LDR)); + + switch (apic_get_reg(apic, APIC_DFR)) { + case APIC_DFR_FLAT: + if (logical_id & mda) + result = 1; + break; + case APIC_DFR_CLUSTER: + if (((logical_id >> 4) == (mda >> 0x4)) + && (logical_id & mda & 0xf)) + result = 1; + break; + default: + printk(KERN_WARNING "Bad DFR vcpu %d: %08x\n", + apic->vcpu->vcpu_id, apic_get_reg(apic, APIC_DFR)); + break; + } + + return result; +} + +static int apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, + int short_hand, int dest, int dest_mode) +{ + int result = 0; + struct kvm_lapic *target = vcpu->arch.apic; + + apic_debug("target %p, source %p, dest 0x%x, " + "dest_mode 0x%x, short_hand 0x%x", + target, source, dest, dest_mode, short_hand); + + ASSERT(!target); + switch (short_hand) { + case APIC_DEST_NOSHORT: + if (dest_mode == 0) { + /* Physical mode. */ + if ((dest == 0xFF) || (dest == kvm_apic_id(target))) + result = 1; + } else + /* Logical mode. */ + result = kvm_apic_match_logical_addr(target, dest); + break; + case APIC_DEST_SELF: + if (target == source) + result = 1; + break; + case APIC_DEST_ALLINC: + result = 1; + break; + case APIC_DEST_ALLBUT: + if (target != source) + result = 1; + break; + default: + printk(KERN_WARNING "Bad dest shorthand value %x\n", + short_hand); + break; + } + + return result; +} + +/* + * Add a pending IRQ into lapic. + * Return 1 if successfully added and 0 if discarded. + */ +static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, + int vector, int level, int trig_mode) +{ + int orig_irr, result = 0; + struct kvm_vcpu *vcpu = apic->vcpu; + + switch (delivery_mode) { + case APIC_DM_FIXED: + case APIC_DM_LOWEST: + /* FIXME add logic for vcpu on reset */ + if (unlikely(!apic_enabled(apic))) + break; + + orig_irr = apic_test_and_set_irr(vector, apic); + if (orig_irr && trig_mode) { + apic_debug("level trig mode repeatedly for vector %d", + vector); + break; + } + + if (trig_mode) { + apic_debug("level trig mode for vector %d", vector); + apic_set_vector(vector, apic->regs + APIC_TMR); + } else + apic_clear_vector(vector, apic->regs + APIC_TMR); + + if (vcpu->arch.mp_state == VCPU_MP_STATE_RUNNABLE) + kvm_vcpu_kick(vcpu); + else if (vcpu->arch.mp_state == VCPU_MP_STATE_HALTED) { + vcpu->arch.mp_state = VCPU_MP_STATE_RUNNABLE; + if (waitqueue_active(&vcpu->wq)) + wake_up_interruptible(&vcpu->wq); + } + + result = (orig_irr == 0); + break; + + case APIC_DM_REMRD: + printk(KERN_DEBUG "Ignoring delivery mode 3\n"); + break; + + case APIC_DM_SMI: + printk(KERN_DEBUG "Ignoring guest SMI\n"); + break; + case APIC_DM_NMI: + printk(KERN_DEBUG "Ignoring guest NMI\n"); + break; + + case APIC_DM_INIT: + if (level) { + if (vcpu->arch.mp_state == VCPU_MP_STATE_RUNNABLE) + printk(KERN_DEBUG + "INIT on a runnable vcpu %d\n", + vcpu->vcpu_id); + vcpu->arch.mp_state = VCPU_MP_STATE_INIT_RECEIVED; + kvm_vcpu_kick(vcpu); + } else { + printk(KERN_DEBUG + "Ignoring de-assert INIT to vcpu %d\n", + vcpu->vcpu_id); + } + + break; + + case APIC_DM_STARTUP: + printk(KERN_DEBUG "SIPI to vcpu %d vector 0x%02x\n", + vcpu->vcpu_id, vector); + if (vcpu->arch.mp_state == VCPU_MP_STATE_INIT_RECEIVED) { + vcpu->arch.sipi_vector = vector; + vcpu->arch.mp_state = VCPU_MP_STATE_SIPI_RECEIVED; + if (waitqueue_active(&vcpu->wq)) + wake_up_interruptible(&vcpu->wq); + } + break; + + default: + printk(KERN_ERR "TODO: unsupported delivery mode %x\n", + delivery_mode); + break; + } + return result; +} + +static struct kvm_lapic *kvm_apic_round_robin(struct kvm *kvm, u8 vector, + unsigned long bitmap) +{ + int last; + int next; + struct kvm_lapic *apic = NULL; + + last = kvm->arch.round_robin_prev_vcpu; + next = last; + + do { + if (++next == KVM_MAX_VCPUS) + next = 0; + if (kvm->vcpus[next] == NULL || !test_bit(next, &bitmap)) + continue; + apic = kvm->vcpus[next]->arch.apic; + if (apic && apic_enabled(apic)) + break; + apic = NULL; + } while (next != last); + kvm->arch.round_robin_prev_vcpu = next; + + if (!apic) + printk(KERN_DEBUG "vcpu not ready for apic_round_robin\n"); + + return apic; +} + +struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector, + unsigned long bitmap) +{ + struct kvm_lapic *apic; + + apic = kvm_apic_round_robin(kvm, vector, bitmap); + if (apic) + return apic->vcpu; + return NULL; +} + +static void apic_set_eoi(struct kvm_lapic *apic) +{ + int vector = apic_find_highest_isr(apic); + + /* + * Not every write EOI will has corresponding ISR, + * one example is when Kernel check timer on setup_IO_APIC + */ + if (vector == -1) + return; + + apic_clear_vector(vector, apic->regs + APIC_ISR); + apic_update_ppr(apic); + + if (apic_test_and_clear_vector(vector, apic->regs + APIC_TMR)) + kvm_ioapic_update_eoi(apic->vcpu->kvm, vector); +} + +static void apic_send_ipi(struct kvm_lapic *apic) +{ + u32 icr_low = apic_get_reg(apic, APIC_ICR); + u32 icr_high = apic_get_reg(apic, APIC_ICR2); + + unsigned int dest = GET_APIC_DEST_FIELD(icr_high); + unsigned int short_hand = icr_low & APIC_SHORT_MASK; + unsigned int trig_mode = icr_low & APIC_INT_LEVELTRIG; + unsigned int level = icr_low & APIC_INT_ASSERT; + unsigned int dest_mode = icr_low & APIC_DEST_MASK; + unsigned int delivery_mode = icr_low & APIC_MODE_MASK; + unsigned int vector = icr_low & APIC_VECTOR_MASK; + + struct kvm_vcpu *target; + struct kvm_vcpu *vcpu; + unsigned long lpr_map = 0; + int i; + + apic_debug("icr_high 0x%x, icr_low 0x%x, " + "short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, " + "dest_mode 0x%x, delivery_mode 0x%x, vector 0x%x\n", + icr_high, icr_low, short_hand, dest, + trig_mode, level, dest_mode, delivery_mode, vector); + + for (i = 0; i < KVM_MAX_VCPUS; i++) { + vcpu = apic->vcpu->kvm->vcpus[i]; + if (!vcpu) + continue; + + if (vcpu->arch.apic && + apic_match_dest(vcpu, apic, short_hand, dest, dest_mode)) { + if (delivery_mode == APIC_DM_LOWEST) + set_bit(vcpu->vcpu_id, &lpr_map); + else + __apic_accept_irq(vcpu->arch.apic, delivery_mode, + vector, level, trig_mode); + } + } + + if (delivery_mode == APIC_DM_LOWEST) { + target = kvm_get_lowest_prio_vcpu(vcpu->kvm, vector, lpr_map); + if (target != NULL) + __apic_accept_irq(target->arch.apic, delivery_mode, + vector, level, trig_mode); + } +} + +static u32 apic_get_tmcct(struct kvm_lapic *apic) +{ + u64 counter_passed; + ktime_t passed, now; + u32 tmcct; + + ASSERT(apic != NULL); + + now = apic->timer.dev.base->get_time(); + tmcct = apic_get_reg(apic, APIC_TMICT); + + /* if initial count is 0, current count should also be 0 */ + if (tmcct == 0) + return 0; + + if (unlikely(ktime_to_ns(now) <= + ktime_to_ns(apic->timer.last_update))) { + /* Wrap around */ + passed = ktime_add(( { + (ktime_t) { + .tv64 = KTIME_MAX - + (apic->timer.last_update).tv64}; } + ), now); + apic_debug("time elapsed\n"); + } else + passed = ktime_sub(now, apic->timer.last_update); + + counter_passed = div64_64(ktime_to_ns(passed), + (APIC_BUS_CYCLE_NS * apic->timer.divide_count)); + + if (counter_passed > tmcct) { + if (unlikely(!apic_lvtt_period(apic))) { + /* one-shot timers stick at 0 until reset */ + tmcct = 0; + } else { + /* + * periodic timers reset to APIC_TMICT when they + * hit 0. The while loop simulates this happening N + * times. (counter_passed %= tmcct) would also work, + * but might be slower or not work on 32-bit?? + */ + while (counter_passed > tmcct) + counter_passed -= tmcct; + tmcct -= counter_passed; + } + } else { + tmcct -= counter_passed; + } + + return tmcct; +} + +static void __report_tpr_access(struct kvm_lapic *apic, bool write) +{ + struct kvm_vcpu *vcpu = apic->vcpu; + struct kvm_run *run = vcpu->run; + + set_bit(KVM_REQ_REPORT_TPR_ACCESS, &vcpu->requests); + kvm_x86_ops->cache_regs(vcpu); + run->tpr_access.rip = vcpu->arch.rip; + run->tpr_access.is_write = write; +} + +static inline void report_tpr_access(struct kvm_lapic *apic, bool write) +{ + if (apic->vcpu->arch.tpr_access_reporting) + __report_tpr_access(apic, write); +} + +static u32 __apic_read(struct kvm_lapic *apic, unsigned int offset) +{ + u32 val = 0; + + if (offset >= LAPIC_MMIO_LENGTH) + return 0; + + switch (offset) { + case APIC_ARBPRI: + printk(KERN_WARNING "Access APIC ARBPRI register " + "which is for P6\n"); + break; + + case APIC_TMCCT: /* Timer CCR */ + val = apic_get_tmcct(apic); + break; + + case APIC_TASKPRI: + report_tpr_access(apic, false); + /* fall thru */ + default: + apic_update_ppr(apic); + val = apic_get_reg(apic, offset); + break; + } + + return val; +} + +static void apic_mmio_read(struct kvm_io_device *this, + gpa_t address, int len, void *data) +{ + struct kvm_lapic *apic = (struct kvm_lapic *)this->private; + unsigned int offset = address - apic->base_address; + unsigned char alignment = offset & 0xf; + u32 result; + + if ((alignment + len) > 4) { + printk(KERN_ERR "KVM_APIC_READ: alignment error %lx %d", + (unsigned long)address, len); + return; + } + result = __apic_read(apic, offset & ~0xf); + + switch (len) { + case 1: + case 2: + case 4: + memcpy(data, (char *)&result + alignment, len); + break; + default: + printk(KERN_ERR "Local APIC read with len = %x, " + "should be 1,2, or 4 instead\n", len); + break; + } +} + +static void update_divide_count(struct kvm_lapic *apic) +{ + u32 tmp1, tmp2, tdcr; + + tdcr = apic_get_reg(apic, APIC_TDCR); + tmp1 = tdcr & 0xf; + tmp2 = ((tmp1 & 0x3) | ((tmp1 & 0x8) >> 1)) + 1; + apic->timer.divide_count = 0x1 << (tmp2 & 0x7); + + apic_debug("timer divide count is 0x%x\n", + apic->timer.divide_count); +} + +static void start_apic_timer(struct kvm_lapic *apic) +{ + ktime_t now = apic->timer.dev.base->get_time(); + + apic->timer.last_update = now; + + apic->timer.period = apic_get_reg(apic, APIC_TMICT) * + APIC_BUS_CYCLE_NS * apic->timer.divide_count; + atomic_set(&apic->timer.pending, 0); + + if (!apic->timer.period) + return; + + hrtimer_start(&apic->timer.dev, + ktime_add_ns(now, apic->timer.period), + HRTIMER_MODE_ABS); + + apic_debug("%s: bus cycle is %" PRId64 "ns, now 0x%016" + PRIx64 ", " + "timer initial count 0x%x, period %lldns, " + "expire @ 0x%016" PRIx64 ".\n", __FUNCTION__, + APIC_BUS_CYCLE_NS, ktime_to_ns(now), + apic_get_reg(apic, APIC_TMICT), + apic->timer.period, + ktime_to_ns(ktime_add_ns(now, + apic->timer.period))); +} + +static void apic_mmio_write(struct kvm_io_device *this, + gpa_t address, int len, const void *data) +{ + struct kvm_lapic *apic = (struct kvm_lapic *)this->private; + unsigned int offset = address - apic->base_address; + unsigned char alignment = offset & 0xf; + u32 val; + + /* + * APIC register must be aligned on 128-bits boundary. + * 32/64/128 bits registers must be accessed thru 32 bits. + * Refer SDM 8.4.1 + */ + if (len != 4 || alignment) { + if (printk_ratelimit()) + printk(KERN_ERR "apic write: bad size=%d %lx\n", + len, (long)address); + return; + } + + val = *(u32 *) data; + + /* too common printing */ + if (offset != APIC_EOI) + apic_debug("%s: offset 0x%x with length 0x%x, and value is " + "0x%x\n", __FUNCTION__, offset, len, val); + + offset &= 0xff0; + + switch (offset) { + case APIC_ID: /* Local APIC ID */ + apic_set_reg(apic, APIC_ID, val); + break; + + case APIC_TASKPRI: + report_tpr_access(apic, true); + apic_set_tpr(apic, val & 0xff); + break; + + case APIC_EOI: + apic_set_eoi(apic); + break; + + case APIC_LDR: + apic_set_reg(apic, APIC_LDR, val & APIC_LDR_MASK); + break; + + case APIC_DFR: + apic_set_reg(apic, APIC_DFR, val | 0x0FFFFFFF); + break; + + case APIC_SPIV: + apic_set_reg(apic, APIC_SPIV, val & 0x3ff); + if (!(val & APIC_SPIV_APIC_ENABLED)) { + int i; + u32 lvt_val; + + for (i = 0; i < APIC_LVT_NUM; i++) { + lvt_val = apic_get_reg(apic, + APIC_LVTT + 0x10 * i); + apic_set_reg(apic, APIC_LVTT + 0x10 * i, + lvt_val | APIC_LVT_MASKED); + } + atomic_set(&apic->timer.pending, 0); + + } + break; + + case APIC_ICR: + /* No delay here, so we always clear the pending bit */ + apic_set_reg(apic, APIC_ICR, val & ~(1 << 12)); + apic_send_ipi(apic); + break; + + case APIC_ICR2: + apic_set_reg(apic, APIC_ICR2, val & 0xff000000); + break; + + case APIC_LVTT: + case APIC_LVTTHMR: + case APIC_LVTPC: + case APIC_LVT0: + case APIC_LVT1: + case APIC_LVTERR: + /* TODO: Check vector */ + if (!apic_sw_enabled(apic)) + val |= APIC_LVT_MASKED; + + val &= apic_lvt_mask[(offset - APIC_LVTT) >> 4]; + apic_set_reg(apic, offset, val); + + break; + + case APIC_TMICT: + hrtimer_cancel(&apic->timer.dev); + apic_set_reg(apic, APIC_TMICT, val); + start_apic_timer(apic); + return; + + case APIC_TDCR: + if (val & 4) + printk(KERN_ERR "KVM_WRITE:TDCR %x\n", val); + apic_set_reg(apic, APIC_TDCR, val); + update_divide_count(apic); + break; + + default: + apic_debug("Local APIC Write to read-only register %x\n", + offset); + break; + } + +} + +static int apic_mmio_range(struct kvm_io_device *this, gpa_t addr) +{ + struct kvm_lapic *apic = (struct kvm_lapic *)this->private; + int ret = 0; + + + if (apic_hw_enabled(apic) && + (addr >= apic->base_address) && + (addr < (apic->base_address + LAPIC_MMIO_LENGTH))) + ret = 1; + + return ret; +} + +void kvm_free_lapic(struct kvm_vcpu *vcpu) +{ + if (!vcpu->arch.apic) + return; + + hrtimer_cancel(&vcpu->arch.apic->timer.dev); + + if (vcpu->arch.apic->regs_page) + __free_page(vcpu->arch.apic->regs_page); + + kfree(vcpu->arch.apic); +} + +/* + *---------------------------------------------------------------------- + * LAPIC interface + *---------------------------------------------------------------------- + */ + +void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8) +{ + struct kvm_lapic *apic = vcpu->arch.apic; + + if (!apic) + return; + apic_set_tpr(apic, ((cr8 & 0x0f) << 4) + | (apic_get_reg(apic, APIC_TASKPRI) & 4)); +} + +u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu) +{ + struct kvm_lapic *apic = vcpu->arch.apic; + u64 tpr; + + if (!apic) + return 0; + tpr = (u64) apic_get_reg(apic, APIC_TASKPRI); + + return (tpr & 0xf0) >> 4; +} +EXPORT_SYMBOL_GPL(kvm_lapic_get_cr8); + +void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) +{ + struct kvm_lapic *apic = vcpu->arch.apic; + + if (!apic) { + value |= MSR_IA32_APICBASE_BSP; + vcpu->arch.apic_base = value; + return; + } + if (apic->vcpu->vcpu_id) + value &= ~MSR_IA32_APICBASE_BSP; + + vcpu->arch.apic_base = value; + apic->base_address = apic->vcpu->arch.apic_base & + MSR_IA32_APICBASE_BASE; + + /* with FSB delivery interrupt, we can restart APIC functionality */ + apic_debug("apic base msr is 0x%016" PRIx64 ", and base address is " + "0x%lx.\n", apic->vcpu->arch.apic_base, apic->base_address); + +} + +u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.apic_base; +} +EXPORT_SYMBOL_GPL(kvm_lapic_get_base); + +void kvm_lapic_reset(struct kvm_vcpu *vcpu) +{ + struct kvm_lapic *apic; + int i; + + apic_debug("%s\n", __FUNCTION__); + + ASSERT(vcpu); + apic = vcpu->arch.apic; + ASSERT(apic != NULL); + + /* Stop the timer in case it's a reset to an active apic */ + hrtimer_cancel(&apic->timer.dev); + + apic_set_reg(apic, APIC_ID, vcpu->vcpu_id << 24); + apic_set_reg(apic, APIC_LVR, APIC_VERSION); + + for (i = 0; i < APIC_LVT_NUM; i++) + apic_set_reg(apic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED); + apic_set_reg(apic, APIC_LVT0, + SET_APIC_DELIVERY_MODE(0, APIC_MODE_EXTINT)); + + apic_set_reg(apic, APIC_DFR, 0xffffffffU); + apic_set_reg(apic, APIC_SPIV, 0xff); + apic_set_reg(apic, APIC_TASKPRI, 0); + apic_set_reg(apic, APIC_LDR, 0); + apic_set_reg(apic, APIC_ESR, 0); + apic_set_reg(apic, APIC_ICR, 0); + apic_set_reg(apic, APIC_ICR2, 0); + apic_set_reg(apic, APIC_TDCR, 0); + apic_set_reg(apic, APIC_TMICT, 0); + for (i = 0; i < 8; i++) { + apic_set_reg(apic, APIC_IRR + 0x10 * i, 0); + apic_set_reg(apic, APIC_ISR + 0x10 * i, 0); + apic_set_reg(apic, APIC_TMR + 0x10 * i, 0); + } + update_divide_count(apic); + atomic_set(&apic->timer.pending, 0); + if (vcpu->vcpu_id == 0) + vcpu->arch.apic_base |= MSR_IA32_APICBASE_BSP; + apic_update_ppr(apic); + + apic_debug(KERN_INFO "%s: vcpu=%p, id=%d, base_msr=" + "0x%016" PRIx64 ", base_address=0x%0lx.\n", __FUNCTION__, + vcpu, kvm_apic_id(apic), + vcpu->arch.apic_base, apic->base_address); +} +EXPORT_SYMBOL_GPL(kvm_lapic_reset); + +int kvm_lapic_enabled(struct kvm_vcpu *vcpu) +{ + struct kvm_lapic *apic = vcpu->arch.apic; + int ret = 0; + + if (!apic) + return 0; + ret = apic_enabled(apic); + + return ret; +} +EXPORT_SYMBOL_GPL(kvm_lapic_enabled); + +/* + *---------------------------------------------------------------------- + * timer interface + *---------------------------------------------------------------------- + */ + +/* TODO: make sure __apic_timer_fn runs in current pCPU */ +static int __apic_timer_fn(struct kvm_lapic *apic) +{ + int result = 0; + wait_queue_head_t *q = &apic->vcpu->wq; + + atomic_inc(&apic->timer.pending); + if (waitqueue_active(q)) { + apic->vcpu->arch.mp_state = VCPU_MP_STATE_RUNNABLE; + wake_up_interruptible(q); + } + if (apic_lvtt_period(apic)) { + result = 1; + apic->timer.dev.expires = ktime_add_ns( + apic->timer.dev.expires, + apic->timer.period); + } + return result; +} + +static int __inject_apic_timer_irq(struct kvm_lapic *apic) +{ + int vector; + + vector = apic_lvt_vector(apic, APIC_LVTT); + return __apic_accept_irq(apic, APIC_DM_FIXED, vector, 1, 0); +} + +static enum hrtimer_restart apic_timer_fn(struct hrtimer *data) +{ + struct kvm_lapic *apic; + int restart_timer = 0; + + apic = container_of(data, struct kvm_lapic, timer.dev); + + restart_timer = __apic_timer_fn(apic); + + if (restart_timer) + return HRTIMER_RESTART; + else + return HRTIMER_NORESTART; +} + +int kvm_create_lapic(struct kvm_vcpu *vcpu) +{ + struct kvm_lapic *apic; + + ASSERT(vcpu != NULL); + apic_debug("apic_init %d\n", vcpu->vcpu_id); + + apic = kzalloc(sizeof(*apic), GFP_KERNEL); + if (!apic) + goto nomem; + + vcpu->arch.apic = apic; + + apic->regs_page = alloc_page(GFP_KERNEL); + if (apic->regs_page == NULL) { + printk(KERN_ERR "malloc apic regs error for vcpu %x\n", + vcpu->vcpu_id); + goto nomem_free_apic; + } + apic->regs = page_address(apic->regs_page); + memset(apic->regs, 0, PAGE_SIZE); + apic->vcpu = vcpu; + + hrtimer_init(&apic->timer.dev, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); + apic->timer.dev.function = apic_timer_fn; + apic->base_address = APIC_DEFAULT_PHYS_BASE; + vcpu->arch.apic_base = APIC_DEFAULT_PHYS_BASE; + + kvm_lapic_reset(vcpu); + apic->dev.read = apic_mmio_read; + apic->dev.write = apic_mmio_write; + apic->dev.in_range = apic_mmio_range; + apic->dev.private = apic; + + return 0; +nomem_free_apic: + kfree(apic); +nomem: + return -ENOMEM; +} +EXPORT_SYMBOL_GPL(kvm_create_lapic); + +int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu) +{ + struct kvm_lapic *apic = vcpu->arch.apic; + int highest_irr; + + if (!apic || !apic_enabled(apic)) + return -1; + + apic_update_ppr(apic); + highest_irr = apic_find_highest_irr(apic); + if ((highest_irr == -1) || + ((highest_irr & 0xF0) <= apic_get_reg(apic, APIC_PROCPRI))) + return -1; + return highest_irr; +} + +int kvm_apic_accept_pic_intr(struct kvm_vcpu *vcpu) +{ + u32 lvt0 = apic_get_reg(vcpu->arch.apic, APIC_LVT0); + int r = 0; + + if (vcpu->vcpu_id == 0) { + if (!apic_hw_enabled(vcpu->arch.apic)) + r = 1; + if ((lvt0 & APIC_LVT_MASKED) == 0 && + GET_APIC_DELIVERY_MODE(lvt0) == APIC_MODE_EXTINT) + r = 1; + } + return r; +} + +void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu) +{ + struct kvm_lapic *apic = vcpu->arch.apic; + + if (apic && apic_lvt_enabled(apic, APIC_LVTT) && + atomic_read(&apic->timer.pending) > 0) { + if (__inject_apic_timer_irq(apic)) + atomic_dec(&apic->timer.pending); + } +} + +void kvm_apic_timer_intr_post(struct kvm_vcpu *vcpu, int vec) +{ + struct kvm_lapic *apic = vcpu->arch.apic; + + if (apic && apic_lvt_vector(apic, APIC_LVTT) == vec) + apic->timer.last_update = ktime_add_ns( + apic->timer.last_update, + apic->timer.period); +} + +int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu) +{ + int vector = kvm_apic_has_interrupt(vcpu); + struct kvm_lapic *apic = vcpu->arch.apic; + + if (vector == -1) + return -1; + + apic_set_vector(vector, apic->regs + APIC_ISR); + apic_update_ppr(apic); + apic_clear_irr(vector, apic); + return vector; +} + +void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu) +{ + struct kvm_lapic *apic = vcpu->arch.apic; + + apic->base_address = vcpu->arch.apic_base & + MSR_IA32_APICBASE_BASE; + apic_set_reg(apic, APIC_LVR, APIC_VERSION); + apic_update_ppr(apic); + hrtimer_cancel(&apic->timer.dev); + update_divide_count(apic); + start_apic_timer(apic); +} + +void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu) +{ + struct kvm_lapic *apic = vcpu->arch.apic; + struct hrtimer *timer; + + if (!apic) + return; + + timer = &apic->timer.dev; + if (hrtimer_cancel(timer)) + hrtimer_start(timer, timer->expires, HRTIMER_MODE_ABS); +} + +void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu) +{ + u32 data; + void *vapic; + + if (!irqchip_in_kernel(vcpu->kvm) || !vcpu->arch.apic->vapic_addr) + return; + + vapic = kmap_atomic(vcpu->arch.apic->vapic_page, KM_USER0); + data = *(u32 *)(vapic + offset_in_page(vcpu->arch.apic->vapic_addr)); + kunmap_atomic(vapic, KM_USER0); + + apic_set_tpr(vcpu->arch.apic, data & 0xff); +} + +void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu) +{ + u32 data, tpr; + int max_irr, max_isr; + struct kvm_lapic *apic; + void *vapic; + + if (!irqchip_in_kernel(vcpu->kvm) || !vcpu->arch.apic->vapic_addr) + return; + + apic = vcpu->arch.apic; + tpr = apic_get_reg(apic, APIC_TASKPRI) & 0xff; + max_irr = apic_find_highest_irr(apic); + if (max_irr < 0) + max_irr = 0; + max_isr = apic_find_highest_isr(apic); + if (max_isr < 0) + max_isr = 0; + data = (tpr & 0xff) | ((max_isr & 0xf0) << 8) | (max_irr << 24); + + vapic = kmap_atomic(vcpu->arch.apic->vapic_page, KM_USER0); + *(u32 *)(vapic + offset_in_page(vcpu->arch.apic->vapic_addr)) = data; + kunmap_atomic(vapic, KM_USER0); +} + +void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr) +{ + if (!irqchip_in_kernel(vcpu->kvm)) + return; + + vcpu->arch.apic->vapic_addr = vapic_addr; +} --- linux-2.6.24.orig/arch/x86/kvm/vmx.h +++ linux-2.6.24/arch/x86/kvm/vmx.h @@ -0,0 +1,330 @@ +#ifndef VMX_H +#define VMX_H + +/* + * vmx.h: VMX Architecture related definitions + * Copyright (c) 2004, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * A few random additions are: + * Copyright (C) 2006 Qumranet + * Avi Kivity + * Yaniv Kamay + * + */ + +/* + * Definitions of Primary Processor-Based VM-Execution Controls. + */ +#define CPU_BASED_VIRTUAL_INTR_PENDING 0x00000004 +#define CPU_BASED_USE_TSC_OFFSETING 0x00000008 +#define CPU_BASED_HLT_EXITING 0x00000080 +#define CPU_BASED_INVLPG_EXITING 0x00000200 +#define CPU_BASED_MWAIT_EXITING 0x00000400 +#define CPU_BASED_RDPMC_EXITING 0x00000800 +#define CPU_BASED_RDTSC_EXITING 0x00001000 +#define CPU_BASED_CR8_LOAD_EXITING 0x00080000 +#define CPU_BASED_CR8_STORE_EXITING 0x00100000 +#define CPU_BASED_TPR_SHADOW 0x00200000 +#define CPU_BASED_MOV_DR_EXITING 0x00800000 +#define CPU_BASED_UNCOND_IO_EXITING 0x01000000 +#define CPU_BASED_USE_IO_BITMAPS 0x02000000 +#define CPU_BASED_USE_MSR_BITMAPS 0x10000000 +#define CPU_BASED_MONITOR_EXITING 0x20000000 +#define CPU_BASED_PAUSE_EXITING 0x40000000 +#define CPU_BASED_ACTIVATE_SECONDARY_CONTROLS 0x80000000 +/* + * Definitions of Secondary Processor-Based VM-Execution Controls. + */ +#define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001 +#define SECONDARY_EXEC_ENABLE_VPID 0x00000020 +#define SECONDARY_EXEC_WBINVD_EXITING 0x00000040 + + +#define PIN_BASED_EXT_INTR_MASK 0x00000001 +#define PIN_BASED_NMI_EXITING 0x00000008 +#define PIN_BASED_VIRTUAL_NMIS 0x00000020 + +#define VM_EXIT_HOST_ADDR_SPACE_SIZE 0x00000200 +#define VM_EXIT_ACK_INTR_ON_EXIT 0x00008000 + +#define VM_ENTRY_IA32E_MODE 0x00000200 +#define VM_ENTRY_SMM 0x00000400 +#define VM_ENTRY_DEACT_DUAL_MONITOR 0x00000800 + +/* VMCS Encodings */ +enum vmcs_field { + VIRTUAL_PROCESSOR_ID = 0x00000000, + GUEST_ES_SELECTOR = 0x00000800, + GUEST_CS_SELECTOR = 0x00000802, + GUEST_SS_SELECTOR = 0x00000804, + GUEST_DS_SELECTOR = 0x00000806, + GUEST_FS_SELECTOR = 0x00000808, + GUEST_GS_SELECTOR = 0x0000080a, + GUEST_LDTR_SELECTOR = 0x0000080c, + GUEST_TR_SELECTOR = 0x0000080e, + HOST_ES_SELECTOR = 0x00000c00, + HOST_CS_SELECTOR = 0x00000c02, + HOST_SS_SELECTOR = 0x00000c04, + HOST_DS_SELECTOR = 0x00000c06, + HOST_FS_SELECTOR = 0x00000c08, + HOST_GS_SELECTOR = 0x00000c0a, + HOST_TR_SELECTOR = 0x00000c0c, + IO_BITMAP_A = 0x00002000, + IO_BITMAP_A_HIGH = 0x00002001, + IO_BITMAP_B = 0x00002002, + IO_BITMAP_B_HIGH = 0x00002003, + MSR_BITMAP = 0x00002004, + MSR_BITMAP_HIGH = 0x00002005, + VM_EXIT_MSR_STORE_ADDR = 0x00002006, + VM_EXIT_MSR_STORE_ADDR_HIGH = 0x00002007, + VM_EXIT_MSR_LOAD_ADDR = 0x00002008, + VM_EXIT_MSR_LOAD_ADDR_HIGH = 0x00002009, + VM_ENTRY_MSR_LOAD_ADDR = 0x0000200a, + VM_ENTRY_MSR_LOAD_ADDR_HIGH = 0x0000200b, + TSC_OFFSET = 0x00002010, + TSC_OFFSET_HIGH = 0x00002011, + VIRTUAL_APIC_PAGE_ADDR = 0x00002012, + VIRTUAL_APIC_PAGE_ADDR_HIGH = 0x00002013, + APIC_ACCESS_ADDR = 0x00002014, + APIC_ACCESS_ADDR_HIGH = 0x00002015, + VMCS_LINK_POINTER = 0x00002800, + VMCS_LINK_POINTER_HIGH = 0x00002801, + GUEST_IA32_DEBUGCTL = 0x00002802, + GUEST_IA32_DEBUGCTL_HIGH = 0x00002803, + PIN_BASED_VM_EXEC_CONTROL = 0x00004000, + CPU_BASED_VM_EXEC_CONTROL = 0x00004002, + EXCEPTION_BITMAP = 0x00004004, + PAGE_FAULT_ERROR_CODE_MASK = 0x00004006, + PAGE_FAULT_ERROR_CODE_MATCH = 0x00004008, + CR3_TARGET_COUNT = 0x0000400a, + VM_EXIT_CONTROLS = 0x0000400c, + VM_EXIT_MSR_STORE_COUNT = 0x0000400e, + VM_EXIT_MSR_LOAD_COUNT = 0x00004010, + VM_ENTRY_CONTROLS = 0x00004012, + VM_ENTRY_MSR_LOAD_COUNT = 0x00004014, + VM_ENTRY_INTR_INFO_FIELD = 0x00004016, + VM_ENTRY_EXCEPTION_ERROR_CODE = 0x00004018, + VM_ENTRY_INSTRUCTION_LEN = 0x0000401a, + TPR_THRESHOLD = 0x0000401c, + SECONDARY_VM_EXEC_CONTROL = 0x0000401e, + VM_INSTRUCTION_ERROR = 0x00004400, + VM_EXIT_REASON = 0x00004402, + VM_EXIT_INTR_INFO = 0x00004404, + VM_EXIT_INTR_ERROR_CODE = 0x00004406, + IDT_VECTORING_INFO_FIELD = 0x00004408, + IDT_VECTORING_ERROR_CODE = 0x0000440a, + VM_EXIT_INSTRUCTION_LEN = 0x0000440c, + VMX_INSTRUCTION_INFO = 0x0000440e, + GUEST_ES_LIMIT = 0x00004800, + GUEST_CS_LIMIT = 0x00004802, + GUEST_SS_LIMIT = 0x00004804, + GUEST_DS_LIMIT = 0x00004806, + GUEST_FS_LIMIT = 0x00004808, + GUEST_GS_LIMIT = 0x0000480a, + GUEST_LDTR_LIMIT = 0x0000480c, + GUEST_TR_LIMIT = 0x0000480e, + GUEST_GDTR_LIMIT = 0x00004810, + GUEST_IDTR_LIMIT = 0x00004812, + GUEST_ES_AR_BYTES = 0x00004814, + GUEST_CS_AR_BYTES = 0x00004816, + GUEST_SS_AR_BYTES = 0x00004818, + GUEST_DS_AR_BYTES = 0x0000481a, + GUEST_FS_AR_BYTES = 0x0000481c, + GUEST_GS_AR_BYTES = 0x0000481e, + GUEST_LDTR_AR_BYTES = 0x00004820, + GUEST_TR_AR_BYTES = 0x00004822, + GUEST_INTERRUPTIBILITY_INFO = 0x00004824, + GUEST_ACTIVITY_STATE = 0X00004826, + GUEST_SYSENTER_CS = 0x0000482A, + HOST_IA32_SYSENTER_CS = 0x00004c00, + CR0_GUEST_HOST_MASK = 0x00006000, + CR4_GUEST_HOST_MASK = 0x00006002, + CR0_READ_SHADOW = 0x00006004, + CR4_READ_SHADOW = 0x00006006, + CR3_TARGET_VALUE0 = 0x00006008, + CR3_TARGET_VALUE1 = 0x0000600a, + CR3_TARGET_VALUE2 = 0x0000600c, + CR3_TARGET_VALUE3 = 0x0000600e, + EXIT_QUALIFICATION = 0x00006400, + GUEST_LINEAR_ADDRESS = 0x0000640a, + GUEST_CR0 = 0x00006800, + GUEST_CR3 = 0x00006802, + GUEST_CR4 = 0x00006804, + GUEST_ES_BASE = 0x00006806, + GUEST_CS_BASE = 0x00006808, + GUEST_SS_BASE = 0x0000680a, + GUEST_DS_BASE = 0x0000680c, + GUEST_FS_BASE = 0x0000680e, + GUEST_GS_BASE = 0x00006810, + GUEST_LDTR_BASE = 0x00006812, + GUEST_TR_BASE = 0x00006814, + GUEST_GDTR_BASE = 0x00006816, + GUEST_IDTR_BASE = 0x00006818, + GUEST_DR7 = 0x0000681a, + GUEST_RSP = 0x0000681c, + GUEST_RIP = 0x0000681e, + GUEST_RFLAGS = 0x00006820, + GUEST_PENDING_DBG_EXCEPTIONS = 0x00006822, + GUEST_SYSENTER_ESP = 0x00006824, + GUEST_SYSENTER_EIP = 0x00006826, + HOST_CR0 = 0x00006c00, + HOST_CR3 = 0x00006c02, + HOST_CR4 = 0x00006c04, + HOST_FS_BASE = 0x00006c06, + HOST_GS_BASE = 0x00006c08, + HOST_TR_BASE = 0x00006c0a, + HOST_GDTR_BASE = 0x00006c0c, + HOST_IDTR_BASE = 0x00006c0e, + HOST_IA32_SYSENTER_ESP = 0x00006c10, + HOST_IA32_SYSENTER_EIP = 0x00006c12, + HOST_RSP = 0x00006c14, + HOST_RIP = 0x00006c16, +}; + +#define VMX_EXIT_REASONS_FAILED_VMENTRY 0x80000000 + +#define EXIT_REASON_EXCEPTION_NMI 0 +#define EXIT_REASON_EXTERNAL_INTERRUPT 1 +#define EXIT_REASON_TRIPLE_FAULT 2 + +#define EXIT_REASON_PENDING_INTERRUPT 7 + +#define EXIT_REASON_TASK_SWITCH 9 +#define EXIT_REASON_CPUID 10 +#define EXIT_REASON_HLT 12 +#define EXIT_REASON_INVLPG 14 +#define EXIT_REASON_RDPMC 15 +#define EXIT_REASON_RDTSC 16 +#define EXIT_REASON_VMCALL 18 +#define EXIT_REASON_VMCLEAR 19 +#define EXIT_REASON_VMLAUNCH 20 +#define EXIT_REASON_VMPTRLD 21 +#define EXIT_REASON_VMPTRST 22 +#define EXIT_REASON_VMREAD 23 +#define EXIT_REASON_VMRESUME 24 +#define EXIT_REASON_VMWRITE 25 +#define EXIT_REASON_VMOFF 26 +#define EXIT_REASON_VMON 27 +#define EXIT_REASON_CR_ACCESS 28 +#define EXIT_REASON_DR_ACCESS 29 +#define EXIT_REASON_IO_INSTRUCTION 30 +#define EXIT_REASON_MSR_READ 31 +#define EXIT_REASON_MSR_WRITE 32 +#define EXIT_REASON_MWAIT_INSTRUCTION 36 +#define EXIT_REASON_TPR_BELOW_THRESHOLD 43 +#define EXIT_REASON_APIC_ACCESS 44 +#define EXIT_REASON_WBINVD 54 + +/* + * Interruption-information format + */ +#define INTR_INFO_VECTOR_MASK 0xff /* 7:0 */ +#define INTR_INFO_INTR_TYPE_MASK 0x700 /* 10:8 */ +#define INTR_INFO_DELIVER_CODE_MASK 0x800 /* 11 */ +#define INTR_INFO_VALID_MASK 0x80000000 /* 31 */ + +#define VECTORING_INFO_VECTOR_MASK INTR_INFO_VECTOR_MASK +#define VECTORING_INFO_TYPE_MASK INTR_INFO_INTR_TYPE_MASK +#define VECTORING_INFO_DELIVER_CODE_MASK INTR_INFO_DELIVER_CODE_MASK +#define VECTORING_INFO_VALID_MASK INTR_INFO_VALID_MASK + +#define INTR_TYPE_EXT_INTR (0 << 8) /* external interrupt */ +#define INTR_TYPE_EXCEPTION (3 << 8) /* processor exception */ +#define INTR_TYPE_SOFT_INTR (4 << 8) /* software interrupt */ + +/* + * Exit Qualifications for MOV for Control Register Access + */ +#define CONTROL_REG_ACCESS_NUM 0x7 /* 2:0, number of control reg.*/ +#define CONTROL_REG_ACCESS_TYPE 0x30 /* 5:4, access type */ +#define CONTROL_REG_ACCESS_REG 0xf00 /* 10:8, general purpose reg. */ +#define LMSW_SOURCE_DATA_SHIFT 16 +#define LMSW_SOURCE_DATA (0xFFFF << LMSW_SOURCE_DATA_SHIFT) /* 16:31 lmsw source */ +#define REG_EAX (0 << 8) +#define REG_ECX (1 << 8) +#define REG_EDX (2 << 8) +#define REG_EBX (3 << 8) +#define REG_ESP (4 << 8) +#define REG_EBP (5 << 8) +#define REG_ESI (6 << 8) +#define REG_EDI (7 << 8) +#define REG_R8 (8 << 8) +#define REG_R9 (9 << 8) +#define REG_R10 (10 << 8) +#define REG_R11 (11 << 8) +#define REG_R12 (12 << 8) +#define REG_R13 (13 << 8) +#define REG_R14 (14 << 8) +#define REG_R15 (15 << 8) + +/* + * Exit Qualifications for MOV for Debug Register Access + */ +#define DEBUG_REG_ACCESS_NUM 0x7 /* 2:0, number of debug reg. */ +#define DEBUG_REG_ACCESS_TYPE 0x10 /* 4, direction of access */ +#define TYPE_MOV_TO_DR (0 << 4) +#define TYPE_MOV_FROM_DR (1 << 4) +#define DEBUG_REG_ACCESS_REG 0xf00 /* 11:8, general purpose reg. */ + + +/* segment AR */ +#define SEGMENT_AR_L_MASK (1 << 13) + +#define AR_TYPE_ACCESSES_MASK 1 +#define AR_TYPE_READABLE_MASK (1 << 1) +#define AR_TYPE_WRITEABLE_MASK (1 << 2) +#define AR_TYPE_CODE_MASK (1 << 3) +#define AR_TYPE_MASK 0x0f +#define AR_TYPE_BUSY_64_TSS 11 +#define AR_TYPE_BUSY_32_TSS 11 +#define AR_TYPE_BUSY_16_TSS 3 +#define AR_TYPE_LDT 2 + +#define AR_UNUSABLE_MASK (1 << 16) +#define AR_S_MASK (1 << 4) +#define AR_P_MASK (1 << 7) +#define AR_L_MASK (1 << 13) +#define AR_DB_MASK (1 << 14) +#define AR_G_MASK (1 << 15) +#define AR_DPL_SHIFT 5 +#define AR_DPL(ar) (((ar) >> AR_DPL_SHIFT) & 3) + +#define AR_RESERVD_MASK 0xfffe0f00 + +#define MSR_IA32_VMX_BASIC 0x480 +#define MSR_IA32_VMX_PINBASED_CTLS 0x481 +#define MSR_IA32_VMX_PROCBASED_CTLS 0x482 +#define MSR_IA32_VMX_EXIT_CTLS 0x483 +#define MSR_IA32_VMX_ENTRY_CTLS 0x484 +#define MSR_IA32_VMX_MISC 0x485 +#define MSR_IA32_VMX_CR0_FIXED0 0x486 +#define MSR_IA32_VMX_CR0_FIXED1 0x487 +#define MSR_IA32_VMX_CR4_FIXED0 0x488 +#define MSR_IA32_VMX_CR4_FIXED1 0x489 +#define MSR_IA32_VMX_VMCS_ENUM 0x48a +#define MSR_IA32_VMX_PROCBASED_CTLS2 0x48b + +#define MSR_IA32_FEATURE_CONTROL 0x3a +#define MSR_IA32_FEATURE_CONTROL_LOCKED 0x1 +#define MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED 0x4 + +#define APIC_ACCESS_PAGE_PRIVATE_MEMSLOT 9 + +#define VMX_NR_VPIDS (1 << 16) +#define VMX_VPID_EXTENT_SINGLE_CONTEXT 1 +#define VMX_VPID_EXTENT_ALL_CONTEXT 2 + +#endif --- linux-2.6.24.orig/arch/x86/kvm/vmx.c +++ linux-2.6.24/arch/x86/kvm/vmx.c @@ -0,0 +1,2747 @@ +/* + * Kernel-based Virtual Machine driver for Linux + * + * This module enables machines with Intel VT-x extensions to run virtual + * machines without emulation or binary translation. + * + * Copyright (C) 2006 Qumranet, Inc. + * + * Authors: + * Avi Kivity + * Yaniv Kamay + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#include "irq.h" +#include "vmx.h" +#include "segment_descriptor.h" +#include "mmu.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +MODULE_AUTHOR("Qumranet"); +MODULE_LICENSE("GPL"); + +static int bypass_guest_pf = 1; +module_param(bypass_guest_pf, bool, 0); + +static int enable_vpid = 1; +module_param(enable_vpid, bool, 0); + +struct vmcs { + u32 revision_id; + u32 abort; + char data[0]; +}; + +struct vcpu_vmx { + struct kvm_vcpu vcpu; + int launched; + u8 fail; + u32 idt_vectoring_info; + struct kvm_msr_entry *guest_msrs; + struct kvm_msr_entry *host_msrs; + int nmsrs; + int save_nmsrs; + int msr_offset_efer; +#ifdef CONFIG_X86_64 + int msr_offset_kernel_gs_base; +#endif + struct vmcs *vmcs; + struct { + int loaded; + u16 fs_sel, gs_sel, ldt_sel; + int gs_ldt_reload_needed; + int fs_reload_needed; + int guest_efer_loaded; + } host_state; + struct { + struct { + bool pending; + u8 vector; + unsigned rip; + } irq; + } rmode; + int vpid; +}; + +static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu) +{ + return container_of(vcpu, struct vcpu_vmx, vcpu); +} + +static int init_rmode_tss(struct kvm *kvm); + +static DEFINE_PER_CPU(struct vmcs *, vmxarea); +static DEFINE_PER_CPU(struct vmcs *, current_vmcs); + +static struct page *vmx_io_bitmap_a; +static struct page *vmx_io_bitmap_b; + +static DECLARE_BITMAP(vmx_vpid_bitmap, VMX_NR_VPIDS); +static DEFINE_SPINLOCK(vmx_vpid_lock); + +static struct vmcs_config { + int size; + int order; + u32 revision_id; + u32 pin_based_exec_ctrl; + u32 cpu_based_exec_ctrl; + u32 cpu_based_2nd_exec_ctrl; + u32 vmexit_ctrl; + u32 vmentry_ctrl; +} vmcs_config; + +#define VMX_SEGMENT_FIELD(seg) \ + [VCPU_SREG_##seg] = { \ + .selector = GUEST_##seg##_SELECTOR, \ + .base = GUEST_##seg##_BASE, \ + .limit = GUEST_##seg##_LIMIT, \ + .ar_bytes = GUEST_##seg##_AR_BYTES, \ + } + +static struct kvm_vmx_segment_field { + unsigned selector; + unsigned base; + unsigned limit; + unsigned ar_bytes; +} kvm_vmx_segment_fields[] = { + VMX_SEGMENT_FIELD(CS), + VMX_SEGMENT_FIELD(DS), + VMX_SEGMENT_FIELD(ES), + VMX_SEGMENT_FIELD(FS), + VMX_SEGMENT_FIELD(GS), + VMX_SEGMENT_FIELD(SS), + VMX_SEGMENT_FIELD(TR), + VMX_SEGMENT_FIELD(LDTR), +}; + +/* + * Keep MSR_K6_STAR at the end, as setup_msrs() will try to optimize it + * away by decrementing the array size. + */ +static const u32 vmx_msr_index[] = { +#ifdef CONFIG_X86_64 + MSR_SYSCALL_MASK, MSR_LSTAR, MSR_CSTAR, MSR_KERNEL_GS_BASE, +#endif + MSR_EFER, MSR_K6_STAR, +}; +#define NR_VMX_MSR ARRAY_SIZE(vmx_msr_index) + +static void load_msrs(struct kvm_msr_entry *e, int n) +{ + int i; + + for (i = 0; i < n; ++i) + wrmsrl(e[i].index, e[i].data); +} + +static void save_msrs(struct kvm_msr_entry *e, int n) +{ + int i; + + for (i = 0; i < n; ++i) + rdmsrl(e[i].index, e[i].data); +} + +static inline int is_page_fault(u32 intr_info) +{ + return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK | + INTR_INFO_VALID_MASK)) == + (INTR_TYPE_EXCEPTION | PF_VECTOR | INTR_INFO_VALID_MASK); +} + +static inline int is_no_device(u32 intr_info) +{ + return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK | + INTR_INFO_VALID_MASK)) == + (INTR_TYPE_EXCEPTION | NM_VECTOR | INTR_INFO_VALID_MASK); +} + +static inline int is_invalid_opcode(u32 intr_info) +{ + return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK | + INTR_INFO_VALID_MASK)) == + (INTR_TYPE_EXCEPTION | UD_VECTOR | INTR_INFO_VALID_MASK); +} + +static inline int is_external_interrupt(u32 intr_info) +{ + return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK)) + == (INTR_TYPE_EXT_INTR | INTR_INFO_VALID_MASK); +} + +static inline int cpu_has_vmx_tpr_shadow(void) +{ + return (vmcs_config.cpu_based_exec_ctrl & CPU_BASED_TPR_SHADOW); +} + +static inline int vm_need_tpr_shadow(struct kvm *kvm) +{ + return ((cpu_has_vmx_tpr_shadow()) && (irqchip_in_kernel(kvm))); +} + +static inline int cpu_has_secondary_exec_ctrls(void) +{ + return (vmcs_config.cpu_based_exec_ctrl & + CPU_BASED_ACTIVATE_SECONDARY_CONTROLS); +} + +static inline bool cpu_has_vmx_virtualize_apic_accesses(void) +{ + return (vmcs_config.cpu_based_2nd_exec_ctrl & + SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES); +} + +static inline int vm_need_virtualize_apic_accesses(struct kvm *kvm) +{ + return ((cpu_has_vmx_virtualize_apic_accesses()) && + (irqchip_in_kernel(kvm))); +} + +static inline int cpu_has_vmx_vpid(void) +{ + return (vmcs_config.cpu_based_2nd_exec_ctrl & + SECONDARY_EXEC_ENABLE_VPID); +} + +static int __find_msr_index(struct vcpu_vmx *vmx, u32 msr) +{ + int i; + + for (i = 0; i < vmx->nmsrs; ++i) + if (vmx->guest_msrs[i].index == msr) + return i; + return -1; +} + +static inline void __invvpid(int ext, u16 vpid, gva_t gva) +{ + struct { + u64 vpid : 16; + u64 rsvd : 48; + u64 gva; + } operand = { vpid, 0, gva }; + + asm volatile (ASM_VMX_INVVPID + /* CF==1 or ZF==1 --> rc = -1 */ + "; ja 1f ; ud2 ; 1:" + : : "a"(&operand), "c"(ext) : "cc", "memory"); +} + +static struct kvm_msr_entry *find_msr_entry(struct vcpu_vmx *vmx, u32 msr) +{ + int i; + + i = __find_msr_index(vmx, msr); + if (i >= 0) + return &vmx->guest_msrs[i]; + return NULL; +} + +static void vmcs_clear(struct vmcs *vmcs) +{ + u64 phys_addr = __pa(vmcs); + u8 error; + + asm volatile (ASM_VMX_VMCLEAR_RAX "; setna %0" + : "=g"(error) : "a"(&phys_addr), "m"(phys_addr) + : "cc", "memory"); + if (error) + printk(KERN_ERR "kvm: vmclear fail: %p/%llx\n", + vmcs, phys_addr); +} + +static void __vcpu_clear(void *arg) +{ + struct vcpu_vmx *vmx = arg; + int cpu = raw_smp_processor_id(); + + if (vmx->vcpu.cpu == cpu) + vmcs_clear(vmx->vmcs); + if (per_cpu(current_vmcs, cpu) == vmx->vmcs) + per_cpu(current_vmcs, cpu) = NULL; + rdtscll(vmx->vcpu.arch.host_tsc); +} + +static void vcpu_clear(struct vcpu_vmx *vmx) +{ + if (vmx->vcpu.cpu == -1) + return; + smp_call_function_single(vmx->vcpu.cpu, __vcpu_clear, vmx, 0, 1); + vmx->launched = 0; +} + +static inline void vpid_sync_vcpu_all(struct vcpu_vmx *vmx) +{ + if (vmx->vpid == 0) + return; + + __invvpid(VMX_VPID_EXTENT_SINGLE_CONTEXT, vmx->vpid, 0); +} + +static unsigned long vmcs_readl(unsigned long field) +{ + unsigned long value; + + asm volatile (ASM_VMX_VMREAD_RDX_RAX + : "=a"(value) : "d"(field) : "cc"); + return value; +} + +static u16 vmcs_read16(unsigned long field) +{ + return vmcs_readl(field); +} + +static u32 vmcs_read32(unsigned long field) +{ + return vmcs_readl(field); +} + +static u64 vmcs_read64(unsigned long field) +{ +#ifdef CONFIG_X86_64 + return vmcs_readl(field); +#else + return vmcs_readl(field) | ((u64)vmcs_readl(field+1) << 32); +#endif +} + +static noinline void vmwrite_error(unsigned long field, unsigned long value) +{ + printk(KERN_ERR "vmwrite error: reg %lx value %lx (err %d)\n", + field, value, vmcs_read32(VM_INSTRUCTION_ERROR)); + dump_stack(); +} + +static void vmcs_writel(unsigned long field, unsigned long value) +{ + u8 error; + + asm volatile (ASM_VMX_VMWRITE_RAX_RDX "; setna %0" + : "=q"(error) : "a"(value), "d"(field) : "cc"); + if (unlikely(error)) + vmwrite_error(field, value); +} + +static void vmcs_write16(unsigned long field, u16 value) +{ + vmcs_writel(field, value); +} + +static void vmcs_write32(unsigned long field, u32 value) +{ + vmcs_writel(field, value); +} + +static void vmcs_write64(unsigned long field, u64 value) +{ +#ifdef CONFIG_X86_64 + vmcs_writel(field, value); +#else + vmcs_writel(field, value); + asm volatile (""); + vmcs_writel(field+1, value >> 32); +#endif +} + +static void vmcs_clear_bits(unsigned long field, u32 mask) +{ + vmcs_writel(field, vmcs_readl(field) & ~mask); +} + +static void vmcs_set_bits(unsigned long field, u32 mask) +{ + vmcs_writel(field, vmcs_readl(field) | mask); +} + +static void update_exception_bitmap(struct kvm_vcpu *vcpu) +{ + u32 eb; + + eb = (1u << PF_VECTOR) | (1u << UD_VECTOR); + if (!vcpu->fpu_active) + eb |= 1u << NM_VECTOR; + if (vcpu->guest_debug.enabled) + eb |= 1u << 1; + if (vcpu->arch.rmode.active) + eb = ~0; + vmcs_write32(EXCEPTION_BITMAP, eb); +} + +static void reload_tss(void) +{ + /* + * VT restores TR but not its size. Useless. + */ + struct descriptor_table gdt; + struct segment_descriptor *descs; + + get_gdt(&gdt); + descs = (void *)gdt.base; + descs[GDT_ENTRY_TSS].type = 9; /* available TSS */ + load_TR_desc(); +} + +static void load_transition_efer(struct vcpu_vmx *vmx) +{ + int efer_offset = vmx->msr_offset_efer; + u64 host_efer = vmx->host_msrs[efer_offset].data; + u64 guest_efer = vmx->guest_msrs[efer_offset].data; + u64 ignore_bits; + + if (efer_offset < 0) + return; + /* + * NX is emulated; LMA and LME handled by hardware; SCE meaninless + * outside long mode + */ + ignore_bits = EFER_NX | EFER_SCE; +#ifdef CONFIG_X86_64 + ignore_bits |= EFER_LMA | EFER_LME; + /* SCE is meaningful only in long mode on Intel */ + if (guest_efer & EFER_LMA) + ignore_bits &= ~(u64)EFER_SCE; +#endif + if ((guest_efer & ~ignore_bits) == (host_efer & ~ignore_bits)) + return; + + vmx->host_state.guest_efer_loaded = 1; + guest_efer &= ~ignore_bits; + guest_efer |= host_efer & ignore_bits; + wrmsrl(MSR_EFER, guest_efer); + vmx->vcpu.stat.efer_reload++; +} + +static void reload_host_efer(struct vcpu_vmx *vmx) +{ + if (vmx->host_state.guest_efer_loaded) { + vmx->host_state.guest_efer_loaded = 0; + load_msrs(vmx->host_msrs + vmx->msr_offset_efer, 1); + } +} + +static void vmx_save_host_state(struct kvm_vcpu *vcpu) +{ + struct vcpu_vmx *vmx = to_vmx(vcpu); + + if (vmx->host_state.loaded) + return; + + vmx->host_state.loaded = 1; + /* + * Set host fs and gs selectors. Unfortunately, 22.2.3 does not + * allow segment selectors with cpl > 0 or ti == 1. + */ + vmx->host_state.ldt_sel = read_ldt(); + vmx->host_state.gs_ldt_reload_needed = vmx->host_state.ldt_sel; + vmx->host_state.fs_sel = read_fs(); + if (!(vmx->host_state.fs_sel & 7)) { + vmcs_write16(HOST_FS_SELECTOR, vmx->host_state.fs_sel); + vmx->host_state.fs_reload_needed = 0; + } else { + vmcs_write16(HOST_FS_SELECTOR, 0); + vmx->host_state.fs_reload_needed = 1; + } + vmx->host_state.gs_sel = read_gs(); + if (!(vmx->host_state.gs_sel & 7)) + vmcs_write16(HOST_GS_SELECTOR, vmx->host_state.gs_sel); + else { + vmcs_write16(HOST_GS_SELECTOR, 0); + vmx->host_state.gs_ldt_reload_needed = 1; + } + +#ifdef CONFIG_X86_64 + vmcs_writel(HOST_FS_BASE, read_msr(MSR_FS_BASE)); + vmcs_writel(HOST_GS_BASE, read_msr(MSR_GS_BASE)); +#else + vmcs_writel(HOST_FS_BASE, segment_base(vmx->host_state.fs_sel)); + vmcs_writel(HOST_GS_BASE, segment_base(vmx->host_state.gs_sel)); +#endif + +#ifdef CONFIG_X86_64 + if (is_long_mode(&vmx->vcpu)) + save_msrs(vmx->host_msrs + + vmx->msr_offset_kernel_gs_base, 1); + +#endif + load_msrs(vmx->guest_msrs, vmx->save_nmsrs); + load_transition_efer(vmx); +} + +static void vmx_load_host_state(struct vcpu_vmx *vmx) +{ + unsigned long flags; + + if (!vmx->host_state.loaded) + return; + + ++vmx->vcpu.stat.host_state_reload; + vmx->host_state.loaded = 0; + if (vmx->host_state.fs_reload_needed) + load_fs(vmx->host_state.fs_sel); + if (vmx->host_state.gs_ldt_reload_needed) { + load_ldt(vmx->host_state.ldt_sel); + /* + * If we have to reload gs, we must take care to + * preserve our gs base. + */ + local_irq_save(flags); + load_gs(vmx->host_state.gs_sel); +#ifdef CONFIG_X86_64 + wrmsrl(MSR_GS_BASE, vmcs_readl(HOST_GS_BASE)); +#endif + local_irq_restore(flags); + } + reload_tss(); + save_msrs(vmx->guest_msrs, vmx->save_nmsrs); + load_msrs(vmx->host_msrs, vmx->save_nmsrs); + reload_host_efer(vmx); +} + +/* + * Switches to specified vcpu, until a matching vcpu_put(), but assumes + * vcpu mutex is already taken. + */ +static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +{ + struct vcpu_vmx *vmx = to_vmx(vcpu); + u64 phys_addr = __pa(vmx->vmcs); + u64 tsc_this, delta; + + if (vcpu->cpu != cpu) { + vcpu_clear(vmx); + kvm_migrate_apic_timer(vcpu); + vpid_sync_vcpu_all(vmx); + } + + if (per_cpu(current_vmcs, cpu) != vmx->vmcs) { + u8 error; + + per_cpu(current_vmcs, cpu) = vmx->vmcs; + asm volatile (ASM_VMX_VMPTRLD_RAX "; setna %0" + : "=g"(error) : "a"(&phys_addr), "m"(phys_addr) + : "cc"); + if (error) + printk(KERN_ERR "kvm: vmptrld %p/%llx fail\n", + vmx->vmcs, phys_addr); + } + + if (vcpu->cpu != cpu) { + struct descriptor_table dt; + unsigned long sysenter_esp; + + vcpu->cpu = cpu; + /* + * Linux uses per-cpu TSS and GDT, so set these when switching + * processors. + */ + vmcs_writel(HOST_TR_BASE, read_tr_base()); /* 22.2.4 */ + get_gdt(&dt); + vmcs_writel(HOST_GDTR_BASE, dt.base); /* 22.2.4 */ + + rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp); + vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */ + + /* + * Make sure the time stamp counter is monotonous. + */ + rdtscll(tsc_this); + delta = vcpu->arch.host_tsc - tsc_this; + vmcs_write64(TSC_OFFSET, vmcs_read64(TSC_OFFSET) + delta); + } +} + +static void vmx_vcpu_put(struct kvm_vcpu *vcpu) +{ + vmx_load_host_state(to_vmx(vcpu)); +} + +static void vmx_fpu_activate(struct kvm_vcpu *vcpu) +{ + if (vcpu->fpu_active) + return; + vcpu->fpu_active = 1; + vmcs_clear_bits(GUEST_CR0, X86_CR0_TS); + if (vcpu->arch.cr0 & X86_CR0_TS) + vmcs_set_bits(GUEST_CR0, X86_CR0_TS); + update_exception_bitmap(vcpu); +} + +static void vmx_fpu_deactivate(struct kvm_vcpu *vcpu) +{ + if (!vcpu->fpu_active) + return; + vcpu->fpu_active = 0; + vmcs_set_bits(GUEST_CR0, X86_CR0_TS); + update_exception_bitmap(vcpu); +} + +static void vmx_vcpu_decache(struct kvm_vcpu *vcpu) +{ + vcpu_clear(to_vmx(vcpu)); +} + +static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu) +{ + return vmcs_readl(GUEST_RFLAGS); +} + +static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) +{ + if (vcpu->arch.rmode.active) + rflags |= IOPL_MASK | X86_EFLAGS_VM; + vmcs_writel(GUEST_RFLAGS, rflags); +} + +static void skip_emulated_instruction(struct kvm_vcpu *vcpu) +{ + unsigned long rip; + u32 interruptibility; + + rip = vmcs_readl(GUEST_RIP); + rip += vmcs_read32(VM_EXIT_INSTRUCTION_LEN); + vmcs_writel(GUEST_RIP, rip); + + /* + * We emulated an instruction, so temporary interrupt blocking + * should be removed, if set. + */ + interruptibility = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO); + if (interruptibility & 3) + vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, + interruptibility & ~3); + vcpu->arch.interrupt_window_open = 1; +} + +static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, + bool has_error_code, u32 error_code) +{ + vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, + nr | INTR_TYPE_EXCEPTION + | (has_error_code ? INTR_INFO_DELIVER_CODE_MASK : 0) + | INTR_INFO_VALID_MASK); + if (has_error_code) + vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code); +} + +static bool vmx_exception_injected(struct kvm_vcpu *vcpu) +{ + struct vcpu_vmx *vmx = to_vmx(vcpu); + + return !(vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK); +} + +/* + * Swap MSR entry in host/guest MSR entry array. + */ +#ifdef CONFIG_X86_64 +static void move_msr_up(struct vcpu_vmx *vmx, int from, int to) +{ + struct kvm_msr_entry tmp; + + tmp = vmx->guest_msrs[to]; + vmx->guest_msrs[to] = vmx->guest_msrs[from]; + vmx->guest_msrs[from] = tmp; + tmp = vmx->host_msrs[to]; + vmx->host_msrs[to] = vmx->host_msrs[from]; + vmx->host_msrs[from] = tmp; +} +#endif + +/* + * Set up the vmcs to automatically save and restore system + * msrs. Don't touch the 64-bit msrs if the guest is in legacy + * mode, as fiddling with msrs is very expensive. + */ +static void setup_msrs(struct vcpu_vmx *vmx) +{ + int save_nmsrs; + + save_nmsrs = 0; +#ifdef CONFIG_X86_64 + if (is_long_mode(&vmx->vcpu)) { + int index; + + index = __find_msr_index(vmx, MSR_SYSCALL_MASK); + if (index >= 0) + move_msr_up(vmx, index, save_nmsrs++); + index = __find_msr_index(vmx, MSR_LSTAR); + if (index >= 0) + move_msr_up(vmx, index, save_nmsrs++); + index = __find_msr_index(vmx, MSR_CSTAR); + if (index >= 0) + move_msr_up(vmx, index, save_nmsrs++); + index = __find_msr_index(vmx, MSR_KERNEL_GS_BASE); + if (index >= 0) + move_msr_up(vmx, index, save_nmsrs++); + /* + * MSR_K6_STAR is only needed on long mode guests, and only + * if efer.sce is enabled. + */ + index = __find_msr_index(vmx, MSR_K6_STAR); + if ((index >= 0) && (vmx->vcpu.arch.shadow_efer & EFER_SCE)) + move_msr_up(vmx, index, save_nmsrs++); + } +#endif + vmx->save_nmsrs = save_nmsrs; + +#ifdef CONFIG_X86_64 + vmx->msr_offset_kernel_gs_base = + __find_msr_index(vmx, MSR_KERNEL_GS_BASE); +#endif + vmx->msr_offset_efer = __find_msr_index(vmx, MSR_EFER); +} + +/* + * reads and returns guest's timestamp counter "register" + * guest_tsc = host_tsc + tsc_offset -- 21.3 + */ +static u64 guest_read_tsc(void) +{ + u64 host_tsc, tsc_offset; + + rdtscll(host_tsc); + tsc_offset = vmcs_read64(TSC_OFFSET); + return host_tsc + tsc_offset; +} + +/* + * writes 'guest_tsc' into guest's timestamp counter "register" + * guest_tsc = host_tsc + tsc_offset ==> tsc_offset = guest_tsc - host_tsc + */ +static void guest_write_tsc(u64 guest_tsc) +{ + u64 host_tsc; + + rdtscll(host_tsc); + vmcs_write64(TSC_OFFSET, guest_tsc - host_tsc); +} + +/* + * Reads an msr value (of 'msr_index') into 'pdata'. + * Returns 0 on success, non-0 otherwise. + * Assumes vcpu_load() was already called. + */ +static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) +{ + u64 data; + struct kvm_msr_entry *msr; + + if (!pdata) { + printk(KERN_ERR "BUG: get_msr called with NULL pdata\n"); + return -EINVAL; + } + + switch (msr_index) { +#ifdef CONFIG_X86_64 + case MSR_FS_BASE: + data = vmcs_readl(GUEST_FS_BASE); + break; + case MSR_GS_BASE: + data = vmcs_readl(GUEST_GS_BASE); + break; + case MSR_EFER: + return kvm_get_msr_common(vcpu, msr_index, pdata); +#endif + case MSR_IA32_TIME_STAMP_COUNTER: + data = guest_read_tsc(); + break; + case MSR_IA32_SYSENTER_CS: + data = vmcs_read32(GUEST_SYSENTER_CS); + break; + case MSR_IA32_SYSENTER_EIP: + data = vmcs_readl(GUEST_SYSENTER_EIP); + break; + case MSR_IA32_SYSENTER_ESP: + data = vmcs_readl(GUEST_SYSENTER_ESP); + break; + default: + msr = find_msr_entry(to_vmx(vcpu), msr_index); + if (msr) { + data = msr->data; + break; + } + return kvm_get_msr_common(vcpu, msr_index, pdata); + } + + *pdata = data; + return 0; +} + +/* + * Writes msr value into into the appropriate "register". + * Returns 0 on success, non-0 otherwise. + * Assumes vcpu_load() was already called. + */ +static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) +{ + struct vcpu_vmx *vmx = to_vmx(vcpu); + struct kvm_msr_entry *msr; + int ret = 0; + + switch (msr_index) { +#ifdef CONFIG_X86_64 + case MSR_EFER: + ret = kvm_set_msr_common(vcpu, msr_index, data); + if (vmx->host_state.loaded) { + reload_host_efer(vmx); + load_transition_efer(vmx); + } + break; + case MSR_FS_BASE: + vmcs_writel(GUEST_FS_BASE, data); + break; + case MSR_GS_BASE: + vmcs_writel(GUEST_GS_BASE, data); + break; +#endif + case MSR_IA32_SYSENTER_CS: + vmcs_write32(GUEST_SYSENTER_CS, data); + break; + case MSR_IA32_SYSENTER_EIP: + vmcs_writel(GUEST_SYSENTER_EIP, data); + break; + case MSR_IA32_SYSENTER_ESP: + vmcs_writel(GUEST_SYSENTER_ESP, data); + break; + case MSR_IA32_TIME_STAMP_COUNTER: + guest_write_tsc(data); + break; + default: + msr = find_msr_entry(vmx, msr_index); + if (msr) { + msr->data = data; + if (vmx->host_state.loaded) + load_msrs(vmx->guest_msrs, vmx->save_nmsrs); + break; + } + ret = kvm_set_msr_common(vcpu, msr_index, data); + } + + return ret; +} + +/* + * Sync the rsp and rip registers into the vcpu structure. This allows + * registers to be accessed by indexing vcpu->arch.regs. + */ +static void vcpu_load_rsp_rip(struct kvm_vcpu *vcpu) +{ + vcpu->arch.regs[VCPU_REGS_RSP] = vmcs_readl(GUEST_RSP); + vcpu->arch.rip = vmcs_readl(GUEST_RIP); +} + +/* + * Syncs rsp and rip back into the vmcs. Should be called after possible + * modification. + */ +static void vcpu_put_rsp_rip(struct kvm_vcpu *vcpu) +{ + vmcs_writel(GUEST_RSP, vcpu->arch.regs[VCPU_REGS_RSP]); + vmcs_writel(GUEST_RIP, vcpu->arch.rip); +} + +static int set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg) +{ + unsigned long dr7 = 0x400; + int old_singlestep; + + old_singlestep = vcpu->guest_debug.singlestep; + + vcpu->guest_debug.enabled = dbg->enabled; + if (vcpu->guest_debug.enabled) { + int i; + + dr7 |= 0x200; /* exact */ + for (i = 0; i < 4; ++i) { + if (!dbg->breakpoints[i].enabled) + continue; + vcpu->guest_debug.bp[i] = dbg->breakpoints[i].address; + dr7 |= 2 << (i*2); /* global enable */ + dr7 |= 0 << (i*4+16); /* execution breakpoint */ + } + + vcpu->guest_debug.singlestep = dbg->singlestep; + } else + vcpu->guest_debug.singlestep = 0; + + if (old_singlestep && !vcpu->guest_debug.singlestep) { + unsigned long flags; + + flags = vmcs_readl(GUEST_RFLAGS); + flags &= ~(X86_EFLAGS_TF | X86_EFLAGS_RF); + vmcs_writel(GUEST_RFLAGS, flags); + } + + update_exception_bitmap(vcpu); + vmcs_writel(GUEST_DR7, dr7); + + return 0; +} + +static int vmx_get_irq(struct kvm_vcpu *vcpu) +{ + struct vcpu_vmx *vmx = to_vmx(vcpu); + u32 idtv_info_field; + + idtv_info_field = vmx->idt_vectoring_info; + if (idtv_info_field & INTR_INFO_VALID_MASK) { + if (is_external_interrupt(idtv_info_field)) + return idtv_info_field & VECTORING_INFO_VECTOR_MASK; + else + printk(KERN_DEBUG "pending exception: not handled yet\n"); + } + return -1; +} + +static __init int cpu_has_kvm_support(void) +{ + unsigned long ecx = cpuid_ecx(1); + return test_bit(5, &ecx); /* CPUID.1:ECX.VMX[bit 5] -> VT */ +} + +static __init int vmx_disabled_by_bios(void) +{ + u64 msr; + + rdmsrl(MSR_IA32_FEATURE_CONTROL, msr); + return (msr & (MSR_IA32_FEATURE_CONTROL_LOCKED | + MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED)) + == MSR_IA32_FEATURE_CONTROL_LOCKED; + /* locked but not enabled */ +} + +static void hardware_enable(void *garbage) +{ + int cpu = raw_smp_processor_id(); + u64 phys_addr = __pa(per_cpu(vmxarea, cpu)); + u64 old; + + rdmsrl(MSR_IA32_FEATURE_CONTROL, old); + if ((old & (MSR_IA32_FEATURE_CONTROL_LOCKED | + MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED)) + != (MSR_IA32_FEATURE_CONTROL_LOCKED | + MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED)) + /* enable and lock */ + wrmsrl(MSR_IA32_FEATURE_CONTROL, old | + MSR_IA32_FEATURE_CONTROL_LOCKED | + MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED); + write_cr4(read_cr4() | X86_CR4_VMXE); /* FIXME: not cpu hotplug safe */ + asm volatile (ASM_VMX_VMXON_RAX : : "a"(&phys_addr), "m"(phys_addr) + : "memory", "cc"); +} + +static void hardware_disable(void *garbage) +{ + asm volatile (ASM_VMX_VMXOFF : : : "cc"); + write_cr4(read_cr4() & ~X86_CR4_VMXE); +} + +static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt, + u32 msr, u32 *result) +{ + u32 vmx_msr_low, vmx_msr_high; + u32 ctl = ctl_min | ctl_opt; + + rdmsr(msr, vmx_msr_low, vmx_msr_high); + + ctl &= vmx_msr_high; /* bit == 0 in high word ==> must be zero */ + ctl |= vmx_msr_low; /* bit == 1 in low word ==> must be one */ + + /* Ensure minimum (required) set of control bits are supported. */ + if (ctl_min & ~ctl) + return -EIO; + + *result = ctl; + return 0; +} + +static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) +{ + u32 vmx_msr_low, vmx_msr_high; + u32 min, opt; + u32 _pin_based_exec_control = 0; + u32 _cpu_based_exec_control = 0; + u32 _cpu_based_2nd_exec_control = 0; + u32 _vmexit_control = 0; + u32 _vmentry_control = 0; + + min = PIN_BASED_EXT_INTR_MASK | PIN_BASED_NMI_EXITING; + opt = 0; + if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PINBASED_CTLS, + &_pin_based_exec_control) < 0) + return -EIO; + + min = CPU_BASED_HLT_EXITING | +#ifdef CONFIG_X86_64 + CPU_BASED_CR8_LOAD_EXITING | + CPU_BASED_CR8_STORE_EXITING | +#endif + CPU_BASED_USE_IO_BITMAPS | + CPU_BASED_MOV_DR_EXITING | + CPU_BASED_USE_TSC_OFFSETING; + opt = CPU_BASED_TPR_SHADOW | + CPU_BASED_ACTIVATE_SECONDARY_CONTROLS; + if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PROCBASED_CTLS, + &_cpu_based_exec_control) < 0) + return -EIO; +#ifdef CONFIG_X86_64 + if ((_cpu_based_exec_control & CPU_BASED_TPR_SHADOW)) + _cpu_based_exec_control &= ~CPU_BASED_CR8_LOAD_EXITING & + ~CPU_BASED_CR8_STORE_EXITING; +#endif + if (_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) { + min = 0; + opt = SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | + SECONDARY_EXEC_WBINVD_EXITING | + SECONDARY_EXEC_ENABLE_VPID; + if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PROCBASED_CTLS2, + &_cpu_based_2nd_exec_control) < 0) + return -EIO; + } +#ifndef CONFIG_X86_64 + if (!(_cpu_based_2nd_exec_control & + SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) + _cpu_based_exec_control &= ~CPU_BASED_TPR_SHADOW; +#endif + + min = 0; +#ifdef CONFIG_X86_64 + min |= VM_EXIT_HOST_ADDR_SPACE_SIZE; +#endif + opt = 0; + if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_EXIT_CTLS, + &_vmexit_control) < 0) + return -EIO; + + min = opt = 0; + if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_ENTRY_CTLS, + &_vmentry_control) < 0) + return -EIO; + + rdmsr(MSR_IA32_VMX_BASIC, vmx_msr_low, vmx_msr_high); + + /* IA-32 SDM Vol 3B: VMCS size is never greater than 4kB. */ + if ((vmx_msr_high & 0x1fff) > PAGE_SIZE) + return -EIO; + +#ifdef CONFIG_X86_64 + /* IA-32 SDM Vol 3B: 64-bit CPUs always have VMX_BASIC_MSR[48]==0. */ + if (vmx_msr_high & (1u<<16)) + return -EIO; +#endif + + /* Require Write-Back (WB) memory type for VMCS accesses. */ + if (((vmx_msr_high >> 18) & 15) != 6) + return -EIO; + + vmcs_conf->size = vmx_msr_high & 0x1fff; + vmcs_conf->order = get_order(vmcs_config.size); + vmcs_conf->revision_id = vmx_msr_low; + + vmcs_conf->pin_based_exec_ctrl = _pin_based_exec_control; + vmcs_conf->cpu_based_exec_ctrl = _cpu_based_exec_control; + vmcs_conf->cpu_based_2nd_exec_ctrl = _cpu_based_2nd_exec_control; + vmcs_conf->vmexit_ctrl = _vmexit_control; + vmcs_conf->vmentry_ctrl = _vmentry_control; + + return 0; +} + +static struct vmcs *alloc_vmcs_cpu(int cpu) +{ + int node = cpu_to_node(cpu); + struct page *pages; + struct vmcs *vmcs; + + pages = alloc_pages_node(node, GFP_KERNEL, vmcs_config.order); + if (!pages) + return NULL; + vmcs = page_address(pages); + memset(vmcs, 0, vmcs_config.size); + vmcs->revision_id = vmcs_config.revision_id; /* vmcs revision id */ + return vmcs; +} + +static struct vmcs *alloc_vmcs(void) +{ + return alloc_vmcs_cpu(raw_smp_processor_id()); +} + +static void free_vmcs(struct vmcs *vmcs) +{ + free_pages((unsigned long)vmcs, vmcs_config.order); +} + +static void free_kvm_area(void) +{ + int cpu; + + for_each_online_cpu(cpu) + free_vmcs(per_cpu(vmxarea, cpu)); +} + +static __init int alloc_kvm_area(void) +{ + int cpu; + + for_each_online_cpu(cpu) { + struct vmcs *vmcs; + + vmcs = alloc_vmcs_cpu(cpu); + if (!vmcs) { + free_kvm_area(); + return -ENOMEM; + } + + per_cpu(vmxarea, cpu) = vmcs; + } + return 0; +} + +static __init int hardware_setup(void) +{ + if (setup_vmcs_config(&vmcs_config) < 0) + return -EIO; + + if (boot_cpu_has(X86_FEATURE_NX)) + kvm_enable_efer_bits(EFER_NX); + + return alloc_kvm_area(); +} + +static __exit void hardware_unsetup(void) +{ + free_kvm_area(); +} + +static void fix_pmode_dataseg(int seg, struct kvm_save_segment *save) +{ + struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg]; + + if (vmcs_readl(sf->base) == save->base && (save->base & AR_S_MASK)) { + vmcs_write16(sf->selector, save->selector); + vmcs_writel(sf->base, save->base); + vmcs_write32(sf->limit, save->limit); + vmcs_write32(sf->ar_bytes, save->ar); + } else { + u32 dpl = (vmcs_read16(sf->selector) & SELECTOR_RPL_MASK) + << AR_DPL_SHIFT; + vmcs_write32(sf->ar_bytes, 0x93 | dpl); + } +} + +static void enter_pmode(struct kvm_vcpu *vcpu) +{ + unsigned long flags; + + vcpu->arch.rmode.active = 0; + + vmcs_writel(GUEST_TR_BASE, vcpu->arch.rmode.tr.base); + vmcs_write32(GUEST_TR_LIMIT, vcpu->arch.rmode.tr.limit); + vmcs_write32(GUEST_TR_AR_BYTES, vcpu->arch.rmode.tr.ar); + + flags = vmcs_readl(GUEST_RFLAGS); + flags &= ~(IOPL_MASK | X86_EFLAGS_VM); + flags |= (vcpu->arch.rmode.save_iopl << IOPL_SHIFT); + vmcs_writel(GUEST_RFLAGS, flags); + + vmcs_writel(GUEST_CR4, (vmcs_readl(GUEST_CR4) & ~X86_CR4_VME) | + (vmcs_readl(CR4_READ_SHADOW) & X86_CR4_VME)); + + update_exception_bitmap(vcpu); + + fix_pmode_dataseg(VCPU_SREG_ES, &vcpu->arch.rmode.es); + fix_pmode_dataseg(VCPU_SREG_DS, &vcpu->arch.rmode.ds); + fix_pmode_dataseg(VCPU_SREG_GS, &vcpu->arch.rmode.gs); + fix_pmode_dataseg(VCPU_SREG_FS, &vcpu->arch.rmode.fs); + + vmcs_write16(GUEST_SS_SELECTOR, 0); + vmcs_write32(GUEST_SS_AR_BYTES, 0x93); + + vmcs_write16(GUEST_CS_SELECTOR, + vmcs_read16(GUEST_CS_SELECTOR) & ~SELECTOR_RPL_MASK); + vmcs_write32(GUEST_CS_AR_BYTES, 0x9b); +} + +static gva_t rmode_tss_base(struct kvm *kvm) +{ + if (!kvm->arch.tss_addr) { + gfn_t base_gfn = kvm->memslots[0].base_gfn + + kvm->memslots[0].npages - 3; + return base_gfn << PAGE_SHIFT; + } + return kvm->arch.tss_addr; +} + +static void fix_rmode_seg(int seg, struct kvm_save_segment *save) +{ + struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg]; + + save->selector = vmcs_read16(sf->selector); + save->base = vmcs_readl(sf->base); + save->limit = vmcs_read32(sf->limit); + save->ar = vmcs_read32(sf->ar_bytes); + vmcs_write16(sf->selector, save->base >> 4); + vmcs_write32(sf->base, save->base & 0xfffff); + vmcs_write32(sf->limit, 0xffff); + vmcs_write32(sf->ar_bytes, 0xf3); +} + +static void enter_rmode(struct kvm_vcpu *vcpu) +{ + unsigned long flags; + + vcpu->arch.rmode.active = 1; + + vcpu->arch.rmode.tr.base = vmcs_readl(GUEST_TR_BASE); + vmcs_writel(GUEST_TR_BASE, rmode_tss_base(vcpu->kvm)); + + vcpu->arch.rmode.tr.limit = vmcs_read32(GUEST_TR_LIMIT); + vmcs_write32(GUEST_TR_LIMIT, RMODE_TSS_SIZE - 1); + + vcpu->arch.rmode.tr.ar = vmcs_read32(GUEST_TR_AR_BYTES); + vmcs_write32(GUEST_TR_AR_BYTES, 0x008b); + + flags = vmcs_readl(GUEST_RFLAGS); + vcpu->arch.rmode.save_iopl = (flags & IOPL_MASK) >> IOPL_SHIFT; + + flags |= IOPL_MASK | X86_EFLAGS_VM; + + vmcs_writel(GUEST_RFLAGS, flags); + vmcs_writel(GUEST_CR4, vmcs_readl(GUEST_CR4) | X86_CR4_VME); + update_exception_bitmap(vcpu); + + vmcs_write16(GUEST_SS_SELECTOR, vmcs_readl(GUEST_SS_BASE) >> 4); + vmcs_write32(GUEST_SS_LIMIT, 0xffff); + vmcs_write32(GUEST_SS_AR_BYTES, 0xf3); + + vmcs_write32(GUEST_CS_AR_BYTES, 0xf3); + vmcs_write32(GUEST_CS_LIMIT, 0xffff); + if (vmcs_readl(GUEST_CS_BASE) == 0xffff0000) + vmcs_writel(GUEST_CS_BASE, 0xf0000); + vmcs_write16(GUEST_CS_SELECTOR, vmcs_readl(GUEST_CS_BASE) >> 4); + + fix_rmode_seg(VCPU_SREG_ES, &vcpu->arch.rmode.es); + fix_rmode_seg(VCPU_SREG_DS, &vcpu->arch.rmode.ds); + fix_rmode_seg(VCPU_SREG_GS, &vcpu->arch.rmode.gs); + fix_rmode_seg(VCPU_SREG_FS, &vcpu->arch.rmode.fs); + + kvm_mmu_reset_context(vcpu); + init_rmode_tss(vcpu->kvm); +} + +#ifdef CONFIG_X86_64 + +static void enter_lmode(struct kvm_vcpu *vcpu) +{ + u32 guest_tr_ar; + + guest_tr_ar = vmcs_read32(GUEST_TR_AR_BYTES); + if ((guest_tr_ar & AR_TYPE_MASK) != AR_TYPE_BUSY_64_TSS) { + printk(KERN_DEBUG "%s: tss fixup for long mode. \n", + __FUNCTION__); + vmcs_write32(GUEST_TR_AR_BYTES, + (guest_tr_ar & ~AR_TYPE_MASK) + | AR_TYPE_BUSY_64_TSS); + } + + vcpu->arch.shadow_efer |= EFER_LMA; + + find_msr_entry(to_vmx(vcpu), MSR_EFER)->data |= EFER_LMA | EFER_LME; + vmcs_write32(VM_ENTRY_CONTROLS, + vmcs_read32(VM_ENTRY_CONTROLS) + | VM_ENTRY_IA32E_MODE); +} + +static void exit_lmode(struct kvm_vcpu *vcpu) +{ + vcpu->arch.shadow_efer &= ~EFER_LMA; + + vmcs_write32(VM_ENTRY_CONTROLS, + vmcs_read32(VM_ENTRY_CONTROLS) + & ~VM_ENTRY_IA32E_MODE); +} + +#endif + +static void vmx_flush_tlb(struct kvm_vcpu *vcpu) +{ + vpid_sync_vcpu_all(to_vmx(vcpu)); +} + +static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu) +{ + vcpu->arch.cr4 &= KVM_GUEST_CR4_MASK; + vcpu->arch.cr4 |= vmcs_readl(GUEST_CR4) & ~KVM_GUEST_CR4_MASK; +} + +static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) +{ + vmx_fpu_deactivate(vcpu); + + if (vcpu->arch.rmode.active && (cr0 & X86_CR0_PE)) + enter_pmode(vcpu); + + if (!vcpu->arch.rmode.active && !(cr0 & X86_CR0_PE)) + enter_rmode(vcpu); + +#ifdef CONFIG_X86_64 + if (vcpu->arch.shadow_efer & EFER_LME) { + if (!is_paging(vcpu) && (cr0 & X86_CR0_PG)) + enter_lmode(vcpu); + if (is_paging(vcpu) && !(cr0 & X86_CR0_PG)) + exit_lmode(vcpu); + } +#endif + + vmcs_writel(CR0_READ_SHADOW, cr0); + vmcs_writel(GUEST_CR0, + (cr0 & ~KVM_GUEST_CR0_MASK) | KVM_VM_CR0_ALWAYS_ON); + vcpu->arch.cr0 = cr0; + + if (!(cr0 & X86_CR0_TS) || !(cr0 & X86_CR0_PE)) + vmx_fpu_activate(vcpu); +} + +static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) +{ + vmx_flush_tlb(vcpu); + vmcs_writel(GUEST_CR3, cr3); + if (vcpu->arch.cr0 & X86_CR0_PE) + vmx_fpu_deactivate(vcpu); +} + +static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) +{ + vmcs_writel(CR4_READ_SHADOW, cr4); + vmcs_writel(GUEST_CR4, cr4 | (vcpu->arch.rmode.active ? + KVM_RMODE_VM_CR4_ALWAYS_ON : KVM_PMODE_VM_CR4_ALWAYS_ON)); + vcpu->arch.cr4 = cr4; +} + +static void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer) +{ + struct vcpu_vmx *vmx = to_vmx(vcpu); + struct kvm_msr_entry *msr = find_msr_entry(vmx, MSR_EFER); + + vcpu->arch.shadow_efer = efer; + if (!msr) + return; + if (efer & EFER_LMA) { + vmcs_write32(VM_ENTRY_CONTROLS, + vmcs_read32(VM_ENTRY_CONTROLS) | + VM_ENTRY_IA32E_MODE); + msr->data = efer; + + } else { + vmcs_write32(VM_ENTRY_CONTROLS, + vmcs_read32(VM_ENTRY_CONTROLS) & + ~VM_ENTRY_IA32E_MODE); + + msr->data = efer & ~EFER_LME; + } + setup_msrs(vmx); +} + +static u64 vmx_get_segment_base(struct kvm_vcpu *vcpu, int seg) +{ + struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg]; + + return vmcs_readl(sf->base); +} + +static void vmx_get_segment(struct kvm_vcpu *vcpu, + struct kvm_segment *var, int seg) +{ + struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg]; + u32 ar; + + var->base = vmcs_readl(sf->base); + var->limit = vmcs_read32(sf->limit); + var->selector = vmcs_read16(sf->selector); + ar = vmcs_read32(sf->ar_bytes); + if (ar & AR_UNUSABLE_MASK) + ar = 0; + var->type = ar & 15; + var->s = (ar >> 4) & 1; + var->dpl = (ar >> 5) & 3; + var->present = (ar >> 7) & 1; + var->avl = (ar >> 12) & 1; + var->l = (ar >> 13) & 1; + var->db = (ar >> 14) & 1; + var->g = (ar >> 15) & 1; + var->unusable = (ar >> 16) & 1; +} + +static u32 vmx_segment_access_rights(struct kvm_segment *var) +{ + u32 ar; + + if (var->unusable) + ar = 1 << 16; + else { + ar = var->type & 15; + ar |= (var->s & 1) << 4; + ar |= (var->dpl & 3) << 5; + ar |= (var->present & 1) << 7; + ar |= (var->avl & 1) << 12; + ar |= (var->l & 1) << 13; + ar |= (var->db & 1) << 14; + ar |= (var->g & 1) << 15; + } + if (ar == 0) /* a 0 value means unusable */ + ar = AR_UNUSABLE_MASK; + + return ar; +} + +static void vmx_set_segment(struct kvm_vcpu *vcpu, + struct kvm_segment *var, int seg) +{ + struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg]; + u32 ar; + + if (vcpu->arch.rmode.active && seg == VCPU_SREG_TR) { + vcpu->arch.rmode.tr.selector = var->selector; + vcpu->arch.rmode.tr.base = var->base; + vcpu->arch.rmode.tr.limit = var->limit; + vcpu->arch.rmode.tr.ar = vmx_segment_access_rights(var); + return; + } + vmcs_writel(sf->base, var->base); + vmcs_write32(sf->limit, var->limit); + vmcs_write16(sf->selector, var->selector); + if (vcpu->arch.rmode.active && var->s) { + /* + * Hack real-mode segments into vm86 compatibility. + */ + if (var->base == 0xffff0000 && var->selector == 0xf000) + vmcs_writel(sf->base, 0xf0000); + ar = 0xf3; + } else + ar = vmx_segment_access_rights(var); + vmcs_write32(sf->ar_bytes, ar); +} + +static void vmx_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l) +{ + u32 ar = vmcs_read32(GUEST_CS_AR_BYTES); + + *db = (ar >> 14) & 1; + *l = (ar >> 13) & 1; +} + +static void vmx_get_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) +{ + dt->limit = vmcs_read32(GUEST_IDTR_LIMIT); + dt->base = vmcs_readl(GUEST_IDTR_BASE); +} + +static void vmx_set_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) +{ + vmcs_write32(GUEST_IDTR_LIMIT, dt->limit); + vmcs_writel(GUEST_IDTR_BASE, dt->base); +} + +static void vmx_get_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) +{ + dt->limit = vmcs_read32(GUEST_GDTR_LIMIT); + dt->base = vmcs_readl(GUEST_GDTR_BASE); +} + +static void vmx_set_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) +{ + vmcs_write32(GUEST_GDTR_LIMIT, dt->limit); + vmcs_writel(GUEST_GDTR_BASE, dt->base); +} + +static int init_rmode_tss(struct kvm *kvm) +{ + gfn_t fn = rmode_tss_base(kvm) >> PAGE_SHIFT; + u16 data = 0; + int ret = 0; + int r; + + down_read(¤t->mm->mmap_sem); + r = kvm_clear_guest_page(kvm, fn, 0, PAGE_SIZE); + if (r < 0) + goto out; + data = TSS_BASE_SIZE + TSS_REDIRECTION_SIZE; + r = kvm_write_guest_page(kvm, fn++, &data, 0x66, sizeof(u16)); + if (r < 0) + goto out; + r = kvm_clear_guest_page(kvm, fn++, 0, PAGE_SIZE); + if (r < 0) + goto out; + r = kvm_clear_guest_page(kvm, fn, 0, PAGE_SIZE); + if (r < 0) + goto out; + data = ~0; + r = kvm_write_guest_page(kvm, fn, &data, + RMODE_TSS_SIZE - 2 * PAGE_SIZE - 1, + sizeof(u8)); + if (r < 0) + goto out; + + ret = 1; +out: + up_read(¤t->mm->mmap_sem); + return ret; +} + +static void seg_setup(int seg) +{ + struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg]; + + vmcs_write16(sf->selector, 0); + vmcs_writel(sf->base, 0); + vmcs_write32(sf->limit, 0xffff); + vmcs_write32(sf->ar_bytes, 0x93); +} + +static int alloc_apic_access_page(struct kvm *kvm) +{ + struct kvm_userspace_memory_region kvm_userspace_mem; + int r = 0; + + down_write(&kvm->slots_lock); + if (kvm->arch.apic_access_page) + goto out; + kvm_userspace_mem.slot = APIC_ACCESS_PAGE_PRIVATE_MEMSLOT; + kvm_userspace_mem.flags = 0; + kvm_userspace_mem.guest_phys_addr = 0xfee00000ULL; + kvm_userspace_mem.memory_size = PAGE_SIZE; + r = __kvm_set_memory_region(kvm, &kvm_userspace_mem, 0); + if (r) + goto out; + + down_read(¤t->mm->mmap_sem); + kvm->arch.apic_access_page = gfn_to_page(kvm, 0xfee00); + up_read(¤t->mm->mmap_sem); +out: + up_write(&kvm->slots_lock); + return r; +} + +static void allocate_vpid(struct vcpu_vmx *vmx) +{ + int vpid; + + vmx->vpid = 0; + if (!enable_vpid || !cpu_has_vmx_vpid()) + return; + spin_lock(&vmx_vpid_lock); + vpid = find_first_zero_bit(vmx_vpid_bitmap, VMX_NR_VPIDS); + if (vpid < VMX_NR_VPIDS) { + vmx->vpid = vpid; + __set_bit(vpid, vmx_vpid_bitmap); + } + spin_unlock(&vmx_vpid_lock); +} + +/* + * Sets up the vmcs for emulated real mode. + */ +static int vmx_vcpu_setup(struct vcpu_vmx *vmx) +{ + u32 host_sysenter_cs; + u32 junk; + unsigned long a; + struct descriptor_table dt; + int i; + unsigned long kvm_vmx_return; + u32 exec_control; + + /* I/O */ + vmcs_write64(IO_BITMAP_A, page_to_phys(vmx_io_bitmap_a)); + vmcs_write64(IO_BITMAP_B, page_to_phys(vmx_io_bitmap_b)); + + vmcs_write64(VMCS_LINK_POINTER, -1ull); /* 22.3.1.5 */ + + /* Control */ + vmcs_write32(PIN_BASED_VM_EXEC_CONTROL, + vmcs_config.pin_based_exec_ctrl); + + exec_control = vmcs_config.cpu_based_exec_ctrl; + if (!vm_need_tpr_shadow(vmx->vcpu.kvm)) { + exec_control &= ~CPU_BASED_TPR_SHADOW; +#ifdef CONFIG_X86_64 + exec_control |= CPU_BASED_CR8_STORE_EXITING | + CPU_BASED_CR8_LOAD_EXITING; +#endif + } + vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, exec_control); + + if (cpu_has_secondary_exec_ctrls()) { + exec_control = vmcs_config.cpu_based_2nd_exec_ctrl; + if (!vm_need_virtualize_apic_accesses(vmx->vcpu.kvm)) + exec_control &= + ~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES; + if (vmx->vpid == 0) + exec_control &= ~SECONDARY_EXEC_ENABLE_VPID; + vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control); + } + + vmcs_write32(PAGE_FAULT_ERROR_CODE_MASK, !!bypass_guest_pf); + vmcs_write32(PAGE_FAULT_ERROR_CODE_MATCH, !!bypass_guest_pf); + vmcs_write32(CR3_TARGET_COUNT, 0); /* 22.2.1 */ + + vmcs_writel(HOST_CR0, read_cr0()); /* 22.2.3 */ + vmcs_writel(HOST_CR4, read_cr4()); /* 22.2.3, 22.2.5 */ + vmcs_writel(HOST_CR3, read_cr3()); /* 22.2.3 FIXME: shadow tables */ + + vmcs_write16(HOST_CS_SELECTOR, __KERNEL_CS); /* 22.2.4 */ + vmcs_write16(HOST_DS_SELECTOR, __KERNEL_DS); /* 22.2.4 */ + vmcs_write16(HOST_ES_SELECTOR, __KERNEL_DS); /* 22.2.4 */ + vmcs_write16(HOST_FS_SELECTOR, read_fs()); /* 22.2.4 */ + vmcs_write16(HOST_GS_SELECTOR, read_gs()); /* 22.2.4 */ + vmcs_write16(HOST_SS_SELECTOR, __KERNEL_DS); /* 22.2.4 */ +#ifdef CONFIG_X86_64 + rdmsrl(MSR_FS_BASE, a); + vmcs_writel(HOST_FS_BASE, a); /* 22.2.4 */ + rdmsrl(MSR_GS_BASE, a); + vmcs_writel(HOST_GS_BASE, a); /* 22.2.4 */ +#else + vmcs_writel(HOST_FS_BASE, 0); /* 22.2.4 */ + vmcs_writel(HOST_GS_BASE, 0); /* 22.2.4 */ +#endif + + vmcs_write16(HOST_TR_SELECTOR, GDT_ENTRY_TSS*8); /* 22.2.4 */ + + get_idt(&dt); + vmcs_writel(HOST_IDTR_BASE, dt.base); /* 22.2.4 */ + + asm("mov $.Lkvm_vmx_return, %0" : "=r"(kvm_vmx_return)); + vmcs_writel(HOST_RIP, kvm_vmx_return); /* 22.2.5 */ + vmcs_write32(VM_EXIT_MSR_STORE_COUNT, 0); + vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, 0); + vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, 0); + + rdmsr(MSR_IA32_SYSENTER_CS, host_sysenter_cs, junk); + vmcs_write32(HOST_IA32_SYSENTER_CS, host_sysenter_cs); + rdmsrl(MSR_IA32_SYSENTER_ESP, a); + vmcs_writel(HOST_IA32_SYSENTER_ESP, a); /* 22.2.3 */ + rdmsrl(MSR_IA32_SYSENTER_EIP, a); + vmcs_writel(HOST_IA32_SYSENTER_EIP, a); /* 22.2.3 */ + + for (i = 0; i < NR_VMX_MSR; ++i) { + u32 index = vmx_msr_index[i]; + u32 data_low, data_high; + u64 data; + int j = vmx->nmsrs; + + if (rdmsr_safe(index, &data_low, &data_high) < 0) + continue; + if (wrmsr_safe(index, data_low, data_high) < 0) + continue; + data = data_low | ((u64)data_high << 32); + vmx->host_msrs[j].index = index; + vmx->host_msrs[j].reserved = 0; + vmx->host_msrs[j].data = data; + vmx->guest_msrs[j] = vmx->host_msrs[j]; + ++vmx->nmsrs; + } + + vmcs_write32(VM_EXIT_CONTROLS, vmcs_config.vmexit_ctrl); + + /* 22.2.1, 20.8.1 */ + vmcs_write32(VM_ENTRY_CONTROLS, vmcs_config.vmentry_ctrl); + + vmcs_writel(CR0_GUEST_HOST_MASK, ~0UL); + vmcs_writel(CR4_GUEST_HOST_MASK, KVM_GUEST_CR4_MASK); + + + return 0; +} + +static int vmx_vcpu_reset(struct kvm_vcpu *vcpu) +{ + struct vcpu_vmx *vmx = to_vmx(vcpu); + u64 msr; + int ret; + + if (!init_rmode_tss(vmx->vcpu.kvm)) { + ret = -ENOMEM; + goto out; + } + + vmx->vcpu.arch.rmode.active = 0; + + vmx->vcpu.arch.regs[VCPU_REGS_RDX] = get_rdx_init_val(); + kvm_set_cr8(&vmx->vcpu, 0); + msr = 0xfee00000 | MSR_IA32_APICBASE_ENABLE; + if (vmx->vcpu.vcpu_id == 0) + msr |= MSR_IA32_APICBASE_BSP; + kvm_set_apic_base(&vmx->vcpu, msr); + + fx_init(&vmx->vcpu); + + /* + * GUEST_CS_BASE should really be 0xffff0000, but VT vm86 mode + * insists on having GUEST_CS_BASE == GUEST_CS_SELECTOR << 4. Sigh. + */ + if (vmx->vcpu.vcpu_id == 0) { + vmcs_write16(GUEST_CS_SELECTOR, 0xf000); + vmcs_writel(GUEST_CS_BASE, 0x000f0000); + } else { + vmcs_write16(GUEST_CS_SELECTOR, vmx->vcpu.arch.sipi_vector << 8); + vmcs_writel(GUEST_CS_BASE, vmx->vcpu.arch.sipi_vector << 12); + } + vmcs_write32(GUEST_CS_LIMIT, 0xffff); + vmcs_write32(GUEST_CS_AR_BYTES, 0x9b); + + seg_setup(VCPU_SREG_DS); + seg_setup(VCPU_SREG_ES); + seg_setup(VCPU_SREG_FS); + seg_setup(VCPU_SREG_GS); + seg_setup(VCPU_SREG_SS); + + vmcs_write16(GUEST_TR_SELECTOR, 0); + vmcs_writel(GUEST_TR_BASE, 0); + vmcs_write32(GUEST_TR_LIMIT, 0xffff); + vmcs_write32(GUEST_TR_AR_BYTES, 0x008b); + + vmcs_write16(GUEST_LDTR_SELECTOR, 0); + vmcs_writel(GUEST_LDTR_BASE, 0); + vmcs_write32(GUEST_LDTR_LIMIT, 0xffff); + vmcs_write32(GUEST_LDTR_AR_BYTES, 0x00082); + + vmcs_write32(GUEST_SYSENTER_CS, 0); + vmcs_writel(GUEST_SYSENTER_ESP, 0); + vmcs_writel(GUEST_SYSENTER_EIP, 0); + + vmcs_writel(GUEST_RFLAGS, 0x02); + if (vmx->vcpu.vcpu_id == 0) + vmcs_writel(GUEST_RIP, 0xfff0); + else + vmcs_writel(GUEST_RIP, 0); + vmcs_writel(GUEST_RSP, 0); + + /* todo: dr0 = dr1 = dr2 = dr3 = 0; dr6 = 0xffff0ff0 */ + vmcs_writel(GUEST_DR7, 0x400); + + vmcs_writel(GUEST_GDTR_BASE, 0); + vmcs_write32(GUEST_GDTR_LIMIT, 0xffff); + + vmcs_writel(GUEST_IDTR_BASE, 0); + vmcs_write32(GUEST_IDTR_LIMIT, 0xffff); + + vmcs_write32(GUEST_ACTIVITY_STATE, 0); + vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, 0); + vmcs_write32(GUEST_PENDING_DBG_EXCEPTIONS, 0); + + guest_write_tsc(0); + + /* Special registers */ + vmcs_write64(GUEST_IA32_DEBUGCTL, 0); + + setup_msrs(vmx); + + vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, 0); /* 22.2.1 */ + + if (cpu_has_vmx_tpr_shadow()) { + vmcs_write64(VIRTUAL_APIC_PAGE_ADDR, 0); + if (vm_need_tpr_shadow(vmx->vcpu.kvm)) + vmcs_write64(VIRTUAL_APIC_PAGE_ADDR, + page_to_phys(vmx->vcpu.arch.apic->regs_page)); + vmcs_write32(TPR_THRESHOLD, 0); + } + + if (vm_need_virtualize_apic_accesses(vmx->vcpu.kvm)) + vmcs_write64(APIC_ACCESS_ADDR, + page_to_phys(vmx->vcpu.kvm->arch.apic_access_page)); + + if (vmx->vpid != 0) + vmcs_write16(VIRTUAL_PROCESSOR_ID, vmx->vpid); + + vmx->vcpu.arch.cr0 = 0x60000010; + vmx_set_cr0(&vmx->vcpu, vmx->vcpu.arch.cr0); /* enter rmode */ + vmx_set_cr4(&vmx->vcpu, 0); + vmx_set_efer(&vmx->vcpu, 0); + vmx_fpu_activate(&vmx->vcpu); + update_exception_bitmap(&vmx->vcpu); + + vpid_sync_vcpu_all(vmx); + + return 0; + +out: + return ret; +} + +static void vmx_inject_irq(struct kvm_vcpu *vcpu, int irq) +{ + struct vcpu_vmx *vmx = to_vmx(vcpu); + + if (vcpu->arch.rmode.active) { + vmx->rmode.irq.pending = true; + vmx->rmode.irq.vector = irq; + vmx->rmode.irq.rip = vmcs_readl(GUEST_RIP); + vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, + irq | INTR_TYPE_SOFT_INTR | INTR_INFO_VALID_MASK); + vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1); + vmcs_writel(GUEST_RIP, vmx->rmode.irq.rip - 1); + return; + } + vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, + irq | INTR_TYPE_EXT_INTR | INTR_INFO_VALID_MASK); +} + +static void kvm_do_inject_irq(struct kvm_vcpu *vcpu) +{ + int word_index = __ffs(vcpu->arch.irq_summary); + int bit_index = __ffs(vcpu->arch.irq_pending[word_index]); + int irq = word_index * BITS_PER_LONG + bit_index; + + clear_bit(bit_index, &vcpu->arch.irq_pending[word_index]); + if (!vcpu->arch.irq_pending[word_index]) + clear_bit(word_index, &vcpu->arch.irq_summary); + vmx_inject_irq(vcpu, irq); +} + + +static void do_interrupt_requests(struct kvm_vcpu *vcpu, + struct kvm_run *kvm_run) +{ + u32 cpu_based_vm_exec_control; + + vcpu->arch.interrupt_window_open = + ((vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_IF) && + (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0); + + if (vcpu->arch.interrupt_window_open && + vcpu->arch.irq_summary && + !(vmcs_read32(VM_ENTRY_INTR_INFO_FIELD) & INTR_INFO_VALID_MASK)) + /* + * If interrupts enabled, and not blocked by sti or mov ss. Good. + */ + kvm_do_inject_irq(vcpu); + + cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL); + if (!vcpu->arch.interrupt_window_open && + (vcpu->arch.irq_summary || kvm_run->request_interrupt_window)) + /* + * Interrupts blocked. Wait for unblock. + */ + cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING; + else + cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING; + vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control); +} + +static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr) +{ + int ret; + struct kvm_userspace_memory_region tss_mem = { + .slot = 8, + .guest_phys_addr = addr, + .memory_size = PAGE_SIZE * 3, + .flags = 0, + }; + + ret = kvm_set_memory_region(kvm, &tss_mem, 0); + if (ret) + return ret; + kvm->arch.tss_addr = addr; + return 0; +} + +static void kvm_guest_debug_pre(struct kvm_vcpu *vcpu) +{ + struct kvm_guest_debug *dbg = &vcpu->guest_debug; + + set_debugreg(dbg->bp[0], 0); + set_debugreg(dbg->bp[1], 1); + set_debugreg(dbg->bp[2], 2); + set_debugreg(dbg->bp[3], 3); + + if (dbg->singlestep) { + unsigned long flags; + + flags = vmcs_readl(GUEST_RFLAGS); + flags |= X86_EFLAGS_TF | X86_EFLAGS_RF; + vmcs_writel(GUEST_RFLAGS, flags); + } +} + +static int handle_rmode_exception(struct kvm_vcpu *vcpu, + int vec, u32 err_code) +{ + if (!vcpu->arch.rmode.active) + return 0; + + /* + * Instruction with address size override prefix opcode 0x67 + * Cause the #SS fault with 0 error code in VM86 mode. + */ + if (((vec == GP_VECTOR) || (vec == SS_VECTOR)) && err_code == 0) + if (emulate_instruction(vcpu, NULL, 0, 0, 0) == EMULATE_DONE) + return 1; + return 0; +} + +static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + struct vcpu_vmx *vmx = to_vmx(vcpu); + u32 intr_info, error_code; + unsigned long cr2, rip; + u32 vect_info; + enum emulation_result er; + + vect_info = vmx->idt_vectoring_info; + intr_info = vmcs_read32(VM_EXIT_INTR_INFO); + + if ((vect_info & VECTORING_INFO_VALID_MASK) && + !is_page_fault(intr_info)) + printk(KERN_ERR "%s: unexpected, vectoring info 0x%x " + "intr info 0x%x\n", __FUNCTION__, vect_info, intr_info); + + if (!irqchip_in_kernel(vcpu->kvm) && is_external_interrupt(vect_info)) { + int irq = vect_info & VECTORING_INFO_VECTOR_MASK; + set_bit(irq, vcpu->arch.irq_pending); + set_bit(irq / BITS_PER_LONG, &vcpu->arch.irq_summary); + } + + if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) /* nmi */ + return 1; /* already handled by vmx_vcpu_run() */ + + if (is_no_device(intr_info)) { + vmx_fpu_activate(vcpu); + return 1; + } + + if (is_invalid_opcode(intr_info)) { + er = emulate_instruction(vcpu, kvm_run, 0, 0, EMULTYPE_TRAP_UD); + if (er != EMULATE_DONE) + kvm_queue_exception(vcpu, UD_VECTOR); + return 1; + } + + error_code = 0; + rip = vmcs_readl(GUEST_RIP); + if (intr_info & INTR_INFO_DELIVER_CODE_MASK) + error_code = vmcs_read32(VM_EXIT_INTR_ERROR_CODE); + if (is_page_fault(intr_info)) { + cr2 = vmcs_readl(EXIT_QUALIFICATION); + return kvm_mmu_page_fault(vcpu, cr2, error_code); + } + + if (vcpu->arch.rmode.active && + handle_rmode_exception(vcpu, intr_info & INTR_INFO_VECTOR_MASK, + error_code)) { + if (vcpu->arch.halt_request) { + vcpu->arch.halt_request = 0; + return kvm_emulate_halt(vcpu); + } + return 1; + } + + if ((intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK)) == + (INTR_TYPE_EXCEPTION | 1)) { + kvm_run->exit_reason = KVM_EXIT_DEBUG; + return 0; + } + kvm_run->exit_reason = KVM_EXIT_EXCEPTION; + kvm_run->ex.exception = intr_info & INTR_INFO_VECTOR_MASK; + kvm_run->ex.error_code = error_code; + return 0; +} + +static int handle_external_interrupt(struct kvm_vcpu *vcpu, + struct kvm_run *kvm_run) +{ + ++vcpu->stat.irq_exits; + return 1; +} + +static int handle_triple_fault(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + kvm_run->exit_reason = KVM_EXIT_SHUTDOWN; + return 0; +} + +static int handle_io(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + unsigned long exit_qualification; + int size, down, in, string, rep; + unsigned port; + + ++vcpu->stat.io_exits; + exit_qualification = vmcs_readl(EXIT_QUALIFICATION); + string = (exit_qualification & 16) != 0; + + if (string) { + if (emulate_instruction(vcpu, + kvm_run, 0, 0, 0) == EMULATE_DO_MMIO) + return 0; + return 1; + } + + size = (exit_qualification & 7) + 1; + in = (exit_qualification & 8) != 0; + down = (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_DF) != 0; + rep = (exit_qualification & 32) != 0; + port = exit_qualification >> 16; + + return kvm_emulate_pio(vcpu, kvm_run, in, size, port); +} + +static void +vmx_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall) +{ + /* + * Patch in the VMCALL instruction: + */ + hypercall[0] = 0x0f; + hypercall[1] = 0x01; + hypercall[2] = 0xc1; +} + +static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + unsigned long exit_qualification; + int cr; + int reg; + + exit_qualification = vmcs_readl(EXIT_QUALIFICATION); + cr = exit_qualification & 15; + reg = (exit_qualification >> 8) & 15; + switch ((exit_qualification >> 4) & 3) { + case 0: /* mov to cr */ + switch (cr) { + case 0: + vcpu_load_rsp_rip(vcpu); + kvm_set_cr0(vcpu, vcpu->arch.regs[reg]); + skip_emulated_instruction(vcpu); + return 1; + case 3: + vcpu_load_rsp_rip(vcpu); + kvm_set_cr3(vcpu, vcpu->arch.regs[reg]); + skip_emulated_instruction(vcpu); + return 1; + case 4: + vcpu_load_rsp_rip(vcpu); + kvm_set_cr4(vcpu, vcpu->arch.regs[reg]); + skip_emulated_instruction(vcpu); + return 1; + case 8: + vcpu_load_rsp_rip(vcpu); + kvm_set_cr8(vcpu, vcpu->arch.regs[reg]); + skip_emulated_instruction(vcpu); + if (irqchip_in_kernel(vcpu->kvm)) + return 1; + kvm_run->exit_reason = KVM_EXIT_SET_TPR; + return 0; + }; + break; + case 2: /* clts */ + vcpu_load_rsp_rip(vcpu); + vmx_fpu_deactivate(vcpu); + vcpu->arch.cr0 &= ~X86_CR0_TS; + vmcs_writel(CR0_READ_SHADOW, vcpu->arch.cr0); + vmx_fpu_activate(vcpu); + skip_emulated_instruction(vcpu); + return 1; + case 1: /*mov from cr*/ + switch (cr) { + case 3: + vcpu_load_rsp_rip(vcpu); + vcpu->arch.regs[reg] = vcpu->arch.cr3; + vcpu_put_rsp_rip(vcpu); + skip_emulated_instruction(vcpu); + return 1; + case 8: + vcpu_load_rsp_rip(vcpu); + vcpu->arch.regs[reg] = kvm_get_cr8(vcpu); + vcpu_put_rsp_rip(vcpu); + skip_emulated_instruction(vcpu); + return 1; + } + break; + case 3: /* lmsw */ + kvm_lmsw(vcpu, (exit_qualification >> LMSW_SOURCE_DATA_SHIFT) & 0x0f); + + skip_emulated_instruction(vcpu); + return 1; + default: + break; + } + kvm_run->exit_reason = 0; + pr_unimpl(vcpu, "unhandled control register: op %d cr %d\n", + (int)(exit_qualification >> 4) & 3, cr); + return 0; +} + +static int handle_dr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + unsigned long exit_qualification; + unsigned long val; + int dr, reg; + + /* + * FIXME: this code assumes the host is debugging the guest. + * need to deal with guest debugging itself too. + */ + exit_qualification = vmcs_readl(EXIT_QUALIFICATION); + dr = exit_qualification & 7; + reg = (exit_qualification >> 8) & 15; + vcpu_load_rsp_rip(vcpu); + if (exit_qualification & 16) { + /* mov from dr */ + switch (dr) { + case 6: + val = 0xffff0ff0; + break; + case 7: + val = 0x400; + break; + default: + val = 0; + } + vcpu->arch.regs[reg] = val; + } else { + /* mov to dr */ + } + vcpu_put_rsp_rip(vcpu); + skip_emulated_instruction(vcpu); + return 1; +} + +static int handle_cpuid(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + kvm_emulate_cpuid(vcpu); + return 1; +} + +static int handle_rdmsr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + u32 ecx = vcpu->arch.regs[VCPU_REGS_RCX]; + u64 data; + + if (vmx_get_msr(vcpu, ecx, &data)) { + kvm_inject_gp(vcpu, 0); + return 1; + } + + /* FIXME: handling of bits 32:63 of rax, rdx */ + vcpu->arch.regs[VCPU_REGS_RAX] = data & -1u; + vcpu->arch.regs[VCPU_REGS_RDX] = (data >> 32) & -1u; + skip_emulated_instruction(vcpu); + return 1; +} + +static int handle_wrmsr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + u32 ecx = vcpu->arch.regs[VCPU_REGS_RCX]; + u64 data = (vcpu->arch.regs[VCPU_REGS_RAX] & -1u) + | ((u64)(vcpu->arch.regs[VCPU_REGS_RDX] & -1u) << 32); + + if (vmx_set_msr(vcpu, ecx, data) != 0) { + kvm_inject_gp(vcpu, 0); + return 1; + } + + skip_emulated_instruction(vcpu); + return 1; +} + +static int handle_tpr_below_threshold(struct kvm_vcpu *vcpu, + struct kvm_run *kvm_run) +{ + return 1; +} + +static int handle_interrupt_window(struct kvm_vcpu *vcpu, + struct kvm_run *kvm_run) +{ + u32 cpu_based_vm_exec_control; + + /* clear pending irq */ + cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL); + cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING; + vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control); + /* + * If the user space waits to inject interrupts, exit as soon as + * possible + */ + if (kvm_run->request_interrupt_window && + !vcpu->arch.irq_summary) { + kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN; + ++vcpu->stat.irq_window_exits; + return 0; + } + return 1; +} + +static int handle_halt(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + skip_emulated_instruction(vcpu); + return kvm_emulate_halt(vcpu); +} + +static int handle_vmcall(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + skip_emulated_instruction(vcpu); + kvm_emulate_hypercall(vcpu); + return 1; +} + +static int handle_wbinvd(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + skip_emulated_instruction(vcpu); + /* TODO: Add support for VT-d/pass-through device */ + return 1; +} + +static int handle_apic_access(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + u64 exit_qualification; + enum emulation_result er; + unsigned long offset; + + exit_qualification = vmcs_read64(EXIT_QUALIFICATION); + offset = exit_qualification & 0xffful; + + er = emulate_instruction(vcpu, kvm_run, 0, 0, 0); + + if (er != EMULATE_DONE) { + printk(KERN_ERR + "Fail to handle apic access vmexit! Offset is 0x%lx\n", + offset); + return -ENOTSUPP; + } + return 1; +} + +/* + * The exit handlers return 1 if the exit was handled fully and guest execution + * may resume. Otherwise they set the kvm_run parameter to indicate what needs + * to be done to userspace and return 0. + */ +static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu, + struct kvm_run *kvm_run) = { + [EXIT_REASON_EXCEPTION_NMI] = handle_exception, + [EXIT_REASON_EXTERNAL_INTERRUPT] = handle_external_interrupt, + [EXIT_REASON_TRIPLE_FAULT] = handle_triple_fault, + [EXIT_REASON_IO_INSTRUCTION] = handle_io, + [EXIT_REASON_CR_ACCESS] = handle_cr, + [EXIT_REASON_DR_ACCESS] = handle_dr, + [EXIT_REASON_CPUID] = handle_cpuid, + [EXIT_REASON_MSR_READ] = handle_rdmsr, + [EXIT_REASON_MSR_WRITE] = handle_wrmsr, + [EXIT_REASON_PENDING_INTERRUPT] = handle_interrupt_window, + [EXIT_REASON_HLT] = handle_halt, + [EXIT_REASON_VMCALL] = handle_vmcall, + [EXIT_REASON_TPR_BELOW_THRESHOLD] = handle_tpr_below_threshold, + [EXIT_REASON_APIC_ACCESS] = handle_apic_access, + [EXIT_REASON_WBINVD] = handle_wbinvd, +}; + +static const int kvm_vmx_max_exit_handlers = + ARRAY_SIZE(kvm_vmx_exit_handlers); + +/* + * The guest has exited. See if we can fix it or if we need userspace + * assistance. + */ +static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) +{ + u32 exit_reason = vmcs_read32(VM_EXIT_REASON); + struct vcpu_vmx *vmx = to_vmx(vcpu); + u32 vectoring_info = vmx->idt_vectoring_info; + + if (unlikely(vmx->fail)) { + kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY; + kvm_run->fail_entry.hardware_entry_failure_reason + = vmcs_read32(VM_INSTRUCTION_ERROR); + return 0; + } + + if ((vectoring_info & VECTORING_INFO_VALID_MASK) && + exit_reason != EXIT_REASON_EXCEPTION_NMI) + printk(KERN_WARNING "%s: unexpected, valid vectoring info and " + "exit reason is 0x%x\n", __FUNCTION__, exit_reason); + if (exit_reason < kvm_vmx_max_exit_handlers + && kvm_vmx_exit_handlers[exit_reason]) + return kvm_vmx_exit_handlers[exit_reason](vcpu, kvm_run); + else { + kvm_run->exit_reason = KVM_EXIT_UNKNOWN; + kvm_run->hw.hardware_exit_reason = exit_reason; + } + return 0; +} + +static void update_tpr_threshold(struct kvm_vcpu *vcpu) +{ + int max_irr, tpr; + + if (!vm_need_tpr_shadow(vcpu->kvm)) + return; + + if (!kvm_lapic_enabled(vcpu) || + ((max_irr = kvm_lapic_find_highest_irr(vcpu)) == -1)) { + vmcs_write32(TPR_THRESHOLD, 0); + return; + } + + tpr = (kvm_lapic_get_cr8(vcpu) & 0x0f) << 4; + vmcs_write32(TPR_THRESHOLD, (max_irr > tpr) ? tpr >> 4 : max_irr >> 4); +} + +static void enable_irq_window(struct kvm_vcpu *vcpu) +{ + u32 cpu_based_vm_exec_control; + + cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL); + cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING; + vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control); +} + +static void vmx_intr_assist(struct kvm_vcpu *vcpu) +{ + struct vcpu_vmx *vmx = to_vmx(vcpu); + u32 idtv_info_field, intr_info_field; + int has_ext_irq, interrupt_window_open; + int vector; + + update_tpr_threshold(vcpu); + + has_ext_irq = kvm_cpu_has_interrupt(vcpu); + intr_info_field = vmcs_read32(VM_ENTRY_INTR_INFO_FIELD); + idtv_info_field = vmx->idt_vectoring_info; + if (intr_info_field & INTR_INFO_VALID_MASK) { + if (idtv_info_field & INTR_INFO_VALID_MASK) { + /* TODO: fault when IDT_Vectoring */ + if (printk_ratelimit()) + printk(KERN_ERR "Fault when IDT_Vectoring\n"); + } + if (has_ext_irq) + enable_irq_window(vcpu); + return; + } + if (unlikely(idtv_info_field & INTR_INFO_VALID_MASK)) { + if ((idtv_info_field & VECTORING_INFO_TYPE_MASK) + == INTR_TYPE_EXT_INTR + && vcpu->arch.rmode.active) { + u8 vect = idtv_info_field & VECTORING_INFO_VECTOR_MASK; + + vmx_inject_irq(vcpu, vect); + if (unlikely(has_ext_irq)) + enable_irq_window(vcpu); + return; + } + + vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, idtv_info_field); + vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, + vmcs_read32(VM_EXIT_INSTRUCTION_LEN)); + + if (unlikely(idtv_info_field & INTR_INFO_DELIVER_CODE_MASK)) + vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, + vmcs_read32(IDT_VECTORING_ERROR_CODE)); + if (unlikely(has_ext_irq)) + enable_irq_window(vcpu); + return; + } + if (!has_ext_irq) + return; + interrupt_window_open = + ((vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_IF) && + (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0); + if (interrupt_window_open) { + vector = kvm_cpu_get_interrupt(vcpu); + vmx_inject_irq(vcpu, vector); + kvm_timer_intr_post(vcpu, vector); + } else + enable_irq_window(vcpu); +} + +/* + * Failure to inject an interrupt should give us the information + * in IDT_VECTORING_INFO_FIELD. However, if the failure occurs + * when fetching the interrupt redirection bitmap in the real-mode + * tss, this doesn't happen. So we do it ourselves. + */ +static void fixup_rmode_irq(struct vcpu_vmx *vmx) +{ + vmx->rmode.irq.pending = 0; + if (vmcs_readl(GUEST_RIP) + 1 != vmx->rmode.irq.rip) + return; + vmcs_writel(GUEST_RIP, vmx->rmode.irq.rip); + if (vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK) { + vmx->idt_vectoring_info &= ~VECTORING_INFO_TYPE_MASK; + vmx->idt_vectoring_info |= INTR_TYPE_EXT_INTR; + return; + } + vmx->idt_vectoring_info = + VECTORING_INFO_VALID_MASK + | INTR_TYPE_EXT_INTR + | vmx->rmode.irq.vector; +} + +static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + struct vcpu_vmx *vmx = to_vmx(vcpu); + u32 intr_info; + + /* + * Loading guest fpu may have cleared host cr0.ts + */ + vmcs_writel(HOST_CR0, read_cr0()); + + asm( + /* Store host registers */ +#ifdef CONFIG_X86_64 + "push %%rdx; push %%rbp;" + "push %%rcx \n\t" +#else + "push %%edx; push %%ebp;" + "push %%ecx \n\t" +#endif + ASM_VMX_VMWRITE_RSP_RDX "\n\t" + /* Check if vmlaunch of vmresume is needed */ + "cmpl $0, %c[launched](%0) \n\t" + /* Load guest registers. Don't clobber flags. */ +#ifdef CONFIG_X86_64 + "mov %c[cr2](%0), %%rax \n\t" + "mov %%rax, %%cr2 \n\t" + "mov %c[rax](%0), %%rax \n\t" + "mov %c[rbx](%0), %%rbx \n\t" + "mov %c[rdx](%0), %%rdx \n\t" + "mov %c[rsi](%0), %%rsi \n\t" + "mov %c[rdi](%0), %%rdi \n\t" + "mov %c[rbp](%0), %%rbp \n\t" + "mov %c[r8](%0), %%r8 \n\t" + "mov %c[r9](%0), %%r9 \n\t" + "mov %c[r10](%0), %%r10 \n\t" + "mov %c[r11](%0), %%r11 \n\t" + "mov %c[r12](%0), %%r12 \n\t" + "mov %c[r13](%0), %%r13 \n\t" + "mov %c[r14](%0), %%r14 \n\t" + "mov %c[r15](%0), %%r15 \n\t" + "mov %c[rcx](%0), %%rcx \n\t" /* kills %0 (rcx) */ +#else + "mov %c[cr2](%0), %%eax \n\t" + "mov %%eax, %%cr2 \n\t" + "mov %c[rax](%0), %%eax \n\t" + "mov %c[rbx](%0), %%ebx \n\t" + "mov %c[rdx](%0), %%edx \n\t" + "mov %c[rsi](%0), %%esi \n\t" + "mov %c[rdi](%0), %%edi \n\t" + "mov %c[rbp](%0), %%ebp \n\t" + "mov %c[rcx](%0), %%ecx \n\t" /* kills %0 (ecx) */ +#endif + /* Enter guest mode */ + "jne .Llaunched \n\t" + ASM_VMX_VMLAUNCH "\n\t" + "jmp .Lkvm_vmx_return \n\t" + ".Llaunched: " ASM_VMX_VMRESUME "\n\t" + ".Lkvm_vmx_return: " + /* Save guest registers, load host registers, keep flags */ +#ifdef CONFIG_X86_64 + "xchg %0, (%%rsp) \n\t" + "mov %%rax, %c[rax](%0) \n\t" + "mov %%rbx, %c[rbx](%0) \n\t" + "pushq (%%rsp); popq %c[rcx](%0) \n\t" + "mov %%rdx, %c[rdx](%0) \n\t" + "mov %%rsi, %c[rsi](%0) \n\t" + "mov %%rdi, %c[rdi](%0) \n\t" + "mov %%rbp, %c[rbp](%0) \n\t" + "mov %%r8, %c[r8](%0) \n\t" + "mov %%r9, %c[r9](%0) \n\t" + "mov %%r10, %c[r10](%0) \n\t" + "mov %%r11, %c[r11](%0) \n\t" + "mov %%r12, %c[r12](%0) \n\t" + "mov %%r13, %c[r13](%0) \n\t" + "mov %%r14, %c[r14](%0) \n\t" + "mov %%r15, %c[r15](%0) \n\t" + "mov %%cr2, %%rax \n\t" + "mov %%rax, %c[cr2](%0) \n\t" + + "pop %%rbp; pop %%rbp; pop %%rdx \n\t" +#else + "xchg %0, (%%esp) \n\t" + "mov %%eax, %c[rax](%0) \n\t" + "mov %%ebx, %c[rbx](%0) \n\t" + "pushl (%%esp); popl %c[rcx](%0) \n\t" + "mov %%edx, %c[rdx](%0) \n\t" + "mov %%esi, %c[rsi](%0) \n\t" + "mov %%edi, %c[rdi](%0) \n\t" + "mov %%ebp, %c[rbp](%0) \n\t" + "mov %%cr2, %%eax \n\t" + "mov %%eax, %c[cr2](%0) \n\t" + + "pop %%ebp; pop %%ebp; pop %%edx \n\t" +#endif + "setbe %c[fail](%0) \n\t" + : : "c"(vmx), "d"((unsigned long)HOST_RSP), + [launched]"i"(offsetof(struct vcpu_vmx, launched)), + [fail]"i"(offsetof(struct vcpu_vmx, fail)), + [rax]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RAX])), + [rbx]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RBX])), + [rcx]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RCX])), + [rdx]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RDX])), + [rsi]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RSI])), + [rdi]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RDI])), + [rbp]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RBP])), +#ifdef CONFIG_X86_64 + [r8]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R8])), + [r9]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R9])), + [r10]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R10])), + [r11]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R11])), + [r12]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R12])), + [r13]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R13])), + [r14]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R14])), + [r15]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R15])), +#endif + [cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2)) + : "cc", "memory" +#ifdef CONFIG_X86_64 + , "rbx", "rdi", "rsi" + , "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" +#else + , "ebx", "edi", "rsi" +#endif + ); + + vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD); + if (vmx->rmode.irq.pending) + fixup_rmode_irq(vmx); + + vcpu->arch.interrupt_window_open = + (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0; + + asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS)); + vmx->launched = 1; + + intr_info = vmcs_read32(VM_EXIT_INTR_INFO); + + /* We need to handle NMIs before interrupts are enabled */ + if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) /* nmi */ + asm("int $2"); +} + +static void vmx_free_vmcs(struct kvm_vcpu *vcpu) +{ + struct vcpu_vmx *vmx = to_vmx(vcpu); + + if (vmx->vmcs) { + on_each_cpu(__vcpu_clear, vmx, 0, 1); + free_vmcs(vmx->vmcs); + vmx->vmcs = NULL; + } +} + +static void vmx_free_vcpu(struct kvm_vcpu *vcpu) +{ + struct vcpu_vmx *vmx = to_vmx(vcpu); + + spin_lock(&vmx_vpid_lock); + if (vmx->vpid != 0) + __clear_bit(vmx->vpid, vmx_vpid_bitmap); + spin_unlock(&vmx_vpid_lock); + vmx_free_vmcs(vcpu); + kfree(vmx->host_msrs); + kfree(vmx->guest_msrs); + kvm_vcpu_uninit(vcpu); + kmem_cache_free(kvm_vcpu_cache, vmx); +} + +static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) +{ + int err; + struct vcpu_vmx *vmx = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL); + int cpu; + + if (!vmx) + return ERR_PTR(-ENOMEM); + + allocate_vpid(vmx); + + err = kvm_vcpu_init(&vmx->vcpu, kvm, id); + if (err) + goto free_vcpu; + + vmx->guest_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!vmx->guest_msrs) { + err = -ENOMEM; + goto uninit_vcpu; + } + + vmx->host_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!vmx->host_msrs) + goto free_guest_msrs; + + vmx->vmcs = alloc_vmcs(); + if (!vmx->vmcs) + goto free_msrs; + + vmcs_clear(vmx->vmcs); + + cpu = get_cpu(); + vmx_vcpu_load(&vmx->vcpu, cpu); + err = vmx_vcpu_setup(vmx); + vmx_vcpu_put(&vmx->vcpu); + put_cpu(); + if (err) + goto free_vmcs; + if (vm_need_virtualize_apic_accesses(kvm)) + if (alloc_apic_access_page(kvm) != 0) + goto free_vmcs; + + return &vmx->vcpu; + +free_vmcs: + free_vmcs(vmx->vmcs); +free_msrs: + kfree(vmx->host_msrs); +free_guest_msrs: + kfree(vmx->guest_msrs); +uninit_vcpu: + kvm_vcpu_uninit(&vmx->vcpu); +free_vcpu: + kmem_cache_free(kvm_vcpu_cache, vmx); + return ERR_PTR(err); +} + +static void __init vmx_check_processor_compat(void *rtn) +{ + struct vmcs_config vmcs_conf; + + *(int *)rtn = 0; + if (setup_vmcs_config(&vmcs_conf) < 0) + *(int *)rtn = -EIO; + if (memcmp(&vmcs_config, &vmcs_conf, sizeof(struct vmcs_config)) != 0) { + printk(KERN_ERR "kvm: CPU %d feature inconsistency!\n", + smp_processor_id()); + *(int *)rtn = -EIO; + } +} + +static struct kvm_x86_ops vmx_x86_ops = { + .cpu_has_kvm_support = cpu_has_kvm_support, + .disabled_by_bios = vmx_disabled_by_bios, + .hardware_setup = hardware_setup, + .hardware_unsetup = hardware_unsetup, + .check_processor_compatibility = vmx_check_processor_compat, + .hardware_enable = hardware_enable, + .hardware_disable = hardware_disable, + .cpu_has_accelerated_tpr = cpu_has_vmx_virtualize_apic_accesses, + + .vcpu_create = vmx_create_vcpu, + .vcpu_free = vmx_free_vcpu, + .vcpu_reset = vmx_vcpu_reset, + + .prepare_guest_switch = vmx_save_host_state, + .vcpu_load = vmx_vcpu_load, + .vcpu_put = vmx_vcpu_put, + .vcpu_decache = vmx_vcpu_decache, + + .set_guest_debug = set_guest_debug, + .guest_debug_pre = kvm_guest_debug_pre, + .get_msr = vmx_get_msr, + .set_msr = vmx_set_msr, + .get_segment_base = vmx_get_segment_base, + .get_segment = vmx_get_segment, + .set_segment = vmx_set_segment, + .get_cs_db_l_bits = vmx_get_cs_db_l_bits, + .decache_cr4_guest_bits = vmx_decache_cr4_guest_bits, + .set_cr0 = vmx_set_cr0, + .set_cr3 = vmx_set_cr3, + .set_cr4 = vmx_set_cr4, + .set_efer = vmx_set_efer, + .get_idt = vmx_get_idt, + .set_idt = vmx_set_idt, + .get_gdt = vmx_get_gdt, + .set_gdt = vmx_set_gdt, + .cache_regs = vcpu_load_rsp_rip, + .decache_regs = vcpu_put_rsp_rip, + .get_rflags = vmx_get_rflags, + .set_rflags = vmx_set_rflags, + + .tlb_flush = vmx_flush_tlb, + + .run = vmx_vcpu_run, + .handle_exit = kvm_handle_exit, + .skip_emulated_instruction = skip_emulated_instruction, + .patch_hypercall = vmx_patch_hypercall, + .get_irq = vmx_get_irq, + .set_irq = vmx_inject_irq, + .queue_exception = vmx_queue_exception, + .exception_injected = vmx_exception_injected, + .inject_pending_irq = vmx_intr_assist, + .inject_pending_vectors = do_interrupt_requests, + + .set_tss_addr = vmx_set_tss_addr, +}; + +static int __init vmx_init(void) +{ + void *iova; + int r; + + vmx_io_bitmap_a = alloc_page(GFP_KERNEL | __GFP_HIGHMEM); + if (!vmx_io_bitmap_a) + return -ENOMEM; + + vmx_io_bitmap_b = alloc_page(GFP_KERNEL | __GFP_HIGHMEM); + if (!vmx_io_bitmap_b) { + r = -ENOMEM; + goto out; + } + + /* + * Allow direct access to the PC debug port (it is often used for I/O + * delays, but the vmexits simply slow things down). + */ + iova = kmap(vmx_io_bitmap_a); + memset(iova, 0xff, PAGE_SIZE); + clear_bit(0x80, iova); + kunmap(vmx_io_bitmap_a); + + iova = kmap(vmx_io_bitmap_b); + memset(iova, 0xff, PAGE_SIZE); + kunmap(vmx_io_bitmap_b); + + set_bit(0, vmx_vpid_bitmap); /* 0 is reserved for host */ + + r = kvm_init(&vmx_x86_ops, sizeof(struct vcpu_vmx), THIS_MODULE); + if (r) + goto out1; + + if (bypass_guest_pf) + kvm_mmu_set_nonpresent_ptes(~0xffeull, 0ull); + + return 0; + +out1: + __free_page(vmx_io_bitmap_b); +out: + __free_page(vmx_io_bitmap_a); + return r; +} + +static void __exit vmx_exit(void) +{ + __free_page(vmx_io_bitmap_b); + __free_page(vmx_io_bitmap_a); + + kvm_exit(); +} + +module_init(vmx_init) +module_exit(vmx_exit) --- linux-2.6.24.orig/arch/x86/kvm/svm.c +++ linux-2.6.24/arch/x86/kvm/svm.c @@ -0,0 +1,1874 @@ +/* + * Kernel-based Virtual Machine driver for Linux + * + * AMD SVM support + * + * Copyright (C) 2006 Qumranet, Inc. + * + * Authors: + * Yaniv Kamay + * Avi Kivity + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ +#include + +#include "kvm_svm.h" +#include "irq.h" +#include "mmu.h" + +#include +#include +#include +#include +#include + +#include + +MODULE_AUTHOR("Qumranet"); +MODULE_LICENSE("GPL"); + +#define IOPM_ALLOC_ORDER 2 +#define MSRPM_ALLOC_ORDER 1 + +#define DB_VECTOR 1 +#define UD_VECTOR 6 +#define GP_VECTOR 13 + +#define DR7_GD_MASK (1 << 13) +#define DR6_BD_MASK (1 << 13) + +#define SEG_TYPE_LDT 2 +#define SEG_TYPE_BUSY_TSS16 3 + +#define SVM_FEATURE_NPT (1 << 0) +#define SVM_FEATURE_LBRV (1 << 1) +#define SVM_DEATURE_SVML (1 << 2) + +#define DEBUGCTL_RESERVED_BITS (~(0x3fULL)) + +/* enable NPT for AMD64 and X86 with PAE */ +#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) +static bool npt_enabled = true; +#else +static bool npt_enabled = false; +#endif +static int npt = 1; + +module_param(npt, int, S_IRUGO); + +static void kvm_reput_irq(struct vcpu_svm *svm); + +static inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu) +{ + return container_of(vcpu, struct vcpu_svm, vcpu); +} + +static unsigned long iopm_base; + +struct kvm_ldttss_desc { + u16 limit0; + u16 base0; + unsigned base1 : 8, type : 5, dpl : 2, p : 1; + unsigned limit1 : 4, zero0 : 3, g : 1, base2 : 8; + u32 base3; + u32 zero1; +} __attribute__((packed)); + +struct svm_cpu_data { + int cpu; + + u64 asid_generation; + u32 max_asid; + u32 next_asid; + struct kvm_ldttss_desc *tss_desc; + + struct page *save_area; +}; + +static DEFINE_PER_CPU(struct svm_cpu_data *, svm_data); +static uint32_t svm_features; + +struct svm_init_data { + int cpu; + int r; +}; + +static u32 msrpm_ranges[] = {0, 0xc0000000, 0xc0010000}; + +#define NUM_MSR_MAPS ARRAY_SIZE(msrpm_ranges) +#define MSRS_RANGE_SIZE 2048 +#define MSRS_IN_RANGE (MSRS_RANGE_SIZE * 8 / 2) + +#define MAX_INST_SIZE 15 + +static inline u32 svm_has(u32 feat) +{ + return svm_features & feat; +} + +static inline u8 pop_irq(struct kvm_vcpu *vcpu) +{ + int word_index = __ffs(vcpu->arch.irq_summary); + int bit_index = __ffs(vcpu->arch.irq_pending[word_index]); + int irq = word_index * BITS_PER_LONG + bit_index; + + clear_bit(bit_index, &vcpu->arch.irq_pending[word_index]); + if (!vcpu->arch.irq_pending[word_index]) + clear_bit(word_index, &vcpu->arch.irq_summary); + return irq; +} + +static inline void push_irq(struct kvm_vcpu *vcpu, u8 irq) +{ + set_bit(irq, vcpu->arch.irq_pending); + set_bit(irq / BITS_PER_LONG, &vcpu->arch.irq_summary); +} + +static inline void clgi(void) +{ + asm volatile (SVM_CLGI); +} + +static inline void stgi(void) +{ + asm volatile (SVM_STGI); +} + +static inline void invlpga(unsigned long addr, u32 asid) +{ + asm volatile (SVM_INVLPGA :: "a"(addr), "c"(asid)); +} + +static inline unsigned long kvm_read_cr2(void) +{ + unsigned long cr2; + + asm volatile ("mov %%cr2, %0" : "=r" (cr2)); + return cr2; +} + +static inline void kvm_write_cr2(unsigned long val) +{ + asm volatile ("mov %0, %%cr2" :: "r" (val)); +} + +static inline unsigned long read_dr6(void) +{ + unsigned long dr6; + + asm volatile ("mov %%dr6, %0" : "=r" (dr6)); + return dr6; +} + +static inline void write_dr6(unsigned long val) +{ + asm volatile ("mov %0, %%dr6" :: "r" (val)); +} + +static inline unsigned long read_dr7(void) +{ + unsigned long dr7; + + asm volatile ("mov %%dr7, %0" : "=r" (dr7)); + return dr7; +} + +static inline void write_dr7(unsigned long val) +{ + asm volatile ("mov %0, %%dr7" :: "r" (val)); +} + +static inline void force_new_asid(struct kvm_vcpu *vcpu) +{ + to_svm(vcpu)->asid_generation--; +} + +static inline void flush_guest_tlb(struct kvm_vcpu *vcpu) +{ + force_new_asid(vcpu); +} + +static void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer) +{ + if (!npt_enabled && !(efer & EFER_LMA)) + efer &= ~EFER_LME; + + to_svm(vcpu)->vmcb->save.efer = efer | MSR_EFER_SVME_MASK; + vcpu->arch.shadow_efer = efer; +} + +static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, + bool has_error_code, u32 error_code) +{ + struct vcpu_svm *svm = to_svm(vcpu); + + svm->vmcb->control.event_inj = nr + | SVM_EVTINJ_VALID + | (has_error_code ? SVM_EVTINJ_VALID_ERR : 0) + | SVM_EVTINJ_TYPE_EXEPT; + svm->vmcb->control.event_inj_err = error_code; +} + +static bool svm_exception_injected(struct kvm_vcpu *vcpu) +{ + struct vcpu_svm *svm = to_svm(vcpu); + + return !(svm->vmcb->control.exit_int_info & SVM_EXITINTINFO_VALID); +} + +static int is_external_interrupt(u32 info) +{ + info &= SVM_EVTINJ_TYPE_MASK | SVM_EVTINJ_VALID; + return info == (SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_INTR); +} + +static void skip_emulated_instruction(struct kvm_vcpu *vcpu) +{ + struct vcpu_svm *svm = to_svm(vcpu); + + if (!svm->next_rip) { + printk(KERN_DEBUG "%s: NOP\n", __FUNCTION__); + return; + } + if (svm->next_rip - svm->vmcb->save.rip > MAX_INST_SIZE) + printk(KERN_ERR "%s: ip 0x%llx next 0x%llx\n", + __FUNCTION__, + svm->vmcb->save.rip, + svm->next_rip); + + vcpu->arch.rip = svm->vmcb->save.rip = svm->next_rip; + svm->vmcb->control.int_state &= ~SVM_INTERRUPT_SHADOW_MASK; + + vcpu->arch.interrupt_window_open = 1; +} + +static int has_svm(void) +{ + uint32_t eax, ebx, ecx, edx; + + if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) { + printk(KERN_INFO "has_svm: not amd\n"); + return 0; + } + + cpuid(0x80000000, &eax, &ebx, &ecx, &edx); + if (eax < SVM_CPUID_FUNC) { + printk(KERN_INFO "has_svm: can't execute cpuid_8000000a\n"); + return 0; + } + + cpuid(0x80000001, &eax, &ebx, &ecx, &edx); + if (!(ecx & (1 << SVM_CPUID_FEATURE_SHIFT))) { + printk(KERN_DEBUG "has_svm: svm not available\n"); + return 0; + } + return 1; +} + +static void svm_hardware_disable(void *garbage) +{ + struct svm_cpu_data *svm_data + = per_cpu(svm_data, raw_smp_processor_id()); + + if (svm_data) { + uint64_t efer; + + wrmsrl(MSR_VM_HSAVE_PA, 0); + rdmsrl(MSR_EFER, efer); + wrmsrl(MSR_EFER, efer & ~MSR_EFER_SVME_MASK); + per_cpu(svm_data, raw_smp_processor_id()) = NULL; + __free_page(svm_data->save_area); + kfree(svm_data); + } +} + +static void svm_hardware_enable(void *garbage) +{ + + struct svm_cpu_data *svm_data; + uint64_t efer; +#ifdef CONFIG_X86_64 + struct desc_ptr gdt_descr; +#else + struct Xgt_desc_struct gdt_descr; +#endif + struct desc_struct *gdt; + int me = raw_smp_processor_id(); + + if (!has_svm()) { + printk(KERN_ERR "svm_cpu_init: err EOPNOTSUPP on %d\n", me); + return; + } + svm_data = per_cpu(svm_data, me); + + if (!svm_data) { + printk(KERN_ERR "svm_cpu_init: svm_data is NULL on %d\n", + me); + return; + } + + svm_data->asid_generation = 1; + svm_data->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1; + svm_data->next_asid = svm_data->max_asid + 1; + + asm volatile ("sgdt %0" : "=m"(gdt_descr)); + gdt = (struct desc_struct *)gdt_descr.address; + svm_data->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS); + + rdmsrl(MSR_EFER, efer); + wrmsrl(MSR_EFER, efer | MSR_EFER_SVME_MASK); + + wrmsrl(MSR_VM_HSAVE_PA, + page_to_pfn(svm_data->save_area) << PAGE_SHIFT); +} + +static int svm_cpu_init(int cpu) +{ + struct svm_cpu_data *svm_data; + int r; + + svm_data = kzalloc(sizeof(struct svm_cpu_data), GFP_KERNEL); + if (!svm_data) + return -ENOMEM; + svm_data->cpu = cpu; + svm_data->save_area = alloc_page(GFP_KERNEL); + r = -ENOMEM; + if (!svm_data->save_area) + goto err_1; + + per_cpu(svm_data, cpu) = svm_data; + + return 0; + +err_1: + kfree(svm_data); + return r; + +} + +static void set_msr_interception(u32 *msrpm, unsigned msr, + int read, int write) +{ + int i; + + for (i = 0; i < NUM_MSR_MAPS; i++) { + if (msr >= msrpm_ranges[i] && + msr < msrpm_ranges[i] + MSRS_IN_RANGE) { + u32 msr_offset = (i * MSRS_IN_RANGE + msr - + msrpm_ranges[i]) * 2; + + u32 *base = msrpm + (msr_offset / 32); + u32 msr_shift = msr_offset % 32; + u32 mask = ((write) ? 0 : 2) | ((read) ? 0 : 1); + *base = (*base & ~(0x3 << msr_shift)) | + (mask << msr_shift); + return; + } + } + BUG(); +} + +static void svm_vcpu_init_msrpm(u32 *msrpm) +{ + memset(msrpm, 0xff, PAGE_SIZE * (1 << MSRPM_ALLOC_ORDER)); + +#ifdef CONFIG_X86_64 + set_msr_interception(msrpm, MSR_GS_BASE, 1, 1); + set_msr_interception(msrpm, MSR_FS_BASE, 1, 1); + set_msr_interception(msrpm, MSR_KERNEL_GS_BASE, 1, 1); + set_msr_interception(msrpm, MSR_LSTAR, 1, 1); + set_msr_interception(msrpm, MSR_CSTAR, 1, 1); + set_msr_interception(msrpm, MSR_SYSCALL_MASK, 1, 1); +#endif + set_msr_interception(msrpm, MSR_K6_STAR, 1, 1); + set_msr_interception(msrpm, MSR_IA32_SYSENTER_CS, 1, 1); + set_msr_interception(msrpm, MSR_IA32_SYSENTER_ESP, 1, 1); + set_msr_interception(msrpm, MSR_IA32_SYSENTER_EIP, 1, 1); +} + +static void svm_enable_lbrv(struct vcpu_svm *svm) +{ + u32 *msrpm = svm->msrpm; + + svm->vmcb->control.lbr_ctl = 1; + set_msr_interception(msrpm, MSR_IA32_LASTBRANCHFROMIP, 1, 1); + set_msr_interception(msrpm, MSR_IA32_LASTBRANCHTOIP, 1, 1); + set_msr_interception(msrpm, MSR_IA32_LASTINTFROMIP, 1, 1); + set_msr_interception(msrpm, MSR_IA32_LASTINTTOIP, 1, 1); +} + +static void svm_disable_lbrv(struct vcpu_svm *svm) +{ + u32 *msrpm = svm->msrpm; + + svm->vmcb->control.lbr_ctl = 0; + set_msr_interception(msrpm, MSR_IA32_LASTBRANCHFROMIP, 0, 0); + set_msr_interception(msrpm, MSR_IA32_LASTBRANCHTOIP, 0, 0); + set_msr_interception(msrpm, MSR_IA32_LASTINTFROMIP, 0, 0); + set_msr_interception(msrpm, MSR_IA32_LASTINTTOIP, 0, 0); +} + +static __init int svm_hardware_setup(void) +{ + int cpu; + struct page *iopm_pages; + void *iopm_va; + int r; + + iopm_pages = alloc_pages(GFP_KERNEL, IOPM_ALLOC_ORDER); + + if (!iopm_pages) + return -ENOMEM; + + iopm_va = page_address(iopm_pages); + memset(iopm_va, 0xff, PAGE_SIZE * (1 << IOPM_ALLOC_ORDER)); + clear_bit(0x80, iopm_va); /* allow direct access to PC debug port */ + iopm_base = page_to_pfn(iopm_pages) << PAGE_SHIFT; + + if (boot_cpu_has(X86_FEATURE_NX)) + kvm_enable_efer_bits(EFER_NX); + + for_each_online_cpu(cpu) { + r = svm_cpu_init(cpu); + if (r) + goto err; + } + + svm_features = cpuid_edx(SVM_CPUID_FUNC); + + if (!svm_has(SVM_FEATURE_NPT)) + npt_enabled = false; + + if (npt_enabled && !npt) { + printk(KERN_INFO "kvm: Nested Paging disabled\n"); + npt_enabled = false; + } + + if (npt_enabled) { + printk(KERN_INFO "kvm: Nested Paging enabled\n"); + kvm_enable_tdp(); + } + + return 0; + +err: + __free_pages(iopm_pages, IOPM_ALLOC_ORDER); + iopm_base = 0; + return r; +} + +static __exit void svm_hardware_unsetup(void) +{ + __free_pages(pfn_to_page(iopm_base >> PAGE_SHIFT), IOPM_ALLOC_ORDER); + iopm_base = 0; +} + +static void init_seg(struct vmcb_seg *seg) +{ + seg->selector = 0; + seg->attrib = SVM_SELECTOR_P_MASK | SVM_SELECTOR_S_MASK | + SVM_SELECTOR_WRITE_MASK; /* Read/Write Data Segment */ + seg->limit = 0xffff; + seg->base = 0; +} + +static void init_sys_seg(struct vmcb_seg *seg, uint32_t type) +{ + seg->selector = 0; + seg->attrib = SVM_SELECTOR_P_MASK | type; + seg->limit = 0xffff; + seg->base = 0; +} + +static void init_vmcb(struct vcpu_svm *svm) +{ + struct vmcb_control_area *control = &svm->vmcb->control; + struct vmcb_save_area *save = &svm->vmcb->save; + + control->intercept_cr_read = INTERCEPT_CR0_MASK | + INTERCEPT_CR3_MASK | + INTERCEPT_CR4_MASK | + INTERCEPT_CR8_MASK; + + control->intercept_cr_write = INTERCEPT_CR0_MASK | + INTERCEPT_CR3_MASK | + INTERCEPT_CR4_MASK | + INTERCEPT_CR8_MASK; + + control->intercept_dr_read = INTERCEPT_DR0_MASK | + INTERCEPT_DR1_MASK | + INTERCEPT_DR2_MASK | + INTERCEPT_DR3_MASK; + + control->intercept_dr_write = INTERCEPT_DR0_MASK | + INTERCEPT_DR1_MASK | + INTERCEPT_DR2_MASK | + INTERCEPT_DR3_MASK | + INTERCEPT_DR5_MASK | + INTERCEPT_DR7_MASK; + + control->intercept_exceptions = (1 << PF_VECTOR) | + (1 << UD_VECTOR); + + + control->intercept = (1ULL << INTERCEPT_INTR) | + (1ULL << INTERCEPT_NMI) | + (1ULL << INTERCEPT_SMI) | + /* + * selective cr0 intercept bug? + * 0: 0f 22 d8 mov %eax,%cr3 + * 3: 0f 20 c0 mov %cr0,%eax + * 6: 0d 00 00 00 80 or $0x80000000,%eax + * b: 0f 22 c0 mov %eax,%cr0 + * set cr3 ->interception + * get cr0 ->interception + * set cr0 -> no interception + */ + /* (1ULL << INTERCEPT_SELECTIVE_CR0) | */ + (1ULL << INTERCEPT_CPUID) | + (1ULL << INTERCEPT_INVD) | + (1ULL << INTERCEPT_HLT) | + (1ULL << INTERCEPT_INVLPGA) | + (1ULL << INTERCEPT_IOIO_PROT) | + (1ULL << INTERCEPT_MSR_PROT) | + (1ULL << INTERCEPT_TASK_SWITCH) | + (1ULL << INTERCEPT_SHUTDOWN) | + (1ULL << INTERCEPT_VMRUN) | + (1ULL << INTERCEPT_VMMCALL) | + (1ULL << INTERCEPT_VMLOAD) | + (1ULL << INTERCEPT_VMSAVE) | + (1ULL << INTERCEPT_STGI) | + (1ULL << INTERCEPT_CLGI) | + (1ULL << INTERCEPT_SKINIT) | + (1ULL << INTERCEPT_WBINVD) | + (1ULL << INTERCEPT_MONITOR) | + (1ULL << INTERCEPT_MWAIT); + + control->iopm_base_pa = iopm_base; + control->msrpm_base_pa = __pa(svm->msrpm); + control->tsc_offset = 0; + control->int_ctl = V_INTR_MASKING_MASK; + + init_seg(&save->es); + init_seg(&save->ss); + init_seg(&save->ds); + init_seg(&save->fs); + init_seg(&save->gs); + + save->cs.selector = 0xf000; + /* Executable/Readable Code Segment */ + save->cs.attrib = SVM_SELECTOR_READ_MASK | SVM_SELECTOR_P_MASK | + SVM_SELECTOR_S_MASK | SVM_SELECTOR_CODE_MASK; + save->cs.limit = 0xffff; + /* + * cs.base should really be 0xffff0000, but vmx can't handle that, so + * be consistent with it. + * + * Replace when we have real mode working for vmx. + */ + save->cs.base = 0xf0000; + + save->gdtr.limit = 0xffff; + save->idtr.limit = 0xffff; + + init_sys_seg(&save->ldtr, SEG_TYPE_LDT); + init_sys_seg(&save->tr, SEG_TYPE_BUSY_TSS16); + + save->efer = MSR_EFER_SVME_MASK; + save->dr6 = 0xffff0ff0; + save->dr7 = 0x400; + save->rflags = 2; + save->rip = 0x0000fff0; + + /* + * cr0 val on cpu init should be 0x60000010, we enable cpu + * cache by default. the orderly way is to enable cache in bios. + */ + save->cr0 = 0x00000010 | X86_CR0_PG | X86_CR0_WP; + save->cr4 = X86_CR4_PAE; + /* rdx = ?? */ + + if (npt_enabled) { + /* Setup VMCB for Nested Paging */ + control->nested_ctl = 1; + control->intercept_exceptions &= ~(1 << PF_VECTOR); + control->intercept_cr_read &= ~(INTERCEPT_CR0_MASK| + INTERCEPT_CR3_MASK); + control->intercept_cr_write &= ~(INTERCEPT_CR0_MASK| + INTERCEPT_CR3_MASK); + save->g_pat = 0x0007040600070406ULL; + /* enable caching because the QEMU Bios doesn't enable it */ + save->cr0 = X86_CR0_ET; + save->cr3 = 0; + save->cr4 = 0; + } + +} + +static int svm_vcpu_reset(struct kvm_vcpu *vcpu) +{ + struct vcpu_svm *svm = to_svm(vcpu); + + init_vmcb(svm); + + if (vcpu->vcpu_id != 0) { + svm->vmcb->save.rip = 0; + svm->vmcb->save.cs.base = svm->vcpu.arch.sipi_vector << 12; + svm->vmcb->save.cs.selector = svm->vcpu.arch.sipi_vector << 8; + } + + return 0; +} + +static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) +{ + struct vcpu_svm *svm; + struct page *page; + struct page *msrpm_pages; + int err; + + svm = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL); + if (!svm) { + err = -ENOMEM; + goto out; + } + + err = kvm_vcpu_init(&svm->vcpu, kvm, id); + if (err) + goto free_svm; + + page = alloc_page(GFP_KERNEL); + if (!page) { + err = -ENOMEM; + goto uninit; + } + + err = -ENOMEM; + msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER); + if (!msrpm_pages) + goto uninit; + svm->msrpm = page_address(msrpm_pages); + svm_vcpu_init_msrpm(svm->msrpm); + + svm->vmcb = page_address(page); + clear_page(svm->vmcb); + svm->vmcb_pa = page_to_pfn(page) << PAGE_SHIFT; + svm->asid_generation = 0; + memset(svm->db_regs, 0, sizeof(svm->db_regs)); + init_vmcb(svm); + + fx_init(&svm->vcpu); + svm->vcpu.fpu_active = 1; + svm->vcpu.arch.apic_base = 0xfee00000 | MSR_IA32_APICBASE_ENABLE; + if (svm->vcpu.vcpu_id == 0) + svm->vcpu.arch.apic_base |= MSR_IA32_APICBASE_BSP; + + return &svm->vcpu; + +uninit: + kvm_vcpu_uninit(&svm->vcpu); +free_svm: + kmem_cache_free(kvm_vcpu_cache, svm); +out: + return ERR_PTR(err); +} + +static void svm_free_vcpu(struct kvm_vcpu *vcpu) +{ + struct vcpu_svm *svm = to_svm(vcpu); + + __free_page(pfn_to_page(svm->vmcb_pa >> PAGE_SHIFT)); + __free_pages(virt_to_page(svm->msrpm), MSRPM_ALLOC_ORDER); + kvm_vcpu_uninit(vcpu); + kmem_cache_free(kvm_vcpu_cache, svm); +} + +static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +{ + struct vcpu_svm *svm = to_svm(vcpu); + int i; + + if (unlikely(cpu != vcpu->cpu)) { + u64 tsc_this, delta; + + /* + * Make sure that the guest sees a monotonically + * increasing TSC. + */ + rdtscll(tsc_this); + delta = vcpu->arch.host_tsc - tsc_this; + svm->vmcb->control.tsc_offset += delta; + vcpu->cpu = cpu; + kvm_migrate_apic_timer(vcpu); + } + + for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++) + rdmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]); +} + +static void svm_vcpu_put(struct kvm_vcpu *vcpu) +{ + struct vcpu_svm *svm = to_svm(vcpu); + int i; + + ++vcpu->stat.host_state_reload; + for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++) + wrmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]); + + rdtscll(vcpu->arch.host_tsc); +} + +static void svm_vcpu_decache(struct kvm_vcpu *vcpu) +{ +} + +static void svm_cache_regs(struct kvm_vcpu *vcpu) +{ + struct vcpu_svm *svm = to_svm(vcpu); + + vcpu->arch.regs[VCPU_REGS_RAX] = svm->vmcb->save.rax; + vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp; + vcpu->arch.rip = svm->vmcb->save.rip; +} + +static void svm_decache_regs(struct kvm_vcpu *vcpu) +{ + struct vcpu_svm *svm = to_svm(vcpu); + svm->vmcb->save.rax = vcpu->arch.regs[VCPU_REGS_RAX]; + svm->vmcb->save.rsp = vcpu->arch.regs[VCPU_REGS_RSP]; + svm->vmcb->save.rip = vcpu->arch.rip; +} + +static unsigned long svm_get_rflags(struct kvm_vcpu *vcpu) +{ + return to_svm(vcpu)->vmcb->save.rflags; +} + +static void svm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) +{ + to_svm(vcpu)->vmcb->save.rflags = rflags; +} + +static struct vmcb_seg *svm_seg(struct kvm_vcpu *vcpu, int seg) +{ + struct vmcb_save_area *save = &to_svm(vcpu)->vmcb->save; + + switch (seg) { + case VCPU_SREG_CS: return &save->cs; + case VCPU_SREG_DS: return &save->ds; + case VCPU_SREG_ES: return &save->es; + case VCPU_SREG_FS: return &save->fs; + case VCPU_SREG_GS: return &save->gs; + case VCPU_SREG_SS: return &save->ss; + case VCPU_SREG_TR: return &save->tr; + case VCPU_SREG_LDTR: return &save->ldtr; + } + BUG(); + return NULL; +} + +static u64 svm_get_segment_base(struct kvm_vcpu *vcpu, int seg) +{ + struct vmcb_seg *s = svm_seg(vcpu, seg); + + return s->base; +} + +static void svm_get_segment(struct kvm_vcpu *vcpu, + struct kvm_segment *var, int seg) +{ + struct vmcb_seg *s = svm_seg(vcpu, seg); + + var->base = s->base; + var->limit = s->limit; + var->selector = s->selector; + var->type = s->attrib & SVM_SELECTOR_TYPE_MASK; + var->s = (s->attrib >> SVM_SELECTOR_S_SHIFT) & 1; + var->dpl = (s->attrib >> SVM_SELECTOR_DPL_SHIFT) & 3; + var->present = (s->attrib >> SVM_SELECTOR_P_SHIFT) & 1; + var->avl = (s->attrib >> SVM_SELECTOR_AVL_SHIFT) & 1; + var->l = (s->attrib >> SVM_SELECTOR_L_SHIFT) & 1; + var->db = (s->attrib >> SVM_SELECTOR_DB_SHIFT) & 1; + var->g = (s->attrib >> SVM_SELECTOR_G_SHIFT) & 1; + var->unusable = !var->present; +} + +static void svm_get_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) +{ + struct vcpu_svm *svm = to_svm(vcpu); + + dt->limit = svm->vmcb->save.idtr.limit; + dt->base = svm->vmcb->save.idtr.base; +} + +static void svm_set_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) +{ + struct vcpu_svm *svm = to_svm(vcpu); + + svm->vmcb->save.idtr.limit = dt->limit; + svm->vmcb->save.idtr.base = dt->base ; +} + +static void svm_get_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) +{ + struct vcpu_svm *svm = to_svm(vcpu); + + dt->limit = svm->vmcb->save.gdtr.limit; + dt->base = svm->vmcb->save.gdtr.base; +} + +static void svm_set_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) +{ + struct vcpu_svm *svm = to_svm(vcpu); + + svm->vmcb->save.gdtr.limit = dt->limit; + svm->vmcb->save.gdtr.base = dt->base ; +} + +static void svm_decache_cr4_guest_bits(struct kvm_vcpu *vcpu) +{ +} + +static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) +{ + struct vcpu_svm *svm = to_svm(vcpu); + +#ifdef CONFIG_X86_64 + if (vcpu->arch.shadow_efer & EFER_LME) { + if (!is_paging(vcpu) && (cr0 & X86_CR0_PG)) { + vcpu->arch.shadow_efer |= EFER_LMA; + svm->vmcb->save.efer |= EFER_LMA | EFER_LME; + } + + if (is_paging(vcpu) && !(cr0 & X86_CR0_PG)) { + vcpu->arch.shadow_efer &= ~EFER_LMA; + svm->vmcb->save.efer &= ~(EFER_LMA | EFER_LME); + } + } +#endif + if (npt_enabled) + goto set; + + if ((vcpu->arch.cr0 & X86_CR0_TS) && !(cr0 & X86_CR0_TS)) { + svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR); + vcpu->fpu_active = 1; + } + + vcpu->arch.cr0 = cr0; + cr0 |= X86_CR0_PG | X86_CR0_WP; + if (!vcpu->fpu_active) { + svm->vmcb->control.intercept_exceptions |= (1 << NM_VECTOR); + cr0 |= X86_CR0_TS; + } +set: + /* + * re-enable caching here because the QEMU bios + * does not do it - this results in some delay at + * reboot + */ + cr0 &= ~(X86_CR0_CD | X86_CR0_NW); + svm->vmcb->save.cr0 = cr0; +} + +static void svm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) +{ + vcpu->arch.cr4 = cr4; + if (!npt_enabled) + cr4 |= X86_CR4_PAE; + to_svm(vcpu)->vmcb->save.cr4 = cr4; +} + +static void svm_set_segment(struct kvm_vcpu *vcpu, + struct kvm_segment *var, int seg) +{ + struct vcpu_svm *svm = to_svm(vcpu); + struct vmcb_seg *s = svm_seg(vcpu, seg); + + s->base = var->base; + s->limit = var->limit; + s->selector = var->selector; + if (var->unusable) + s->attrib = 0; + else { + s->attrib = (var->type & SVM_SELECTOR_TYPE_MASK); + s->attrib |= (var->s & 1) << SVM_SELECTOR_S_SHIFT; + s->attrib |= (var->dpl & 3) << SVM_SELECTOR_DPL_SHIFT; + s->attrib |= (var->present & 1) << SVM_SELECTOR_P_SHIFT; + s->attrib |= (var->avl & 1) << SVM_SELECTOR_AVL_SHIFT; + s->attrib |= (var->l & 1) << SVM_SELECTOR_L_SHIFT; + s->attrib |= (var->db & 1) << SVM_SELECTOR_DB_SHIFT; + s->attrib |= (var->g & 1) << SVM_SELECTOR_G_SHIFT; + } + if (seg == VCPU_SREG_CS) + svm->vmcb->save.cpl + = (svm->vmcb->save.cs.attrib + >> SVM_SELECTOR_DPL_SHIFT) & 3; + +} + +/* FIXME: + + svm(vcpu)->vmcb->control.int_ctl &= ~V_TPR_MASK; + svm(vcpu)->vmcb->control.int_ctl |= (sregs->cr8 & V_TPR_MASK); + +*/ + +static int svm_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg) +{ + return -EOPNOTSUPP; +} + +static int svm_get_irq(struct kvm_vcpu *vcpu) +{ + struct vcpu_svm *svm = to_svm(vcpu); + u32 exit_int_info = svm->vmcb->control.exit_int_info; + + if (is_external_interrupt(exit_int_info)) + return exit_int_info & SVM_EVTINJ_VEC_MASK; + return -1; +} + +static void load_host_msrs(struct kvm_vcpu *vcpu) +{ +#ifdef CONFIG_X86_64 + wrmsrl(MSR_GS_BASE, to_svm(vcpu)->host_gs_base); +#endif +} + +static void save_host_msrs(struct kvm_vcpu *vcpu) +{ +#ifdef CONFIG_X86_64 + rdmsrl(MSR_GS_BASE, to_svm(vcpu)->host_gs_base); +#endif +} + +static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *svm_data) +{ + if (svm_data->next_asid > svm_data->max_asid) { + ++svm_data->asid_generation; + svm_data->next_asid = 1; + svm->vmcb->control.tlb_ctl = TLB_CONTROL_FLUSH_ALL_ASID; + } + + svm->vcpu.cpu = svm_data->cpu; + svm->asid_generation = svm_data->asid_generation; + svm->vmcb->control.asid = svm_data->next_asid++; +} + +static unsigned long svm_get_dr(struct kvm_vcpu *vcpu, int dr) +{ + return to_svm(vcpu)->db_regs[dr]; +} + +static void svm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long value, + int *exception) +{ + struct vcpu_svm *svm = to_svm(vcpu); + + *exception = 0; + + if (svm->vmcb->save.dr7 & DR7_GD_MASK) { + svm->vmcb->save.dr7 &= ~DR7_GD_MASK; + svm->vmcb->save.dr6 |= DR6_BD_MASK; + *exception = DB_VECTOR; + return; + } + + switch (dr) { + case 0 ... 3: + svm->db_regs[dr] = value; + return; + case 4 ... 5: + if (vcpu->arch.cr4 & X86_CR4_DE) { + *exception = UD_VECTOR; + return; + } + case 7: { + if (value & ~((1ULL << 32) - 1)) { + *exception = GP_VECTOR; + return; + } + svm->vmcb->save.dr7 = value; + return; + } + default: + printk(KERN_DEBUG "%s: unexpected dr %u\n", + __FUNCTION__, dr); + *exception = UD_VECTOR; + return; + } +} + +static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) +{ + u32 exit_int_info = svm->vmcb->control.exit_int_info; + struct kvm *kvm = svm->vcpu.kvm; + u64 fault_address; + u32 error_code; + + if (!irqchip_in_kernel(kvm) && + is_external_interrupt(exit_int_info)) + push_irq(&svm->vcpu, exit_int_info & SVM_EVTINJ_VEC_MASK); + + fault_address = svm->vmcb->control.exit_info_2; + error_code = svm->vmcb->control.exit_info_1; + return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code); +} + +static int ud_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) +{ + int er; + + er = emulate_instruction(&svm->vcpu, kvm_run, 0, 0, EMULTYPE_TRAP_UD); + if (er != EMULATE_DONE) + kvm_queue_exception(&svm->vcpu, UD_VECTOR); + return 1; +} + +static int nm_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) +{ + svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR); + if (!(svm->vcpu.arch.cr0 & X86_CR0_TS)) + svm->vmcb->save.cr0 &= ~X86_CR0_TS; + svm->vcpu.fpu_active = 1; + + return 1; +} + +static int shutdown_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) +{ + /* + * VMCB is undefined after a SHUTDOWN intercept + * so reinitialize it. + */ + clear_page(svm->vmcb); + init_vmcb(svm); + + kvm_run->exit_reason = KVM_EXIT_SHUTDOWN; + return 0; +} + +static int io_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) +{ + u32 io_info = svm->vmcb->control.exit_info_1; /* address size bug? */ + int size, down, in, string, rep; + unsigned port; + + ++svm->vcpu.stat.io_exits; + + svm->next_rip = svm->vmcb->control.exit_info_2; + + string = (io_info & SVM_IOIO_STR_MASK) != 0; + + if (string) { + if (emulate_instruction(&svm->vcpu, + kvm_run, 0, 0, 0) == EMULATE_DO_MMIO) + return 0; + return 1; + } + + in = (io_info & SVM_IOIO_TYPE_MASK) != 0; + port = io_info >> 16; + size = (io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT; + rep = (io_info & SVM_IOIO_REP_MASK) != 0; + down = (svm->vmcb->save.rflags & X86_EFLAGS_DF) != 0; + + return kvm_emulate_pio(&svm->vcpu, kvm_run, in, size, port); +} + +static int nop_on_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) +{ + return 1; +} + +static int halt_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) +{ + svm->next_rip = svm->vmcb->save.rip + 1; + skip_emulated_instruction(&svm->vcpu); + return kvm_emulate_halt(&svm->vcpu); +} + +static int vmmcall_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) +{ + svm->next_rip = svm->vmcb->save.rip + 3; + skip_emulated_instruction(&svm->vcpu); + kvm_emulate_hypercall(&svm->vcpu); + return 1; +} + +static int invalid_op_interception(struct vcpu_svm *svm, + struct kvm_run *kvm_run) +{ + kvm_queue_exception(&svm->vcpu, UD_VECTOR); + return 1; +} + +static int task_switch_interception(struct vcpu_svm *svm, + struct kvm_run *kvm_run) +{ + pr_unimpl(&svm->vcpu, "%s: task switch is unsupported\n", __FUNCTION__); + kvm_run->exit_reason = KVM_EXIT_UNKNOWN; + return 0; +} + +static int cpuid_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) +{ + svm->next_rip = svm->vmcb->save.rip + 2; + kvm_emulate_cpuid(&svm->vcpu); + return 1; +} + +static int emulate_on_interception(struct vcpu_svm *svm, + struct kvm_run *kvm_run) +{ + if (emulate_instruction(&svm->vcpu, NULL, 0, 0, 0) != EMULATE_DONE) + pr_unimpl(&svm->vcpu, "%s: failed\n", __FUNCTION__); + return 1; +} + +static int cr8_write_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) +{ + emulate_instruction(&svm->vcpu, NULL, 0, 0, 0); + if (irqchip_in_kernel(svm->vcpu.kvm)) + return 1; + kvm_run->exit_reason = KVM_EXIT_SET_TPR; + return 0; +} + +static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data) +{ + struct vcpu_svm *svm = to_svm(vcpu); + + switch (ecx) { + case MSR_IA32_TIME_STAMP_COUNTER: { + u64 tsc; + + rdtscll(tsc); + *data = svm->vmcb->control.tsc_offset + tsc; + break; + } + case MSR_K6_STAR: + *data = svm->vmcb->save.star; + break; +#ifdef CONFIG_X86_64 + case MSR_LSTAR: + *data = svm->vmcb->save.lstar; + break; + case MSR_CSTAR: + *data = svm->vmcb->save.cstar; + break; + case MSR_KERNEL_GS_BASE: + *data = svm->vmcb->save.kernel_gs_base; + break; + case MSR_SYSCALL_MASK: + *data = svm->vmcb->save.sfmask; + break; +#endif + case MSR_IA32_SYSENTER_CS: + *data = svm->vmcb->save.sysenter_cs; + break; + case MSR_IA32_SYSENTER_EIP: + *data = svm->vmcb->save.sysenter_eip; + break; + case MSR_IA32_SYSENTER_ESP: + *data = svm->vmcb->save.sysenter_esp; + break; + /* Nobody will change the following 5 values in the VMCB so + we can safely return them on rdmsr. They will always be 0 + until LBRV is implemented. */ + case MSR_IA32_DEBUGCTLMSR: + *data = svm->vmcb->save.dbgctl; + break; + case MSR_IA32_LASTBRANCHFROMIP: + *data = svm->vmcb->save.br_from; + break; + case MSR_IA32_LASTBRANCHTOIP: + *data = svm->vmcb->save.br_to; + break; + case MSR_IA32_LASTINTFROMIP: + *data = svm->vmcb->save.last_excp_from; + break; + case MSR_IA32_LASTINTTOIP: + *data = svm->vmcb->save.last_excp_to; + break; + default: + return kvm_get_msr_common(vcpu, ecx, data); + } + return 0; +} + +static int rdmsr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) +{ + u32 ecx = svm->vcpu.arch.regs[VCPU_REGS_RCX]; + u64 data; + + if (svm_get_msr(&svm->vcpu, ecx, &data)) + kvm_inject_gp(&svm->vcpu, 0); + else { + svm->vmcb->save.rax = data & 0xffffffff; + svm->vcpu.arch.regs[VCPU_REGS_RDX] = data >> 32; + svm->next_rip = svm->vmcb->save.rip + 2; + skip_emulated_instruction(&svm->vcpu); + } + return 1; +} + +static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) +{ + struct vcpu_svm *svm = to_svm(vcpu); + + switch (ecx) { + case MSR_IA32_TIME_STAMP_COUNTER: { + u64 tsc; + + rdtscll(tsc); + svm->vmcb->control.tsc_offset = data - tsc; + break; + } + case MSR_K6_STAR: + svm->vmcb->save.star = data; + break; +#ifdef CONFIG_X86_64 + case MSR_LSTAR: + svm->vmcb->save.lstar = data; + break; + case MSR_CSTAR: + svm->vmcb->save.cstar = data; + break; + case MSR_KERNEL_GS_BASE: + svm->vmcb->save.kernel_gs_base = data; + break; + case MSR_SYSCALL_MASK: + svm->vmcb->save.sfmask = data; + break; +#endif + case MSR_IA32_SYSENTER_CS: + svm->vmcb->save.sysenter_cs = data; + break; + case MSR_IA32_SYSENTER_EIP: + svm->vmcb->save.sysenter_eip = data; + break; + case MSR_IA32_SYSENTER_ESP: + svm->vmcb->save.sysenter_esp = data; + break; + case MSR_IA32_DEBUGCTLMSR: + if (!svm_has(SVM_FEATURE_LBRV)) { + pr_unimpl(vcpu, "%s: MSR_IA32_DEBUGCTL 0x%llx, nop\n", + __FUNCTION__, data); + break; + } + if (data & DEBUGCTL_RESERVED_BITS) + return 1; + + svm->vmcb->save.dbgctl = data; + if (data & (1ULL<<0)) + svm_enable_lbrv(svm); + else + svm_disable_lbrv(svm); + break; + case MSR_K7_EVNTSEL0: + case MSR_K7_EVNTSEL1: + case MSR_K7_EVNTSEL2: + case MSR_K7_EVNTSEL3: + /* + * only support writing 0 to the performance counters for now + * to make Windows happy. Should be replaced by a real + * performance counter emulation later. + */ + if (data != 0) + goto unhandled; + break; + default: + unhandled: + return kvm_set_msr_common(vcpu, ecx, data); + } + return 0; +} + +static int wrmsr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) +{ + u32 ecx = svm->vcpu.arch.regs[VCPU_REGS_RCX]; + u64 data = (svm->vmcb->save.rax & -1u) + | ((u64)(svm->vcpu.arch.regs[VCPU_REGS_RDX] & -1u) << 32); + svm->next_rip = svm->vmcb->save.rip + 2; + if (svm_set_msr(&svm->vcpu, ecx, data)) + kvm_inject_gp(&svm->vcpu, 0); + else + skip_emulated_instruction(&svm->vcpu); + return 1; +} + +static int msr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) +{ + if (svm->vmcb->control.exit_info_1) + return wrmsr_interception(svm, kvm_run); + else + return rdmsr_interception(svm, kvm_run); +} + +static int interrupt_window_interception(struct vcpu_svm *svm, + struct kvm_run *kvm_run) +{ + svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_VINTR); + svm->vmcb->control.int_ctl &= ~V_IRQ_MASK; + /* + * If the user space waits to inject interrupts, exit as soon as + * possible + */ + if (kvm_run->request_interrupt_window && + !svm->vcpu.arch.irq_summary) { + ++svm->vcpu.stat.irq_window_exits; + kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN; + return 0; + } + + return 1; +} + +static int (*svm_exit_handlers[])(struct vcpu_svm *svm, + struct kvm_run *kvm_run) = { + [SVM_EXIT_READ_CR0] = emulate_on_interception, + [SVM_EXIT_READ_CR3] = emulate_on_interception, + [SVM_EXIT_READ_CR4] = emulate_on_interception, + [SVM_EXIT_READ_CR8] = emulate_on_interception, + /* for now: */ + [SVM_EXIT_WRITE_CR0] = emulate_on_interception, + [SVM_EXIT_WRITE_CR3] = emulate_on_interception, + [SVM_EXIT_WRITE_CR4] = emulate_on_interception, + [SVM_EXIT_WRITE_CR8] = cr8_write_interception, + [SVM_EXIT_READ_DR0] = emulate_on_interception, + [SVM_EXIT_READ_DR1] = emulate_on_interception, + [SVM_EXIT_READ_DR2] = emulate_on_interception, + [SVM_EXIT_READ_DR3] = emulate_on_interception, + [SVM_EXIT_WRITE_DR0] = emulate_on_interception, + [SVM_EXIT_WRITE_DR1] = emulate_on_interception, + [SVM_EXIT_WRITE_DR2] = emulate_on_interception, + [SVM_EXIT_WRITE_DR3] = emulate_on_interception, + [SVM_EXIT_WRITE_DR5] = emulate_on_interception, + [SVM_EXIT_WRITE_DR7] = emulate_on_interception, + [SVM_EXIT_EXCP_BASE + UD_VECTOR] = ud_interception, + [SVM_EXIT_EXCP_BASE + PF_VECTOR] = pf_interception, + [SVM_EXIT_EXCP_BASE + NM_VECTOR] = nm_interception, + [SVM_EXIT_INTR] = nop_on_interception, + [SVM_EXIT_NMI] = nop_on_interception, + [SVM_EXIT_SMI] = nop_on_interception, + [SVM_EXIT_INIT] = nop_on_interception, + [SVM_EXIT_VINTR] = interrupt_window_interception, + /* [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception, */ + [SVM_EXIT_CPUID] = cpuid_interception, + [SVM_EXIT_INVD] = emulate_on_interception, + [SVM_EXIT_HLT] = halt_interception, + [SVM_EXIT_INVLPG] = emulate_on_interception, + [SVM_EXIT_INVLPGA] = invalid_op_interception, + [SVM_EXIT_IOIO] = io_interception, + [SVM_EXIT_MSR] = msr_interception, + [SVM_EXIT_TASK_SWITCH] = task_switch_interception, + [SVM_EXIT_SHUTDOWN] = shutdown_interception, + [SVM_EXIT_VMRUN] = invalid_op_interception, + [SVM_EXIT_VMMCALL] = vmmcall_interception, + [SVM_EXIT_VMLOAD] = invalid_op_interception, + [SVM_EXIT_VMSAVE] = invalid_op_interception, + [SVM_EXIT_STGI] = invalid_op_interception, + [SVM_EXIT_CLGI] = invalid_op_interception, + [SVM_EXIT_SKINIT] = invalid_op_interception, + [SVM_EXIT_WBINVD] = emulate_on_interception, + [SVM_EXIT_MONITOR] = invalid_op_interception, + [SVM_EXIT_MWAIT] = invalid_op_interception, + [SVM_EXIT_NPF] = pf_interception, +}; + +static int handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) +{ + struct vcpu_svm *svm = to_svm(vcpu); + u32 exit_code = svm->vmcb->control.exit_code; + + if (npt_enabled) { + int mmu_reload = 0; + if ((vcpu->arch.cr0 ^ svm->vmcb->save.cr0) & X86_CR0_PG) { + svm_set_cr0(vcpu, svm->vmcb->save.cr0); + mmu_reload = 1; + } + vcpu->arch.cr0 = svm->vmcb->save.cr0; + vcpu->arch.cr3 = svm->vmcb->save.cr3; + if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) { + if (!load_pdptrs(vcpu, vcpu->arch.cr3)) { + kvm_inject_gp(vcpu, 0); + return 1; + } + } + if (mmu_reload) { + kvm_mmu_reset_context(vcpu); + kvm_mmu_load(vcpu); + } + } + + kvm_reput_irq(svm); + + if (svm->vmcb->control.exit_code == SVM_EXIT_ERR) { + kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY; + kvm_run->fail_entry.hardware_entry_failure_reason + = svm->vmcb->control.exit_code; + return 0; + } + + if (is_external_interrupt(svm->vmcb->control.exit_int_info) && + exit_code != SVM_EXIT_EXCP_BASE + PF_VECTOR && + exit_code != SVM_EXIT_NPF) + printk(KERN_ERR "%s: unexpected exit_ini_info 0x%x " + "exit_code 0x%x\n", + __FUNCTION__, svm->vmcb->control.exit_int_info, + exit_code); + + if (exit_code >= ARRAY_SIZE(svm_exit_handlers) + || !svm_exit_handlers[exit_code]) { + kvm_run->exit_reason = KVM_EXIT_UNKNOWN; + kvm_run->hw.hardware_exit_reason = exit_code; + return 0; + } + + return svm_exit_handlers[exit_code](svm, kvm_run); +} + +static void reload_tss(struct kvm_vcpu *vcpu) +{ + int cpu = raw_smp_processor_id(); + + struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu); + svm_data->tss_desc->type = 9; /* available 32/64-bit TSS */ + load_TR_desc(); +} + +static void pre_svm_run(struct vcpu_svm *svm) +{ + int cpu = raw_smp_processor_id(); + + struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu); + + svm->vmcb->control.tlb_ctl = TLB_CONTROL_DO_NOTHING; + if (svm->vcpu.cpu != cpu || + svm->asid_generation != svm_data->asid_generation) + new_asid(svm, svm_data); +} + + +static inline void svm_inject_irq(struct vcpu_svm *svm, int irq) +{ + struct vmcb_control_area *control; + + control = &svm->vmcb->control; + control->int_vector = irq; + control->int_ctl &= ~V_INTR_PRIO_MASK; + control->int_ctl |= V_IRQ_MASK | + ((/*control->int_vector >> 4*/ 0xf) << V_INTR_PRIO_SHIFT); +} + +static void svm_set_irq(struct kvm_vcpu *vcpu, int irq) +{ + struct vcpu_svm *svm = to_svm(vcpu); + + svm_inject_irq(svm, irq); +} + +static void svm_intr_assist(struct kvm_vcpu *vcpu) +{ + struct vcpu_svm *svm = to_svm(vcpu); + struct vmcb *vmcb = svm->vmcb; + int intr_vector = -1; + + if ((vmcb->control.exit_int_info & SVM_EVTINJ_VALID) && + ((vmcb->control.exit_int_info & SVM_EVTINJ_TYPE_MASK) == 0)) { + intr_vector = vmcb->control.exit_int_info & + SVM_EVTINJ_VEC_MASK; + vmcb->control.exit_int_info = 0; + svm_inject_irq(svm, intr_vector); + return; + } + + if (vmcb->control.int_ctl & V_IRQ_MASK) + return; + + if (!kvm_cpu_has_interrupt(vcpu)) + return; + + if (!(vmcb->save.rflags & X86_EFLAGS_IF) || + (vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) || + (vmcb->control.event_inj & SVM_EVTINJ_VALID)) { + /* unable to deliver irq, set pending irq */ + vmcb->control.intercept |= (1ULL << INTERCEPT_VINTR); + svm_inject_irq(svm, 0x0); + return; + } + /* Okay, we can deliver the interrupt: grab it and update PIC state. */ + intr_vector = kvm_cpu_get_interrupt(vcpu); + svm_inject_irq(svm, intr_vector); + kvm_timer_intr_post(vcpu, intr_vector); +} + +static void kvm_reput_irq(struct vcpu_svm *svm) +{ + struct vmcb_control_area *control = &svm->vmcb->control; + + if ((control->int_ctl & V_IRQ_MASK) + && !irqchip_in_kernel(svm->vcpu.kvm)) { + control->int_ctl &= ~V_IRQ_MASK; + push_irq(&svm->vcpu, control->int_vector); + } + + svm->vcpu.arch.interrupt_window_open = + !(control->int_state & SVM_INTERRUPT_SHADOW_MASK); +} + +static void svm_do_inject_vector(struct vcpu_svm *svm) +{ + struct kvm_vcpu *vcpu = &svm->vcpu; + int word_index = __ffs(vcpu->arch.irq_summary); + int bit_index = __ffs(vcpu->arch.irq_pending[word_index]); + int irq = word_index * BITS_PER_LONG + bit_index; + + clear_bit(bit_index, &vcpu->arch.irq_pending[word_index]); + if (!vcpu->arch.irq_pending[word_index]) + clear_bit(word_index, &vcpu->arch.irq_summary); + svm_inject_irq(svm, irq); +} + +static void do_interrupt_requests(struct kvm_vcpu *vcpu, + struct kvm_run *kvm_run) +{ + struct vcpu_svm *svm = to_svm(vcpu); + struct vmcb_control_area *control = &svm->vmcb->control; + + svm->vcpu.arch.interrupt_window_open = + (!(control->int_state & SVM_INTERRUPT_SHADOW_MASK) && + (svm->vmcb->save.rflags & X86_EFLAGS_IF)); + + if (svm->vcpu.arch.interrupt_window_open && svm->vcpu.arch.irq_summary) + /* + * If interrupts enabled, and not blocked by sti or mov ss. Good. + */ + svm_do_inject_vector(svm); + + /* + * Interrupts blocked. Wait for unblock. + */ + if (!svm->vcpu.arch.interrupt_window_open && + (svm->vcpu.arch.irq_summary || kvm_run->request_interrupt_window)) + control->intercept |= 1ULL << INTERCEPT_VINTR; + else + control->intercept &= ~(1ULL << INTERCEPT_VINTR); +} + +static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr) +{ + return 0; +} + +static void save_db_regs(unsigned long *db_regs) +{ + asm volatile ("mov %%dr0, %0" : "=r"(db_regs[0])); + asm volatile ("mov %%dr1, %0" : "=r"(db_regs[1])); + asm volatile ("mov %%dr2, %0" : "=r"(db_regs[2])); + asm volatile ("mov %%dr3, %0" : "=r"(db_regs[3])); +} + +static void load_db_regs(unsigned long *db_regs) +{ + asm volatile ("mov %0, %%dr0" : : "r"(db_regs[0])); + asm volatile ("mov %0, %%dr1" : : "r"(db_regs[1])); + asm volatile ("mov %0, %%dr2" : : "r"(db_regs[2])); + asm volatile ("mov %0, %%dr3" : : "r"(db_regs[3])); +} + +static void svm_flush_tlb(struct kvm_vcpu *vcpu) +{ + force_new_asid(vcpu); +} + +static void svm_prepare_guest_switch(struct kvm_vcpu *vcpu) +{ +} + +static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + struct vcpu_svm *svm = to_svm(vcpu); + u16 fs_selector; + u16 gs_selector; + u16 ldt_selector; + + pre_svm_run(svm); + + save_host_msrs(vcpu); + fs_selector = read_fs(); + gs_selector = read_gs(); + ldt_selector = read_ldt(); + svm->host_cr2 = kvm_read_cr2(); + svm->host_dr6 = read_dr6(); + svm->host_dr7 = read_dr7(); + svm->vmcb->save.cr2 = vcpu->arch.cr2; + /* required for live migration with NPT */ + if (npt_enabled) + svm->vmcb->save.cr3 = vcpu->arch.cr3; + + if (svm->vmcb->save.dr7 & 0xff) { + write_dr7(0); + save_db_regs(svm->host_db_regs); + load_db_regs(svm->db_regs); + } + + clgi(); + + local_irq_enable(); + + asm volatile ( +#ifdef CONFIG_X86_64 + "push %%rbp; \n\t" +#else + "push %%ebp; \n\t" +#endif + +#ifdef CONFIG_X86_64 + "mov %c[rbx](%[svm]), %%rbx \n\t" + "mov %c[rcx](%[svm]), %%rcx \n\t" + "mov %c[rdx](%[svm]), %%rdx \n\t" + "mov %c[rsi](%[svm]), %%rsi \n\t" + "mov %c[rdi](%[svm]), %%rdi \n\t" + "mov %c[rbp](%[svm]), %%rbp \n\t" + "mov %c[r8](%[svm]), %%r8 \n\t" + "mov %c[r9](%[svm]), %%r9 \n\t" + "mov %c[r10](%[svm]), %%r10 \n\t" + "mov %c[r11](%[svm]), %%r11 \n\t" + "mov %c[r12](%[svm]), %%r12 \n\t" + "mov %c[r13](%[svm]), %%r13 \n\t" + "mov %c[r14](%[svm]), %%r14 \n\t" + "mov %c[r15](%[svm]), %%r15 \n\t" +#else + "mov %c[rbx](%[svm]), %%ebx \n\t" + "mov %c[rcx](%[svm]), %%ecx \n\t" + "mov %c[rdx](%[svm]), %%edx \n\t" + "mov %c[rsi](%[svm]), %%esi \n\t" + "mov %c[rdi](%[svm]), %%edi \n\t" + "mov %c[rbp](%[svm]), %%ebp \n\t" +#endif + +#ifdef CONFIG_X86_64 + /* Enter guest mode */ + "push %%rax \n\t" + "mov %c[vmcb](%[svm]), %%rax \n\t" + SVM_VMLOAD "\n\t" + SVM_VMRUN "\n\t" + SVM_VMSAVE "\n\t" + "pop %%rax \n\t" +#else + /* Enter guest mode */ + "push %%eax \n\t" + "mov %c[vmcb](%[svm]), %%eax \n\t" + SVM_VMLOAD "\n\t" + SVM_VMRUN "\n\t" + SVM_VMSAVE "\n\t" + "pop %%eax \n\t" +#endif + + /* Save guest registers, load host registers */ +#ifdef CONFIG_X86_64 + "mov %%rbx, %c[rbx](%[svm]) \n\t" + "mov %%rcx, %c[rcx](%[svm]) \n\t" + "mov %%rdx, %c[rdx](%[svm]) \n\t" + "mov %%rsi, %c[rsi](%[svm]) \n\t" + "mov %%rdi, %c[rdi](%[svm]) \n\t" + "mov %%rbp, %c[rbp](%[svm]) \n\t" + "mov %%r8, %c[r8](%[svm]) \n\t" + "mov %%r9, %c[r9](%[svm]) \n\t" + "mov %%r10, %c[r10](%[svm]) \n\t" + "mov %%r11, %c[r11](%[svm]) \n\t" + "mov %%r12, %c[r12](%[svm]) \n\t" + "mov %%r13, %c[r13](%[svm]) \n\t" + "mov %%r14, %c[r14](%[svm]) \n\t" + "mov %%r15, %c[r15](%[svm]) \n\t" + + "pop %%rbp; \n\t" +#else + "mov %%ebx, %c[rbx](%[svm]) \n\t" + "mov %%ecx, %c[rcx](%[svm]) \n\t" + "mov %%edx, %c[rdx](%[svm]) \n\t" + "mov %%esi, %c[rsi](%[svm]) \n\t" + "mov %%edi, %c[rdi](%[svm]) \n\t" + "mov %%ebp, %c[rbp](%[svm]) \n\t" + + "pop %%ebp; \n\t" +#endif + : + : [svm]"a"(svm), + [vmcb]"i"(offsetof(struct vcpu_svm, vmcb_pa)), + [rbx]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_RBX])), + [rcx]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_RCX])), + [rdx]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_RDX])), + [rsi]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_RSI])), + [rdi]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_RDI])), + [rbp]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_RBP])) +#ifdef CONFIG_X86_64 + , [r8]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_R8])), + [r9]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_R9])), + [r10]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_R10])), + [r11]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_R11])), + [r12]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_R12])), + [r13]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_R13])), + [r14]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_R14])), + [r15]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_R15])) +#endif + : "cc", "memory" +#ifdef CONFIG_X86_64 + , "rbx", "rcx", "rdx", "rsi", "rdi" + , "r8", "r9", "r10", "r11" , "r12", "r13", "r14", "r15" +#else + , "ebx", "ecx", "edx" , "esi", "edi" +#endif + ); + + if ((svm->vmcb->save.dr7 & 0xff)) + load_db_regs(svm->host_db_regs); + + vcpu->arch.cr2 = svm->vmcb->save.cr2; + + write_dr6(svm->host_dr6); + write_dr7(svm->host_dr7); + kvm_write_cr2(svm->host_cr2); + + load_fs(fs_selector); + load_gs(gs_selector); + load_ldt(ldt_selector); + load_host_msrs(vcpu); + + reload_tss(vcpu); + + local_irq_disable(); + + stgi(); + + svm->next_rip = 0; +} + +static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root) +{ + struct vcpu_svm *svm = to_svm(vcpu); + + if (npt_enabled) { + svm->vmcb->control.nested_cr3 = root; + force_new_asid(vcpu); + return; + } + + svm->vmcb->save.cr3 = root; + force_new_asid(vcpu); + + if (vcpu->fpu_active) { + svm->vmcb->control.intercept_exceptions |= (1 << NM_VECTOR); + svm->vmcb->save.cr0 |= X86_CR0_TS; + vcpu->fpu_active = 0; + } +} + +static int is_disabled(void) +{ + u64 vm_cr; + + rdmsrl(MSR_VM_CR, vm_cr); + if (vm_cr & (1 << SVM_VM_CR_SVM_DISABLE)) + return 1; + + return 0; +} + +static void +svm_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall) +{ + /* + * Patch in the VMMCALL instruction: + */ + hypercall[0] = 0x0f; + hypercall[1] = 0x01; + hypercall[2] = 0xd9; +} + +static void svm_check_processor_compat(void *rtn) +{ + *(int *)rtn = 0; +} + +static bool svm_cpu_has_accelerated_tpr(void) +{ + return false; +} + +static struct kvm_x86_ops svm_x86_ops = { + .cpu_has_kvm_support = has_svm, + .disabled_by_bios = is_disabled, + .hardware_setup = svm_hardware_setup, + .hardware_unsetup = svm_hardware_unsetup, + .check_processor_compatibility = svm_check_processor_compat, + .hardware_enable = svm_hardware_enable, + .hardware_disable = svm_hardware_disable, + .cpu_has_accelerated_tpr = svm_cpu_has_accelerated_tpr, + + .vcpu_create = svm_create_vcpu, + .vcpu_free = svm_free_vcpu, + .vcpu_reset = svm_vcpu_reset, + + .prepare_guest_switch = svm_prepare_guest_switch, + .vcpu_load = svm_vcpu_load, + .vcpu_put = svm_vcpu_put, + .vcpu_decache = svm_vcpu_decache, + + .set_guest_debug = svm_guest_debug, + .get_msr = svm_get_msr, + .set_msr = svm_set_msr, + .get_segment_base = svm_get_segment_base, + .get_segment = svm_get_segment, + .set_segment = svm_set_segment, + .get_cs_db_l_bits = kvm_get_cs_db_l_bits, + .decache_cr4_guest_bits = svm_decache_cr4_guest_bits, + .set_cr0 = svm_set_cr0, + .set_cr3 = svm_set_cr3, + .set_cr4 = svm_set_cr4, + .set_efer = svm_set_efer, + .get_idt = svm_get_idt, + .set_idt = svm_set_idt, + .get_gdt = svm_get_gdt, + .set_gdt = svm_set_gdt, + .get_dr = svm_get_dr, + .set_dr = svm_set_dr, + .cache_regs = svm_cache_regs, + .decache_regs = svm_decache_regs, + .get_rflags = svm_get_rflags, + .set_rflags = svm_set_rflags, + + .tlb_flush = svm_flush_tlb, + + .run = svm_vcpu_run, + .handle_exit = handle_exit, + .skip_emulated_instruction = skip_emulated_instruction, + .patch_hypercall = svm_patch_hypercall, + .get_irq = svm_get_irq, + .set_irq = svm_set_irq, + .queue_exception = svm_queue_exception, + .exception_injected = svm_exception_injected, + .inject_pending_irq = svm_intr_assist, + .inject_pending_vectors = do_interrupt_requests, + + .set_tss_addr = svm_set_tss_addr, +}; + +static int __init svm_init(void) +{ + return kvm_init(&svm_x86_ops, sizeof(struct vcpu_svm), + THIS_MODULE); +} + +static void __exit svm_exit(void) +{ + kvm_exit(); +} + +module_init(svm_init) +module_exit(svm_exit) --- linux-2.6.24.orig/arch/x86/kvm/mmu.c +++ linux-2.6.24/arch/x86/kvm/mmu.c @@ -0,0 +1,2174 @@ +/* + * Kernel-based Virtual Machine driver for Linux + * + * This module enables machines with Intel VT-x extensions to run virtual + * machines without emulation or binary translation. + * + * MMU support + * + * Copyright (C) 2006 Qumranet, Inc. + * + * Authors: + * Yaniv Kamay + * Avi Kivity + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#include "vmx.h" +#include "mmu.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * When setting this variable to true it enables Two-Dimensional-Paging + * where the hardware walks 2 page tables: + * 1. the guest-virtual to guest-physical + * 2. while doing 1. it walks guest-physical to host-physical + * If the hardware supports that we don't need to do shadow paging. + */ +static bool tdp_enabled = false; + +#undef MMU_DEBUG + +#undef AUDIT + +#ifdef AUDIT +static void kvm_mmu_audit(struct kvm_vcpu *vcpu, const char *msg); +#else +static void kvm_mmu_audit(struct kvm_vcpu *vcpu, const char *msg) {} +#endif + +#ifdef MMU_DEBUG + +#define pgprintk(x...) do { if (dbg) printk(x); } while (0) +#define rmap_printk(x...) do { if (dbg) printk(x); } while (0) + +#else + +#define pgprintk(x...) do { } while (0) +#define rmap_printk(x...) do { } while (0) + +#endif + +#if defined(MMU_DEBUG) || defined(AUDIT) +static int dbg = 1; +#endif + +#ifndef MMU_DEBUG +#define ASSERT(x) do { } while (0) +#else +#define ASSERT(x) \ + if (!(x)) { \ + printk(KERN_WARNING "assertion failed %s:%d: %s\n", \ + __FILE__, __LINE__, #x); \ + } +#endif + +#define PT64_PT_BITS 9 +#define PT64_ENT_PER_PAGE (1 << PT64_PT_BITS) +#define PT32_PT_BITS 10 +#define PT32_ENT_PER_PAGE (1 << PT32_PT_BITS) + +#define PT_WRITABLE_SHIFT 1 + +#define PT_PRESENT_MASK (1ULL << 0) +#define PT_WRITABLE_MASK (1ULL << PT_WRITABLE_SHIFT) +#define PT_USER_MASK (1ULL << 2) +#define PT_PWT_MASK (1ULL << 3) +#define PT_PCD_MASK (1ULL << 4) +#define PT_ACCESSED_MASK (1ULL << 5) +#define PT_DIRTY_MASK (1ULL << 6) +#define PT_PAGE_SIZE_MASK (1ULL << 7) +#define PT_PAT_MASK (1ULL << 7) +#define PT_GLOBAL_MASK (1ULL << 8) +#define PT64_NX_SHIFT 63 +#define PT64_NX_MASK (1ULL << PT64_NX_SHIFT) + +#define PT_PAT_SHIFT 7 +#define PT_DIR_PAT_SHIFT 12 +#define PT_DIR_PAT_MASK (1ULL << PT_DIR_PAT_SHIFT) + +#define PT32_DIR_PSE36_SIZE 4 +#define PT32_DIR_PSE36_SHIFT 13 +#define PT32_DIR_PSE36_MASK \ + (((1ULL << PT32_DIR_PSE36_SIZE) - 1) << PT32_DIR_PSE36_SHIFT) + + +#define PT_FIRST_AVAIL_BITS_SHIFT 9 +#define PT64_SECOND_AVAIL_BITS_SHIFT 52 + +#define VALID_PAGE(x) ((x) != INVALID_PAGE) + +#define PT64_LEVEL_BITS 9 + +#define PT64_LEVEL_SHIFT(level) \ + (PAGE_SHIFT + (level - 1) * PT64_LEVEL_BITS) + +#define PT64_LEVEL_MASK(level) \ + (((1ULL << PT64_LEVEL_BITS) - 1) << PT64_LEVEL_SHIFT(level)) + +#define PT64_INDEX(address, level)\ + (((address) >> PT64_LEVEL_SHIFT(level)) & ((1 << PT64_LEVEL_BITS) - 1)) + + +#define PT32_LEVEL_BITS 10 + +#define PT32_LEVEL_SHIFT(level) \ + (PAGE_SHIFT + (level - 1) * PT32_LEVEL_BITS) + +#define PT32_LEVEL_MASK(level) \ + (((1ULL << PT32_LEVEL_BITS) - 1) << PT32_LEVEL_SHIFT(level)) + +#define PT32_INDEX(address, level)\ + (((address) >> PT32_LEVEL_SHIFT(level)) & ((1 << PT32_LEVEL_BITS) - 1)) + + +#define PT64_BASE_ADDR_MASK (((1ULL << 52) - 1) & ~(u64)(PAGE_SIZE-1)) +#define PT64_DIR_BASE_ADDR_MASK \ + (PT64_BASE_ADDR_MASK & ~((1ULL << (PAGE_SHIFT + PT64_LEVEL_BITS)) - 1)) + +#define PT32_BASE_ADDR_MASK PAGE_MASK +#define PT32_DIR_BASE_ADDR_MASK \ + (PAGE_MASK & ~((1ULL << (PAGE_SHIFT + PT32_LEVEL_BITS)) - 1)) + +#define PT64_PERM_MASK (PT_PRESENT_MASK | PT_WRITABLE_MASK | PT_USER_MASK \ + | PT64_NX_MASK) + +#define PFERR_PRESENT_MASK (1U << 0) +#define PFERR_WRITE_MASK (1U << 1) +#define PFERR_USER_MASK (1U << 2) +#define PFERR_FETCH_MASK (1U << 4) + +#define PT64_ROOT_LEVEL 4 +#define PT32_ROOT_LEVEL 2 +#define PT32E_ROOT_LEVEL 3 + +#define PT_DIRECTORY_LEVEL 2 +#define PT_PAGE_TABLE_LEVEL 1 + +#define RMAP_EXT 4 + +#define ACC_EXEC_MASK 1 +#define ACC_WRITE_MASK PT_WRITABLE_MASK +#define ACC_USER_MASK PT_USER_MASK +#define ACC_ALL (ACC_EXEC_MASK | ACC_WRITE_MASK | ACC_USER_MASK) + +struct kvm_rmap_desc { + u64 *shadow_ptes[RMAP_EXT]; + struct kvm_rmap_desc *more; +}; + +static struct kmem_cache *pte_chain_cache; +static struct kmem_cache *rmap_desc_cache; +static struct kmem_cache *mmu_page_header_cache; + +static u64 __read_mostly shadow_trap_nonpresent_pte; +static u64 __read_mostly shadow_notrap_nonpresent_pte; + +void kvm_mmu_set_nonpresent_ptes(u64 trap_pte, u64 notrap_pte) +{ + shadow_trap_nonpresent_pte = trap_pte; + shadow_notrap_nonpresent_pte = notrap_pte; +} +EXPORT_SYMBOL_GPL(kvm_mmu_set_nonpresent_ptes); + +static int is_write_protection(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.cr0 & X86_CR0_WP; +} + +static int is_cpuid_PSE36(void) +{ + return 1; +} + +static int is_nx(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.shadow_efer & EFER_NX; +} + +static int is_present_pte(unsigned long pte) +{ + return pte & PT_PRESENT_MASK; +} + +static int is_shadow_present_pte(u64 pte) +{ + return pte != shadow_trap_nonpresent_pte + && pte != shadow_notrap_nonpresent_pte; +} + +static int is_large_pte(u64 pte) +{ + return pte & PT_PAGE_SIZE_MASK; +} + +static int is_writeble_pte(unsigned long pte) +{ + return pte & PT_WRITABLE_MASK; +} + +static int is_dirty_pte(unsigned long pte) +{ + return pte & PT_DIRTY_MASK; +} + +static int is_rmap_pte(u64 pte) +{ + return pte != shadow_trap_nonpresent_pte + && pte != shadow_notrap_nonpresent_pte; +} + +static gfn_t pse36_gfn_delta(u32 gpte) +{ + int shift = 32 - PT32_DIR_PSE36_SHIFT - PAGE_SHIFT; + + return (gpte & PT32_DIR_PSE36_MASK) << shift; +} + +static void set_shadow_pte(u64 *sptep, u64 spte) +{ +#ifdef CONFIG_X86_64 + set_64bit((unsigned long *)sptep, spte); +#else + set_64bit((unsigned long long *)sptep, spte); +#endif +} + +static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache, + struct kmem_cache *base_cache, int min) +{ + void *obj; + + if (cache->nobjs >= min) + return 0; + while (cache->nobjs < ARRAY_SIZE(cache->objects)) { + obj = kmem_cache_zalloc(base_cache, GFP_KERNEL); + if (!obj) + return -ENOMEM; + cache->objects[cache->nobjs++] = obj; + } + return 0; +} + +static void mmu_free_memory_cache(struct kvm_mmu_memory_cache *mc) +{ + while (mc->nobjs) + kfree(mc->objects[--mc->nobjs]); +} + +static int mmu_topup_memory_cache_page(struct kvm_mmu_memory_cache *cache, + int min) +{ + struct page *page; + + if (cache->nobjs >= min) + return 0; + while (cache->nobjs < ARRAY_SIZE(cache->objects)) { + page = alloc_page(GFP_KERNEL); + if (!page) + return -ENOMEM; + set_page_private(page, 0); + cache->objects[cache->nobjs++] = page_address(page); + } + return 0; +} + +static void mmu_free_memory_cache_page(struct kvm_mmu_memory_cache *mc) +{ + while (mc->nobjs) + free_page((unsigned long)mc->objects[--mc->nobjs]); +} + +static int mmu_topup_memory_caches(struct kvm_vcpu *vcpu) +{ + int r; + + r = mmu_topup_memory_cache(&vcpu->arch.mmu_pte_chain_cache, + pte_chain_cache, 4); + if (r) + goto out; + r = mmu_topup_memory_cache(&vcpu->arch.mmu_rmap_desc_cache, + rmap_desc_cache, 1); + if (r) + goto out; + r = mmu_topup_memory_cache_page(&vcpu->arch.mmu_page_cache, 8); + if (r) + goto out; + r = mmu_topup_memory_cache(&vcpu->arch.mmu_page_header_cache, + mmu_page_header_cache, 4); +out: + return r; +} + +static void mmu_free_memory_caches(struct kvm_vcpu *vcpu) +{ + mmu_free_memory_cache(&vcpu->arch.mmu_pte_chain_cache); + mmu_free_memory_cache(&vcpu->arch.mmu_rmap_desc_cache); + mmu_free_memory_cache_page(&vcpu->arch.mmu_page_cache); + mmu_free_memory_cache(&vcpu->arch.mmu_page_header_cache); +} + +static void *mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc, + size_t size) +{ + void *p; + + BUG_ON(!mc->nobjs); + p = mc->objects[--mc->nobjs]; + memset(p, 0, size); + return p; +} + +static struct kvm_pte_chain *mmu_alloc_pte_chain(struct kvm_vcpu *vcpu) +{ + return mmu_memory_cache_alloc(&vcpu->arch.mmu_pte_chain_cache, + sizeof(struct kvm_pte_chain)); +} + +static void mmu_free_pte_chain(struct kvm_pte_chain *pc) +{ + kfree(pc); +} + +static struct kvm_rmap_desc *mmu_alloc_rmap_desc(struct kvm_vcpu *vcpu) +{ + return mmu_memory_cache_alloc(&vcpu->arch.mmu_rmap_desc_cache, + sizeof(struct kvm_rmap_desc)); +} + +static void mmu_free_rmap_desc(struct kvm_rmap_desc *rd) +{ + kfree(rd); +} + +/* + * Return the pointer to the largepage write count for a given + * gfn, handling slots that are not large page aligned. + */ +static int *slot_largepage_idx(gfn_t gfn, struct kvm_memory_slot *slot) +{ + unsigned long idx; + + idx = (gfn / KVM_PAGES_PER_HPAGE) - + (slot->base_gfn / KVM_PAGES_PER_HPAGE); + return &slot->lpage_info[idx].write_count; +} + +static void account_shadowed(struct kvm *kvm, gfn_t gfn) +{ + int *write_count; + + write_count = slot_largepage_idx(gfn, gfn_to_memslot(kvm, gfn)); + *write_count += 1; + WARN_ON(*write_count > KVM_PAGES_PER_HPAGE); +} + +static void unaccount_shadowed(struct kvm *kvm, gfn_t gfn) +{ + int *write_count; + + write_count = slot_largepage_idx(gfn, gfn_to_memslot(kvm, gfn)); + *write_count -= 1; + WARN_ON(*write_count < 0); +} + +static int has_wrprotected_page(struct kvm *kvm, gfn_t gfn) +{ + struct kvm_memory_slot *slot = gfn_to_memslot(kvm, gfn); + int *largepage_idx; + + if (slot) { + largepage_idx = slot_largepage_idx(gfn, slot); + return *largepage_idx; + } + + return 1; +} + +static int host_largepage_backed(struct kvm *kvm, gfn_t gfn) +{ + struct vm_area_struct *vma; + unsigned long addr; + + addr = gfn_to_hva(kvm, gfn); + if (kvm_is_error_hva(addr)) + return 0; + + vma = find_vma(current->mm, addr); + if (vma && is_vm_hugetlb_page(vma)) + return 1; + + return 0; +} + +static int is_largepage_backed(struct kvm_vcpu *vcpu, gfn_t large_gfn) +{ + struct kvm_memory_slot *slot; + + if (has_wrprotected_page(vcpu->kvm, large_gfn)) + return 0; + + if (!host_largepage_backed(vcpu->kvm, large_gfn)) + return 0; + + slot = gfn_to_memslot(vcpu->kvm, large_gfn); + if (slot && slot->dirty_bitmap) + return 0; + + return 1; +} + +/* + * Take gfn and return the reverse mapping to it. + * Note: gfn must be unaliased before this function get called + */ + +static unsigned long *gfn_to_rmap(struct kvm *kvm, gfn_t gfn, int lpage) +{ + struct kvm_memory_slot *slot; + unsigned long idx; + + slot = gfn_to_memslot(kvm, gfn); + if (!lpage) + return &slot->rmap[gfn - slot->base_gfn]; + + idx = (gfn / KVM_PAGES_PER_HPAGE) - + (slot->base_gfn / KVM_PAGES_PER_HPAGE); + + return &slot->lpage_info[idx].rmap_pde; +} + +/* + * Reverse mapping data structures: + * + * If rmapp bit zero is zero, then rmapp point to the shadw page table entry + * that points to page_address(page). + * + * If rmapp bit zero is one, (then rmap & ~1) points to a struct kvm_rmap_desc + * containing more mappings. + */ +static void rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn, int lpage) +{ + struct kvm_mmu_page *sp; + struct kvm_rmap_desc *desc; + unsigned long *rmapp; + int i; + + if (!is_rmap_pte(*spte)) + return; + gfn = unalias_gfn(vcpu->kvm, gfn); + sp = page_header(__pa(spte)); + sp->gfns[spte - sp->spt] = gfn; + rmapp = gfn_to_rmap(vcpu->kvm, gfn, lpage); + if (!*rmapp) { + rmap_printk("rmap_add: %p %llx 0->1\n", spte, *spte); + *rmapp = (unsigned long)spte; + } else if (!(*rmapp & 1)) { + rmap_printk("rmap_add: %p %llx 1->many\n", spte, *spte); + desc = mmu_alloc_rmap_desc(vcpu); + desc->shadow_ptes[0] = (u64 *)*rmapp; + desc->shadow_ptes[1] = spte; + *rmapp = (unsigned long)desc | 1; + } else { + rmap_printk("rmap_add: %p %llx many->many\n", spte, *spte); + desc = (struct kvm_rmap_desc *)(*rmapp & ~1ul); + while (desc->shadow_ptes[RMAP_EXT-1] && desc->more) + desc = desc->more; + if (desc->shadow_ptes[RMAP_EXT-1]) { + desc->more = mmu_alloc_rmap_desc(vcpu); + desc = desc->more; + } + for (i = 0; desc->shadow_ptes[i]; ++i) + ; + desc->shadow_ptes[i] = spte; + } +} + +static void rmap_desc_remove_entry(unsigned long *rmapp, + struct kvm_rmap_desc *desc, + int i, + struct kvm_rmap_desc *prev_desc) +{ + int j; + + for (j = RMAP_EXT - 1; !desc->shadow_ptes[j] && j > i; --j) + ; + desc->shadow_ptes[i] = desc->shadow_ptes[j]; + desc->shadow_ptes[j] = NULL; + if (j != 0) + return; + if (!prev_desc && !desc->more) + *rmapp = (unsigned long)desc->shadow_ptes[0]; + else + if (prev_desc) + prev_desc->more = desc->more; + else + *rmapp = (unsigned long)desc->more | 1; + mmu_free_rmap_desc(desc); +} + +static void rmap_remove(struct kvm *kvm, u64 *spte) +{ + struct kvm_rmap_desc *desc; + struct kvm_rmap_desc *prev_desc; + struct kvm_mmu_page *sp; + struct page *page; + unsigned long *rmapp; + int i; + + if (!is_rmap_pte(*spte)) + return; + sp = page_header(__pa(spte)); + page = pfn_to_page((*spte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT); + mark_page_accessed(page); + if (is_writeble_pte(*spte)) + kvm_release_page_dirty(page); + else + kvm_release_page_clean(page); + rmapp = gfn_to_rmap(kvm, sp->gfns[spte - sp->spt], is_large_pte(*spte)); + if (!*rmapp) { + printk(KERN_ERR "rmap_remove: %p %llx 0->BUG\n", spte, *spte); + BUG(); + } else if (!(*rmapp & 1)) { + rmap_printk("rmap_remove: %p %llx 1->0\n", spte, *spte); + if ((u64 *)*rmapp != spte) { + printk(KERN_ERR "rmap_remove: %p %llx 1->BUG\n", + spte, *spte); + BUG(); + } + *rmapp = 0; + } else { + rmap_printk("rmap_remove: %p %llx many->many\n", spte, *spte); + desc = (struct kvm_rmap_desc *)(*rmapp & ~1ul); + prev_desc = NULL; + while (desc) { + for (i = 0; i < RMAP_EXT && desc->shadow_ptes[i]; ++i) + if (desc->shadow_ptes[i] == spte) { + rmap_desc_remove_entry(rmapp, + desc, i, + prev_desc); + return; + } + prev_desc = desc; + desc = desc->more; + } + BUG(); + } +} + +static u64 *rmap_next(struct kvm *kvm, unsigned long *rmapp, u64 *spte) +{ + struct kvm_rmap_desc *desc; + struct kvm_rmap_desc *prev_desc; + u64 *prev_spte; + int i; + + if (!*rmapp) + return NULL; + else if (!(*rmapp & 1)) { + if (!spte) + return (u64 *)*rmapp; + return NULL; + } + desc = (struct kvm_rmap_desc *)(*rmapp & ~1ul); + prev_desc = NULL; + prev_spte = NULL; + while (desc) { + for (i = 0; i < RMAP_EXT && desc->shadow_ptes[i]; ++i) { + if (prev_spte == spte) + return desc->shadow_ptes[i]; + prev_spte = desc->shadow_ptes[i]; + } + desc = desc->more; + } + return NULL; +} + +static void rmap_write_protect(struct kvm *kvm, u64 gfn) +{ + unsigned long *rmapp; + u64 *spte; + int write_protected = 0; + + gfn = unalias_gfn(kvm, gfn); + rmapp = gfn_to_rmap(kvm, gfn, 0); + + spte = rmap_next(kvm, rmapp, NULL); + while (spte) { + BUG_ON(!spte); + BUG_ON(!(*spte & PT_PRESENT_MASK)); + rmap_printk("rmap_write_protect: spte %p %llx\n", spte, *spte); + if (is_writeble_pte(*spte)) { + set_shadow_pte(spte, *spte & ~PT_WRITABLE_MASK); + write_protected = 1; + } + spte = rmap_next(kvm, rmapp, spte); + } + /* check for huge page mappings */ + rmapp = gfn_to_rmap(kvm, gfn, 1); + spte = rmap_next(kvm, rmapp, NULL); + while (spte) { + BUG_ON(!spte); + BUG_ON(!(*spte & PT_PRESENT_MASK)); + BUG_ON((*spte & (PT_PAGE_SIZE_MASK|PT_PRESENT_MASK)) != (PT_PAGE_SIZE_MASK|PT_PRESENT_MASK)); + pgprintk("rmap_write_protect(large): spte %p %llx %lld\n", spte, *spte, gfn); + if (is_writeble_pte(*spte)) { + rmap_remove(kvm, spte); + --kvm->stat.lpages; + set_shadow_pte(spte, shadow_trap_nonpresent_pte); + write_protected = 1; + } + spte = rmap_next(kvm, rmapp, spte); + } + + if (write_protected) + kvm_flush_remote_tlbs(kvm); + + account_shadowed(kvm, gfn); +} + +#ifdef MMU_DEBUG +static int is_empty_shadow_page(u64 *spt) +{ + u64 *pos; + u64 *end; + + for (pos = spt, end = pos + PAGE_SIZE / sizeof(u64); pos != end; pos++) + if (*pos != shadow_trap_nonpresent_pte) { + printk(KERN_ERR "%s: %p %llx\n", __FUNCTION__, + pos, *pos); + return 0; + } + return 1; +} +#endif + +static void kvm_mmu_free_page(struct kvm *kvm, struct kvm_mmu_page *sp) +{ + ASSERT(is_empty_shadow_page(sp->spt)); + list_del(&sp->link); + __free_page(virt_to_page(sp->spt)); + __free_page(virt_to_page(sp->gfns)); + kfree(sp); + ++kvm->arch.n_free_mmu_pages; +} + +static unsigned kvm_page_table_hashfn(gfn_t gfn) +{ + return gfn & ((1 << KVM_MMU_HASH_SHIFT) - 1); +} + +static struct kvm_mmu_page *kvm_mmu_alloc_page(struct kvm_vcpu *vcpu, + u64 *parent_pte) +{ + struct kvm_mmu_page *sp; + + sp = mmu_memory_cache_alloc(&vcpu->arch.mmu_page_header_cache, sizeof *sp); + sp->spt = mmu_memory_cache_alloc(&vcpu->arch.mmu_page_cache, PAGE_SIZE); + sp->gfns = mmu_memory_cache_alloc(&vcpu->arch.mmu_page_cache, PAGE_SIZE); + set_page_private(virt_to_page(sp->spt), (unsigned long)sp); + list_add(&sp->link, &vcpu->kvm->arch.active_mmu_pages); + ASSERT(is_empty_shadow_page(sp->spt)); + sp->slot_bitmap = 0; + sp->multimapped = 0; + sp->parent_pte = parent_pte; + --vcpu->kvm->arch.n_free_mmu_pages; + return sp; +} + +static void mmu_page_add_parent_pte(struct kvm_vcpu *vcpu, + struct kvm_mmu_page *sp, u64 *parent_pte) +{ + struct kvm_pte_chain *pte_chain; + struct hlist_node *node; + int i; + + if (!parent_pte) + return; + if (!sp->multimapped) { + u64 *old = sp->parent_pte; + + if (!old) { + sp->parent_pte = parent_pte; + return; + } + sp->multimapped = 1; + pte_chain = mmu_alloc_pte_chain(vcpu); + INIT_HLIST_HEAD(&sp->parent_ptes); + hlist_add_head(&pte_chain->link, &sp->parent_ptes); + pte_chain->parent_ptes[0] = old; + } + hlist_for_each_entry(pte_chain, node, &sp->parent_ptes, link) { + if (pte_chain->parent_ptes[NR_PTE_CHAIN_ENTRIES-1]) + continue; + for (i = 0; i < NR_PTE_CHAIN_ENTRIES; ++i) + if (!pte_chain->parent_ptes[i]) { + pte_chain->parent_ptes[i] = parent_pte; + return; + } + } + pte_chain = mmu_alloc_pte_chain(vcpu); + BUG_ON(!pte_chain); + hlist_add_head(&pte_chain->link, &sp->parent_ptes); + pte_chain->parent_ptes[0] = parent_pte; +} + +static void mmu_page_remove_parent_pte(struct kvm_mmu_page *sp, + u64 *parent_pte) +{ + struct kvm_pte_chain *pte_chain; + struct hlist_node *node; + int i; + + if (!sp->multimapped) { + BUG_ON(sp->parent_pte != parent_pte); + sp->parent_pte = NULL; + return; + } + hlist_for_each_entry(pte_chain, node, &sp->parent_ptes, link) + for (i = 0; i < NR_PTE_CHAIN_ENTRIES; ++i) { + if (!pte_chain->parent_ptes[i]) + break; + if (pte_chain->parent_ptes[i] != parent_pte) + continue; + while (i + 1 < NR_PTE_CHAIN_ENTRIES + && pte_chain->parent_ptes[i + 1]) { + pte_chain->parent_ptes[i] + = pte_chain->parent_ptes[i + 1]; + ++i; + } + pte_chain->parent_ptes[i] = NULL; + if (i == 0) { + hlist_del(&pte_chain->link); + mmu_free_pte_chain(pte_chain); + if (hlist_empty(&sp->parent_ptes)) { + sp->multimapped = 0; + sp->parent_pte = NULL; + } + } + return; + } + BUG(); +} + +static struct kvm_mmu_page *kvm_mmu_lookup_page(struct kvm *kvm, gfn_t gfn) +{ + unsigned index; + struct hlist_head *bucket; + struct kvm_mmu_page *sp; + struct hlist_node *node; + + pgprintk("%s: looking for gfn %lx\n", __FUNCTION__, gfn); + index = kvm_page_table_hashfn(gfn); + bucket = &kvm->arch.mmu_page_hash[index]; + hlist_for_each_entry(sp, node, bucket, hash_link) + if (sp->gfn == gfn && !sp->role.metaphysical + && !sp->role.invalid) { + pgprintk("%s: found role %x\n", + __FUNCTION__, sp->role.word); + return sp; + } + return NULL; +} + +static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, + gfn_t gfn, + gva_t gaddr, + unsigned level, + int metaphysical, + unsigned access, + u64 *parent_pte, + bool *new_page) +{ + union kvm_mmu_page_role role; + unsigned index; + unsigned quadrant; + struct hlist_head *bucket; + struct kvm_mmu_page *sp; + struct hlist_node *node; + + role.word = 0; + role.glevels = vcpu->arch.mmu.root_level; + role.level = level; + role.metaphysical = metaphysical; + role.access = access; + if (vcpu->arch.mmu.root_level <= PT32_ROOT_LEVEL) { + quadrant = gaddr >> (PAGE_SHIFT + (PT64_PT_BITS * level)); + quadrant &= (1 << ((PT32_PT_BITS - PT64_PT_BITS) * level)) - 1; + role.quadrant = quadrant; + } + pgprintk("%s: looking gfn %lx role %x\n", __FUNCTION__, + gfn, role.word); + index = kvm_page_table_hashfn(gfn); + bucket = &vcpu->kvm->arch.mmu_page_hash[index]; + hlist_for_each_entry(sp, node, bucket, hash_link) + if (sp->gfn == gfn && sp->role.word == role.word) { + mmu_page_add_parent_pte(vcpu, sp, parent_pte); + pgprintk("%s: found\n", __FUNCTION__); + return sp; + } + ++vcpu->kvm->stat.mmu_cache_miss; + sp = kvm_mmu_alloc_page(vcpu, parent_pte); + if (!sp) + return sp; + pgprintk("%s: adding gfn %lx role %x\n", __FUNCTION__, gfn, role.word); + sp->gfn = gfn; + sp->role = role; + hlist_add_head(&sp->hash_link, bucket); + if (!metaphysical) + rmap_write_protect(vcpu->kvm, gfn); + vcpu->arch.mmu.prefetch_page(vcpu, sp); + if (new_page) + *new_page = 1; + return sp; +} + +static void kvm_mmu_page_unlink_children(struct kvm *kvm, + struct kvm_mmu_page *sp) +{ + unsigned i; + u64 *pt; + u64 ent; + + pt = sp->spt; + + if (sp->role.level == PT_PAGE_TABLE_LEVEL) { + for (i = 0; i < PT64_ENT_PER_PAGE; ++i) { + if (is_shadow_present_pte(pt[i])) + rmap_remove(kvm, &pt[i]); + pt[i] = shadow_trap_nonpresent_pte; + } + kvm_flush_remote_tlbs(kvm); + return; + } + + for (i = 0; i < PT64_ENT_PER_PAGE; ++i) { + ent = pt[i]; + + if (is_shadow_present_pte(ent)) { + if (!is_large_pte(ent)) { + ent &= PT64_BASE_ADDR_MASK; + mmu_page_remove_parent_pte(page_header(ent), + &pt[i]); + } else { + --kvm->stat.lpages; + rmap_remove(kvm, &pt[i]); + } + } + pt[i] = shadow_trap_nonpresent_pte; + } + kvm_flush_remote_tlbs(kvm); +} + +static void kvm_mmu_put_page(struct kvm_mmu_page *sp, u64 *parent_pte) +{ + mmu_page_remove_parent_pte(sp, parent_pte); +} + +static void kvm_mmu_reset_last_pte_updated(struct kvm *kvm) +{ + int i; + + for (i = 0; i < KVM_MAX_VCPUS; ++i) + if (kvm->vcpus[i]) + kvm->vcpus[i]->arch.last_pte_updated = NULL; +} + +static void kvm_mmu_zap_page(struct kvm *kvm, struct kvm_mmu_page *sp) +{ + u64 *parent_pte; + + ++kvm->stat.mmu_shadow_zapped; + while (sp->multimapped || sp->parent_pte) { + if (!sp->multimapped) + parent_pte = sp->parent_pte; + else { + struct kvm_pte_chain *chain; + + chain = container_of(sp->parent_ptes.first, + struct kvm_pte_chain, link); + parent_pte = chain->parent_ptes[0]; + } + BUG_ON(!parent_pte); + kvm_mmu_put_page(sp, parent_pte); + set_shadow_pte(parent_pte, shadow_trap_nonpresent_pte); + } + kvm_mmu_page_unlink_children(kvm, sp); + if (!sp->root_count) { + if (!sp->role.metaphysical) + unaccount_shadowed(kvm, sp->gfn); + hlist_del(&sp->hash_link); + kvm_mmu_free_page(kvm, sp); + } else { + list_move(&sp->link, &kvm->arch.active_mmu_pages); + sp->role.invalid = 1; + kvm_reload_remote_mmus(kvm); + } + kvm_mmu_reset_last_pte_updated(kvm); +} + +/* + * Changing the number of mmu pages allocated to the vm + * Note: if kvm_nr_mmu_pages is too small, you will get dead lock + */ +void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages) +{ + /* + * If we set the number of mmu pages to be smaller be than the + * number of actived pages , we must to free some mmu pages before we + * change the value + */ + + if ((kvm->arch.n_alloc_mmu_pages - kvm->arch.n_free_mmu_pages) > + kvm_nr_mmu_pages) { + int n_used_mmu_pages = kvm->arch.n_alloc_mmu_pages + - kvm->arch.n_free_mmu_pages; + + while (n_used_mmu_pages > kvm_nr_mmu_pages) { + struct kvm_mmu_page *page; + + page = container_of(kvm->arch.active_mmu_pages.prev, + struct kvm_mmu_page, link); + kvm_mmu_zap_page(kvm, page); + n_used_mmu_pages--; + } + kvm->arch.n_free_mmu_pages = 0; + } + else + kvm->arch.n_free_mmu_pages += kvm_nr_mmu_pages + - kvm->arch.n_alloc_mmu_pages; + + kvm->arch.n_alloc_mmu_pages = kvm_nr_mmu_pages; +} + +static int kvm_mmu_unprotect_page(struct kvm *kvm, gfn_t gfn) +{ + unsigned index; + struct hlist_head *bucket; + struct kvm_mmu_page *sp; + struct hlist_node *node, *n; + int r; + + pgprintk("%s: looking for gfn %lx\n", __FUNCTION__, gfn); + r = 0; + index = kvm_page_table_hashfn(gfn); + bucket = &kvm->arch.mmu_page_hash[index]; + hlist_for_each_entry_safe(sp, node, n, bucket, hash_link) + if (sp->gfn == gfn && !sp->role.metaphysical) { + pgprintk("%s: gfn %lx role %x\n", __FUNCTION__, gfn, + sp->role.word); + kvm_mmu_zap_page(kvm, sp); + r = 1; + } + return r; +} + +static void mmu_unshadow(struct kvm *kvm, gfn_t gfn) +{ + struct kvm_mmu_page *sp; + + while ((sp = kvm_mmu_lookup_page(kvm, gfn)) != NULL) { + pgprintk("%s: zap %lx %x\n", __FUNCTION__, gfn, sp->role.word); + kvm_mmu_zap_page(kvm, sp); + } +} + +static void page_header_update_slot(struct kvm *kvm, void *pte, gfn_t gfn) +{ + int slot = memslot_id(kvm, gfn_to_memslot(kvm, gfn)); + struct kvm_mmu_page *sp = page_header(__pa(pte)); + + __set_bit(slot, &sp->slot_bitmap); +} + +struct page *gva_to_page(struct kvm_vcpu *vcpu, gva_t gva) +{ + struct page *page; + + gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gva); + + if (gpa == UNMAPPED_GVA) + return NULL; + + down_read(¤t->mm->mmap_sem); + page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT); + up_read(¤t->mm->mmap_sem); + + return page; +} + +static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, + unsigned pt_access, unsigned pte_access, + int user_fault, int write_fault, int dirty, + int *ptwrite, int largepage, gfn_t gfn, + struct page *page) +{ + u64 spte; + int was_rmapped = is_rmap_pte(*shadow_pte); + int was_writeble = is_writeble_pte(*shadow_pte); + + /* + * If we overwrite a PTE page pointer with a 2MB PMD, unlink + * the parent of the now unreachable PTE. + */ + if (largepage) { + if (was_rmapped && !is_large_pte(*shadow_pte)) { + struct kvm_mmu_page *child; + u64 pte = *shadow_pte; + + child = page_header(pte & PT64_BASE_ADDR_MASK); + mmu_page_remove_parent_pte(child, shadow_pte); + } + was_rmapped = is_large_pte(*shadow_pte); + } + + pgprintk("%s: spte %llx access %x write_fault %d" + " user_fault %d gfn %lx\n", + __FUNCTION__, *shadow_pte, pt_access, + write_fault, user_fault, gfn); + + /* + * We don't set the accessed bit, since we sometimes want to see + * whether the guest actually used the pte (in order to detect + * demand paging). + */ + spte = PT_PRESENT_MASK | PT_DIRTY_MASK; + if (!dirty) + pte_access &= ~ACC_WRITE_MASK; + if (!(pte_access & ACC_EXEC_MASK)) + spte |= PT64_NX_MASK; + + spte |= PT_PRESENT_MASK; + if (pte_access & ACC_USER_MASK) + spte |= PT_USER_MASK; + if (largepage) + spte |= PT_PAGE_SIZE_MASK; + + spte |= page_to_phys(page); + + if ((pte_access & ACC_WRITE_MASK) + || (write_fault && !is_write_protection(vcpu) && !user_fault)) { + struct kvm_mmu_page *shadow; + + spte |= PT_WRITABLE_MASK; + if (user_fault) { + mmu_unshadow(vcpu->kvm, gfn); + goto unshadowed; + } + + shadow = kvm_mmu_lookup_page(vcpu->kvm, gfn); + if (shadow || + (largepage && has_wrprotected_page(vcpu->kvm, gfn))) { + pgprintk("%s: found shadow page for %lx, marking ro\n", + __FUNCTION__, gfn); + pte_access &= ~ACC_WRITE_MASK; + if (is_writeble_pte(spte)) { + spte &= ~PT_WRITABLE_MASK; + kvm_x86_ops->tlb_flush(vcpu); + } + if (write_fault) + *ptwrite = 1; + } + } + +unshadowed: + + if (pte_access & ACC_WRITE_MASK) + mark_page_dirty(vcpu->kvm, gfn); + + pgprintk("%s: setting spte %llx\n", __FUNCTION__, spte); + pgprintk("instantiating %s PTE (%s) at %d (%llx) addr %llx\n", + (spte&PT_PAGE_SIZE_MASK)? "2MB" : "4kB", + (spte&PT_WRITABLE_MASK)?"RW":"R", gfn, spte, shadow_pte); + set_shadow_pte(shadow_pte, spte); + if (!was_rmapped && (spte & PT_PAGE_SIZE_MASK) + && (spte & PT_PRESENT_MASK)) + ++vcpu->kvm->stat.lpages; + + page_header_update_slot(vcpu->kvm, shadow_pte, gfn); + if (!was_rmapped) { + rmap_add(vcpu, shadow_pte, gfn, largepage); + if (!is_rmap_pte(*shadow_pte)) + kvm_release_page_clean(page); + } else { + if (was_writeble) + kvm_release_page_dirty(page); + else + kvm_release_page_clean(page); + } + if (!ptwrite || !*ptwrite) + vcpu->arch.last_pte_updated = shadow_pte; +} + +static void nonpaging_new_cr3(struct kvm_vcpu *vcpu) +{ +} + +static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write, + int largepage, gfn_t gfn, struct page *page, + int level) +{ + hpa_t table_addr = vcpu->arch.mmu.root_hpa; + int pt_write = 0; + + for (; ; level--) { + u32 index = PT64_INDEX(v, level); + u64 *table; + + ASSERT(VALID_PAGE(table_addr)); + table = __va(table_addr); + + if (level == 1) { + mmu_set_spte(vcpu, &table[index], ACC_ALL, ACC_ALL, + 0, write, 1, &pt_write, 0, gfn, page); + return pt_write; + } + + if (largepage && level == 2) { + mmu_set_spte(vcpu, &table[index], ACC_ALL, ACC_ALL, + 0, write, 1, &pt_write, 1, gfn, page); + return pt_write; + } + + if (table[index] == shadow_trap_nonpresent_pte) { + struct kvm_mmu_page *new_table; + gfn_t pseudo_gfn; + + pseudo_gfn = (v & PT64_DIR_BASE_ADDR_MASK) + >> PAGE_SHIFT; + new_table = kvm_mmu_get_page(vcpu, pseudo_gfn, + v, level - 1, + 1, ACC_ALL, &table[index], + NULL); + if (!new_table) { + pgprintk("nonpaging_map: ENOMEM\n"); + kvm_release_page_clean(page); + return -ENOMEM; + } + + table[index] = __pa(new_table->spt) | PT_PRESENT_MASK + | PT_WRITABLE_MASK | PT_USER_MASK; + } + table_addr = table[index] & PT64_BASE_ADDR_MASK; + } +} + +static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn) +{ + int r; + int largepage = 0; + + struct page *page; + + down_read(&vcpu->kvm->slots_lock); + + down_read(¤t->mm->mmap_sem); + if (is_largepage_backed(vcpu, gfn & ~(KVM_PAGES_PER_HPAGE-1))) { + gfn &= ~(KVM_PAGES_PER_HPAGE-1); + largepage = 1; + } + + page = gfn_to_page(vcpu->kvm, gfn); + up_read(¤t->mm->mmap_sem); + + /* mmio */ + if (is_error_page(page)) { + kvm_release_page_clean(page); + up_read(&vcpu->kvm->slots_lock); + return 1; + } + + spin_lock(&vcpu->kvm->mmu_lock); + kvm_mmu_free_some_pages(vcpu); + r = __direct_map(vcpu, v, write, largepage, gfn, page, + PT32E_ROOT_LEVEL); + spin_unlock(&vcpu->kvm->mmu_lock); + + up_read(&vcpu->kvm->slots_lock); + + return r; +} + + +static void nonpaging_prefetch_page(struct kvm_vcpu *vcpu, + struct kvm_mmu_page *sp) +{ + int i; + + for (i = 0; i < PT64_ENT_PER_PAGE; ++i) + sp->spt[i] = shadow_trap_nonpresent_pte; +} + +static void mmu_free_roots(struct kvm_vcpu *vcpu) +{ + int i; + struct kvm_mmu_page *sp; + + if (!VALID_PAGE(vcpu->arch.mmu.root_hpa)) + return; + spin_lock(&vcpu->kvm->mmu_lock); +#ifdef CONFIG_X86_64 + if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL) { + hpa_t root = vcpu->arch.mmu.root_hpa; + + sp = page_header(root); + --sp->root_count; + if (!sp->root_count && sp->role.invalid) + kvm_mmu_zap_page(vcpu->kvm, sp); + vcpu->arch.mmu.root_hpa = INVALID_PAGE; + spin_unlock(&vcpu->kvm->mmu_lock); + return; + } +#endif + for (i = 0; i < 4; ++i) { + hpa_t root = vcpu->arch.mmu.pae_root[i]; + + if (root) { + root &= PT64_BASE_ADDR_MASK; + sp = page_header(root); + --sp->root_count; + if (!sp->root_count && sp->role.invalid) + kvm_mmu_zap_page(vcpu->kvm, sp); + } + vcpu->arch.mmu.pae_root[i] = INVALID_PAGE; + } + spin_unlock(&vcpu->kvm->mmu_lock); + vcpu->arch.mmu.root_hpa = INVALID_PAGE; +} + +static void mmu_alloc_roots(struct kvm_vcpu *vcpu) +{ + int i; + gfn_t root_gfn; + struct kvm_mmu_page *sp; + int metaphysical = 0; + + root_gfn = vcpu->arch.cr3 >> PAGE_SHIFT; + +#ifdef CONFIG_X86_64 + if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL) { + hpa_t root = vcpu->arch.mmu.root_hpa; + + ASSERT(!VALID_PAGE(root)); + if (tdp_enabled) + metaphysical = 1; + sp = kvm_mmu_get_page(vcpu, root_gfn, 0, + PT64_ROOT_LEVEL, metaphysical, + ACC_ALL, NULL, NULL); + root = __pa(sp->spt); + ++sp->root_count; + vcpu->arch.mmu.root_hpa = root; + return; + } +#endif + metaphysical = !is_paging(vcpu); + if (tdp_enabled) + metaphysical = 1; + for (i = 0; i < 4; ++i) { + hpa_t root = vcpu->arch.mmu.pae_root[i]; + + ASSERT(!VALID_PAGE(root)); + if (vcpu->arch.mmu.root_level == PT32E_ROOT_LEVEL) { + if (!is_present_pte(vcpu->arch.pdptrs[i])) { + vcpu->arch.mmu.pae_root[i] = 0; + continue; + } + root_gfn = vcpu->arch.pdptrs[i] >> PAGE_SHIFT; + } else if (vcpu->arch.mmu.root_level == 0) + root_gfn = 0; + sp = kvm_mmu_get_page(vcpu, root_gfn, i << 30, + PT32_ROOT_LEVEL, metaphysical, + ACC_ALL, NULL, NULL); + root = __pa(sp->spt); + ++sp->root_count; + vcpu->arch.mmu.pae_root[i] = root | PT_PRESENT_MASK; + } + vcpu->arch.mmu.root_hpa = __pa(vcpu->arch.mmu.pae_root); +} + +static gpa_t nonpaging_gva_to_gpa(struct kvm_vcpu *vcpu, gva_t vaddr) +{ + return vaddr; +} + +static int nonpaging_page_fault(struct kvm_vcpu *vcpu, gva_t gva, + u32 error_code) +{ + gfn_t gfn; + int r; + + pgprintk("%s: gva %lx error %x\n", __FUNCTION__, gva, error_code); + r = mmu_topup_memory_caches(vcpu); + if (r) + return r; + + ASSERT(vcpu); + ASSERT(VALID_PAGE(vcpu->arch.mmu.root_hpa)); + + gfn = gva >> PAGE_SHIFT; + + return nonpaging_map(vcpu, gva & PAGE_MASK, + error_code & PFERR_WRITE_MASK, gfn); +} + +static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa, + u32 error_code) +{ + struct page *page; + int r; + int largepage = 0; + gfn_t gfn = gpa >> PAGE_SHIFT; + + ASSERT(vcpu); + ASSERT(VALID_PAGE(vcpu->arch.mmu.root_hpa)); + + r = mmu_topup_memory_caches(vcpu); + if (r) + return r; + + down_read(¤t->mm->mmap_sem); + if (is_largepage_backed(vcpu, gfn & ~(KVM_PAGES_PER_HPAGE-1))) { + gfn &= ~(KVM_PAGES_PER_HPAGE-1); + largepage = 1; + } + page = gfn_to_page(vcpu->kvm, gfn); + if (is_error_page(page)) { + kvm_release_page_clean(page); + up_read(¤t->mm->mmap_sem); + return 1; + } + spin_lock(&vcpu->kvm->mmu_lock); + kvm_mmu_free_some_pages(vcpu); + r = __direct_map(vcpu, gpa, error_code & PFERR_WRITE_MASK, + largepage, gfn, page, TDP_ROOT_LEVEL); + spin_unlock(&vcpu->kvm->mmu_lock); + up_read(¤t->mm->mmap_sem); + + return r; +} + +static void nonpaging_free(struct kvm_vcpu *vcpu) +{ + mmu_free_roots(vcpu); +} + +static int nonpaging_init_context(struct kvm_vcpu *vcpu) +{ + struct kvm_mmu *context = &vcpu->arch.mmu; + + context->new_cr3 = nonpaging_new_cr3; + context->page_fault = nonpaging_page_fault; + context->gva_to_gpa = nonpaging_gva_to_gpa; + context->free = nonpaging_free; + context->prefetch_page = nonpaging_prefetch_page; + context->root_level = 0; + context->shadow_root_level = PT32E_ROOT_LEVEL; + context->root_hpa = INVALID_PAGE; + return 0; +} + +void kvm_mmu_flush_tlb(struct kvm_vcpu *vcpu) +{ + ++vcpu->stat.tlb_flush; + kvm_x86_ops->tlb_flush(vcpu); +} + +static void paging_new_cr3(struct kvm_vcpu *vcpu) +{ + pgprintk("%s: cr3 %lx\n", __FUNCTION__, vcpu->arch.cr3); + mmu_free_roots(vcpu); +} + +static void inject_page_fault(struct kvm_vcpu *vcpu, + u64 addr, + u32 err_code) +{ + kvm_inject_page_fault(vcpu, addr, err_code); +} + +static void paging_free(struct kvm_vcpu *vcpu) +{ + nonpaging_free(vcpu); +} + +#define PTTYPE 64 +#include "paging_tmpl.h" +#undef PTTYPE + +#define PTTYPE 32 +#include "paging_tmpl.h" +#undef PTTYPE + +static int paging64_init_context_common(struct kvm_vcpu *vcpu, int level) +{ + struct kvm_mmu *context = &vcpu->arch.mmu; + + ASSERT(is_pae(vcpu)); + context->new_cr3 = paging_new_cr3; + context->page_fault = paging64_page_fault; + context->gva_to_gpa = paging64_gva_to_gpa; + context->prefetch_page = paging64_prefetch_page; + context->free = paging_free; + context->root_level = level; + context->shadow_root_level = level; + context->root_hpa = INVALID_PAGE; + return 0; +} + +static int paging64_init_context(struct kvm_vcpu *vcpu) +{ + return paging64_init_context_common(vcpu, PT64_ROOT_LEVEL); +} + +static int paging32_init_context(struct kvm_vcpu *vcpu) +{ + struct kvm_mmu *context = &vcpu->arch.mmu; + + context->new_cr3 = paging_new_cr3; + context->page_fault = paging32_page_fault; + context->gva_to_gpa = paging32_gva_to_gpa; + context->free = paging_free; + context->prefetch_page = paging32_prefetch_page; + context->root_level = PT32_ROOT_LEVEL; + context->shadow_root_level = PT32E_ROOT_LEVEL; + context->root_hpa = INVALID_PAGE; + return 0; +} + +static int paging32E_init_context(struct kvm_vcpu *vcpu) +{ + return paging64_init_context_common(vcpu, PT32E_ROOT_LEVEL); +} + +static int init_kvm_tdp_mmu(struct kvm_vcpu *vcpu) +{ + struct kvm_mmu *context = &vcpu->arch.mmu; + + context->new_cr3 = nonpaging_new_cr3; + context->page_fault = tdp_page_fault; + context->free = nonpaging_free; + context->prefetch_page = nonpaging_prefetch_page; + context->shadow_root_level = TDP_ROOT_LEVEL; + context->root_hpa = INVALID_PAGE; + + if (!is_paging(vcpu)) { + context->gva_to_gpa = nonpaging_gva_to_gpa; + context->root_level = 0; + } else if (is_long_mode(vcpu)) { + context->gva_to_gpa = paging64_gva_to_gpa; + context->root_level = PT64_ROOT_LEVEL; + } else if (is_pae(vcpu)) { + context->gva_to_gpa = paging64_gva_to_gpa; + context->root_level = PT32E_ROOT_LEVEL; + } else { + context->gva_to_gpa = paging32_gva_to_gpa; + context->root_level = PT32_ROOT_LEVEL; + } + + return 0; +} + +static int init_kvm_softmmu(struct kvm_vcpu *vcpu) +{ + ASSERT(vcpu); + ASSERT(!VALID_PAGE(vcpu->arch.mmu.root_hpa)); + + if (!is_paging(vcpu)) + return nonpaging_init_context(vcpu); + else if (is_long_mode(vcpu)) + return paging64_init_context(vcpu); + else if (is_pae(vcpu)) + return paging32E_init_context(vcpu); + else + return paging32_init_context(vcpu); +} + +static int init_kvm_mmu(struct kvm_vcpu *vcpu) +{ + if (tdp_enabled) + return init_kvm_tdp_mmu(vcpu); + else + return init_kvm_softmmu(vcpu); +} + +static void destroy_kvm_mmu(struct kvm_vcpu *vcpu) +{ + ASSERT(vcpu); + if (VALID_PAGE(vcpu->arch.mmu.root_hpa)) { + vcpu->arch.mmu.free(vcpu); + vcpu->arch.mmu.root_hpa = INVALID_PAGE; + } +} + +int kvm_mmu_reset_context(struct kvm_vcpu *vcpu) +{ + destroy_kvm_mmu(vcpu); + return init_kvm_mmu(vcpu); +} +EXPORT_SYMBOL_GPL(kvm_mmu_reset_context); + +int kvm_mmu_load(struct kvm_vcpu *vcpu) +{ + int r; + + r = mmu_topup_memory_caches(vcpu); + if (r) + goto out; + spin_lock(&vcpu->kvm->mmu_lock); + kvm_mmu_free_some_pages(vcpu); + mmu_alloc_roots(vcpu); + spin_unlock(&vcpu->kvm->mmu_lock); + kvm_x86_ops->set_cr3(vcpu, vcpu->arch.mmu.root_hpa); + kvm_mmu_flush_tlb(vcpu); +out: + return r; +} +EXPORT_SYMBOL_GPL(kvm_mmu_load); + +void kvm_mmu_unload(struct kvm_vcpu *vcpu) +{ + mmu_free_roots(vcpu); +} + +static void mmu_pte_write_zap_pte(struct kvm_vcpu *vcpu, + struct kvm_mmu_page *sp, + u64 *spte) +{ + u64 pte; + struct kvm_mmu_page *child; + + pte = *spte; + if (is_shadow_present_pte(pte)) { + if (sp->role.level == PT_PAGE_TABLE_LEVEL || + is_large_pte(pte)) + rmap_remove(vcpu->kvm, spte); + else { + child = page_header(pte & PT64_BASE_ADDR_MASK); + mmu_page_remove_parent_pte(child, spte); + } + } + set_shadow_pte(spte, shadow_trap_nonpresent_pte); + if (is_large_pte(pte)) + --vcpu->kvm->stat.lpages; +} + +static void mmu_pte_write_new_pte(struct kvm_vcpu *vcpu, + struct kvm_mmu_page *sp, + u64 *spte, + const void *new) +{ + if ((sp->role.level != PT_PAGE_TABLE_LEVEL) + && !vcpu->arch.update_pte.largepage) { + ++vcpu->kvm->stat.mmu_pde_zapped; + return; + } + + ++vcpu->kvm->stat.mmu_pte_updated; + if (sp->role.glevels == PT32_ROOT_LEVEL) + paging32_update_pte(vcpu, sp, spte, new); + else + paging64_update_pte(vcpu, sp, spte, new); +} + +static bool need_remote_flush(u64 old, u64 new) +{ + if (!is_shadow_present_pte(old)) + return false; + if (!is_shadow_present_pte(new)) + return true; + if ((old ^ new) & PT64_BASE_ADDR_MASK) + return true; + old ^= PT64_NX_MASK; + new ^= PT64_NX_MASK; + return (old & ~new & PT64_PERM_MASK) != 0; +} + +static void mmu_pte_write_flush_tlb(struct kvm_vcpu *vcpu, u64 old, u64 new) +{ + if (need_remote_flush(old, new)) + kvm_flush_remote_tlbs(vcpu->kvm); + else + kvm_mmu_flush_tlb(vcpu); +} + +static bool last_updated_pte_accessed(struct kvm_vcpu *vcpu) +{ + u64 *spte = vcpu->arch.last_pte_updated; + + return !!(spte && (*spte & PT_ACCESSED_MASK)); +} + +static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, + const u8 *new, int bytes) +{ + gfn_t gfn; + int r; + u64 gpte = 0; + struct page *page; + + vcpu->arch.update_pte.largepage = 0; + + if (bytes != 4 && bytes != 8) + return; + + /* + * Assume that the pte write on a page table of the same type + * as the current vcpu paging mode. This is nearly always true + * (might be false while changing modes). Note it is verified later + * by update_pte(). + */ + if (is_pae(vcpu)) { + /* Handle a 32-bit guest writing two halves of a 64-bit gpte */ + if ((bytes == 4) && (gpa % 4 == 0)) { + r = kvm_read_guest(vcpu->kvm, gpa & ~(u64)7, &gpte, 8); + if (r) + return; + memcpy((void *)&gpte + (gpa % 8), new, 4); + } else if ((bytes == 8) && (gpa % 8 == 0)) { + memcpy((void *)&gpte, new, 8); + } + } else { + if ((bytes == 4) && (gpa % 4 == 0)) + memcpy((void *)&gpte, new, 4); + } + if (!is_present_pte(gpte)) + return; + gfn = (gpte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT; + + down_read(¤t->mm->mmap_sem); + if (is_large_pte(gpte) && is_largepage_backed(vcpu, gfn)) { + gfn &= ~(KVM_PAGES_PER_HPAGE-1); + vcpu->arch.update_pte.largepage = 1; + } + page = gfn_to_page(vcpu->kvm, gfn); + up_read(¤t->mm->mmap_sem); + + if (is_error_page(page)) { + kvm_release_page_clean(page); + return; + } + vcpu->arch.update_pte.gfn = gfn; + vcpu->arch.update_pte.page = page; +} + +void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, + const u8 *new, int bytes) +{ + gfn_t gfn = gpa >> PAGE_SHIFT; + struct kvm_mmu_page *sp; + struct hlist_node *node, *n; + struct hlist_head *bucket; + unsigned index; + u64 entry, gentry; + u64 *spte; + unsigned offset = offset_in_page(gpa); + unsigned pte_size; + unsigned page_offset; + unsigned misaligned; + unsigned quadrant; + int level; + int flooded = 0; + int npte; + int r; + + pgprintk("%s: gpa %llx bytes %d\n", __FUNCTION__, gpa, bytes); + mmu_guess_page_from_pte_write(vcpu, gpa, new, bytes); + spin_lock(&vcpu->kvm->mmu_lock); + kvm_mmu_free_some_pages(vcpu); + ++vcpu->kvm->stat.mmu_pte_write; + kvm_mmu_audit(vcpu, "pre pte write"); + if (gfn == vcpu->arch.last_pt_write_gfn + && !last_updated_pte_accessed(vcpu)) { + ++vcpu->arch.last_pt_write_count; + if (vcpu->arch.last_pt_write_count >= 3) + flooded = 1; + } else { + vcpu->arch.last_pt_write_gfn = gfn; + vcpu->arch.last_pt_write_count = 1; + vcpu->arch.last_pte_updated = NULL; + } + index = kvm_page_table_hashfn(gfn); + bucket = &vcpu->kvm->arch.mmu_page_hash[index]; + hlist_for_each_entry_safe(sp, node, n, bucket, hash_link) { + if (sp->gfn != gfn || sp->role.metaphysical) + continue; + pte_size = sp->role.glevels == PT32_ROOT_LEVEL ? 4 : 8; + misaligned = (offset ^ (offset + bytes - 1)) & ~(pte_size - 1); + misaligned |= bytes < 4; + if (misaligned || flooded) { + /* + * Misaligned accesses are too much trouble to fix + * up; also, they usually indicate a page is not used + * as a page table. + * + * If we're seeing too many writes to a page, + * it may no longer be a page table, or we may be + * forking, in which case it is better to unmap the + * page. + */ + pgprintk("misaligned: gpa %llx bytes %d role %x\n", + gpa, bytes, sp->role.word); + kvm_mmu_zap_page(vcpu->kvm, sp); + ++vcpu->kvm->stat.mmu_flooded; + continue; + } + page_offset = offset; + level = sp->role.level; + npte = 1; + if (sp->role.glevels == PT32_ROOT_LEVEL) { + page_offset <<= 1; /* 32->64 */ + /* + * A 32-bit pde maps 4MB while the shadow pdes map + * only 2MB. So we need to double the offset again + * and zap two pdes instead of one. + */ + if (level == PT32_ROOT_LEVEL) { + page_offset &= ~7; /* kill rounding error */ + page_offset <<= 1; + npte = 2; + } + quadrant = page_offset >> PAGE_SHIFT; + page_offset &= ~PAGE_MASK; + if (quadrant != sp->role.quadrant) + continue; + } + spte = &sp->spt[page_offset / sizeof(*spte)]; + if ((gpa & (pte_size - 1)) || (bytes < pte_size)) { + gentry = 0; + r = kvm_read_guest_atomic(vcpu->kvm, + gpa & ~(u64)(pte_size - 1), + &gentry, pte_size); + new = (const void *)&gentry; + if (r < 0) + new = NULL; + } + while (npte--) { + entry = *spte; + mmu_pte_write_zap_pte(vcpu, sp, spte); + if (new) + mmu_pte_write_new_pte(vcpu, sp, spte, new); + mmu_pte_write_flush_tlb(vcpu, entry, *spte); + ++spte; + } + } + kvm_mmu_audit(vcpu, "post pte write"); + spin_unlock(&vcpu->kvm->mmu_lock); + if (vcpu->arch.update_pte.page) { + kvm_release_page_clean(vcpu->arch.update_pte.page); + vcpu->arch.update_pte.page = NULL; + } +} + +int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva) +{ + gpa_t gpa; + int r; + + down_read(&vcpu->kvm->slots_lock); + gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gva); + up_read(&vcpu->kvm->slots_lock); + + spin_lock(&vcpu->kvm->mmu_lock); + r = kvm_mmu_unprotect_page(vcpu->kvm, gpa >> PAGE_SHIFT); + spin_unlock(&vcpu->kvm->mmu_lock); + return r; +} + +void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu) +{ + while (vcpu->kvm->arch.n_free_mmu_pages < KVM_REFILL_PAGES) { + struct kvm_mmu_page *sp; + + sp = container_of(vcpu->kvm->arch.active_mmu_pages.prev, + struct kvm_mmu_page, link); + kvm_mmu_zap_page(vcpu->kvm, sp); + ++vcpu->kvm->stat.mmu_recycled; + } +} + +int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code) +{ + int r; + enum emulation_result er; + + r = vcpu->arch.mmu.page_fault(vcpu, cr2, error_code); + if (r < 0) + goto out; + + if (!r) { + r = 1; + goto out; + } + + r = mmu_topup_memory_caches(vcpu); + if (r) + goto out; + + er = emulate_instruction(vcpu, vcpu->run, cr2, error_code, 0); + + switch (er) { + case EMULATE_DONE: + return 1; + case EMULATE_DO_MMIO: + ++vcpu->stat.mmio_exits; + return 0; + case EMULATE_FAIL: + kvm_report_emulation_failure(vcpu, "pagetable"); + return 1; + default: + BUG(); + } +out: + return r; +} +EXPORT_SYMBOL_GPL(kvm_mmu_page_fault); + +void kvm_enable_tdp(void) +{ + tdp_enabled = true; +} +EXPORT_SYMBOL_GPL(kvm_enable_tdp); + +static void free_mmu_pages(struct kvm_vcpu *vcpu) +{ + struct kvm_mmu_page *sp; + + while (!list_empty(&vcpu->kvm->arch.active_mmu_pages)) { + sp = container_of(vcpu->kvm->arch.active_mmu_pages.next, + struct kvm_mmu_page, link); + kvm_mmu_zap_page(vcpu->kvm, sp); + } + free_page((unsigned long)vcpu->arch.mmu.pae_root); +} + +static int alloc_mmu_pages(struct kvm_vcpu *vcpu) +{ + struct page *page; + int i; + + ASSERT(vcpu); + + if (vcpu->kvm->arch.n_requested_mmu_pages) + vcpu->kvm->arch.n_free_mmu_pages = + vcpu->kvm->arch.n_requested_mmu_pages; + else + vcpu->kvm->arch.n_free_mmu_pages = + vcpu->kvm->arch.n_alloc_mmu_pages; + /* + * When emulating 32-bit mode, cr3 is only 32 bits even on x86_64. + * Therefore we need to allocate shadow page tables in the first + * 4GB of memory, which happens to fit the DMA32 zone. + */ + page = alloc_page(GFP_KERNEL | __GFP_DMA32); + if (!page) + goto error_1; + vcpu->arch.mmu.pae_root = page_address(page); + for (i = 0; i < 4; ++i) + vcpu->arch.mmu.pae_root[i] = INVALID_PAGE; + + return 0; + +error_1: + free_mmu_pages(vcpu); + return -ENOMEM; +} + +int kvm_mmu_create(struct kvm_vcpu *vcpu) +{ + ASSERT(vcpu); + ASSERT(!VALID_PAGE(vcpu->arch.mmu.root_hpa)); + + return alloc_mmu_pages(vcpu); +} + +int kvm_mmu_setup(struct kvm_vcpu *vcpu) +{ + ASSERT(vcpu); + ASSERT(!VALID_PAGE(vcpu->arch.mmu.root_hpa)); + + return init_kvm_mmu(vcpu); +} + +void kvm_mmu_destroy(struct kvm_vcpu *vcpu) +{ + ASSERT(vcpu); + + destroy_kvm_mmu(vcpu); + free_mmu_pages(vcpu); + mmu_free_memory_caches(vcpu); +} + +void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot) +{ + struct kvm_mmu_page *sp; + + list_for_each_entry(sp, &kvm->arch.active_mmu_pages, link) { + int i; + u64 *pt; + + if (!test_bit(slot, &sp->slot_bitmap)) + continue; + + pt = sp->spt; + for (i = 0; i < PT64_ENT_PER_PAGE; ++i) + /* avoid RMW */ + if (pt[i] & PT_WRITABLE_MASK) + pt[i] &= ~PT_WRITABLE_MASK; + } +} + +void kvm_mmu_zap_all(struct kvm *kvm) +{ + struct kvm_mmu_page *sp, *node; + + spin_lock(&kvm->mmu_lock); + list_for_each_entry_safe(sp, node, &kvm->arch.active_mmu_pages, link) + kvm_mmu_zap_page(kvm, sp); + spin_unlock(&kvm->mmu_lock); + + kvm_flush_remote_tlbs(kvm); +} + +void kvm_mmu_module_exit(void) +{ + if (pte_chain_cache) + kmem_cache_destroy(pte_chain_cache); + if (rmap_desc_cache) + kmem_cache_destroy(rmap_desc_cache); + if (mmu_page_header_cache) + kmem_cache_destroy(mmu_page_header_cache); +} + +int kvm_mmu_module_init(void) +{ + pte_chain_cache = kmem_cache_create("kvm_pte_chain", + sizeof(struct kvm_pte_chain), + 0, 0, NULL); + if (!pte_chain_cache) + goto nomem; + rmap_desc_cache = kmem_cache_create("kvm_rmap_desc", + sizeof(struct kvm_rmap_desc), + 0, 0, NULL); + if (!rmap_desc_cache) + goto nomem; + + mmu_page_header_cache = kmem_cache_create("kvm_mmu_page_header", + sizeof(struct kvm_mmu_page), + 0, 0, NULL); + if (!mmu_page_header_cache) + goto nomem; + + return 0; + +nomem: + kvm_mmu_module_exit(); + return -ENOMEM; +} + +/* + * Caculate mmu pages needed for kvm. + */ +unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm) +{ + int i; + unsigned int nr_mmu_pages; + unsigned int nr_pages = 0; + + for (i = 0; i < kvm->nmemslots; i++) + nr_pages += kvm->memslots[i].npages; + + nr_mmu_pages = nr_pages * KVM_PERMILLE_MMU_PAGES / 1000; + nr_mmu_pages = max(nr_mmu_pages, + (unsigned int) KVM_MIN_ALLOC_MMU_PAGES); + + return nr_mmu_pages; +} + +#ifdef AUDIT + +static const char *audit_msg; + +static gva_t canonicalize(gva_t gva) +{ +#ifdef CONFIG_X86_64 + gva = (long long)(gva << 16) >> 16; +#endif + return gva; +} + +static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte, + gva_t va, int level) +{ + u64 *pt = __va(page_pte & PT64_BASE_ADDR_MASK); + int i; + gva_t va_delta = 1ul << (PAGE_SHIFT + 9 * (level - 1)); + + for (i = 0; i < PT64_ENT_PER_PAGE; ++i, va += va_delta) { + u64 ent = pt[i]; + + if (ent == shadow_trap_nonpresent_pte) + continue; + + va = canonicalize(va); + if (level > 1) { + if (ent == shadow_notrap_nonpresent_pte) + printk(KERN_ERR "audit: (%s) nontrapping pte" + " in nonleaf level: levels %d gva %lx" + " level %d pte %llx\n", audit_msg, + vcpu->arch.mmu.root_level, va, level, ent); + + audit_mappings_page(vcpu, ent, va, level - 1); + } else { + gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, va); + struct page *page = gpa_to_page(vcpu, gpa); + hpa_t hpa = page_to_phys(page); + + if (is_shadow_present_pte(ent) + && (ent & PT64_BASE_ADDR_MASK) != hpa) + printk(KERN_ERR "xx audit error: (%s) levels %d" + " gva %lx gpa %llx hpa %llx ent %llx %d\n", + audit_msg, vcpu->arch.mmu.root_level, + va, gpa, hpa, ent, + is_shadow_present_pte(ent)); + else if (ent == shadow_notrap_nonpresent_pte + && !is_error_hpa(hpa)) + printk(KERN_ERR "audit: (%s) notrap shadow," + " valid guest gva %lx\n", audit_msg, va); + kvm_release_page_clean(page); + + } + } +} + +static void audit_mappings(struct kvm_vcpu *vcpu) +{ + unsigned i; + + if (vcpu->arch.mmu.root_level == 4) + audit_mappings_page(vcpu, vcpu->arch.mmu.root_hpa, 0, 4); + else + for (i = 0; i < 4; ++i) + if (vcpu->arch.mmu.pae_root[i] & PT_PRESENT_MASK) + audit_mappings_page(vcpu, + vcpu->arch.mmu.pae_root[i], + i << 30, + 2); +} + +static int count_rmaps(struct kvm_vcpu *vcpu) +{ + int nmaps = 0; + int i, j, k; + + for (i = 0; i < KVM_MEMORY_SLOTS; ++i) { + struct kvm_memory_slot *m = &vcpu->kvm->memslots[i]; + struct kvm_rmap_desc *d; + + for (j = 0; j < m->npages; ++j) { + unsigned long *rmapp = &m->rmap[j]; + + if (!*rmapp) + continue; + if (!(*rmapp & 1)) { + ++nmaps; + continue; + } + d = (struct kvm_rmap_desc *)(*rmapp & ~1ul); + while (d) { + for (k = 0; k < RMAP_EXT; ++k) + if (d->shadow_ptes[k]) + ++nmaps; + else + break; + d = d->more; + } + } + } + return nmaps; +} + +static int count_writable_mappings(struct kvm_vcpu *vcpu) +{ + int nmaps = 0; + struct kvm_mmu_page *sp; + int i; + + list_for_each_entry(sp, &vcpu->kvm->arch.active_mmu_pages, link) { + u64 *pt = sp->spt; + + if (sp->role.level != PT_PAGE_TABLE_LEVEL) + continue; + + for (i = 0; i < PT64_ENT_PER_PAGE; ++i) { + u64 ent = pt[i]; + + if (!(ent & PT_PRESENT_MASK)) + continue; + if (!(ent & PT_WRITABLE_MASK)) + continue; + ++nmaps; + } + } + return nmaps; +} + +static void audit_rmap(struct kvm_vcpu *vcpu) +{ + int n_rmap = count_rmaps(vcpu); + int n_actual = count_writable_mappings(vcpu); + + if (n_rmap != n_actual) + printk(KERN_ERR "%s: (%s) rmap %d actual %d\n", + __FUNCTION__, audit_msg, n_rmap, n_actual); +} + +static void audit_write_protection(struct kvm_vcpu *vcpu) +{ + struct kvm_mmu_page *sp; + struct kvm_memory_slot *slot; + unsigned long *rmapp; + gfn_t gfn; + + list_for_each_entry(sp, &vcpu->kvm->arch.active_mmu_pages, link) { + if (sp->role.metaphysical) + continue; + + slot = gfn_to_memslot(vcpu->kvm, sp->gfn); + gfn = unalias_gfn(vcpu->kvm, sp->gfn); + rmapp = &slot->rmap[gfn - slot->base_gfn]; + if (*rmapp) + printk(KERN_ERR "%s: (%s) shadow page has writable" + " mappings: gfn %lx role %x\n", + __FUNCTION__, audit_msg, sp->gfn, + sp->role.word); + } +} + +static void kvm_mmu_audit(struct kvm_vcpu *vcpu, const char *msg) +{ + int olddbg = dbg; + + dbg = 0; + audit_msg = msg; + audit_rmap(vcpu); + audit_write_protection(vcpu); + audit_mappings(vcpu); + dbg = olddbg; +} + +#endif --- linux-2.6.24.orig/arch/x86/kvm/Makefile +++ linux-2.6.24/arch/x86/kvm/Makefile @@ -0,0 +1,14 @@ +# +# Makefile for Kernel-based Virtual Machine module +# + +common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o) + +EXTRA_CFLAGS += -Ivirt/kvm -Iarch/x86/kvm + +kvm-objs := $(common-objs) x86.o mmu.o x86_emulate.o i8259.o irq.o lapic.o +obj-$(CONFIG_KVM) += kvm.o +kvm-intel-objs = vmx.o +obj-$(CONFIG_KVM_INTEL) += kvm-intel.o +kvm-amd-objs = svm.o +obj-$(CONFIG_KVM_AMD) += kvm-amd.o --- linux-2.6.24.orig/arch/x86/kvm/irq.c +++ linux-2.6.24/arch/x86/kvm/irq.c @@ -0,0 +1,78 @@ +/* + * irq.c: API for in kernel interrupt controller + * Copyright (c) 2007, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * Authors: + * Yaozu (Eddie) Dong + * + */ + +#include +#include + +#include "irq.h" + +/* + * check if there is pending interrupt without + * intack. + */ +int kvm_cpu_has_interrupt(struct kvm_vcpu *v) +{ + struct kvm_pic *s; + + if (kvm_apic_has_interrupt(v) == -1) { /* LAPIC */ + if (kvm_apic_accept_pic_intr(v)) { + s = pic_irqchip(v->kvm); /* PIC */ + return s->output; + } else + return 0; + } + return 1; +} +EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt); + +/* + * Read pending interrupt vector and intack. + */ +int kvm_cpu_get_interrupt(struct kvm_vcpu *v) +{ + struct kvm_pic *s; + int vector; + + vector = kvm_get_apic_interrupt(v); /* APIC */ + if (vector == -1) { + if (kvm_apic_accept_pic_intr(v)) { + s = pic_irqchip(v->kvm); + s->output = 0; /* PIC */ + vector = kvm_pic_read_irq(s); + } + } + return vector; +} +EXPORT_SYMBOL_GPL(kvm_cpu_get_interrupt); + +void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu) +{ + kvm_inject_apic_timer_irqs(vcpu); + /* TODO: PIT, RTC etc. */ +} +EXPORT_SYMBOL_GPL(kvm_inject_pending_timer_irqs); + +void kvm_timer_intr_post(struct kvm_vcpu *vcpu, int vec) +{ + kvm_apic_timer_intr_post(vcpu, vec); + /* TODO: PIT, RTC etc. */ +} +EXPORT_SYMBOL_GPL(kvm_timer_intr_post); --- linux-2.6.24.orig/arch/x86/kvm/irq.h +++ linux-2.6.24/arch/x86/kvm/irq.h @@ -0,0 +1,88 @@ +/* + * irq.h: in kernel interrupt controller related definitions + * Copyright (c) 2007, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * Authors: + * Yaozu (Eddie) Dong + * + */ + +#ifndef __IRQ_H +#define __IRQ_H + +#include +#include +#include + +#include "iodev.h" +#include "ioapic.h" +#include "lapic.h" + +struct kvm; +struct kvm_vcpu; + +typedef void irq_request_func(void *opaque, int level); + +struct kvm_kpic_state { + u8 last_irr; /* edge detection */ + u8 irr; /* interrupt request register */ + u8 imr; /* interrupt mask register */ + u8 isr; /* interrupt service register */ + u8 priority_add; /* highest irq priority */ + u8 irq_base; + u8 read_reg_select; + u8 poll; + u8 special_mask; + u8 init_state; + u8 auto_eoi; + u8 rotate_on_auto_eoi; + u8 special_fully_nested_mode; + u8 init4; /* true if 4 byte init */ + u8 elcr; /* PIIX edge/trigger selection */ + u8 elcr_mask; + struct kvm_pic *pics_state; +}; + +struct kvm_pic { + struct kvm_kpic_state pics[2]; /* 0 is master pic, 1 is slave pic */ + irq_request_func *irq_request; + void *irq_request_opaque; + int output; /* intr from master PIC */ + struct kvm_io_device dev; +}; + +struct kvm_pic *kvm_create_pic(struct kvm *kvm); +void kvm_pic_set_irq(void *opaque, int irq, int level); +int kvm_pic_read_irq(struct kvm_pic *s); +void kvm_pic_update_irq(struct kvm_pic *s); + +static inline struct kvm_pic *pic_irqchip(struct kvm *kvm) +{ + return kvm->arch.vpic; +} + +static inline int irqchip_in_kernel(struct kvm *kvm) +{ + return pic_irqchip(kvm) != NULL; +} + +void kvm_pic_reset(struct kvm_kpic_state *s); + +void kvm_timer_intr_post(struct kvm_vcpu *vcpu, int vec); +void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu); +void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu); +void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu); + +#endif --- linux-2.6.24.orig/arch/x86/kvm/paging_tmpl.h +++ linux-2.6.24/arch/x86/kvm/paging_tmpl.h @@ -0,0 +1,505 @@ +/* + * Kernel-based Virtual Machine driver for Linux + * + * This module enables machines with Intel VT-x extensions to run virtual + * machines without emulation or binary translation. + * + * MMU support + * + * Copyright (C) 2006 Qumranet, Inc. + * + * Authors: + * Yaniv Kamay + * Avi Kivity + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +/* + * We need the mmu code to access both 32-bit and 64-bit guest ptes, + * so the code in this file is compiled twice, once per pte size. + */ + +#if PTTYPE == 64 + #define pt_element_t u64 + #define guest_walker guest_walker64 + #define FNAME(name) paging##64_##name + #define PT_BASE_ADDR_MASK PT64_BASE_ADDR_MASK + #define PT_DIR_BASE_ADDR_MASK PT64_DIR_BASE_ADDR_MASK + #define PT_INDEX(addr, level) PT64_INDEX(addr, level) + #define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level) + #define PT_LEVEL_MASK(level) PT64_LEVEL_MASK(level) + #define PT_LEVEL_BITS PT64_LEVEL_BITS + #ifdef CONFIG_X86_64 + #define PT_MAX_FULL_LEVELS 4 + #define CMPXCHG cmpxchg + #else + #define CMPXCHG cmpxchg64 + #define PT_MAX_FULL_LEVELS 2 + #endif +#elif PTTYPE == 32 + #define pt_element_t u32 + #define guest_walker guest_walker32 + #define FNAME(name) paging##32_##name + #define PT_BASE_ADDR_MASK PT32_BASE_ADDR_MASK + #define PT_DIR_BASE_ADDR_MASK PT32_DIR_BASE_ADDR_MASK + #define PT_INDEX(addr, level) PT32_INDEX(addr, level) + #define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level) + #define PT_LEVEL_MASK(level) PT32_LEVEL_MASK(level) + #define PT_LEVEL_BITS PT32_LEVEL_BITS + #define PT_MAX_FULL_LEVELS 2 + #define CMPXCHG cmpxchg +#else + #error Invalid PTTYPE value +#endif + +#define gpte_to_gfn FNAME(gpte_to_gfn) +#define gpte_to_gfn_pde FNAME(gpte_to_gfn_pde) + +/* + * The guest_walker structure emulates the behavior of the hardware page + * table walker. + */ +struct guest_walker { + int level; + gfn_t table_gfn[PT_MAX_FULL_LEVELS]; + pt_element_t ptes[PT_MAX_FULL_LEVELS]; + gpa_t pte_gpa[PT_MAX_FULL_LEVELS]; + unsigned pt_access; + unsigned pte_access; + gfn_t gfn; + u32 error_code; +}; + +static gfn_t gpte_to_gfn(pt_element_t gpte) +{ + return (gpte & PT_BASE_ADDR_MASK) >> PAGE_SHIFT; +} + +static gfn_t gpte_to_gfn_pde(pt_element_t gpte) +{ + return (gpte & PT_DIR_BASE_ADDR_MASK) >> PAGE_SHIFT; +} + +static bool FNAME(cmpxchg_gpte)(struct kvm *kvm, + gfn_t table_gfn, unsigned index, + pt_element_t orig_pte, pt_element_t new_pte) +{ + pt_element_t ret; + pt_element_t *table; + struct page *page; + + down_read(¤t->mm->mmap_sem); + page = gfn_to_page(kvm, table_gfn); + up_read(¤t->mm->mmap_sem); + + table = kmap_atomic(page, KM_USER0); + + ret = CMPXCHG(&table[index], orig_pte, new_pte); + + kunmap_atomic(table, KM_USER0); + + kvm_release_page_dirty(page); + + return (ret != orig_pte); +} + +static unsigned FNAME(gpte_access)(struct kvm_vcpu *vcpu, pt_element_t gpte) +{ + unsigned access; + + access = (gpte & (PT_WRITABLE_MASK | PT_USER_MASK)) | ACC_EXEC_MASK; +#if PTTYPE == 64 + if (is_nx(vcpu)) + access &= ~(gpte >> PT64_NX_SHIFT); +#endif + return access; +} + +/* + * Fetch a guest pte for a guest virtual address + */ +static int FNAME(walk_addr)(struct guest_walker *walker, + struct kvm_vcpu *vcpu, gva_t addr, + int write_fault, int user_fault, int fetch_fault) +{ + pt_element_t pte; + gfn_t table_gfn; + unsigned index, pt_access, pte_access; + gpa_t pte_gpa; + + pgprintk("%s: addr %lx\n", __FUNCTION__, addr); +walk: + walker->level = vcpu->arch.mmu.root_level; + pte = vcpu->arch.cr3; +#if PTTYPE == 64 + if (!is_long_mode(vcpu)) { + pte = vcpu->arch.pdptrs[(addr >> 30) & 3]; + if (!is_present_pte(pte)) + goto not_present; + --walker->level; + } +#endif + ASSERT((!is_long_mode(vcpu) && is_pae(vcpu)) || + (vcpu->arch.cr3 & CR3_NONPAE_RESERVED_BITS) == 0); + + pt_access = ACC_ALL; + + for (;;) { + index = PT_INDEX(addr, walker->level); + + table_gfn = gpte_to_gfn(pte); + pte_gpa = gfn_to_gpa(table_gfn); + pte_gpa += index * sizeof(pt_element_t); + walker->table_gfn[walker->level - 1] = table_gfn; + walker->pte_gpa[walker->level - 1] = pte_gpa; + pgprintk("%s: table_gfn[%d] %lx\n", __FUNCTION__, + walker->level - 1, table_gfn); + + kvm_read_guest(vcpu->kvm, pte_gpa, &pte, sizeof(pte)); + + if (!is_present_pte(pte)) + goto not_present; + + if (write_fault && !is_writeble_pte(pte)) + if (user_fault || is_write_protection(vcpu)) + goto access_error; + + if (user_fault && !(pte & PT_USER_MASK)) + goto access_error; + +#if PTTYPE == 64 + if (fetch_fault && is_nx(vcpu) && (pte & PT64_NX_MASK)) + goto access_error; +#endif + + if (!(pte & PT_ACCESSED_MASK)) { + mark_page_dirty(vcpu->kvm, table_gfn); + if (FNAME(cmpxchg_gpte)(vcpu->kvm, table_gfn, + index, pte, pte|PT_ACCESSED_MASK)) + goto walk; + pte |= PT_ACCESSED_MASK; + } + + pte_access = pt_access & FNAME(gpte_access)(vcpu, pte); + + walker->ptes[walker->level - 1] = pte; + + if (walker->level == PT_PAGE_TABLE_LEVEL) { + walker->gfn = gpte_to_gfn(pte); + break; + } + + if (walker->level == PT_DIRECTORY_LEVEL + && (pte & PT_PAGE_SIZE_MASK) + && (PTTYPE == 64 || is_pse(vcpu))) { + walker->gfn = gpte_to_gfn_pde(pte); + walker->gfn += PT_INDEX(addr, PT_PAGE_TABLE_LEVEL); + if (PTTYPE == 32 && is_cpuid_PSE36()) + walker->gfn += pse36_gfn_delta(pte); + break; + } + + pt_access = pte_access; + --walker->level; + } + + if (write_fault && !is_dirty_pte(pte)) { + bool ret; + + mark_page_dirty(vcpu->kvm, table_gfn); + ret = FNAME(cmpxchg_gpte)(vcpu->kvm, table_gfn, index, pte, + pte|PT_DIRTY_MASK); + if (ret) + goto walk; + pte |= PT_DIRTY_MASK; + kvm_mmu_pte_write(vcpu, pte_gpa, (u8 *)&pte, sizeof(pte)); + walker->ptes[walker->level - 1] = pte; + } + + walker->pt_access = pt_access; + walker->pte_access = pte_access; + pgprintk("%s: pte %llx pte_access %x pt_access %x\n", + __FUNCTION__, (u64)pte, pt_access, pte_access); + return 1; + +not_present: + walker->error_code = 0; + goto err; + +access_error: + walker->error_code = PFERR_PRESENT_MASK; + +err: + if (write_fault) + walker->error_code |= PFERR_WRITE_MASK; + if (user_fault) + walker->error_code |= PFERR_USER_MASK; + if (fetch_fault) + walker->error_code |= PFERR_FETCH_MASK; + return 0; +} + +static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page, + u64 *spte, const void *pte) +{ + pt_element_t gpte; + unsigned pte_access; + struct page *npage; + int largepage = vcpu->arch.update_pte.largepage; + + gpte = *(const pt_element_t *)pte; + if (~gpte & (PT_PRESENT_MASK | PT_ACCESSED_MASK)) { + if (!is_present_pte(gpte)) + set_shadow_pte(spte, shadow_notrap_nonpresent_pte); + return; + } + pgprintk("%s: gpte %llx spte %p\n", __FUNCTION__, (u64)gpte, spte); + pte_access = page->role.access & FNAME(gpte_access)(vcpu, gpte); + if (gpte_to_gfn(gpte) != vcpu->arch.update_pte.gfn) + return; + npage = vcpu->arch.update_pte.page; + if (!npage) + return; + get_page(npage); + mmu_set_spte(vcpu, spte, page->role.access, pte_access, 0, 0, + gpte & PT_DIRTY_MASK, NULL, largepage, gpte_to_gfn(gpte), + npage); +} + +/* + * Fetch a shadow pte for a specific level in the paging hierarchy. + */ +static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, + struct guest_walker *walker, + int user_fault, int write_fault, int largepage, + int *ptwrite, struct page *page) +{ + hpa_t shadow_addr; + int level; + u64 *shadow_ent; + unsigned access = walker->pt_access; + + if (!is_present_pte(walker->ptes[walker->level - 1])) + return NULL; + + shadow_addr = vcpu->arch.mmu.root_hpa; + level = vcpu->arch.mmu.shadow_root_level; + if (level == PT32E_ROOT_LEVEL) { + shadow_addr = vcpu->arch.mmu.pae_root[(addr >> 30) & 3]; + shadow_addr &= PT64_BASE_ADDR_MASK; + --level; + } + + for (; ; level--) { + u32 index = SHADOW_PT_INDEX(addr, level); + struct kvm_mmu_page *shadow_page; + u64 shadow_pte; + int metaphysical; + gfn_t table_gfn; + bool new_page = 0; + + shadow_ent = ((u64 *)__va(shadow_addr)) + index; + if (level == PT_PAGE_TABLE_LEVEL) + break; + + if (largepage && level == PT_DIRECTORY_LEVEL) + break; + + if (is_shadow_present_pte(*shadow_ent) + && !is_large_pte(*shadow_ent)) { + shadow_addr = *shadow_ent & PT64_BASE_ADDR_MASK; + continue; + } + + if (is_large_pte(*shadow_ent)) + rmap_remove(vcpu->kvm, shadow_ent); + + if (level - 1 == PT_PAGE_TABLE_LEVEL + && walker->level == PT_DIRECTORY_LEVEL) { + metaphysical = 1; + if (!is_dirty_pte(walker->ptes[level - 1])) + access &= ~ACC_WRITE_MASK; + table_gfn = gpte_to_gfn(walker->ptes[level - 1]); + } else { + metaphysical = 0; + table_gfn = walker->table_gfn[level - 2]; + } + shadow_page = kvm_mmu_get_page(vcpu, table_gfn, addr, level-1, + metaphysical, access, + shadow_ent, &new_page); + if (new_page && !metaphysical) { + int r; + pt_element_t curr_pte; + r = kvm_read_guest_atomic(vcpu->kvm, + walker->pte_gpa[level - 2], + &curr_pte, sizeof(curr_pte)); + if (r || curr_pte != walker->ptes[level - 2]) { + kvm_release_page_clean(page); + return NULL; + } + } + shadow_addr = __pa(shadow_page->spt); + shadow_pte = shadow_addr | PT_PRESENT_MASK | PT_ACCESSED_MASK + | PT_WRITABLE_MASK | PT_USER_MASK; + *shadow_ent = shadow_pte; + } + + mmu_set_spte(vcpu, shadow_ent, access, walker->pte_access & access, + user_fault, write_fault, + walker->ptes[walker->level-1] & PT_DIRTY_MASK, + ptwrite, largepage, walker->gfn, page); + + return shadow_ent; +} + +/* + * Page fault handler. There are several causes for a page fault: + * - there is no shadow pte for the guest pte + * - write access through a shadow pte marked read only so that we can set + * the dirty bit + * - write access to a shadow pte marked read only so we can update the page + * dirty bitmap, when userspace requests it + * - mmio access; in this case we will never install a present shadow pte + * - normal guest page fault due to the guest pte marked not present, not + * writable, or not executable + * + * Returns: 1 if we need to emulate the instruction, 0 otherwise, or + * a negative value on error. + */ +static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, + u32 error_code) +{ + int write_fault = error_code & PFERR_WRITE_MASK; + int user_fault = error_code & PFERR_USER_MASK; + int fetch_fault = error_code & PFERR_FETCH_MASK; + struct guest_walker walker; + u64 *shadow_pte; + int write_pt = 0; + int r; + struct page *page; + int largepage = 0; + + pgprintk("%s: addr %lx err %x\n", __FUNCTION__, addr, error_code); + kvm_mmu_audit(vcpu, "pre page fault"); + + r = mmu_topup_memory_caches(vcpu); + if (r) + return r; + + down_read(&vcpu->kvm->slots_lock); + /* + * Look up the shadow pte for the faulting address. + */ + r = FNAME(walk_addr)(&walker, vcpu, addr, write_fault, user_fault, + fetch_fault); + + /* + * The page is not mapped by the guest. Let the guest handle it. + */ + if (!r) { + pgprintk("%s: guest page fault\n", __FUNCTION__); + inject_page_fault(vcpu, addr, walker.error_code); + vcpu->arch.last_pt_write_count = 0; /* reset fork detector */ + up_read(&vcpu->kvm->slots_lock); + return 0; + } + + down_read(¤t->mm->mmap_sem); + if (walker.level == PT_DIRECTORY_LEVEL) { + gfn_t large_gfn; + large_gfn = walker.gfn & ~(KVM_PAGES_PER_HPAGE-1); + if (is_largepage_backed(vcpu, large_gfn)) { + walker.gfn = large_gfn; + largepage = 1; + } + } + page = gfn_to_page(vcpu->kvm, walker.gfn); + up_read(¤t->mm->mmap_sem); + + /* mmio */ + if (is_error_page(page)) { + pgprintk("gfn %x is mmio\n", walker.gfn); + kvm_release_page_clean(page); + up_read(&vcpu->kvm->slots_lock); + return 1; + } + + spin_lock(&vcpu->kvm->mmu_lock); + kvm_mmu_free_some_pages(vcpu); + shadow_pte = FNAME(fetch)(vcpu, addr, &walker, user_fault, write_fault, + largepage, &write_pt, page); + + pgprintk("%s: shadow pte %p %llx ptwrite %d\n", __FUNCTION__, + shadow_pte, *shadow_pte, write_pt); + + if (!write_pt) + vcpu->arch.last_pt_write_count = 0; /* reset fork detector */ + + ++vcpu->stat.pf_fixed; + kvm_mmu_audit(vcpu, "post page fault (fixed)"); + spin_unlock(&vcpu->kvm->mmu_lock); + up_read(&vcpu->kvm->slots_lock); + + return write_pt; +} + +static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr) +{ + struct guest_walker walker; + gpa_t gpa = UNMAPPED_GVA; + int r; + + r = FNAME(walk_addr)(&walker, vcpu, vaddr, 0, 0, 0); + + if (r) { + gpa = gfn_to_gpa(walker.gfn); + gpa |= vaddr & ~PAGE_MASK; + } + + return gpa; +} + +static void FNAME(prefetch_page)(struct kvm_vcpu *vcpu, + struct kvm_mmu_page *sp) +{ + int i, offset = 0, r = 0; + pt_element_t pt; + + if (sp->role.metaphysical + || (PTTYPE == 32 && sp->role.level > PT_PAGE_TABLE_LEVEL)) { + nonpaging_prefetch_page(vcpu, sp); + return; + } + + if (PTTYPE == 32) + offset = sp->role.quadrant << PT64_LEVEL_BITS; + + for (i = 0; i < PT64_ENT_PER_PAGE; ++i) { + gpa_t pte_gpa = gfn_to_gpa(sp->gfn); + pte_gpa += (i+offset) * sizeof(pt_element_t); + + r = kvm_read_guest_atomic(vcpu->kvm, pte_gpa, &pt, + sizeof(pt_element_t)); + if (r || is_present_pte(pt)) + sp->spt[i] = shadow_trap_nonpresent_pte; + else + sp->spt[i] = shadow_notrap_nonpresent_pte; + } +} + +#undef pt_element_t +#undef guest_walker +#undef FNAME +#undef PT_BASE_ADDR_MASK +#undef PT_INDEX +#undef SHADOW_PT_INDEX +#undef PT_LEVEL_MASK +#undef PT_DIR_BASE_ADDR_MASK +#undef PT_LEVEL_BITS +#undef PT_MAX_FULL_LEVELS +#undef gpte_to_gfn +#undef gpte_to_gfn_pde +#undef CMPXCHG --- linux-2.6.24.orig/arch/x86/pci/mmconfig_32.c +++ linux-2.6.24/arch/x86/pci/mmconfig_32.c @@ -30,10 +30,6 @@ struct acpi_mcfg_allocation *cfg; int cfg_num; - if (seg == 0 && bus < PCI_MMCFG_MAX_CHECK_BUS && - test_bit(PCI_SLOT(devfn) + 32*bus, pci_mmcfg_fallback_slots)) - return 0; - for (cfg_num = 0; cfg_num < pci_mmcfg_config_num; cfg_num++) { cfg = &pci_mmcfg_config[cfg_num]; if (cfg->pci_segment == seg && @@ -68,13 +64,16 @@ u32 base; if ((bus > 255) || (devfn > 255) || (reg > 4095)) { - *value = -1; +err: *value = -1; return -EINVAL; } + if (reg < 256) + return pci_conf1_read(seg,bus,devfn,reg,len,value); + base = get_base_addr(seg, bus, devfn); if (!base) - return pci_conf1_read(seg,bus,devfn,reg,len,value); + goto err; spin_lock_irqsave(&pci_config_lock, flags); @@ -105,9 +104,12 @@ if ((bus > 255) || (devfn > 255) || (reg > 4095)) return -EINVAL; + if (reg < 256) + return pci_conf1_write(seg,bus,devfn,reg,len,value); + base = get_base_addr(seg, bus, devfn); if (!base) - return pci_conf1_write(seg,bus,devfn,reg,len,value); + return -EINVAL; spin_lock_irqsave(&pci_config_lock, flags); @@ -134,12 +136,6 @@ .write = pci_mmcfg_write, }; -int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus, - unsigned int devfn) -{ - return get_base_addr(seg, bus, devfn) != 0; -} - int __init pci_mmcfg_arch_init(void) { printk(KERN_INFO "PCI: Using MMCONFIG\n"); --- linux-2.6.24.orig/arch/x86/pci/mmconfig_64.c +++ linux-2.6.24/arch/x86/pci/mmconfig_64.c @@ -40,9 +40,7 @@ static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) { char __iomem *addr; - if (seg == 0 && bus < PCI_MMCFG_MAX_CHECK_BUS && - test_bit(32*bus + PCI_SLOT(devfn), pci_mmcfg_fallback_slots)) - return NULL; + addr = get_virt(seg, bus); if (!addr) return NULL; @@ -56,13 +54,16 @@ /* Why do we have this when nobody checks it. How about a BUG()!? -AK */ if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) { - *value = -1; +err: *value = -1; return -EINVAL; } + if (reg < 256) + return pci_conf1_read(seg,bus,devfn,reg,len,value); + addr = pci_dev_base(seg, bus, devfn); if (!addr) - return pci_conf1_read(seg,bus,devfn,reg,len,value); + goto err; switch (len) { case 1: @@ -88,9 +89,12 @@ if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) return -EINVAL; + if (reg < 256) + return pci_conf1_write(seg,bus,devfn,reg,len,value); + addr = pci_dev_base(seg, bus, devfn); if (!addr) - return pci_conf1_write(seg,bus,devfn,reg,len,value); + return -EINVAL; switch (len) { case 1: @@ -126,12 +130,6 @@ return addr; } -int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus, - unsigned int devfn) -{ - return pci_dev_base(seg, bus, devfn) != NULL; -} - int __init pci_mmcfg_arch_init(void) { int i; --- linux-2.6.24.orig/arch/x86/pci/common.c +++ linux-2.6.24/arch/x86/pci/common.c @@ -17,8 +17,7 @@ #include "pci.h" -unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | - PCI_PROBE_MMCONF; +unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2; static int pci_bf_sort; int pci_routeirq; @@ -147,6 +146,22 @@ } #endif +#ifdef CONFIG_PCI_MMCONFIG +static int __devinit working_mmconfig(struct dmi_system_id *d) +{ + pci_probe |= PCI_PROBE_MMCONF; + return 0; +} + +static int __devinit blacklist_mmconfig(struct dmi_system_id *d) +{ + pci_probe &= ~PCI_PROBE_MMCONF; + printk(KERN_INFO "%s detected: disabling MMCONFIG PCI access", + d->ident); + return 0; +} +#endif /*CONFIG_PCI_MMCONFIG*/ + static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = { #ifdef __i386__ /* @@ -334,13 +349,16 @@ {} }; +void __init dmi_check_pciprobe(void) +{ + dmi_check_system(pciprobe_dmi_table); +} + struct pci_bus * __devinit pcibios_scan_root(int busnum) { struct pci_bus *bus = NULL; struct pci_sysdata *sd; - dmi_check_system(pciprobe_dmi_table); - while ((bus = pci_find_next_bus(bus)) != NULL) { if (bus->number == busnum) { /* Already scanned */ @@ -443,6 +461,10 @@ pci_probe &= ~PCI_PROBE_MMCONF; return NULL; } + else if (!strcmp(str, "mmconf")) { + pci_probe |= PCI_PROBE_MMCONF; + return NULL; + } #endif else if (!strcmp(str, "noacpi")) { acpi_noirq_set(); --- linux-2.6.24.orig/arch/x86/pci/pci.h +++ linux-2.6.24/arch/x86/pci/pci.h @@ -39,6 +39,8 @@ pci_dmi_bf, }; +extern void __init dmi_check_pciprobe(void); + /* pci-i386.c */ extern unsigned int pcibios_max_latency; @@ -98,13 +100,6 @@ /* pci-mmconfig.c */ -/* Verify the first 16 busses. We assume that systems with more busses - get MCFG right. */ -#define PCI_MMCFG_MAX_CHECK_BUS 16 -extern DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS); - -extern int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus, - unsigned int devfn); extern int __init pci_mmcfg_arch_init(void); /* --- linux-2.6.24.orig/arch/x86/pci/i386.c +++ linux-2.6.24/arch/x86/pci/i386.c @@ -125,7 +125,8 @@ pr = pci_find_parent_resource(dev, r); if (!r->start || !pr || request_resource(pr, r) < 0) { - printk(KERN_ERR "PCI: Cannot allocate " + printk(KERN_WARNING + "PCI: Cannot allocate " "resource region %d " "of bridge %s\n", idx, pci_name(dev)); @@ -168,7 +169,8 @@ r->start, r->end, r->flags, disabled, pass); pr = pci_find_parent_resource(dev, r); if (!pr || request_resource(pr, r) < 0) { - printk(KERN_ERR "PCI: Cannot allocate " + printk(KERN_WARNING + "PCI: Cannot allocate " "resource region %d " "of device %s\n", idx, pci_name(dev)); --- linux-2.6.24.orig/arch/x86/pci/init.c +++ linux-2.6.24/arch/x86/pci/init.c @@ -32,6 +32,8 @@ printk(KERN_ERR "PCI: Fatal: No config space access function found\n"); + dmi_check_pciprobe(); + return 0; } arch_initcall(pci_access_init); --- linux-2.6.24.orig/arch/x86/pci/mmconfig-shared.c +++ linux-2.6.24/arch/x86/pci/mmconfig-shared.c @@ -22,42 +22,9 @@ #define MMCONFIG_APER_MIN (2 * 1024*1024) #define MMCONFIG_APER_MAX (256 * 1024*1024) -DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS); - /* Indicate if the mmcfg resources have been placed into the resource table. */ static int __initdata pci_mmcfg_resources_inserted; -/* K8 systems have some devices (typically in the builtin northbridge) - that are only accessible using type1 - Normally this can be expressed in the MCFG by not listing them - and assigning suitable _SEGs, but this isn't implemented in some BIOS. - Instead try to discover all devices on bus 0 that are unreachable using MM - and fallback for them. */ -static void __init unreachable_devices(void) -{ - int i, bus; - /* Use the max bus number from ACPI here? */ - for (bus = 0; bus < PCI_MMCFG_MAX_CHECK_BUS; bus++) { - for (i = 0; i < 32; i++) { - unsigned int devfn = PCI_DEVFN(i, 0); - u32 val1, val2; - - pci_conf1_read(0, bus, devfn, 0, 4, &val1); - if (val1 == 0xffffffff) - continue; - - if (pci_mmcfg_arch_reachable(0, bus, devfn)) { - raw_pci_ops->read(0, bus, devfn, 0, 4, &val2); - if (val1 == val2) - continue; - } - set_bit(i + 32 * bus, pci_mmcfg_fallback_slots); - printk(KERN_NOTICE "PCI: No mmconfig possible on device" - " %02x:%02x\n", bus, i); - } - } -} - static const char __init *pci_mmcfg_e7520(void) { u32 win; @@ -270,8 +237,6 @@ return; if (pci_mmcfg_arch_init()) { - if (type == 1) - unreachable_devices(); if (known_bridge) pci_mmcfg_insert_resources(IORESOURCE_BUSY); pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; --- linux-2.6.24.orig/arch/x86/pci/acpi.c +++ linux-2.6.24/arch/x86/pci/acpi.c @@ -219,8 +219,21 @@ if (pxm >= 0) sd->node = pxm_to_node(pxm); #endif + /* + * Maybe the desired pci bus has been already scanned. In such case + * it is unnecessary to scan the pci bus with the given domain,busnum. + */ + bus = pci_find_bus(domain, busnum); + if (bus) { + /* + * If the desired bus exits, the content of bus->sysdata will + * be replaced by sd. + */ + memcpy(bus->sysdata, sd, sizeof(*sd)); + kfree(sd); + } else + bus = pci_scan_bus_parented(NULL, busnum, &pci_root_ops, sd); - bus = pci_scan_bus_parented(NULL, busnum, &pci_root_ops, sd); if (!bus) kfree(sd); @@ -228,7 +241,7 @@ if (bus != NULL) { if (pxm >= 0) { printk("bus %d -> pxm %d -> node %d\n", - busnum, pxm, sd->node); + busnum, pxm, pxm_to_node(pxm)); } } #endif --- linux-2.6.24.orig/arch/x86/lguest/boot.c +++ linux-2.6.24/arch/x86/lguest/boot.c @@ -67,6 +67,7 @@ #include #include #include +#include /* for struct machine_ops */ /*G:010 Welcome to the Guest! * @@ -812,7 +813,7 @@ * rather than virtual addresses, so we use __pa() here. */ static void lguest_power_off(void) { - hcall(LHCALL_CRASH, __pa("Power down"), 0, 0); + hcall(LHCALL_SHUTDOWN, __pa("Power down"), LGUEST_SHUTDOWN_POWEROFF, 0); } /* @@ -822,7 +823,7 @@ */ static int lguest_panic(struct notifier_block *nb, unsigned long l, void *p) { - hcall(LHCALL_CRASH, __pa(p), 0, 0); + hcall(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF, 0); /* The hcall won't return, but to keep gcc happy, we're "done". */ return NOTIFY_DONE; } @@ -926,6 +927,11 @@ return insn_len; } +static void lguest_restart(char *reason) +{ + hcall(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART, 0); +} + /*G:030 Once we get to lguest_init(), we know we're a Guest. The pv_ops * structures in the kernel provide points for (almost) every routine we have * to override to avoid privileged instructions. */ @@ -1059,6 +1065,7 @@ * the Guest routine to power off. */ pm_power_off = lguest_power_off; + machine_ops.restart = lguest_restart; /* Now we're set up, call start_kernel() in init/main.c and we proceed * to boot as normal. It never returns. */ start_kernel(); --- linux-2.6.24.orig/arch/x86/ia32/ia32_signal.c +++ linux-2.6.24/arch/x86/ia32/ia32_signal.c @@ -494,7 +494,7 @@ regs->ss = __USER32_DS; set_fs(USER_DS); - regs->eflags &= ~TF_MASK; + regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF); if (test_thread_flag(TIF_SINGLESTEP)) ptrace_notify(SIGTRAP); @@ -600,7 +600,7 @@ regs->ss = __USER32_DS; set_fs(USER_DS); - regs->eflags &= ~TF_MASK; + regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF); if (test_thread_flag(TIF_SINGLESTEP)) ptrace_notify(SIGTRAP); --- linux-2.6.24.orig/arch/x86/boot/edd.c +++ linux-2.6.24/arch/x86/boot/edd.c @@ -128,16 +128,24 @@ { char eddarg[8]; int do_mbr = 1; +#ifdef CONFIG_EDD_OFF + int do_edd = 0; +#else int do_edd = 1; +#endif int devno; struct edd_info ei, *edp; u32 *mbrptr; if (cmdline_find_option("edd", eddarg, sizeof eddarg) > 0) { - if (!strcmp(eddarg, "skipmbr") || !strcmp(eddarg, "skip")) + if (!strcmp(eddarg, "skipmbr") || !strcmp(eddarg, "skip")) { + do_edd = 1; do_mbr = 0; + } else if (!strcmp(eddarg, "off")) do_edd = 0; + else if (!strcmp(eddarg, "on")) + do_edd = 1; } edp = boot_params.eddbuf; --- linux-2.6.24.orig/arch/x86/boot/compressed/misc_64.c +++ linux-2.6.24/arch/x86/boot/compressed/misc_64.c @@ -184,8 +184,6 @@ static void *memset(void *s, int c, unsigned n); static void *memcpy(void *dest, const void *src, unsigned n); -static void putstr(const char *); - static long free_mem_ptr; static long free_mem_end_ptr; @@ -228,7 +226,8 @@ { free_mem_ptr = (long) *ptr; } - + +#ifdef CONFIG_WRAPPER_PRINT static void scroll(void) { int i; @@ -269,11 +268,14 @@ RM_SCREEN_INFO.orig_y = y; pos = (x + cols * y) * 2; /* Update cursor position */ - outb_p(14, vidport); - outb_p(0xff & (pos >> 9), vidport+1); - outb_p(15, vidport); - outb_p(0xff & (pos >> 1), vidport+1); -} + outb(14, vidport); + outb(0xff & (pos >> 9), vidport+1); + outb(15, vidport); + outb(0xff & (pos >> 1), vidport+1); +} +#else +#define putstr(__x) do{}while(0) +#endif /* CONFIG_WRAPPER_PRINT */ static void* memset(void* s, int c, unsigned n) { --- linux-2.6.24.orig/arch/x86/boot/compressed/misc_32.c +++ linux-2.6.24/arch/x86/boot/compressed/misc_32.c @@ -184,8 +184,6 @@ static void *memset(void *s, int c, unsigned n); static void *memcpy(void *dest, const void *src, unsigned n); -static void putstr(const char *); - static unsigned long free_mem_ptr; static unsigned long free_mem_end_ptr; @@ -232,7 +230,8 @@ { free_mem_ptr = (unsigned long) *ptr; } - + +#ifdef CONFIG_WRAPPER_PRINT static void scroll(void) { int i; @@ -276,11 +275,14 @@ RM_SCREEN_INFO.orig_y = y; pos = (x + cols * y) * 2; /* Update cursor position */ - outb_p(14, vidport); - outb_p(0xff & (pos >> 9), vidport+1); - outb_p(15, vidport); - outb_p(0xff & (pos >> 1), vidport+1); -} + outb(14, vidport); + outb(0xff & (pos >> 9), vidport+1); + outb(15, vidport); + outb(0xff & (pos >> 1), vidport+1); +} +#else +#define putstr(__x) do{}while(0) +#endif /* CONFIG_WRAPPER_PRINT */ static void* memset(void* s, int c, unsigned n) { --- linux-2.6.24.orig/arch/x86/mm/pageattr_64.c +++ linux-2.6.24/arch/x86/mm/pageattr_64.c @@ -207,7 +207,7 @@ if (__pa(address) < KERNEL_TEXT_SIZE) { unsigned long addr2; pgprot_t prot2; - addr2 = __START_KERNEL_map + __pa(address); + addr2 = __START_KERNEL_map + __pa(address) - phys_base; /* Make sure the kernel mappings stay executable */ prot2 = pte_pgprot(pte_mkexec(pfn_pte(0, prot))); err = __change_page_attr(addr2, pfn, prot2, --- linux-2.6.24.orig/arch/x86/mm/init_32.c +++ linux-2.6.24/arch/x86/mm/init_32.c @@ -223,22 +223,48 @@ } for (i = 0; i < e820.nr_map; i++) { - - if (e820.map[i].type != E820_RAM) /* not usable memory */ + /* + * Not usable memory: + */ + if (e820.map[i].type != E820_RAM) continue; + addr = (e820.map[i].addr + PAGE_SIZE-1) >> PAGE_SHIFT; + end = (e820.map[i].addr + e820.map[i].size) >> PAGE_SHIFT; + /* - * !!!FIXME!!! Some BIOSen report areas as RAM that - * are not. Notably the 640->1Mb area. We need a sanity - * check here. + * Sanity check: Some BIOSen report areas as RAM that + * are not. Notably the 640->1Mb area, which is the + * PCI BIOS area. */ - addr = (e820.map[i].addr+PAGE_SIZE-1) >> PAGE_SHIFT; - end = (e820.map[i].addr+e820.map[i].size) >> PAGE_SHIFT; - if ((pagenr >= addr) && (pagenr < end)) + if (addr >= (BIOS_BEGIN >> PAGE_SHIFT) && + end < (BIOS_END >> PAGE_SHIFT)) + continue; + + if ((pagenr >= addr) && (pagenr < end)) return 1; } return 0; } +/* + * devmem_is_allowed() checks to see if /dev/mem access to a certain address + * is valid. The argument is a physical page number. + * + * + * On x86, access has to be given to the first megabyte of ram because that area + * contains bios code and data regions used by X and dosemu and similar apps. + * Access has to be given to non-kernel-ram areas as well, these contain the PCI + * mmio resources as well as potential bios/acpi data regions. + */ +int devmem_is_allowed(unsigned long pagenr) +{ + if (pagenr <= 256) + return 1; + if (!page_is_ram(pagenr)) + return 1; + return 0; +} + #ifdef CONFIG_HIGHMEM pte_t *kmap_pte; pgprot_t kmap_prot; --- linux-2.6.24.orig/arch/x86/mm/init_64.c +++ linux-2.6.24/arch/x86/mm/init_64.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -512,6 +513,71 @@ } #endif +int page_is_ram(unsigned long pagenr) +{ + int i; + unsigned long addr, end; + + if (efi_enabled) { + efi_memory_desc_t *md; + void *p; + + for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { + md = p; + if (!is_available_memory(md)) + continue; + addr = (md->phys_addr+PAGE_SIZE-1) >> PAGE_SHIFT; + end = (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >> PAGE_SHIFT; + + if ((pagenr >= addr) && (pagenr < end)) + return 1; + } + return 0; + } + + for (i = 0; i < e820.nr_map; i++) { + /* + * Not usable memory: + */ + if (e820.map[i].type != E820_RAM) + continue; + addr = (e820.map[i].addr + PAGE_SIZE-1) >> PAGE_SHIFT; + end = (e820.map[i].addr + e820.map[i].size) >> PAGE_SHIFT; + + /* + * Sanity check: Some BIOSen report areas as RAM that + * are not. Notably the 640->1Mb area, which is the + * PCI BIOS area. + */ + if (addr >= (BIOS_BEGIN >> PAGE_SHIFT) && + end < (BIOS_END >> PAGE_SHIFT)) + continue; + + if ((pagenr >= addr) && (pagenr < end)) + return 1; + } + return 0; +} + +/* + * devmem_is_allowed() checks to see if /dev/mem access to a certain address + * is valid. The argument is a physical page number. + * + * + * On x86, access has to be given to the first megabyte of ram because that area + * contains bios code and data regions used by X and dosemu and similar apps. + * Access has to be given to non-kernel-ram areas as well, these contain the PCI + * mmio resources as well as potential bios/acpi data regions. + */ +int devmem_is_allowed(unsigned long pagenr) +{ + if (pagenr <= 256) + return 1; + if (!page_is_ram(pagenr)) + return 1; + return 0; +} + static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules, kcore_vsyscall; --- linux-2.6.24.orig/arch/x86/mm/mmap_64.c +++ linux-2.6.24/arch/x86/mm/mmap_64.c @@ -1,29 +1,117 @@ -/* Copyright 2005 Andi Kleen, SuSE Labs. - * Licensed under GPL, v.2 +/* + * linux/arch/x86-64/mm/mmap.c + * + * flexible mmap layout support + * + * Based on code by Ingo Molnar and Andi Kleen, copyrighted + * as follows: + * + * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina. + * All Rights Reserved. + * Copyright 2005 Andi Kleen, SUSE Labs. + * Copyright 2007 Jiri Kosina, SUSE Labs. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * */ + +#include #include -#include #include +#include +#include #include -/* Notebook: move the mmap code from sys_x86_64.c over here. */ +/* + * Top of mmap area (just below the process stack). + * + * Leave an at least ~128 MB hole. + */ +#define MIN_GAP (128*1024*1024) +#define MAX_GAP (TASK_SIZE/6*5) + +static inline unsigned long mmap_base(void) +{ + unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur; + + if (gap < MIN_GAP) + gap = MIN_GAP; + else if (gap > MAX_GAP) + gap = MAX_GAP; + return TASK_SIZE - (gap & PAGE_MASK); +} + +static inline int mmap_is_32(void) +{ +#ifdef CONFIG_IA32_EMULATION + if (test_thread_flag(TIF_IA32)) + return 1; +#endif + return 0; +} + +static inline int mmap_is_legacy(void) +{ + if (current->personality & ADDR_COMPAT_LAYOUT) + return 1; + + if (current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) + return 1; + + return sysctl_legacy_va_layout; +} + +/* + * This function, called very early during the creation of a new + * process VM image, sets up which VM layout function to use: + */ void arch_pick_mmap_layout(struct mm_struct *mm) { + int rnd = 0; + if (current->flags & PF_RANDOMIZE) { + /* + * Add 28bit randomness which is about 40bits of address space + * because mmap base has to be page aligned. + * or ~1/128 of the total user VM + * (total user address space is 47bits) + */ + rnd = get_random_int() & 0xfffffff; + } + + /* + * Fall back to the standard layout if the personality + * bit is set, or if the expected stack growth is unlimited: + */ + if (mmap_is_32()) { #ifdef CONFIG_IA32_EMULATION - if (current_thread_info()->flags & _TIF_IA32) + /* ia32_pick_mmap_layout has its own. */ return ia32_pick_mmap_layout(mm); #endif - mm->mmap_base = TASK_UNMAPPED_BASE; + } else if(mmap_is_legacy()) { + mm->mmap_base = TASK_UNMAPPED_BASE; + mm->get_unmapped_area = arch_get_unmapped_area; + mm->unmap_area = arch_unmap_area; + } else { + mm->mmap_base = mmap_base(); + mm->get_unmapped_area = arch_get_unmapped_area_topdown; + mm->unmap_area = arch_unmap_area_topdown; + if (current->flags & PF_RANDOMIZE) + rnd = -rnd; + } if (current->flags & PF_RANDOMIZE) { - /* Add 28bit randomness which is about 40bits of address space - because mmap base has to be page aligned. - or ~1/128 of the total user VM - (total user address space is 47bits) */ - unsigned rnd = get_random_int() & 0xfffffff; - mm->mmap_base += ((unsigned long)rnd) << PAGE_SHIFT; + mm->mmap_base += ((long)rnd) << PAGE_SHIFT; } - mm->get_unmapped_area = arch_get_unmapped_area; - mm->unmap_area = arch_unmap_area; } - --- linux-2.6.24.orig/arch/x86/kernel/entry_64.S +++ linux-2.6.24/arch/x86/kernel/entry_64.S @@ -779,7 +779,7 @@ swapgs paranoid_restore\trace: RESTORE_ALL 8 - iretq + jmp iret_label paranoid_userspace\trace: GET_THREAD_INFO(%rcx) movl threadinfo_flags(%rcx),%ebx --- linux-2.6.24.orig/arch/x86/kernel/signal_32.c +++ linux-2.6.24/arch/x86/kernel/signal_32.c @@ -396,7 +396,7 @@ * The tracer may want to single-step inside the * handler too. */ - regs->eflags &= ~TF_MASK; + regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF); if (test_thread_flag(TIF_SINGLESTEP)) ptrace_notify(SIGTRAP); @@ -489,7 +489,7 @@ * The tracer may want to single-step inside the * handler too. */ - regs->eflags &= ~TF_MASK; + regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF); if (test_thread_flag(TIF_SINGLESTEP)) ptrace_notify(SIGTRAP); --- linux-2.6.24.orig/arch/x86/kernel/Makefile_64 +++ linux-2.6.24/arch/x86/kernel/Makefile_64 @@ -11,7 +11,7 @@ x8664_ksyms_64.o i387_64.o syscall_64.o vsyscall_64.o \ setup64.o bootflag.o e820_64.o reboot_64.o quirks.o i8237.o \ pci-dma_64.o pci-nommu_64.o alternative.o hpet.o tsc_64.o bugs_64.o \ - i8253.o + i8253.o io_delay.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-y += cpu/ --- linux-2.6.24.orig/arch/x86/kernel/smpboot_64.c +++ linux-2.6.24/arch/x86/kernel/smpboot_64.c @@ -338,7 +338,7 @@ if (nmi_watchdog == NMI_IO_APIC) { disable_8259A_irq(0); - enable_NMI_through_LVT0(NULL); + enable_NMI_through_LVT0(); enable_8259A_irq(0); } --- linux-2.6.24.orig/arch/x86/kernel/signal_64.c +++ linux-2.6.24/arch/x86/kernel/signal_64.c @@ -295,7 +295,7 @@ see include/asm-x86_64/uaccess.h for details. */ set_fs(USER_DS); - regs->eflags &= ~TF_MASK; + regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF); if (test_thread_flag(TIF_SINGLESTEP)) ptrace_notify(SIGTRAP); #ifdef DEBUG_SIG --- linux-2.6.24.orig/arch/x86/kernel/io_delay.c +++ linux-2.6.24/arch/x86/kernel/io_delay.c @@ -0,0 +1,121 @@ +/* + * I/O delay strategies for inb_p/outb_p + * + * Allow for a DMI based override of port 0x80, needed for certain HP laptops + * and possibly other systems. Also allow for the gradual elimination of + * outb_p/inb_p API uses. + */ +#include +#include +#include +#include +#include +#include + +int io_delay_type __read_mostly = CONFIG_DEFAULT_IO_DELAY_TYPE; + +static int __initdata io_delay_override; + +/* + * Paravirt wants native_io_delay to be a constant. + */ +void native_io_delay(void) +{ + switch (io_delay_type) { + default: + case CONFIG_IO_DELAY_TYPE_0X80: + asm volatile ("outb %al, $0x80"); + break; + case CONFIG_IO_DELAY_TYPE_0XED: + asm volatile ("outb %al, $0xed"); + break; + case CONFIG_IO_DELAY_TYPE_UDELAY: + /* + * 2 usecs is an upper-bound for the outb delay but + * note that udelay doesn't have the bus-level + * side-effects that outb does, nor does udelay() have + * precise timings during very early bootup (the delays + * are shorter until calibrated): + */ + udelay(2); + case CONFIG_IO_DELAY_TYPE_NONE: + break; + } +} +EXPORT_SYMBOL(native_io_delay); + +static int __init dmi_io_delay_0xed_port(const struct dmi_system_id *id) +{ + if (io_delay_type == CONFIG_IO_DELAY_TYPE_0X80) { + printk(KERN_NOTICE "%s: using 0xed I/O delay port\n", + id->ident); + io_delay_type = CONFIG_IO_DELAY_TYPE_0XED; + } + + return 0; +} + +/* + * Quirk table for systems that misbehave (lock up, etc.) if port + * 0x80 is used: + */ +static struct dmi_system_id __initdata io_delay_0xed_port_dmi_table[] = { + { + .callback = dmi_io_delay_0xed_port, + .ident = "Compaq Presario V6000", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"), + DMI_MATCH(DMI_BOARD_NAME, "30B7") + } + }, + { + .callback = dmi_io_delay_0xed_port, + .ident = "HP Pavilion dv9000z", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"), + DMI_MATCH(DMI_BOARD_NAME, "30B9") + } + }, + { + .callback = dmi_io_delay_0xed_port, + .ident = "HP Pavilion dv6000", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"), + DMI_MATCH(DMI_BOARD_NAME, "30B8") + } + }, + { + .callback = dmi_io_delay_0xed_port, + .ident = "HP Pavilion tx1000", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"), + DMI_MATCH(DMI_BOARD_NAME, "30BF") + } + }, + { } +}; + +void __init io_delay_init(void) +{ + if (!io_delay_override) + dmi_check_system(io_delay_0xed_port_dmi_table); +} + +static int __init io_delay_param(char *s) +{ + if (!strcmp(s, "0x80")) + io_delay_type = CONFIG_IO_DELAY_TYPE_0X80; + else if (!strcmp(s, "0xed")) + io_delay_type = CONFIG_IO_DELAY_TYPE_0XED; + else if (!strcmp(s, "udelay")) + io_delay_type = CONFIG_IO_DELAY_TYPE_UDELAY; + else if (!strcmp(s, "none")) + io_delay_type = CONFIG_IO_DELAY_TYPE_NONE; + else + return -EINVAL; + + io_delay_override = 1; + return 0; +} + +early_param("io_delay", io_delay_param); --- linux-2.6.24.orig/arch/x86/kernel/apic_64.c +++ linux-2.6.24/arch/x86/kernel/apic_64.c @@ -151,7 +151,7 @@ return send_status; } -void enable_NMI_through_LVT0 (void * dummy) +void enable_NMI_through_LVT0(void) { unsigned int v; --- linux-2.6.24.orig/arch/x86/kernel/reboot_32.c +++ linux-2.6.24/arch/x86/kernel/reboot_32.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -39,6 +40,9 @@ case 'c': /* "cold" reboot (with memory testing etc) */ reboot_mode = 0x0; break; + case 'a': /* reboot through ACPI BIOS. */ + reboot_thru_bios = 2; + break; case 'b': /* "bios" reboot by jumping through the BIOS */ reboot_thru_bios = 1; break; @@ -74,6 +78,20 @@ */ /* + * Some machines require the "reboot=a" commandline option, this quirk makes + * that automatic. + */ +static int __init set_acpi_reboot(const struct dmi_system_id *d) +{ + if (!reboot_thru_bios) { + printk(KERN_INFO "%s detected. Using ACPI for reboots.\n", + d->ident); + reboot_thru_bios = 2; + } + return 0; +} + +/* * Some machines require the "reboot=b" commandline option, this quirk makes that automatic. */ static int __init set_bios_reboot(const struct dmi_system_id *d) @@ -135,6 +153,15 @@ DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"), }, }, + { /* Handle problems with rebooting classmate PC after suspend */ + .callback = set_acpi_reboot, + .ident = "Intel powered classmate PC", + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, + "Intel powered classmate PC"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Gen 1.5"), + }, + }, { } }; @@ -357,6 +384,9 @@ if (efi_enabled) efi.reset_system(EFI_RESET_WARM, EFI_SUCCESS, 0, NULL); + if (reboot_thru_bios == 2) + acpi_reboot(); + machine_real_restart(jump_to_bios, sizeof(jump_to_bios)); } --- linux-2.6.24.orig/arch/x86/kernel/smpboot_32.c +++ linux-2.6.24/arch/x86/kernel/smpboot_32.c @@ -405,7 +405,7 @@ setup_secondary_clock(); if (nmi_watchdog == NMI_IO_APIC) { disable_8259A_irq(0); - enable_NMI_through_LVT0(NULL); + enable_NMI_through_LVT0(); enable_8259A_irq(0); } /* @@ -882,6 +882,11 @@ /* mark "stuck" area as not stuck */ *((volatile unsigned long *)trampoline_base) = 0; + /* + * Cleanup possible dangling ends... + */ + smpboot_restore_warm_reset_vector(); + return boot_error; } @@ -1083,11 +1088,6 @@ } /* - * Cleanup possible dangling ends... - */ - smpboot_restore_warm_reset_vector(); - - /* * Allow the user to impress friends. */ Dprintk("Before bogomips.\n"); --- linux-2.6.24.orig/arch/x86/kernel/reboot_64.c +++ linux-2.6.24/arch/x86/kernel/reboot_64.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -28,6 +29,7 @@ static long no_idt[3]; static enum { + BOOT_ACPI = 'a', BOOT_TRIPLE = 't', BOOT_KBD = 'k' } reboot_type = BOOT_KBD; @@ -56,6 +58,7 @@ case 't': case 'b': case 'k': + case 'a': reboot_type = *str; break; case 'f': @@ -146,7 +149,11 @@ reboot_type = BOOT_KBD; break; - } + case BOOT_ACPI: + acpi_reboot(); + reboot_type = BOOT_KBD; + break; + } } } --- linux-2.6.24.orig/arch/x86/kernel/io_apic_32.c +++ linux-2.6.24/arch/x86/kernel/io_apic_32.c @@ -2080,7 +2080,7 @@ .eoi = ack_apic, }; -static void setup_nmi (void) +static void __init setup_nmi(void) { /* * Dirty trick to enable the NMI watchdog ... @@ -2093,7 +2093,7 @@ */ apic_printk(APIC_VERBOSE, KERN_INFO "activating NMI Watchdog ..."); - on_each_cpu(enable_NMI_through_LVT0, NULL, 1, 1); + enable_NMI_through_LVT0(); apic_printk(APIC_VERBOSE, " done.\n"); } @@ -2306,6 +2306,9 @@ for (i = FIRST_SYSTEM_VECTOR; i < NR_VECTORS; i++) set_bit(i, used_vectors); + /* Mark FIRST_DEVICE_VECTOR which is assigned to IRQ0 as used. */ + set_bit(FIRST_DEVICE_VECTOR, used_vectors); + enable_IO_APIC(); if (acpi_ioapic) @@ -2478,6 +2481,7 @@ dynamic_irq_cleanup(irq); spin_lock_irqsave(&vector_lock, flags); + clear_bit(irq_vector[irq], used_vectors); irq_vector[irq] = 0; spin_unlock_irqrestore(&vector_lock, flags); } --- linux-2.6.24.orig/arch/x86/kernel/tsc_32.c +++ linux-2.6.24/arch/x86/kernel/tsc_32.c @@ -267,15 +267,28 @@ /* clock source code */ -static unsigned long current_tsc_khz = 0; +static unsigned long current_tsc_khz; +static struct clocksource clocksource_tsc; +/* + * We compare the TSC to the cycle_last value in the clocksource + * structure to avoid a nasty time-warp issue. This can be observed in + * a very small window right after one CPU updated cycle_last under + * xtime lock and the other CPU reads a TSC value which is smaller + * than the cycle_last reference value due to a TSC which is slighty + * behind. This delta is nowhere else observable, but in that case it + * results in a forward time jump in the range of hours due to the + * unsigned delta calculation of the time keeping core code, which is + * necessary to support wrapping clocksources like pm timer. + */ static cycle_t read_tsc(void) { cycle_t ret; rdtscll(ret); - return ret; + return ret >= clocksource_tsc.cycle_last ? + ret : clocksource_tsc.cycle_last; } static struct clocksource clocksource_tsc = { --- linux-2.6.24.orig/arch/x86/kernel/sys_x86_64.c +++ linux-2.6.24/arch/x86/kernel/sys_x86_64.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -65,6 +66,7 @@ unsigned long *end) { if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) { + unsigned long new_begin; /* This is usually used needed to map code in small model, so it needs to be in the first 31bit. Limit it to that. This means we need to move the @@ -74,6 +76,11 @@ of playground for now. -AK */ *begin = 0x40000000; *end = 0x80000000; + if (current->flags & PF_RANDOMIZE) { + new_begin = randomize_range(*begin, *begin + 0x02000000, 0); + if (new_begin) + *begin = new_begin; + } } else { *begin = TASK_UNMAPPED_BASE; *end = TASK_SIZE; @@ -143,6 +150,97 @@ } } + +unsigned long +arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, + const unsigned long len, const unsigned long pgoff, + const unsigned long flags) +{ + struct vm_area_struct *vma; + struct mm_struct *mm = current->mm; + unsigned long addr = addr0; + + /* requested length too big for entire address space */ + if (len > TASK_SIZE) + return -ENOMEM; + + if (flags & MAP_FIXED) + return addr; + + /* for MAP_32BIT mappings we force the legact mmap base */ + if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) + goto bottomup; + + /* requesting a specific address */ + if (addr) { + addr = PAGE_ALIGN(addr); + vma = find_vma(mm, addr); + if (TASK_SIZE - len >= addr && + (!vma || addr + len <= vma->vm_start)) + return addr; + } + + /* check if free_area_cache is useful for us */ + if (len <= mm->cached_hole_size) { + mm->cached_hole_size = 0; + mm->free_area_cache = mm->mmap_base; + } + + /* either no address requested or can't fit in requested address hole */ + addr = mm->free_area_cache; + + /* make sure it can fit in the remaining address space */ + if (addr > len) { + vma = find_vma(mm, addr-len); + if (!vma || addr <= vma->vm_start) + /* remember the address as a hint for next time */ + return (mm->free_area_cache = addr-len); + } + + if (mm->mmap_base < len) + goto bottomup; + + addr = mm->mmap_base-len; + + do { + /* + * Lookup failure means no vma is above this address, + * else if new region fits below vma->vm_start, + * return with success: + */ + vma = find_vma(mm, addr); + if (!vma || addr+len <= vma->vm_start) + /* remember the address as a hint for next time */ + return (mm->free_area_cache = addr); + + /* remember the largest hole we saw so far */ + if (addr + mm->cached_hole_size < vma->vm_start) + mm->cached_hole_size = vma->vm_start - addr; + + /* try just below the current vma->vm_start */ + addr = vma->vm_start-len; + } while (len < vma->vm_start); + +bottomup: + /* + * A failed mmap() very likely causes application failure, + * so fall back to the bottom-up function here. This scenario + * can happen with large stack limits and large mmap() + * allocations. + */ + mm->cached_hole_size = ~0UL; + mm->free_area_cache = TASK_UNMAPPED_BASE; + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags); + /* + * Restore the topdown base: + */ + mm->free_area_cache = mm->mmap_base; + mm->cached_hole_size = ~0UL; + + return addr; +} + + asmlinkage long sys_uname(struct new_utsname __user * name) { int err; --- linux-2.6.24.orig/arch/x86/kernel/pci-gart_64.c +++ linux-2.6.24/arch/x86/kernel/pci-gart_64.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -492,6 +493,83 @@ return aper_base; } +static void enable_gart_translations(void) +{ + int i; + + for (i = 0; i < num_k8_northbridges; i++) { + struct pci_dev *dev = k8_northbridges[i]; + u32 ctl; + u32 gatt_reg; + + gatt_reg = __pa(agp_gatt_table) >> 12; + gatt_reg <<= 4; + pci_write_config_dword(dev, 0x98, gatt_reg); + pci_read_config_dword(dev, 0x90, &ctl); + + ctl |= 1; + ctl &= ~((1<<4) | (1<<5)); + + pci_write_config_dword(dev, 0x90, ctl); + } +} + +/* + * If fix_up_north_bridges is set, the north bridges have to be fixed up on + * resume in the same way as they are handled in gart_iommu_hole_init(). + */ +static bool fix_up_north_bridges; +static u32 aperture_order; +static u32 aperture_alloc; + +void set_up_gart_resume(u32 aper_order, u32 aper_alloc) +{ + fix_up_north_bridges = true; + aperture_order = aper_order; + aperture_alloc = aper_alloc; +} + +static int gart_resume(struct sys_device *dev) +{ + printk(KERN_INFO "PCI-DMA: Resuming GART IOMMU\n"); + + if (fix_up_north_bridges) { + int i; + + printk(KERN_INFO "PCI-DMA: Restoring GART aperture settings\n"); + + for (i = 0; i < num_k8_northbridges; i++) { + struct pci_dev *dev = k8_northbridges[i]; + + /* + * Don't enable translations just yet. That is the next + * step. Restore the pre-suspend aperture settings. + */ + pci_write_config_dword(dev, 0x90, aperture_order << 1); + pci_write_config_dword(dev, 0x94, aperture_alloc >> 25); + } + } + + enable_gart_translations(); + + return 0; +} + +static int gart_suspend(struct sys_device *dev, pm_message_t state) +{ + return 0; +} + +static struct sysdev_class gart_sysdev_class = { + .suspend = gart_suspend, + .resume = gart_resume, +}; + +static struct sys_device device_gart = { + .id = 0, + .cls = &gart_sysdev_class, +}; + /* * Private Northbridge GATT initialization in case we cannot use the * AGP driver for some reason. @@ -502,7 +580,7 @@ void *gatt; unsigned aper_base, new_aper_base; unsigned aper_size, gatt_size, new_aper_size; - int i; + int i, error; printk(KERN_INFO "PCI-DMA: Disabling AGP.\n"); aper_size = aper_base = info->aper_size = 0; @@ -536,21 +614,14 @@ memset(gatt, 0, gatt_size); agp_gatt_table = gatt; - for (i = 0; i < num_k8_northbridges; i++) { - u32 ctl; - u32 gatt_reg; - - dev = k8_northbridges[i]; - gatt_reg = __pa(gatt) >> 12; - gatt_reg <<= 4; - pci_write_config_dword(dev, 0x98, gatt_reg); - pci_read_config_dword(dev, 0x90, &ctl); - - ctl |= 1; - ctl &= ~((1<<4) | (1<<5)); + enable_gart_translations(); - pci_write_config_dword(dev, 0x90, ctl); - } + error = sysdev_class_register(&gart_sysdev_class); + if (!error) + error = sysdev_register(&device_gart); + if (error) + panic("Could not register gart_sysdev -- " \ + "would corrupt data on next suspend"); flush_gart(); printk("PCI-DMA: aperture base @ %x size %u KB\n",aper_base, aper_size>>10); --- linux-2.6.24.orig/arch/x86/kernel/machine_kexec_64.c +++ linux-2.6.24/arch/x86/kernel/machine_kexec_64.c @@ -233,6 +233,7 @@ void arch_crash_save_vmcoreinfo(void) { + VMCOREINFO_SYMBOL(phys_base); VMCOREINFO_SYMBOL(init_level4_pgt); #ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE --- linux-2.6.24.orig/arch/x86/kernel/tsc_sync.c +++ linux-2.6.24/arch/x86/kernel/tsc_sync.c @@ -46,7 +46,7 @@ cycles_t start, now, prev, end; int i; - start = get_cycles_sync(); + start = get_cycles(); /* * The measurement runs for 20 msecs: */ @@ -61,7 +61,7 @@ */ __raw_spin_lock(&sync_lock); prev = last_tsc; - now = get_cycles_sync(); + now = get_cycles(); last_tsc = now; __raw_spin_unlock(&sync_lock); --- linux-2.6.24.orig/arch/x86/kernel/setup_64.c +++ linux-2.6.24/arch/x86/kernel/setup_64.c @@ -311,6 +311,8 @@ dmi_scan_machine(); + io_delay_init(); + #ifdef CONFIG_SMP /* setup to use the static apicid table during kernel startup */ x86_cpu_to_apicid_ptr = (void *)&x86_cpu_to_apicid_init; @@ -679,8 +681,8 @@ if (c->x86 == 0xf || c->x86 == 0x10 || c->x86 == 0x11) set_bit(X86_FEATURE_K8, &c->x86_capability); - /* RDTSC can be speculated around */ - clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); + /* MFENCE stops RDTSC speculation */ + set_bit(X86_FEATURE_MFENCE_RDTSC, &c->x86_capability); /* Family 10 doesn't support C states in MWAIT so don't use it */ if (c->x86 == 0x10 && !force_mwait) @@ -814,10 +816,7 @@ set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability); if (c->x86 == 6) set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability); - if (c->x86 == 15) - set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); - else - clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); + set_bit(X86_FEATURE_LFENCE_RDTSC, &c->x86_capability); c->x86_max_cores = intel_num_cpu_cores(c); srat_detect_node(); --- linux-2.6.24.orig/arch/x86/kernel/Makefile_32 +++ linux-2.6.24/arch/x86/kernel/Makefile_32 @@ -8,7 +8,7 @@ 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 \ pci-dma_32.o i386_ksyms_32.o i387_32.o bootflag.o e820_32.o\ - quirks.o i8237.o topology.o alternative.o i8253.o tsc_32.o + quirks.o i8237.o topology.o alternative.o i8253.o tsc_32.o io_delay.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-y += cpu/ --- linux-2.6.24.orig/arch/x86/kernel/setup_32.c +++ linux-2.6.24/arch/x86/kernel/setup_32.c @@ -648,6 +648,8 @@ dmi_scan_machine(); + io_delay_init();; + #ifdef CONFIG_X86_GENERICARCH generic_apic_probe(); #endif --- linux-2.6.24.orig/arch/x86/kernel/tsc_64.c +++ linux-2.6.24/arch/x86/kernel/tsc_64.c @@ -10,6 +10,7 @@ #include #include +#include static int notsc __initdata = 0; @@ -133,12 +134,12 @@ int i; for (i = 0; i < MAX_RETRIES; i++) { - t1 = get_cycles_sync(); + t1 = get_cycles(); if (hpet) *hpet = hpet_readl(HPET_COUNTER) & 0xFFFFFFFF; else *pm = acpi_pm_read_early(); - t2 = get_cycles_sync(); + t2 = get_cycles(); if ((t2 - t1) < SMI_TRESHOLD) return t2; } @@ -162,9 +163,9 @@ outb(0xb0, 0x43); outb((CLOCK_TICK_RATE / (1000 / 50)) & 0xff, 0x42); outb((CLOCK_TICK_RATE / (1000 / 50)) >> 8, 0x42); - tr1 = get_cycles_sync(); + tr1 = get_cycles(); while ((inb(0x61) & 0x20) == 0); - tr2 = get_cycles_sync(); + tr2 = get_cycles(); tsc2 = tsc_read_refs(&pm2, hpet ? &hpet2 : NULL); @@ -246,18 +247,34 @@ __setup("notsc", notsc_setup); +static struct clocksource clocksource_tsc; -/* clock source code: */ +/* + * We compare the TSC to the cycle_last value in the clocksource + * structure to avoid a nasty time-warp. This can be observed in a + * very small window right after one CPU updated cycle_last under + * xtime/vsyscall_gtod lock and the other CPU reads a TSC value which + * is smaller than the cycle_last reference value due to a TSC which + * is slighty behind. This delta is nowhere else observable, but in + * that case it results in a forward time jump in the range of hours + * due to the unsigned delta calculation of the time keeping core + * code, which is necessary to support wrapping clocksources like pm + * timer. + */ static cycle_t read_tsc(void) { - cycle_t ret = (cycle_t)get_cycles_sync(); - return ret; + cycle_t ret = (cycle_t)get_cycles(); + + return ret >= clocksource_tsc.cycle_last ? + ret : clocksource_tsc.cycle_last; } static cycle_t __vsyscall_fn vread_tsc(void) { - cycle_t ret = (cycle_t)get_cycles_sync(); - return ret; + cycle_t ret = (cycle_t)vget_cycles(); + + return ret >= __vsyscall_gtod_data.clock.cycle_last ? + ret : __vsyscall_gtod_data.clock.cycle_last; } static struct clocksource clocksource_tsc = { --- linux-2.6.24.orig/arch/x86/kernel/aperture_64.c +++ linux-2.6.24/arch/x86/kernel/aperture_64.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -75,6 +76,8 @@ printk("Mapping aperture over %d KB of RAM @ %lx\n", aper_size >> 10, __pa(p)); insert_aperture_resource((u32)__pa(p), aper_size); + register_nosave_region((u32)__pa(p) >> PAGE_SHIFT, + (u32)__pa(p+aper_size) >> PAGE_SHIFT); return (u32)__pa(p); } @@ -296,4 +299,6 @@ write_pci_config(0, num, 3, 0x90, aper_order<<1); write_pci_config(0, num, 3, 0x94, aper_alloc>>25); } + + set_up_gart_resume(aper_order, aper_alloc); } --- linux-2.6.24.orig/arch/x86/kernel/stacktrace.c +++ linux-2.6.24/arch/x86/kernel/stacktrace.c @@ -33,6 +33,19 @@ trace->entries[trace->nr_entries++] = addr; } +static void save_stack_address_nosched(void *data, unsigned long addr) +{ + struct stack_trace *trace = (struct stack_trace *)data; + if (in_sched_functions(addr)) + return; + if (trace->skip > 0) { + trace->skip--; + return; + } + if (trace->nr_entries < trace->max_entries) + trace->entries[trace->nr_entries++] = addr; +} + static const struct stacktrace_ops save_stack_ops = { .warning = save_stack_warning, .warning_symbol = save_stack_warning_symbol, @@ -40,6 +53,13 @@ .address = save_stack_address, }; +static const struct stacktrace_ops save_stack_ops_nosched = { + .warning = save_stack_warning, + .warning_symbol = save_stack_warning_symbol, + .stack = save_stack_stack, + .address = save_stack_address_nosched, +}; + /* * Save stack-backtrace addresses into a stack_trace buffer. */ @@ -50,3 +70,10 @@ trace->entries[trace->nr_entries++] = ULONG_MAX; } EXPORT_SYMBOL(save_stack_trace); + +void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) +{ + dump_trace(tsk, NULL, NULL, &save_stack_ops_nosched, trace); + if (trace->nr_entries < trace->max_entries) + trace->entries[trace->nr_entries++] = ULONG_MAX; +} --- linux-2.6.24.orig/arch/x86/kernel/process_64.c +++ linux-2.6.24/arch/x86/kernel/process_64.c @@ -212,14 +212,13 @@ current_thread_info()->status |= TS_POLLING; /* endless idle loop with no priority at all */ while (1) { + tick_nohz_stop_sched_tick(); while (!need_resched()) { void (*idle)(void); if (__get_cpu_var(cpu_idle_state)) __get_cpu_var(cpu_idle_state) = 0; - tick_nohz_stop_sched_tick(); - rmb(); idle = pm_idle; if (!idle) --- linux-2.6.24.orig/arch/x86/kernel/time_64.c +++ linux-2.6.24/arch/x86/kernel/time_64.c @@ -241,7 +241,7 @@ rdtscl(tsc_start); do { rdmsrl(MSR_K7_PERFCTR0 + i, pmc_now); - tsc_now = get_cycles_sync(); + tsc_now = get_cycles(); } while ((tsc_now - tsc_start) < TICK_COUNT); local_irq_restore(flags); --- linux-2.6.24.orig/arch/x86/kernel/io_apic_64.c +++ linux-2.6.24/arch/x86/kernel/io_apic_64.c @@ -1565,7 +1565,7 @@ .end = end_lapic_irq, }; -static void setup_nmi (void) +static void __init setup_nmi(void) { /* * Dirty trick to enable the NMI watchdog ... @@ -1578,7 +1578,7 @@ */ printk(KERN_INFO "activating NMI Watchdog ..."); - enable_NMI_through_LVT0(NULL); + enable_NMI_through_LVT0(); printk(" done.\n"); } @@ -1654,7 +1654,7 @@ * * FIXME: really need to revamp this for modern platforms only. */ -static inline void check_timer(void) +static inline void __init check_timer(void) { struct irq_cfg *cfg = irq_cfg + 0; int apic1, pin1, apic2, pin2; --- linux-2.6.24.orig/arch/x86/kernel/apic_32.c +++ linux-2.6.24/arch/x86/kernel/apic_32.c @@ -154,7 +154,7 @@ /** * enable_NMI_through_LVT0 - enable NMI through local vector table 0 */ -void enable_NMI_through_LVT0 (void * dummy) +void __cpuinit enable_NMI_through_LVT0(void) { unsigned int v = APIC_DM_NMI; --- linux-2.6.24.orig/arch/x86/kernel/cpu/amd.c +++ linux-2.6.24/arch/x86/kernel/cpu/amd.c @@ -301,6 +301,9 @@ /* K6s reports MCEs but don't actually have all the MSRs */ if (c->x86 < 6) clear_bit(X86_FEATURE_MCE, c->x86_capability); + + if (cpu_has_xmm2) + set_bit(X86_FEATURE_MFENCE_RDTSC, c->x86_capability); } static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 * c, unsigned int size) --- linux-2.6.24.orig/arch/x86/kernel/cpu/intel.c +++ linux-2.6.24/arch/x86/kernel/cpu/intel.c @@ -201,9 +201,10 @@ } #endif + if (cpu_has_xmm2) + set_bit(X86_FEATURE_LFENCE_RDTSC, c->x86_capability); if (c->x86 == 15) { set_bit(X86_FEATURE_P4, c->x86_capability); - set_bit(X86_FEATURE_SYNC_RDTSC, c->x86_capability); } if (c->x86 == 6) set_bit(X86_FEATURE_P3, c->x86_capability); --- linux-2.6.24.orig/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c +++ linux-2.6.24/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c @@ -44,6 +44,7 @@ CPU_DOTHAN_A1, CPU_DOTHAN_A2, CPU_DOTHAN_B0, + CPU_DOTHAN_C0, CPU_MP4HT_D0, CPU_MP4HT_E0, }; @@ -53,6 +54,7 @@ [CPU_DOTHAN_A1] = { 6, 13, 1 }, [CPU_DOTHAN_A2] = { 6, 13, 2 }, [CPU_DOTHAN_B0] = { 6, 13, 6 }, + [CPU_DOTHAN_C0] = { 6, 13, 8 }, [CPU_MP4HT_D0] = {15, 3, 4 }, [CPU_MP4HT_E0] = {15, 4, 1 }, }; @@ -194,6 +196,88 @@ }; #undef OP + +#define OPEX(mhz, base, mva, mvb, mvc, mvd) \ +{ \ + .frequency = (mhz) * 1000, \ + .index = (((mhz)/(base)) << 8) | ((mva - 700) / 16) \ +} + +/* Intel Pentium M processor 730 / 1.60 GHz (Sonoma) */ +static struct cpufreq_frequency_table sonoma_1596[] = +{ + OPEX( 798, 133, 988, 988, 988, 988), + OPEX(1064, 133, 1116, 1111, 1084, 1079), + OPEX(1330, 133, 1244, 1233, 1180, 1169), + OPEX(1596, 133, 1356, 1356, 1260, 1260), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 740 / 1.73 GHz (Sonoma) */ +static struct cpufreq_frequency_table sonoma_1729[] = +{ + OPEX( 798, 133, 988, 988, 988, 988), + OPEX(1064, 133, 1100, 1093, 1068, 1066), + OPEX(1330, 133, 1212, 1198, 1148, 1143), + OPEX(1729, 133, 1356, 1356, 1260, 1260), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 750 / 1.86 GHz (Sonoma) */ +static struct cpufreq_frequency_table sonoma_1862[] = +{ + OPEX( 798, 133, 988, 988, 988, 988), + OPEX(1064, 133, 1084, 1080, 1068, 1056), + OPEX(1330, 133, 1180, 1172, 1132, 1124), + OPEX(1596, 133, 1276, 1264, 1196, 1192), + OPEX(1862, 133, 1356, 1356, 1260, 1260), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 760 / 2.00 GHz (Sonoma) */ +static struct cpufreq_frequency_table sonoma_1995[] = +{ + OPEX( 798, 133, 988, 988, 988, 988), + OPEX(1064, 133, 1084, 1070, 1052, 1048), + OPEX(1330, 133, 1164, 1152, 1116, 1109), + OPEX(1596, 133, 1244, 1233, 1180, 1169), + OPEX(1995, 133, 1356, 1356, 1260, 1260), + { .frequency = CPUFREQ_TABLE_END } +}; +/* Intel Pentium M processor 770 / 2.13 GHz (Sonoma) */ +static struct cpufreq_frequency_table sonoma_2128[] = +{ + OPEX( 798, 133, 988, 988, 988, 988), + OPEX(1064, 133, 1068, 1065, 1052, 1042), + OPEX(1330, 133, 1148, 1142, 1100, 1097), + OPEX(1596, 133, 1228, 1218, 1164, 1151), + OPEX(1862, 133, 1308, 1295, 1212, 1206), + OPEX(2128, 133, 1372, 1372, 1260, 1260), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 780 / 2.26 GHz (Sonoma) */ +static struct cpufreq_frequency_table sonoma_2261[] = +{ + OPEX( 798, 133, 988, 988, 988, 988), + OPEX(1064, 133, 1068, 1064, 1052, 1037), + OPEX(1330, 133, 1148, 1139, 1100, 1087), + OPEX(1596, 133, 1228, 1215, 1148, 1136), + OPEX(1862, 133, 1292, 1291, 1196, 1186), + OPEX(2261, 133, 1404, 1404, 1260, 1260), + { .frequency = CPUFREQ_TABLE_END } +}; + +#undef OPEX + +#define SONOMA(cpuid, max, base, name) \ +{ .cpu_id = cpuid, \ + .model_name = "Intel(R) Pentium(R) M processor " name "GHz", \ + .max_freq = (max)*1000, \ + .op_points = sonoma_##max, \ +} + + #define _BANIAS(cpuid, max, name) \ { .cpu_id = cpuid, \ .model_name = "Intel(R) Pentium(R) M processor " name "MHz", \ @@ -216,6 +300,15 @@ BANIAS(1600), BANIAS(1700), + /* Builtin tables for Dothan C0 CPUs, a.k.a Sonoma */ + SONOMA(&cpu_ids[CPU_DOTHAN_C0], 1596, 133, "1.60"), + SONOMA(&cpu_ids[CPU_DOTHAN_C0], 1729, 133, "1.73"), + SONOMA(&cpu_ids[CPU_DOTHAN_C0], 1862, 133, "1.86"), + SONOMA(&cpu_ids[CPU_DOTHAN_C0], 1995, 133, "2.00"), + SONOMA(&cpu_ids[CPU_DOTHAN_C0], 2128, 133, "2.13"), + SONOMA(&cpu_ids[CPU_DOTHAN_C0], 2261, 133, "2.26"), + + /* NULL model_name is a wildcard */ { &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL }, { &cpu_ids[CPU_DOTHAN_A2], NULL, 0, NULL }, --- linux-2.6.24.orig/arch/x86/kernel/cpu/mcheck/mce_64.c +++ linux-2.6.24/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -31,7 +31,7 @@ #include #define MISC_MCELOG_MINOR 227 -#define NR_BANKS 6 +#define NR_SYSFS_BANKS 6 atomic_t mce_entry; @@ -46,7 +46,7 @@ */ static int tolerant = 1; static int banks; -static unsigned long bank[NR_BANKS] = { [0 ... NR_BANKS-1] = ~0UL }; +static unsigned long bank[NR_SYSFS_BANKS] = { [0 ... NR_SYSFS_BANKS-1] = ~0UL }; static unsigned long notify_user; static int rip_msr; static int mce_bootlog = 1; @@ -209,7 +209,7 @@ barrier(); for (i = 0; i < banks; i++) { - if (!bank[i]) + if (i < NR_SYSFS_BANKS && !bank[i]) continue; m.misc = 0; @@ -444,9 +444,10 @@ rdmsrl(MSR_IA32_MCG_CAP, cap); banks = cap & 0xff; - if (banks > NR_BANKS) { - printk(KERN_INFO "MCE: warning: using only %d banks\n", banks); - banks = NR_BANKS; + if (banks > MCE_EXTENDED_BANK) { + printk(KERN_INFO "MCE: warning: using only %d banks\n", + MCE_EXTENDED_BANK); + banks = MCE_EXTENDED_BANK; } /* Use accurate RIP reporting if available. */ if ((cap & (1<<9)) && ((cap >> 16) & 0xff) >= 9) @@ -462,7 +463,7 @@ wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff); for (i = 0; i < banks; i++) { - wrmsrl(MSR_IA32_MC0_CTL+4*i, bank[i]); + wrmsrl(MSR_IA32_MC0_CTL+4*i, ~0UL); wrmsrl(MSR_IA32_MC0_STATUS+4*i, 0); } } @@ -765,7 +766,10 @@ } \ static SYSDEV_ATTR(name, 0644, show_ ## name, set_ ## name); -/* TBD should generate these dynamically based on number of available banks */ +/* + * TBD should generate these dynamically based on number of available banks. + * Have only 6 contol banks in /sysfs until then. + */ ACCESSOR(bank0ctl,bank[0],mce_restart()) ACCESSOR(bank1ctl,bank[1],mce_restart()) ACCESSOR(bank2ctl,bank[2],mce_restart()) --- linux-2.6.24.orig/arch/x86/kernel/acpi/boot.c +++ linux-2.6.24/arch/x86/kernel/acpi/boot.c @@ -592,9 +592,25 @@ * RSDP signature. */ for (offset = 0; offset < length; offset += 16) { - if (strncmp((char *)(phys_to_virt(start) + offset), "RSD PTR ", sig_len)) - continue; - return (start + offset); + if (strncmp((char *)(phys_to_virt(start) + offset), "RSD PTR ", sig_len) == 0) { + /* 2007-09-24 TJ + * The ACPI specification states the first 20 bytes of the RSDP table + * must have a checksum of 0 (ACPI 1.0b RSDP table is 20 bytes long). + * The signature can appear in multiple memory locations so don't rely + * on it as the sole proof of a valid table. + * This fixes broken/disabled ACPI problems with Acer Travelmate C100 + * (and others) where the first signature match is accepted without + * confirming the checksum. + */ + unsigned int i; + unsigned char checksum; + unsigned char *table = (unsigned char *)(phys_to_virt(start) + offset); + for (checksum = 0, i = 0; i < 20; i++) + checksum += table[i]; + + printk(KERN_WARNING PREFIX "RSDP signature @ 0x%0.8lX checksum %d\n", table, checksum); + if (checksum == 0) return (start + offset); + } } return 0; --- linux-2.6.24.orig/arch/x86/lib/copy_user_nocache_64.S +++ linux-2.6.24/arch/x86/lib/copy_user_nocache_64.S @@ -145,19 +145,19 @@ /* table sorted by exception address */ .section __ex_table,"a" .align 8 - .quad .Ls1,.Ls1e - .quad .Ls2,.Ls2e - .quad .Ls3,.Ls3e - .quad .Ls4,.Ls4e - .quad .Ld1,.Ls1e + .quad .Ls1,.Ls1e /* .Ls[1-4] - 0 bytes copied */ + .quad .Ls2,.Ls1e + .quad .Ls3,.Ls1e + .quad .Ls4,.Ls1e + .quad .Ld1,.Ls1e /* .Ld[1-4] - 0..24 bytes coped */ .quad .Ld2,.Ls2e .quad .Ld3,.Ls3e .quad .Ld4,.Ls4e - .quad .Ls5,.Ls5e - .quad .Ls6,.Ls6e - .quad .Ls7,.Ls7e - .quad .Ls8,.Ls8e - .quad .Ld5,.Ls5e + .quad .Ls5,.Ls5e /* .Ls[5-8] - 32 bytes copied */ + .quad .Ls6,.Ls5e + .quad .Ls7,.Ls5e + .quad .Ls8,.Ls5e + .quad .Ld5,.Ls5e /* .Ld[5-8] - 32..56 bytes copied */ .quad .Ld6,.Ls6e .quad .Ld7,.Ls7e .quad .Ld8,.Ls8e @@ -172,11 +172,8 @@ .quad .Le5,.Le_zero .previous - /* compute 64-offset for main loop. 8 bytes accuracy with error on the - pessimistic side. this is gross. it would be better to fix the - interface. */ /* eax: zero, ebx: 64 */ -.Ls1e: addl $8,%eax +.Ls1e: addl $8,%eax /* eax: bytes left uncopied: Ls1e: 64 .. Ls8e: 8 */ .Ls2e: addl $8,%eax .Ls3e: addl $8,%eax .Ls4e: addl $8,%eax --- linux-2.6.24.orig/arch/x86/lib/copy_user_64.S +++ linux-2.6.24/arch/x86/lib/copy_user_64.S @@ -217,19 +217,19 @@ /* table sorted by exception address */ .section __ex_table,"a" .align 8 - .quad .Ls1,.Ls1e - .quad .Ls2,.Ls2e - .quad .Ls3,.Ls3e - .quad .Ls4,.Ls4e - .quad .Ld1,.Ls1e + .quad .Ls1,.Ls1e /* Ls1-Ls4 have copied zero bytes */ + .quad .Ls2,.Ls1e + .quad .Ls3,.Ls1e + .quad .Ls4,.Ls1e + .quad .Ld1,.Ls1e /* Ld1-Ld4 have copied 0-24 bytes */ .quad .Ld2,.Ls2e .quad .Ld3,.Ls3e .quad .Ld4,.Ls4e - .quad .Ls5,.Ls5e - .quad .Ls6,.Ls6e - .quad .Ls7,.Ls7e - .quad .Ls8,.Ls8e - .quad .Ld5,.Ls5e + .quad .Ls5,.Ls5e /* Ls5-Ls8 have copied 32 bytes */ + .quad .Ls6,.Ls5e + .quad .Ls7,.Ls5e + .quad .Ls8,.Ls5e + .quad .Ld5,.Ls5e /* Ld5-Ld8 have copied 32-56 bytes */ .quad .Ld6,.Ls6e .quad .Ld7,.Ls7e .quad .Ld8,.Ls8e @@ -244,11 +244,8 @@ .quad .Le5,.Le_zero .previous - /* compute 64-offset for main loop. 8 bytes accuracy with error on the - pessimistic side. this is gross. it would be better to fix the - interface. */ /* eax: zero, ebx: 64 */ -.Ls1e: addl $8,%eax +.Ls1e: addl $8,%eax /* eax is bytes left uncopied within the loop (Ls1e: 64 .. Ls8e: 8) */ .Ls2e: addl $8,%eax .Ls3e: addl $8,%eax .Ls4e: addl $8,%eax --- linux-2.6.24.orig/arch/x86/xen/enlighten.c +++ linux-2.6.24/arch/x86/xen/enlighten.c @@ -95,7 +95,7 @@ * * 0: not available, 1: available */ -static int have_vcpu_info_placement = 0; +static int have_vcpu_info_placement = 1; static void __init xen_vcpu_setup(int cpu) { @@ -103,6 +103,7 @@ int err; struct vcpu_info *vcpup; + BUG_ON(HYPERVISOR_shared_info == &dummy_shared_info); per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; if (!have_vcpu_info_placement) @@ -153,6 +154,7 @@ if (*eax == 1) maskedx = ~((1 << X86_FEATURE_APIC) | /* disable APIC */ (1 << X86_FEATURE_ACPI) | /* disable ACPI */ + (1 << X86_FEATURE_SEP) | /* disable SEP */ (1 << X86_FEATURE_ACC)); /* thermal monitoring */ asm(XEN_EMULATE_PREFIX "cpuid" @@ -791,30 +793,40 @@ xen_write_cr3(__pa(base)); } -static __init void xen_pagetable_setup_done(pgd_t *base) +static __init void setup_shared_info(void) { - /* This will work as long as patching hasn't happened yet - (which it hasn't) */ - pv_mmu_ops.alloc_pt = xen_alloc_pt; - pv_mmu_ops.set_pte = xen_set_pte; - if (!xen_feature(XENFEAT_auto_translated_physmap)) { + unsigned long addr = fix_to_virt(FIX_PARAVIRT_BOOTMAP); + /* * Create a mapping for the shared info page. * Should be set_fixmap(), but shared_info is a machine * address with no corresponding pseudo-phys address. */ - set_pte_mfn(fix_to_virt(FIX_PARAVIRT_BOOTMAP), + set_pte_mfn(addr, PFN_DOWN(xen_start_info->shared_info), PAGE_KERNEL); - HYPERVISOR_shared_info = - (struct shared_info *)fix_to_virt(FIX_PARAVIRT_BOOTMAP); - + HYPERVISOR_shared_info = (struct shared_info *)addr; } else HYPERVISOR_shared_info = (struct shared_info *)__va(xen_start_info->shared_info); +#ifndef CONFIG_SMP + /* In UP this is as good a place as any to set up shared info */ + xen_setup_vcpu_info_placement(); +#endif +} + +static __init void xen_pagetable_setup_done(pgd_t *base) +{ + /* This will work as long as patching hasn't happened yet + (which it hasn't) */ + pv_mmu_ops.alloc_pt = xen_alloc_pt; + pv_mmu_ops.set_pte = xen_set_pte; + + setup_shared_info(); + /* Actually pin the pagetable down, but we can't set PG_pinned yet because the page structures don't exist yet. */ { @@ -1165,15 +1177,9 @@ x86_write_percpu(xen_cr3, __pa(pgd)); x86_write_percpu(xen_current_cr3, __pa(pgd)); -#ifdef CONFIG_SMP /* Don't do the full vcpu_info placement stuff until we have a - possible map. */ + possible map and a non-dummy shared_info. */ per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; -#else - /* May as well do it now, since there's no good time to call - it later on UP. */ - xen_setup_vcpu_info_placement(); -#endif pv_info.kernel_rpl = 1; if (xen_feature(XENFEAT_supervisor_mode_kernel)) --- linux-2.6.24.orig/arch/x86/xen/xen-asm.S +++ linux-2.6.24/arch/x86/xen/xen-asm.S @@ -33,12 +33,17 @@ events, then enter the hypervisor to get them handled. */ ENTRY(xen_irq_enable_direct) - /* Clear mask and test pending */ - andw $0x00ff, PER_CPU_VAR(xen_vcpu_info)+XEN_vcpu_info_pending + /* Unmask events */ + movb $0, PER_CPU_VAR(xen_vcpu_info)+XEN_vcpu_info_mask + /* Preempt here doesn't matter because that will deal with any pending interrupts. The pending check may end up being run on the wrong CPU, but that doesn't hurt. */ + + /* Test for pending */ + testb $0xff, PER_CPU_VAR(xen_vcpu_info)+XEN_vcpu_info_pending jz 1f + 2: call check_events 1: ENDPATCH(xen_irq_enable_direct) --- linux-2.6.24.orig/arch/parisc/kernel/pdc_cons.c +++ linux-2.6.24/arch/parisc/kernel/pdc_cons.c @@ -52,10 +52,18 @@ #include #include /* for iodc_call() proto and friends */ +static spinlock_t pdc_console_lock = SPIN_LOCK_UNLOCKED; static void pdc_console_write(struct console *co, const char *s, unsigned count) { - pdc_iodc_print(s, count); + int i = 0; + unsigned long flags; + + spin_lock_irqsave(&pdc_console_lock, flags); + do { + i += pdc_iodc_print(s + i, count - i); + } while (i < count); + spin_unlock_irqrestore(&pdc_console_lock, flags); } void pdc_printf(const char *fmt, ...) @@ -73,7 +81,14 @@ int pdc_console_poll_key(struct console *co) { - return pdc_iodc_getc(); + int c; + unsigned long flags; + + spin_lock_irqsave(&pdc_console_lock, flags); + c = pdc_iodc_getc(); + spin_unlock_irqrestore(&pdc_console_lock, flags); + + return c; } static int pdc_console_setup(struct console *co, char *options) --- linux-2.6.24.orig/arch/parisc/kernel/signal.c +++ linux-2.6.24/arch/parisc/kernel/signal.c @@ -534,7 +534,8 @@ * Flushing one cacheline is cheap. * "sync" on bigger (> 4 way) boxes is not. */ - flush_icache_range(regs->gr[30], regs->gr[30] + 4); + flush_user_dcache_range(regs->gr[30], regs->gr[30] + 4); + flush_user_icache_range(regs->gr[30], regs->gr[30] + 4); regs->gr[31] = regs->gr[30] + 8; /* Preserve original r28. */ --- linux-2.6.24.orig/arch/parisc/kernel/firmware.c +++ linux-2.6.24/arch/parisc/kernel/firmware.c @@ -1080,6 +1080,9 @@ spin_unlock_irqrestore(&pdc_lock, flags); } +/* locked by pdc_console_lock */ +static int __attribute__((aligned(8))) iodc_retbuf[32]; +static char __attribute__((aligned(64))) iodc_dbuf[4096]; /** * pdc_iodc_print - Console print using IODC. @@ -1091,24 +1094,20 @@ * Since the HP console requires CR+LF to perform a 'newline', we translate * "\n" to "\r\n". */ -int pdc_iodc_print(unsigned char *str, unsigned count) +int pdc_iodc_print(const unsigned char *str, unsigned count) { - /* XXX Should we spinlock posx usage */ static int posx; /* for simple TAB-Simulation... */ - int __attribute__((aligned(8))) iodc_retbuf[32]; - char __attribute__((aligned(64))) iodc_dbuf[4096]; unsigned int i; unsigned long flags; - memset(iodc_dbuf, 0, 4096); - for (i = 0; i < count && i < 2048;) { + for (i = 0; i < count && i < 79;) { switch(str[i]) { case '\n': iodc_dbuf[i+0] = '\r'; iodc_dbuf[i+1] = '\n'; i += 2; posx = 0; - break; + goto print; case '\t': while (posx & 7) { iodc_dbuf[i] = ' '; @@ -1124,6 +1123,16 @@ } } + /* if we're at the end of line, and not already inserting a newline, + * insert one anyway. iodc console doesn't claim to support >79 char + * lines. don't account for this in the return value. + */ + if (i == 79 && iodc_dbuf[i-1] != '\n') { + iodc_dbuf[i+0] = '\r'; + iodc_dbuf[i+1] = '\n'; + } + +print: spin_lock_irqsave(&pdc_lock, flags); real32_call(PAGE0->mem_cons.iodc_io, (unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT, @@ -1142,11 +1151,9 @@ */ int pdc_iodc_getc(void) { - unsigned long flags; - static int __attribute__((aligned(8))) iodc_retbuf[32]; - static char __attribute__((aligned(64))) iodc_dbuf[4096]; int ch; int status; + unsigned long flags; /* Bail if no console input device. */ if (!PAGE0->mem_kbd.iodc_io) --- linux-2.6.24.orig/arch/sparc64/mm/tlb.c +++ linux-2.6.24/arch/sparc64/mm/tlb.c @@ -23,10 +23,11 @@ void flush_tlb_pending(void) { - struct mmu_gather *mp = &__get_cpu_var(mmu_gathers); + struct mmu_gather *mp; preempt_disable(); + mp = &__get_cpu_var(mmu_gathers); if (mp->tlb_nr) { flush_tsb_user(mp); --- linux-2.6.24.orig/arch/sparc64/kernel/ldc.c +++ linux-2.6.24/arch/sparc64/kernel/ldc.c @@ -290,7 +290,8 @@ return p + (lp->tx_tail / LDC_PACKET_SIZE); } -static int set_tx_tail(struct ldc_channel *lp, unsigned long tail) +static int set_tx_tail(struct ldc_channel *lp, + unsigned long tail) { unsigned long orig_tail = lp->tx_tail; int limit = 1000; @@ -314,30 +315,6 @@ return -EBUSY; } -/* This just updates the head value in the hypervisor using - * a polling loop with a timeout. The caller takes care of - * upating software state representing the head change, if any. - */ -static int __set_rx_head(struct ldc_channel *lp, unsigned long head) -{ - int limit = 1000; - - while (limit-- > 0) { - unsigned long err; - - err = sun4v_ldc_rx_set_qhead(lp->id, head); - if (!err) - return 0; - - if (err != HV_EWOULDBLOCK) - return -EINVAL; - - udelay(1); - } - - return -EBUSY; -} - static int send_tx_packet(struct ldc_channel *lp, struct ldc_packet *p, unsigned long new_tail) @@ -818,7 +795,7 @@ * everything. */ if (lp->flags & LDC_FLAG_RESET) { - (void) __set_rx_head(lp, lp->rx_tail); + (void) sun4v_ldc_rx_set_qhead(lp->id, lp->rx_tail); goto out; } @@ -847,7 +824,7 @@ while (lp->rx_head != lp->rx_tail) { struct ldc_packet *p; - unsigned long new; + unsigned long new, hv_err; int err; p = lp->rx_base + (lp->rx_head / LDC_PACKET_SIZE); @@ -882,8 +859,8 @@ new = 0; lp->rx_head = new; - err = __set_rx_head(lp, new); - if (err < 0) { + hv_err = sun4v_ldc_rx_set_qhead(lp->id, new); + if (hv_err) { (void) ldc_abort(lp); break; } @@ -1452,8 +1429,8 @@ new = rx_advance(lp, lp->rx_head); lp->rx_head = new; - err = __set_rx_head(lp, new); - if (err < 0) + hv_err = sun4v_ldc_rx_set_qhead(lp->id, new); + if (hv_err) err = -ECONNRESET; else err = LDC_PACKET_SIZE; @@ -1537,6 +1514,7 @@ static int rx_bad_seq(struct ldc_channel *lp, struct ldc_packet *p, struct ldc_packet *first_frag) { + unsigned long hv_err; int err; if (first_frag) @@ -1546,8 +1524,8 @@ if (err) return err; - err = __set_rx_head(lp, lp->rx_tail); - if (err < 0) + hv_err = sun4v_ldc_rx_set_qhead(lp->id, lp->rx_tail); + if (hv_err) return ldc_abort(lp); return 0; @@ -1601,9 +1579,10 @@ static int rx_set_head(struct ldc_channel *lp, unsigned long head) { - int err = __set_rx_head(lp, head); + unsigned long hv_err; - if (err < 0) + hv_err = sun4v_ldc_rx_set_qhead(lp->id, head); + if (hv_err) return ldc_abort(lp); lp->rx_head = head; --- linux-2.6.24.orig/arch/sparc64/kernel/sys_sparc.c +++ linux-2.6.24/arch/sparc64/kernel/sys_sparc.c @@ -547,13 +547,13 @@ if (len >= STACK_TOP32) return -EINVAL; - if ((flags & MAP_FIXED) && addr > STACK_TOP32 - len) + if (addr > STACK_TOP32 - len) return -EINVAL; } else { if (len >= VA_EXCLUDE_START) return -EINVAL; - if ((flags & MAP_FIXED) && invalid_64bit_range(addr, len)) + if (invalid_64bit_range(addr, len)) return -EINVAL; } --- linux-2.6.24.orig/arch/sparc64/kernel/ptrace.c +++ linux-2.6.24/arch/sparc64/kernel/ptrace.c @@ -127,6 +127,8 @@ if (tlb_type == hypervisor) return; + preempt_disable(); + #ifdef DCACHE_ALIASING_POSSIBLE /* If bit 13 of the kernel address we used to access the * user page is the same as the virtual address that page @@ -165,6 +167,8 @@ for (; start < end; start += icache_line_size) flushi(start); } + + preempt_enable(); } asmlinkage void do_ptrace(struct pt_regs *regs) --- linux-2.6.24.orig/arch/sparc64/kernel/signal.c +++ linux-2.6.24/arch/sparc64/kernel/signal.c @@ -354,7 +354,7 @@ static inline int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) { - unsigned long *fpregs = (unsigned long *)(regs+1); + unsigned long *fpregs = current_thread_info()->fpregs; unsigned long fprs; int err = 0; --- linux-2.6.24.orig/arch/sparc64/lib/rwsem.S +++ linux-2.6.24/arch/sparc64/lib/rwsem.S @@ -6,7 +6,7 @@ #include - .section .sched.text + .section .sched.text, "ax" .globl __down_read __down_read: --- linux-2.6.24.orig/arch/arm/mach-pxa/clock.c +++ linux-2.6.24/arch/arm/mach-pxa/clock.c @@ -23,18 +23,27 @@ static DEFINE_MUTEX(clocks_mutex); static DEFINE_SPINLOCK(clocks_lock); +static struct clk *clk_lookup(struct device *dev, const char *id) +{ + struct clk *p; + + list_for_each_entry(p, &clocks, node) + if (strcmp(id, p->name) == 0 && p->dev == dev) + return p; + + return NULL; +} + struct clk *clk_get(struct device *dev, const char *id) { struct clk *p, *clk = ERR_PTR(-ENOENT); mutex_lock(&clocks_mutex); - list_for_each_entry(p, &clocks, node) { - if (strcmp(id, p->name) == 0 && - (p->dev == NULL || p->dev == dev)) { - clk = p; - break; - } - } + p = clk_lookup(dev, id); + if (!p) + p = clk_lookup(NULL, id); + if (p) + clk = p; mutex_unlock(&clocks_mutex); return clk; --- linux-2.6.24.orig/arch/s390/lib/uaccess_std.c +++ linux-2.6.24/arch/s390/lib/uaccess_std.c @@ -293,10 +293,10 @@ asm volatile( " sacf 256\n" - " cs %1,%4,0(%5)\n" - "0: lr %0,%1\n" - "1: sacf 0\n" - EX_TABLE(0b,1b) + "0: cs %1,%4,0(%5)\n" + "1: lr %0,%1\n" + "2: sacf 0\n" + EX_TABLE(0b,2b) EX_TABLE(1b,2b) : "=d" (ret), "+d" (oldval), "=m" (*uaddr) : "0" (-EFAULT), "d" (newval), "a" (uaddr), "m" (*uaddr) : "cc", "memory" ); --- linux-2.6.24.orig/arch/s390/lib/uaccess_pt.c +++ linux-2.6.24/arch/s390/lib/uaccess_pt.c @@ -406,6 +406,8 @@ { int ret; + if (!current->mm) + return -EFAULT; spin_lock(¤t->mm->page_table_lock); uaddr = (int __user *) __dat_user_addr((unsigned long) uaddr); if (!uaddr) { --- linux-2.6.24.orig/sound/core/seq/oss/seq_oss_synth.c +++ linux-2.6.24/sound/core/seq/oss/seq_oss_synth.c @@ -599,6 +599,9 @@ { struct seq_oss_synth *rec; + if (dev < 0 || dev >= dp->max_synthdev) + return -ENXIO; + if (dp->synths[dev].is_midi) { struct midi_info minf; snd_seq_oss_midi_make_info(dp, dp->synths[dev].midi_mapped, &minf); --- linux-2.6.24.orig/sound/pci/hda/patch_sigmatel.c +++ linux-2.6.24/sound/pci/hda/patch_sigmatel.c @@ -76,6 +76,7 @@ STAC_INTEL_MAC_V1, STAC_INTEL_MAC_V2, STAC_INTEL_MAC_V3, + STAC_INTEL_MAC_V3_S, STAC_INTEL_MAC_V4, STAC_INTEL_MAC_V5, /* for backward compatibility */ @@ -858,6 +859,12 @@ 0x400000fc, 0x400000fb, }; +static unsigned int intel_mac_v3_s_pin_configs[10] = { + 0x012b4050, 0x90a00110, 0x90100140, 0x400000f0, + 0x400000f0, 0x010b3020, 0x014be060, 0x01cbe030, + 0x400000f0, 0x400000f0, +}; + static unsigned int intel_mac_v4_pin_configs[10] = { 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f, 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240, @@ -878,6 +885,7 @@ [STAC_INTEL_MAC_V1] = intel_mac_v1_pin_configs, [STAC_INTEL_MAC_V2] = intel_mac_v2_pin_configs, [STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs, + [STAC_INTEL_MAC_V3_S] = intel_mac_v3_s_pin_configs, [STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs, [STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs, /* for backward compatibility */ @@ -2587,7 +2595,10 @@ case 0x106b1700: case 0x106b0200: case 0x106b1e00: - spec->board_config = STAC_INTEL_MAC_V3; + if (codec->revision_id == 0x103401)/*LP: #87253*/ + spec->board_config = STAC_INTEL_MAC_V3_S; + else + spec->board_config = STAC_INTEL_MAC_V3; break; case 0x106b1a00: case 0x00000100: --- linux-2.6.24.orig/sound/pci/hda/hda_intel.c +++ linux-2.6.24/sound/pci/hda/hda_intel.c @@ -555,7 +555,8 @@ } if (!chip->rirb.cmds) return chip->rirb.res; /* the last value */ - schedule_timeout_uninterruptible(1); + udelay(10); + cond_resched(); } while (time_after_eq(timeout, jiffies)); if (chip->msi) { --- linux-2.6.24.orig/virt/kvm/iodev.h +++ linux-2.6.24/virt/kvm/iodev.h @@ -0,0 +1,63 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __KVM_IODEV_H__ +#define __KVM_IODEV_H__ + +#include + +struct kvm_io_device { + void (*read)(struct kvm_io_device *this, + gpa_t addr, + int len, + void *val); + void (*write)(struct kvm_io_device *this, + gpa_t addr, + int len, + const void *val); + int (*in_range)(struct kvm_io_device *this, gpa_t addr); + void (*destructor)(struct kvm_io_device *this); + + void *private; +}; + +static inline void kvm_iodevice_read(struct kvm_io_device *dev, + gpa_t addr, + int len, + void *val) +{ + dev->read(dev, addr, len, val); +} + +static inline void kvm_iodevice_write(struct kvm_io_device *dev, + gpa_t addr, + int len, + const void *val) +{ + dev->write(dev, addr, len, val); +} + +static inline int kvm_iodevice_inrange(struct kvm_io_device *dev, gpa_t addr) +{ + return dev->in_range(dev, addr); +} + +static inline void kvm_iodevice_destructor(struct kvm_io_device *dev) +{ + if (dev->destructor) + dev->destructor(dev); +} + +#endif /* __KVM_IODEV_H__ */ --- linux-2.6.24.orig/virt/kvm/ioapic.h +++ linux-2.6.24/virt/kvm/ioapic.h @@ -0,0 +1,95 @@ +#ifndef __KVM_IO_APIC_H +#define __KVM_IO_APIC_H + +#include + +#include "iodev.h" + +struct kvm; +struct kvm_vcpu; + +#define IOAPIC_NUM_PINS KVM_IOAPIC_NUM_PINS +#define IOAPIC_VERSION_ID 0x11 /* IOAPIC version */ +#define IOAPIC_EDGE_TRIG 0 +#define IOAPIC_LEVEL_TRIG 1 + +#define IOAPIC_DEFAULT_BASE_ADDRESS 0xfec00000 +#define IOAPIC_MEM_LENGTH 0x100 + +/* Direct registers. */ +#define IOAPIC_REG_SELECT 0x00 +#define IOAPIC_REG_WINDOW 0x10 +#define IOAPIC_REG_EOI 0x40 /* IA64 IOSAPIC only */ + +/* Indirect registers. */ +#define IOAPIC_REG_APIC_ID 0x00 /* x86 IOAPIC only */ +#define IOAPIC_REG_VERSION 0x01 +#define IOAPIC_REG_ARB_ID 0x02 /* x86 IOAPIC only */ + +/*ioapic delivery mode*/ +#define IOAPIC_FIXED 0x0 +#define IOAPIC_LOWEST_PRIORITY 0x1 +#define IOAPIC_PMI 0x2 +#define IOAPIC_NMI 0x4 +#define IOAPIC_INIT 0x5 +#define IOAPIC_EXTINT 0x7 + +struct kvm_ioapic { + u64 base_address; + u32 ioregsel; + u32 id; + u32 irr; + u32 pad; + union ioapic_redir_entry { + u64 bits; + struct { + u8 vector; + u8 delivery_mode:3; + u8 dest_mode:1; + u8 delivery_status:1; + u8 polarity:1; + u8 remote_irr:1; + u8 trig_mode:1; + u8 mask:1; + u8 reserve:7; + u8 reserved[4]; + u8 dest_id; + } fields; + } redirtbl[IOAPIC_NUM_PINS]; + struct kvm_io_device dev; + struct kvm *kvm; +}; + +#ifdef DEBUG +#define ASSERT(x) \ +do { \ + if (!(x)) { \ + printk(KERN_EMERG "assertion failed %s: %d: %s\n", \ + __FILE__, __LINE__, #x); \ + BUG(); \ + } \ +} while (0) +#else +#define ASSERT(x) do { } while (0) +#endif + +static inline struct kvm_ioapic *ioapic_irqchip(struct kvm *kvm) +{ + return kvm->arch.vioapic; +} + +#ifdef CONFIG_IA64 +static inline int irqchip_in_kernel(struct kvm *kvm) +{ + return 1; +} +#endif + +struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector, + unsigned long bitmap); +void kvm_ioapic_update_eoi(struct kvm *kvm, int vector); +int kvm_ioapic_init(struct kvm *kvm); +void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level); +void kvm_ioapic_reset(struct kvm_ioapic *ioapic); + +#endif --- linux-2.6.24.orig/virt/kvm/ioapic.c +++ linux-2.6.24/virt/kvm/ioapic.c @@ -0,0 +1,411 @@ +/* + * Copyright (C) 2001 MandrakeSoft S.A. + * + * MandrakeSoft S.A. + * 43, rue d'Aboukir + * 75002 Paris - France + * http://www.linux-mandrake.com/ + * http://www.mandrakesoft.com/ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Yunhong Jiang + * Yaozu (Eddie) Dong + * Based on Xen 3.1 code. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ioapic.h" +#include "lapic.h" + +#if 0 +#define ioapic_debug(fmt,arg...) printk(KERN_WARNING fmt,##arg) +#else +#define ioapic_debug(fmt, arg...) +#endif +static void ioapic_deliver(struct kvm_ioapic *vioapic, int irq); + +static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic, + unsigned long addr, + unsigned long length) +{ + unsigned long result = 0; + + switch (ioapic->ioregsel) { + case IOAPIC_REG_VERSION: + result = ((((IOAPIC_NUM_PINS - 1) & 0xff) << 16) + | (IOAPIC_VERSION_ID & 0xff)); + break; + + case IOAPIC_REG_APIC_ID: + case IOAPIC_REG_ARB_ID: + result = ((ioapic->id & 0xf) << 24); + break; + + default: + { + u32 redir_index = (ioapic->ioregsel - 0x10) >> 1; + u64 redir_content; + + ASSERT(redir_index < IOAPIC_NUM_PINS); + + redir_content = ioapic->redirtbl[redir_index].bits; + result = (ioapic->ioregsel & 0x1) ? + (redir_content >> 32) & 0xffffffff : + redir_content & 0xffffffff; + break; + } + } + + return result; +} + +static void ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx) +{ + union ioapic_redir_entry *pent; + + pent = &ioapic->redirtbl[idx]; + + if (!pent->fields.mask) { + ioapic_deliver(ioapic, idx); + if (pent->fields.trig_mode == IOAPIC_LEVEL_TRIG) + pent->fields.remote_irr = 1; + } + if (!pent->fields.trig_mode) + ioapic->irr &= ~(1 << idx); +} + +static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) +{ + unsigned index; + + switch (ioapic->ioregsel) { + case IOAPIC_REG_VERSION: + /* Writes are ignored. */ + break; + + case IOAPIC_REG_APIC_ID: + ioapic->id = (val >> 24) & 0xf; + break; + + case IOAPIC_REG_ARB_ID: + break; + + default: + index = (ioapic->ioregsel - 0x10) >> 1; + + ioapic_debug("change redir index %x val %x\n", index, val); + if (index >= IOAPIC_NUM_PINS) + return; + if (ioapic->ioregsel & 1) { + ioapic->redirtbl[index].bits &= 0xffffffff; + ioapic->redirtbl[index].bits |= (u64) val << 32; + } else { + ioapic->redirtbl[index].bits &= ~0xffffffffULL; + ioapic->redirtbl[index].bits |= (u32) val; + ioapic->redirtbl[index].fields.remote_irr = 0; + } + if (ioapic->irr & (1 << index)) + ioapic_service(ioapic, index); + break; + } +} + +static void ioapic_inj_irq(struct kvm_ioapic *ioapic, + struct kvm_vcpu *vcpu, + u8 vector, u8 trig_mode, u8 delivery_mode) +{ + ioapic_debug("irq %d trig %d deliv %d\n", vector, trig_mode, + delivery_mode); + + ASSERT((delivery_mode == IOAPIC_FIXED) || + (delivery_mode == IOAPIC_LOWEST_PRIORITY)); + + kvm_apic_set_irq(vcpu, vector, trig_mode); +} + +static u32 ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest, + u8 dest_mode) +{ + u32 mask = 0; + int i; + struct kvm *kvm = ioapic->kvm; + struct kvm_vcpu *vcpu; + + ioapic_debug("dest %d dest_mode %d\n", dest, dest_mode); + + if (dest_mode == 0) { /* Physical mode. */ + if (dest == 0xFF) { /* Broadcast. */ + for (i = 0; i < KVM_MAX_VCPUS; ++i) + if (kvm->vcpus[i] && kvm->vcpus[i]->arch.apic) + mask |= 1 << i; + return mask; + } + for (i = 0; i < KVM_MAX_VCPUS; ++i) { + vcpu = kvm->vcpus[i]; + if (!vcpu) + continue; + if (kvm_apic_match_physical_addr(vcpu->arch.apic, dest)) { + if (vcpu->arch.apic) + mask = 1 << i; + break; + } + } + } else if (dest != 0) /* Logical mode, MDA non-zero. */ + for (i = 0; i < KVM_MAX_VCPUS; ++i) { + vcpu = kvm->vcpus[i]; + if (!vcpu) + continue; + if (vcpu->arch.apic && + kvm_apic_match_logical_addr(vcpu->arch.apic, dest)) + mask |= 1 << vcpu->vcpu_id; + } + ioapic_debug("mask %x\n", mask); + return mask; +} + +static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq) +{ + u8 dest = ioapic->redirtbl[irq].fields.dest_id; + u8 dest_mode = ioapic->redirtbl[irq].fields.dest_mode; + u8 delivery_mode = ioapic->redirtbl[irq].fields.delivery_mode; + u8 vector = ioapic->redirtbl[irq].fields.vector; + u8 trig_mode = ioapic->redirtbl[irq].fields.trig_mode; + u32 deliver_bitmask; + struct kvm_vcpu *vcpu; + int vcpu_id; + + ioapic_debug("dest=%x dest_mode=%x delivery_mode=%x " + "vector=%x trig_mode=%x\n", + dest, dest_mode, delivery_mode, vector, trig_mode); + + deliver_bitmask = ioapic_get_delivery_bitmask(ioapic, dest, dest_mode); + if (!deliver_bitmask) { + ioapic_debug("no target on destination\n"); + return; + } + + switch (delivery_mode) { + case IOAPIC_LOWEST_PRIORITY: + vcpu = kvm_get_lowest_prio_vcpu(ioapic->kvm, vector, + deliver_bitmask); +#ifdef CONFIG_X86 + if (irq == 0) + vcpu = ioapic->kvm->vcpus[0]; +#endif + if (vcpu != NULL) + ioapic_inj_irq(ioapic, vcpu, vector, + trig_mode, delivery_mode); + else + ioapic_debug("null lowest prio vcpu: " + "mask=%x vector=%x delivery_mode=%x\n", + deliver_bitmask, vector, IOAPIC_LOWEST_PRIORITY); + break; + case IOAPIC_FIXED: +#ifdef CONFIG_X86 + if (irq == 0) + deliver_bitmask = 1; +#endif + for (vcpu_id = 0; deliver_bitmask != 0; vcpu_id++) { + if (!(deliver_bitmask & (1 << vcpu_id))) + continue; + deliver_bitmask &= ~(1 << vcpu_id); + vcpu = ioapic->kvm->vcpus[vcpu_id]; + if (vcpu) { + ioapic_inj_irq(ioapic, vcpu, vector, + trig_mode, delivery_mode); + } + } + break; + + /* TODO: NMI */ + default: + printk(KERN_WARNING "Unsupported delivery mode %d\n", + delivery_mode); + break; + } +} + +void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level) +{ + u32 old_irr = ioapic->irr; + u32 mask = 1 << irq; + union ioapic_redir_entry entry; + + if (irq >= 0 && irq < IOAPIC_NUM_PINS) { + entry = ioapic->redirtbl[irq]; + level ^= entry.fields.polarity; + if (!level) + ioapic->irr &= ~mask; + else { + ioapic->irr |= mask; + if ((!entry.fields.trig_mode && old_irr != ioapic->irr) + || !entry.fields.remote_irr) + ioapic_service(ioapic, irq); + } + } +} + +static int get_eoi_gsi(struct kvm_ioapic *ioapic, int vector) +{ + int i; + + for (i = 0; i < IOAPIC_NUM_PINS; i++) + if (ioapic->redirtbl[i].fields.vector == vector) + return i; + return -1; +} + +void kvm_ioapic_update_eoi(struct kvm *kvm, int vector) +{ + struct kvm_ioapic *ioapic = kvm->arch.vioapic; + union ioapic_redir_entry *ent; + int gsi; + + gsi = get_eoi_gsi(ioapic, vector); + if (gsi == -1) { + printk(KERN_WARNING "Can't find redir item for %d EOI\n", + vector); + return; + } + + ent = &ioapic->redirtbl[gsi]; + ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG); + + ent->fields.remote_irr = 0; + if (!ent->fields.mask && (ioapic->irr & (1 << gsi))) + ioapic_deliver(ioapic, gsi); +} + +static int ioapic_in_range(struct kvm_io_device *this, gpa_t addr) +{ + struct kvm_ioapic *ioapic = (struct kvm_ioapic *)this->private; + + return ((addr >= ioapic->base_address && + (addr < ioapic->base_address + IOAPIC_MEM_LENGTH))); +} + +static void ioapic_mmio_read(struct kvm_io_device *this, gpa_t addr, int len, + void *val) +{ + struct kvm_ioapic *ioapic = (struct kvm_ioapic *)this->private; + u32 result; + + ioapic_debug("addr %lx\n", (unsigned long)addr); + ASSERT(!(addr & 0xf)); /* check alignment */ + + addr &= 0xff; + switch (addr) { + case IOAPIC_REG_SELECT: + result = ioapic->ioregsel; + break; + + case IOAPIC_REG_WINDOW: + result = ioapic_read_indirect(ioapic, addr, len); + break; + + default: + result = 0; + break; + } + switch (len) { + case 8: + *(u64 *) val = result; + break; + case 1: + case 2: + case 4: + memcpy(val, (char *)&result, len); + break; + default: + printk(KERN_WARNING "ioapic: wrong length %d\n", len); + } +} + +static void ioapic_mmio_write(struct kvm_io_device *this, gpa_t addr, int len, + const void *val) +{ + struct kvm_ioapic *ioapic = (struct kvm_ioapic *)this->private; + u32 data; + + ioapic_debug("ioapic_mmio_write addr=%p len=%d val=%p\n", + (void*)addr, len, val); + ASSERT(!(addr & 0xf)); /* check alignment */ + if (len == 4 || len == 8) + data = *(u32 *) val; + else { + printk(KERN_WARNING "ioapic: Unsupported size %d\n", len); + return; + } + + addr &= 0xff; + switch (addr) { + case IOAPIC_REG_SELECT: + ioapic->ioregsel = data; + break; + + case IOAPIC_REG_WINDOW: + ioapic_write_indirect(ioapic, data); + break; +#ifdef CONFIG_IA64 + case IOAPIC_REG_EOI: + kvm_ioapic_update_eoi(ioapic->kvm, data); + break; +#endif + + default: + break; + } +} + +void kvm_ioapic_reset(struct kvm_ioapic *ioapic) +{ + int i; + + for (i = 0; i < IOAPIC_NUM_PINS; i++) + ioapic->redirtbl[i].fields.mask = 1; + ioapic->base_address = IOAPIC_DEFAULT_BASE_ADDRESS; + ioapic->ioregsel = 0; + ioapic->irr = 0; + ioapic->id = 0; +} + +int kvm_ioapic_init(struct kvm *kvm) +{ + struct kvm_ioapic *ioapic; + + ioapic = kzalloc(sizeof(struct kvm_ioapic), GFP_KERNEL); + if (!ioapic) + return -ENOMEM; + kvm->arch.vioapic = ioapic; + kvm_ioapic_reset(ioapic); + ioapic->dev.read = ioapic_mmio_read; + ioapic->dev.write = ioapic_mmio_write; + ioapic->dev.in_range = ioapic_in_range; + ioapic->dev.private = ioapic; + ioapic->kvm = kvm; + kvm_io_bus_register_dev(&kvm->mmio_bus, &ioapic->dev); + return 0; +} --- linux-2.6.24.orig/virt/kvm/kvm_main.c +++ linux-2.6.24/virt/kvm/kvm_main.c @@ -0,0 +1,1451 @@ +/* + * Kernel-based Virtual Machine driver for Linux + * + * This module enables machines with Intel VT-x extensions to run virtual + * machines without emulation or binary translation. + * + * Copyright (C) 2006 Qumranet, Inc. + * + * Authors: + * Avi Kivity + * Yaniv Kamay + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#include "iodev.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +MODULE_AUTHOR("Qumranet"); +MODULE_LICENSE("GPL"); + +DEFINE_SPINLOCK(kvm_lock); +LIST_HEAD(vm_list); + +static cpumask_t cpus_hardware_enabled; + +struct kmem_cache *kvm_vcpu_cache; +EXPORT_SYMBOL_GPL(kvm_vcpu_cache); + +static __read_mostly struct preempt_ops kvm_preempt_ops; + +static struct dentry *debugfs_dir; + +static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl, + unsigned long arg); + +static inline int valid_vcpu(int n) +{ + return likely(n >= 0 && n < KVM_MAX_VCPUS); +} + +/* + * Switches to specified vcpu, until a matching vcpu_put() + */ +void vcpu_load(struct kvm_vcpu *vcpu) +{ + int cpu; + + mutex_lock(&vcpu->mutex); + cpu = get_cpu(); + preempt_notifier_register(&vcpu->preempt_notifier); + kvm_arch_vcpu_load(vcpu, cpu); + put_cpu(); +} + +void vcpu_put(struct kvm_vcpu *vcpu) +{ + preempt_disable(); + kvm_arch_vcpu_put(vcpu); + preempt_notifier_unregister(&vcpu->preempt_notifier); + preempt_enable(); + mutex_unlock(&vcpu->mutex); +} + +static void ack_flush(void *_completed) +{ +} + +void kvm_flush_remote_tlbs(struct kvm *kvm) +{ + int i, cpu; + cpumask_t cpus; + struct kvm_vcpu *vcpu; + + cpus_clear(cpus); + for (i = 0; i < KVM_MAX_VCPUS; ++i) { + vcpu = kvm->vcpus[i]; + if (!vcpu) + continue; + if (test_and_set_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests)) + continue; + cpu = vcpu->cpu; + if (cpu != -1 && cpu != raw_smp_processor_id()) + cpu_set(cpu, cpus); + } + if (cpus_empty(cpus)) + return; + ++kvm->stat.remote_tlb_flush; + smp_call_function_mask(cpus, ack_flush, NULL, 1); +} + +void kvm_reload_remote_mmus(struct kvm *kvm) +{ + int i, cpu; + cpumask_t cpus; + struct kvm_vcpu *vcpu; + + cpus_clear(cpus); + for (i = 0; i < KVM_MAX_VCPUS; ++i) { + vcpu = kvm->vcpus[i]; + if (!vcpu) + continue; + if (test_and_set_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests)) + continue; + cpu = vcpu->cpu; + if (cpu != -1 && cpu != raw_smp_processor_id()) + cpu_set(cpu, cpus); + } + if (cpus_empty(cpus)) + return; + smp_call_function_mask(cpus, ack_flush, NULL, 1); +} + + +int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id) +{ + struct page *page; + int r; + + mutex_init(&vcpu->mutex); + vcpu->cpu = -1; + vcpu->kvm = kvm; + vcpu->vcpu_id = id; + init_waitqueue_head(&vcpu->wq); + + page = alloc_page(GFP_KERNEL | __GFP_ZERO); + if (!page) { + r = -ENOMEM; + goto fail; + } + vcpu->run = page_address(page); + + r = kvm_arch_vcpu_init(vcpu); + if (r < 0) + goto fail_free_run; + return 0; + +fail_free_run: + free_page((unsigned long)vcpu->run); +fail: + return r; +} +EXPORT_SYMBOL_GPL(kvm_vcpu_init); + +void kvm_vcpu_uninit(struct kvm_vcpu *vcpu) +{ + kvm_arch_vcpu_uninit(vcpu); + free_page((unsigned long)vcpu->run); +} +EXPORT_SYMBOL_GPL(kvm_vcpu_uninit); + +static struct kvm *kvm_create_vm(void) +{ + struct kvm *kvm = kvm_arch_create_vm(); + + if (IS_ERR(kvm)) + goto out; + + kvm->mm = current->mm; + atomic_inc(&kvm->mm->mm_count); + spin_lock_init(&kvm->mmu_lock); + kvm_io_bus_init(&kvm->pio_bus); + mutex_init(&kvm->lock); + kvm_io_bus_init(&kvm->mmio_bus); + init_rwsem(&kvm->slots_lock); + spin_lock(&kvm_lock); + list_add(&kvm->vm_list, &vm_list); + spin_unlock(&kvm_lock); +out: + return kvm; +} + +/* + * Free any memory in @free but not in @dont. + */ +static void kvm_free_physmem_slot(struct kvm_memory_slot *free, + struct kvm_memory_slot *dont) +{ + if (!dont || free->rmap != dont->rmap) + vfree(free->rmap); + + if (!dont || free->dirty_bitmap != dont->dirty_bitmap) + vfree(free->dirty_bitmap); + + if (!dont || free->lpage_info != dont->lpage_info) + vfree(free->lpage_info); + + free->npages = 0; + free->dirty_bitmap = NULL; + free->rmap = NULL; + free->lpage_info = NULL; +} + +void kvm_free_physmem(struct kvm *kvm) +{ + int i; + + for (i = 0; i < kvm->nmemslots; ++i) + kvm_free_physmem_slot(&kvm->memslots[i], NULL); +} + +static void kvm_destroy_vm(struct kvm *kvm) +{ + struct mm_struct *mm = kvm->mm; + + spin_lock(&kvm_lock); + list_del(&kvm->vm_list); + spin_unlock(&kvm_lock); + kvm_io_bus_destroy(&kvm->pio_bus); + kvm_io_bus_destroy(&kvm->mmio_bus); + kvm_arch_destroy_vm(kvm); + mmdrop(mm); +} + +static int kvm_vm_release(struct inode *inode, struct file *filp) +{ + struct kvm *kvm = filp->private_data; + + kvm_destroy_vm(kvm); + return 0; +} + +/* + * Allocate some memory and give it an address in the guest physical address + * space. + * + * Discontiguous memory is allowed, mostly for framebuffers. + * + * Must be called holding mmap_sem for write. + */ +int __kvm_set_memory_region(struct kvm *kvm, + struct kvm_userspace_memory_region *mem, + int user_alloc) +{ + int r; + gfn_t base_gfn; + unsigned long npages; + unsigned long i; + struct kvm_memory_slot *memslot; + struct kvm_memory_slot old, new; + + r = -EINVAL; + /* General sanity checks */ + if (mem->memory_size & (PAGE_SIZE - 1)) + goto out; + if (mem->guest_phys_addr & (PAGE_SIZE - 1)) + goto out; + if (mem->slot >= KVM_MEMORY_SLOTS + KVM_PRIVATE_MEM_SLOTS) + goto out; + if (mem->guest_phys_addr + mem->memory_size < mem->guest_phys_addr) + goto out; + + memslot = &kvm->memslots[mem->slot]; + base_gfn = mem->guest_phys_addr >> PAGE_SHIFT; + npages = mem->memory_size >> PAGE_SHIFT; + + if (!npages) + mem->flags &= ~KVM_MEM_LOG_DIRTY_PAGES; + + new = old = *memslot; + + new.base_gfn = base_gfn; + new.npages = npages; + new.flags = mem->flags; + + /* Disallow changing a memory slot's size. */ + r = -EINVAL; + if (npages && old.npages && npages != old.npages) + goto out_free; + + /* Check for overlaps */ + r = -EEXIST; + for (i = 0; i < KVM_MEMORY_SLOTS; ++i) { + struct kvm_memory_slot *s = &kvm->memslots[i]; + + if (s == memslot) + continue; + if (!((base_gfn + npages <= s->base_gfn) || + (base_gfn >= s->base_gfn + s->npages))) + goto out_free; + } + + /* Free page dirty bitmap if unneeded */ + if (!(new.flags & KVM_MEM_LOG_DIRTY_PAGES)) + new.dirty_bitmap = NULL; + + r = -ENOMEM; + + /* Allocate if a slot is being created */ + if (npages && !new.rmap) { + new.rmap = vmalloc(npages * sizeof(struct page *)); + + if (!new.rmap) + goto out_free; + + memset(new.rmap, 0, npages * sizeof(*new.rmap)); + + new.user_alloc = user_alloc; + new.userspace_addr = mem->userspace_addr; + } + if (npages && !new.lpage_info) { + int largepages = npages / KVM_PAGES_PER_HPAGE; + if (npages % KVM_PAGES_PER_HPAGE) + largepages++; + new.lpage_info = vmalloc(largepages * sizeof(*new.lpage_info)); + + if (!new.lpage_info) + goto out_free; + + memset(new.lpage_info, 0, largepages * sizeof(*new.lpage_info)); + + if (base_gfn % KVM_PAGES_PER_HPAGE) + new.lpage_info[0].write_count = 1; + if ((base_gfn+npages) % KVM_PAGES_PER_HPAGE) + new.lpage_info[largepages-1].write_count = 1; + } + + /* Allocate page dirty bitmap if needed */ + if ((new.flags & KVM_MEM_LOG_DIRTY_PAGES) && !new.dirty_bitmap) { + unsigned dirty_bytes = ALIGN(npages, BITS_PER_LONG) / 8; + + new.dirty_bitmap = vmalloc(dirty_bytes); + if (!new.dirty_bitmap) + goto out_free; + memset(new.dirty_bitmap, 0, dirty_bytes); + } + + if (mem->slot >= kvm->nmemslots) + kvm->nmemslots = mem->slot + 1; + + *memslot = new; + + r = kvm_arch_set_memory_region(kvm, mem, old, user_alloc); + if (r) { + *memslot = old; + goto out_free; + } + + kvm_free_physmem_slot(&old, &new); + return 0; + +out_free: + kvm_free_physmem_slot(&new, &old); +out: + return r; + +} +EXPORT_SYMBOL_GPL(__kvm_set_memory_region); + +int kvm_set_memory_region(struct kvm *kvm, + struct kvm_userspace_memory_region *mem, + int user_alloc) +{ + int r; + + down_write(&kvm->slots_lock); + r = __kvm_set_memory_region(kvm, mem, user_alloc); + up_write(&kvm->slots_lock); + return r; +} +EXPORT_SYMBOL_GPL(kvm_set_memory_region); + +int kvm_vm_ioctl_set_memory_region(struct kvm *kvm, + struct + kvm_userspace_memory_region *mem, + int user_alloc) +{ + if (mem->slot >= KVM_MEMORY_SLOTS) + return -EINVAL; + return kvm_set_memory_region(kvm, mem, user_alloc); +} + +int kvm_get_dirty_log(struct kvm *kvm, + struct kvm_dirty_log *log, int *is_dirty) +{ + struct kvm_memory_slot *memslot; + int r, i; + int n; + unsigned long any = 0; + + r = -EINVAL; + if (log->slot >= KVM_MEMORY_SLOTS) + goto out; + + memslot = &kvm->memslots[log->slot]; + r = -ENOENT; + if (!memslot->dirty_bitmap) + goto out; + + n = ALIGN(memslot->npages, BITS_PER_LONG) / 8; + + for (i = 0; !any && i < n/sizeof(long); ++i) + any = memslot->dirty_bitmap[i]; + + r = -EFAULT; + if (copy_to_user(log->dirty_bitmap, memslot->dirty_bitmap, n)) + goto out; + + if (any) + *is_dirty = 1; + + r = 0; +out: + return r; +} + +int is_error_page(struct page *page) +{ + return page == bad_page; +} +EXPORT_SYMBOL_GPL(is_error_page); + +static inline unsigned long bad_hva(void) +{ + return PAGE_OFFSET; +} + +int kvm_is_error_hva(unsigned long addr) +{ + return addr == bad_hva(); +} +EXPORT_SYMBOL_GPL(kvm_is_error_hva); + +static struct kvm_memory_slot *__gfn_to_memslot(struct kvm *kvm, gfn_t gfn) +{ + int i; + + for (i = 0; i < kvm->nmemslots; ++i) { + struct kvm_memory_slot *memslot = &kvm->memslots[i]; + + if (gfn >= memslot->base_gfn + && gfn < memslot->base_gfn + memslot->npages) + return memslot; + } + return NULL; +} + +struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn) +{ + gfn = unalias_gfn(kvm, gfn); + return __gfn_to_memslot(kvm, gfn); +} + +int kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn) +{ + int i; + + gfn = unalias_gfn(kvm, gfn); + for (i = 0; i < KVM_MEMORY_SLOTS; ++i) { + struct kvm_memory_slot *memslot = &kvm->memslots[i]; + + if (gfn >= memslot->base_gfn + && gfn < memslot->base_gfn + memslot->npages) + return 1; + } + return 0; +} +EXPORT_SYMBOL_GPL(kvm_is_visible_gfn); + +unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn) +{ + struct kvm_memory_slot *slot; + + gfn = unalias_gfn(kvm, gfn); + slot = __gfn_to_memslot(kvm, gfn); + if (!slot) + return bad_hva(); + return (slot->userspace_addr + (gfn - slot->base_gfn) * PAGE_SIZE); +} + +/* + * Requires current->mm->mmap_sem to be held + */ +struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn) +{ + struct page *page[1]; + unsigned long addr; + int npages; + + might_sleep(); + + addr = gfn_to_hva(kvm, gfn); + if (kvm_is_error_hva(addr)) { + get_page(bad_page); + return bad_page; + } + + npages = get_user_pages(current, current->mm, addr, 1, 1, 1, page, + NULL); + + if (npages != 1) { + get_page(bad_page); + return bad_page; + } + + return page[0]; +} + +EXPORT_SYMBOL_GPL(gfn_to_page); + +void kvm_release_page_clean(struct page *page) +{ + put_page(page); +} +EXPORT_SYMBOL_GPL(kvm_release_page_clean); + +void kvm_release_page_dirty(struct page *page) +{ + if (!PageReserved(page)) + SetPageDirty(page); + put_page(page); +} +EXPORT_SYMBOL_GPL(kvm_release_page_dirty); + +static int next_segment(unsigned long len, int offset) +{ + if (len > PAGE_SIZE - offset) + return PAGE_SIZE - offset; + else + return len; +} + +int kvm_read_guest_page(struct kvm *kvm, gfn_t gfn, void *data, int offset, + int len) +{ + int r; + unsigned long addr; + + addr = gfn_to_hva(kvm, gfn); + if (kvm_is_error_hva(addr)) + return -EFAULT; + r = copy_from_user(data, (void __user *)addr + offset, len); + if (r) + return -EFAULT; + return 0; +} +EXPORT_SYMBOL_GPL(kvm_read_guest_page); + +int kvm_read_guest(struct kvm *kvm, gpa_t gpa, void *data, unsigned long len) +{ + gfn_t gfn = gpa >> PAGE_SHIFT; + int seg; + int offset = offset_in_page(gpa); + int ret; + + while ((seg = next_segment(len, offset)) != 0) { + ret = kvm_read_guest_page(kvm, gfn, data, offset, seg); + if (ret < 0) + return ret; + offset = 0; + len -= seg; + data += seg; + ++gfn; + } + return 0; +} +EXPORT_SYMBOL_GPL(kvm_read_guest); + +int kvm_read_guest_atomic(struct kvm *kvm, gpa_t gpa, void *data, + unsigned long len) +{ + int r; + unsigned long addr; + gfn_t gfn = gpa >> PAGE_SHIFT; + int offset = offset_in_page(gpa); + + addr = gfn_to_hva(kvm, gfn); + if (kvm_is_error_hva(addr)) + return -EFAULT; + pagefault_disable(); + r = __copy_from_user_inatomic(data, (void __user *)addr + offset, len); + pagefault_enable(); + if (r) + return -EFAULT; + return 0; +} +EXPORT_SYMBOL(kvm_read_guest_atomic); + +int kvm_write_guest_page(struct kvm *kvm, gfn_t gfn, const void *data, + int offset, int len) +{ + int r; + unsigned long addr; + + addr = gfn_to_hva(kvm, gfn); + if (kvm_is_error_hva(addr)) + return -EFAULT; + r = copy_to_user((void __user *)addr + offset, data, len); + if (r) + return -EFAULT; + mark_page_dirty(kvm, gfn); + return 0; +} +EXPORT_SYMBOL_GPL(kvm_write_guest_page); + +int kvm_write_guest(struct kvm *kvm, gpa_t gpa, const void *data, + unsigned long len) +{ + gfn_t gfn = gpa >> PAGE_SHIFT; + int seg; + int offset = offset_in_page(gpa); + int ret; + + while ((seg = next_segment(len, offset)) != 0) { + ret = kvm_write_guest_page(kvm, gfn, data, offset, seg); + if (ret < 0) + return ret; + offset = 0; + len -= seg; + data += seg; + ++gfn; + } + return 0; +} + +int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len) +{ + return kvm_write_guest_page(kvm, gfn, empty_zero_page, offset, len); +} +EXPORT_SYMBOL_GPL(kvm_clear_guest_page); + +int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len) +{ + gfn_t gfn = gpa >> PAGE_SHIFT; + int seg; + int offset = offset_in_page(gpa); + int ret; + + while ((seg = next_segment(len, offset)) != 0) { + ret = kvm_clear_guest_page(kvm, gfn, offset, seg); + if (ret < 0) + return ret; + offset = 0; + len -= seg; + ++gfn; + } + return 0; +} +EXPORT_SYMBOL_GPL(kvm_clear_guest); + +void mark_page_dirty(struct kvm *kvm, gfn_t gfn) +{ + struct kvm_memory_slot *memslot; + + gfn = unalias_gfn(kvm, gfn); + memslot = __gfn_to_memslot(kvm, gfn); + if (memslot && memslot->dirty_bitmap) { + unsigned long rel_gfn = gfn - memslot->base_gfn; + + /* avoid RMW */ + if (!test_bit(rel_gfn, memslot->dirty_bitmap)) + set_bit(rel_gfn, memslot->dirty_bitmap); + } +} + +/* + * The vCPU has executed a HLT instruction with in-kernel mode enabled. + */ +void kvm_vcpu_block(struct kvm_vcpu *vcpu) +{ + DECLARE_WAITQUEUE(wait, current); + + add_wait_queue(&vcpu->wq, &wait); + + /* + * We will block until either an interrupt or a signal wakes us up + */ + while (!kvm_cpu_has_interrupt(vcpu) + && !signal_pending(current) + && !kvm_arch_vcpu_runnable(vcpu)) { + set_current_state(TASK_INTERRUPTIBLE); + vcpu_put(vcpu); + schedule(); + vcpu_load(vcpu); + } + + __set_current_state(TASK_RUNNING); + remove_wait_queue(&vcpu->wq, &wait); +} + +void kvm_resched(struct kvm_vcpu *vcpu) +{ + if (!need_resched()) + return; + cond_resched(); +} +EXPORT_SYMBOL_GPL(kvm_resched); + +static int kvm_vcpu_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + struct kvm_vcpu *vcpu = vma->vm_file->private_data; + struct page *page; + + if (vmf->pgoff == 0) + page = virt_to_page(vcpu->run); +#ifdef CONFIG_X86 + else if (vmf->pgoff == KVM_PIO_PAGE_OFFSET) + page = virt_to_page(vcpu->arch.pio_data); +#endif + else + return VM_FAULT_SIGBUS; + get_page(page); + vmf->page = page; + return 0; +} + +static struct vm_operations_struct kvm_vcpu_vm_ops = { + .fault = kvm_vcpu_fault, +}; + +static int kvm_vcpu_mmap(struct file *file, struct vm_area_struct *vma) +{ + vma->vm_ops = &kvm_vcpu_vm_ops; + return 0; +} + +static int kvm_vcpu_release(struct inode *inode, struct file *filp) +{ + struct kvm_vcpu *vcpu = filp->private_data; + + fput(vcpu->kvm->filp); + return 0; +} + +static const struct file_operations kvm_vcpu_fops = { + .release = kvm_vcpu_release, + .unlocked_ioctl = kvm_vcpu_ioctl, + .compat_ioctl = kvm_vcpu_ioctl, + .mmap = kvm_vcpu_mmap, +}; + +/* + * Allocates an inode for the vcpu. + */ +static int create_vcpu_fd(struct kvm_vcpu *vcpu) +{ + int fd, r; + struct inode *inode; + struct file *file; + + r = anon_inode_getfd(&fd, &inode, &file, + "kvm-vcpu", &kvm_vcpu_fops, vcpu); + if (r) + return r; + atomic_inc(&vcpu->kvm->filp->f_count); + return fd; +} + +/* + * Creates some virtual cpus. Good luck creating more than one. + */ +static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, int n) +{ + int r; + struct kvm_vcpu *vcpu; + + if (!valid_vcpu(n)) + return -EINVAL; + + vcpu = kvm_arch_vcpu_create(kvm, n); + if (IS_ERR(vcpu)) + return PTR_ERR(vcpu); + + preempt_notifier_init(&vcpu->preempt_notifier, &kvm_preempt_ops); + + r = kvm_arch_vcpu_setup(vcpu); + if (r) + goto vcpu_destroy; + + mutex_lock(&kvm->lock); + if (kvm->vcpus[n]) { + r = -EEXIST; + mutex_unlock(&kvm->lock); + goto vcpu_destroy; + } + kvm->vcpus[n] = vcpu; + mutex_unlock(&kvm->lock); + + /* Now it's all set up, let userspace reach it */ + r = create_vcpu_fd(vcpu); + if (r < 0) + goto unlink; + return r; + +unlink: + mutex_lock(&kvm->lock); + kvm->vcpus[n] = NULL; + mutex_unlock(&kvm->lock); +vcpu_destroy: + kvm_arch_vcpu_destroy(vcpu); + return r; +} + +static int kvm_vcpu_ioctl_set_sigmask(struct kvm_vcpu *vcpu, sigset_t *sigset) +{ + if (sigset) { + sigdelsetmask(sigset, sigmask(SIGKILL)|sigmask(SIGSTOP)); + vcpu->sigset_active = 1; + vcpu->sigset = *sigset; + } else + vcpu->sigset_active = 0; + return 0; +} + +static long kvm_vcpu_ioctl(struct file *filp, + unsigned int ioctl, unsigned long arg) +{ + struct kvm_vcpu *vcpu = filp->private_data; + void __user *argp = (void __user *)arg; + int r; + + if (vcpu->kvm->mm != current->mm) + return -EIO; + switch (ioctl) { + case KVM_RUN: + r = -EINVAL; + if (arg) + goto out; + r = kvm_arch_vcpu_ioctl_run(vcpu, vcpu->run); + break; + case KVM_GET_REGS: { + struct kvm_regs kvm_regs; + + memset(&kvm_regs, 0, sizeof kvm_regs); + r = kvm_arch_vcpu_ioctl_get_regs(vcpu, &kvm_regs); + if (r) + goto out; + r = -EFAULT; + if (copy_to_user(argp, &kvm_regs, sizeof kvm_regs)) + goto out; + r = 0; + break; + } + case KVM_SET_REGS: { + struct kvm_regs kvm_regs; + + r = -EFAULT; + if (copy_from_user(&kvm_regs, argp, sizeof kvm_regs)) + goto out; + r = kvm_arch_vcpu_ioctl_set_regs(vcpu, &kvm_regs); + if (r) + goto out; + r = 0; + break; + } + case KVM_GET_SREGS: { + struct kvm_sregs kvm_sregs; + + memset(&kvm_sregs, 0, sizeof kvm_sregs); + r = kvm_arch_vcpu_ioctl_get_sregs(vcpu, &kvm_sregs); + if (r) + goto out; + r = -EFAULT; + if (copy_to_user(argp, &kvm_sregs, sizeof kvm_sregs)) + goto out; + r = 0; + break; + } + case KVM_SET_SREGS: { + struct kvm_sregs kvm_sregs; + + r = -EFAULT; + if (copy_from_user(&kvm_sregs, argp, sizeof kvm_sregs)) + goto out; + r = kvm_arch_vcpu_ioctl_set_sregs(vcpu, &kvm_sregs); + if (r) + goto out; + r = 0; + break; + } + case KVM_TRANSLATE: { + struct kvm_translation tr; + + r = -EFAULT; + if (copy_from_user(&tr, argp, sizeof tr)) + goto out; + r = kvm_arch_vcpu_ioctl_translate(vcpu, &tr); + if (r) + goto out; + r = -EFAULT; + if (copy_to_user(argp, &tr, sizeof tr)) + goto out; + r = 0; + break; + } + case KVM_DEBUG_GUEST: { + struct kvm_debug_guest dbg; + + r = -EFAULT; + if (copy_from_user(&dbg, argp, sizeof dbg)) + goto out; + r = kvm_arch_vcpu_ioctl_debug_guest(vcpu, &dbg); + if (r) + goto out; + r = 0; + break; + } + case KVM_SET_SIGNAL_MASK: { + struct kvm_signal_mask __user *sigmask_arg = argp; + struct kvm_signal_mask kvm_sigmask; + sigset_t sigset, *p; + + p = NULL; + if (argp) { + r = -EFAULT; + if (copy_from_user(&kvm_sigmask, argp, + sizeof kvm_sigmask)) + goto out; + r = -EINVAL; + if (kvm_sigmask.len != sizeof sigset) + goto out; + r = -EFAULT; + if (copy_from_user(&sigset, sigmask_arg->sigset, + sizeof sigset)) + goto out; + p = &sigset; + } + r = kvm_vcpu_ioctl_set_sigmask(vcpu, &sigset); + break; + } + case KVM_GET_FPU: { + struct kvm_fpu fpu; + + memset(&fpu, 0, sizeof fpu); + r = kvm_arch_vcpu_ioctl_get_fpu(vcpu, &fpu); + if (r) + goto out; + r = -EFAULT; + if (copy_to_user(argp, &fpu, sizeof fpu)) + goto out; + r = 0; + break; + } + case KVM_SET_FPU: { + struct kvm_fpu fpu; + + r = -EFAULT; + if (copy_from_user(&fpu, argp, sizeof fpu)) + goto out; + r = kvm_arch_vcpu_ioctl_set_fpu(vcpu, &fpu); + if (r) + goto out; + r = 0; + break; + } + default: + r = kvm_arch_vcpu_ioctl(filp, ioctl, arg); + } +out: + return r; +} + +static long kvm_vm_ioctl(struct file *filp, + unsigned int ioctl, unsigned long arg) +{ + struct kvm *kvm = filp->private_data; + void __user *argp = (void __user *)arg; + int r; + + if (kvm->mm != current->mm) + return -EIO; + switch (ioctl) { + case KVM_CREATE_VCPU: + r = kvm_vm_ioctl_create_vcpu(kvm, arg); + if (r < 0) + goto out; + break; + case KVM_SET_USER_MEMORY_REGION: { + struct kvm_userspace_memory_region kvm_userspace_mem; + + r = -EFAULT; + if (copy_from_user(&kvm_userspace_mem, argp, + sizeof kvm_userspace_mem)) + goto out; + + r = kvm_vm_ioctl_set_memory_region(kvm, &kvm_userspace_mem, 1); + if (r) + goto out; + break; + } + case KVM_GET_DIRTY_LOG: { + struct kvm_dirty_log log; + + r = -EFAULT; + if (copy_from_user(&log, argp, sizeof log)) + goto out; + r = kvm_vm_ioctl_get_dirty_log(kvm, &log); + if (r) + goto out; + break; + } + default: + r = kvm_arch_vm_ioctl(filp, ioctl, arg); + } +out: + return r; +} + +static int kvm_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + struct kvm *kvm = vma->vm_file->private_data; + struct page *page; + + if (!kvm_is_visible_gfn(kvm, vmf->pgoff)) + return VM_FAULT_SIGBUS; + page = gfn_to_page(kvm, vmf->pgoff); + if (is_error_page(page)) { + kvm_release_page_clean(page); + return VM_FAULT_SIGBUS; + } + vmf->page = page; + return 0; +} + +static struct vm_operations_struct kvm_vm_vm_ops = { + .fault = kvm_vm_fault, +}; + +static int kvm_vm_mmap(struct file *file, struct vm_area_struct *vma) +{ + vma->vm_ops = &kvm_vm_vm_ops; + return 0; +} + +static const struct file_operations kvm_vm_fops = { + .release = kvm_vm_release, + .unlocked_ioctl = kvm_vm_ioctl, + .compat_ioctl = kvm_vm_ioctl, + .mmap = kvm_vm_mmap, +}; + +static int kvm_dev_ioctl_create_vm(void) +{ + int fd, r; + struct inode *inode; + struct file *file; + struct kvm *kvm; + + kvm = kvm_create_vm(); + if (IS_ERR(kvm)) + return PTR_ERR(kvm); + r = anon_inode_getfd(&fd, &inode, &file, "kvm-vm", &kvm_vm_fops, kvm); + if (r) { + kvm_destroy_vm(kvm); + return r; + } + + kvm->filp = file; + + return fd; +} + +static long kvm_dev_ioctl(struct file *filp, + unsigned int ioctl, unsigned long arg) +{ + void __user *argp = (void __user *)arg; + long r = -EINVAL; + + switch (ioctl) { + case KVM_GET_API_VERSION: + r = -EINVAL; + if (arg) + goto out; + r = KVM_API_VERSION; + break; + case KVM_CREATE_VM: + r = -EINVAL; + if (arg) + goto out; + r = kvm_dev_ioctl_create_vm(); + break; + case KVM_CHECK_EXTENSION: + r = kvm_dev_ioctl_check_extension((long)argp); + break; + case KVM_GET_VCPU_MMAP_SIZE: + r = -EINVAL; + if (arg) + goto out; + r = PAGE_SIZE; /* struct kvm_run */ +#ifdef CONFIG_X86 + r += PAGE_SIZE; /* pio data page */ +#endif + break; + default: + return kvm_arch_dev_ioctl(filp, ioctl, arg); + } +out: + return r; +} + +static struct file_operations kvm_chardev_ops = { + .unlocked_ioctl = kvm_dev_ioctl, + .compat_ioctl = kvm_dev_ioctl, +}; + +static struct miscdevice kvm_dev = { + KVM_MINOR, + "kvm", + &kvm_chardev_ops, +}; + +static void hardware_enable(void *junk) +{ + int cpu = raw_smp_processor_id(); + + if (cpu_isset(cpu, cpus_hardware_enabled)) + return; + cpu_set(cpu, cpus_hardware_enabled); + kvm_arch_hardware_enable(NULL); +} + +static void hardware_disable(void *junk) +{ + int cpu = raw_smp_processor_id(); + + if (!cpu_isset(cpu, cpus_hardware_enabled)) + return; + cpu_clear(cpu, cpus_hardware_enabled); + decache_vcpus_on_cpu(cpu); + kvm_arch_hardware_disable(NULL); +} + +static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val, + void *v) +{ + int cpu = (long)v; + + val &= ~CPU_TASKS_FROZEN; + switch (val) { + case CPU_DYING: + printk(KERN_INFO "kvm: disabling virtualization on CPU%d\n", + cpu); + hardware_disable(NULL); + break; + case CPU_UP_CANCELED: + printk(KERN_INFO "kvm: disabling virtualization on CPU%d\n", + cpu); + smp_call_function_single(cpu, hardware_disable, NULL, 0, 1); + break; + case CPU_ONLINE: + printk(KERN_INFO "kvm: enabling virtualization on CPU%d\n", + cpu); + smp_call_function_single(cpu, hardware_enable, NULL, 0, 1); + break; + } + return NOTIFY_OK; +} + +static int kvm_reboot(struct notifier_block *notifier, unsigned long val, + void *v) +{ + if (val == SYS_RESTART) { + /* + * Some (well, at least mine) BIOSes hang on reboot if + * in vmx root mode. + */ + printk(KERN_INFO "kvm: exiting hardware virtualization\n"); + on_each_cpu(hardware_disable, NULL, 0, 1); + } + return NOTIFY_OK; +} + +static struct notifier_block kvm_reboot_notifier = { + .notifier_call = kvm_reboot, + .priority = 0, +}; + +void kvm_io_bus_init(struct kvm_io_bus *bus) +{ + memset(bus, 0, sizeof(*bus)); +} + +void kvm_io_bus_destroy(struct kvm_io_bus *bus) +{ + int i; + + for (i = 0; i < bus->dev_count; i++) { + struct kvm_io_device *pos = bus->devs[i]; + + kvm_iodevice_destructor(pos); + } +} + +struct kvm_io_device *kvm_io_bus_find_dev(struct kvm_io_bus *bus, gpa_t addr) +{ + int i; + + for (i = 0; i < bus->dev_count; i++) { + struct kvm_io_device *pos = bus->devs[i]; + + if (pos->in_range(pos, addr)) + return pos; + } + + return NULL; +} + +void kvm_io_bus_register_dev(struct kvm_io_bus *bus, struct kvm_io_device *dev) +{ + BUG_ON(bus->dev_count > (NR_IOBUS_DEVS-1)); + + bus->devs[bus->dev_count++] = dev; +} + +static struct notifier_block kvm_cpu_notifier = { + .notifier_call = kvm_cpu_hotplug, + .priority = 20, /* must be > scheduler priority */ +}; + +static u64 vm_stat_get(void *_offset) +{ + unsigned offset = (long)_offset; + u64 total = 0; + struct kvm *kvm; + + spin_lock(&kvm_lock); + list_for_each_entry(kvm, &vm_list, vm_list) + total += *(u32 *)((void *)kvm + offset); + spin_unlock(&kvm_lock); + return total; +} + +DEFINE_SIMPLE_ATTRIBUTE(vm_stat_fops, vm_stat_get, NULL, "%llu\n"); + +static u64 vcpu_stat_get(void *_offset) +{ + unsigned offset = (long)_offset; + u64 total = 0; + struct kvm *kvm; + struct kvm_vcpu *vcpu; + int i; + + spin_lock(&kvm_lock); + list_for_each_entry(kvm, &vm_list, vm_list) + for (i = 0; i < KVM_MAX_VCPUS; ++i) { + vcpu = kvm->vcpus[i]; + if (vcpu) + total += *(u32 *)((void *)vcpu + offset); + } + spin_unlock(&kvm_lock); + return total; +} + +DEFINE_SIMPLE_ATTRIBUTE(vcpu_stat_fops, vcpu_stat_get, NULL, "%llu\n"); + +static struct file_operations *stat_fops[] = { + [KVM_STAT_VCPU] = &vcpu_stat_fops, + [KVM_STAT_VM] = &vm_stat_fops, +}; + +static void kvm_init_debug(void) +{ + struct kvm_stats_debugfs_item *p; + + debugfs_dir = debugfs_create_dir("kvm", NULL); + for (p = debugfs_entries; p->name; ++p) + p->dentry = debugfs_create_file(p->name, 0444, debugfs_dir, + (void *)(long)p->offset, + stat_fops[p->kind]); +} + +static void kvm_exit_debug(void) +{ + struct kvm_stats_debugfs_item *p; + + for (p = debugfs_entries; p->name; ++p) + debugfs_remove(p->dentry); + debugfs_remove(debugfs_dir); +} + +static int kvm_suspend(struct sys_device *dev, pm_message_t state) +{ + hardware_disable(NULL); + return 0; +} + +static int kvm_resume(struct sys_device *dev) +{ + hardware_enable(NULL); + return 0; +} + +static struct sysdev_class kvm_sysdev_class = { + set_kset_name("kvm"), + .suspend = kvm_suspend, + .resume = kvm_resume, +}; + +static struct sys_device kvm_sysdev = { + .id = 0, + .cls = &kvm_sysdev_class, +}; + +struct page *bad_page; + +static inline +struct kvm_vcpu *preempt_notifier_to_vcpu(struct preempt_notifier *pn) +{ + return container_of(pn, struct kvm_vcpu, preempt_notifier); +} + +static void kvm_sched_in(struct preempt_notifier *pn, int cpu) +{ + struct kvm_vcpu *vcpu = preempt_notifier_to_vcpu(pn); + + kvm_arch_vcpu_load(vcpu, cpu); +} + +static void kvm_sched_out(struct preempt_notifier *pn, + struct task_struct *next) +{ + struct kvm_vcpu *vcpu = preempt_notifier_to_vcpu(pn); + + kvm_arch_vcpu_put(vcpu); +} + +int kvm_init(void *opaque, unsigned int vcpu_size, + struct module *module) +{ + int r; + int cpu; + + kvm_init_debug(); + + r = kvm_arch_init(opaque); + if (r) + goto out_fail; + + bad_page = alloc_page(GFP_KERNEL | __GFP_ZERO); + + if (bad_page == NULL) { + r = -ENOMEM; + goto out; + } + + r = kvm_arch_hardware_setup(); + if (r < 0) + goto out_free_0; + + for_each_online_cpu(cpu) { + smp_call_function_single(cpu, + kvm_arch_check_processor_compat, + &r, 0, 1); + if (r < 0) + goto out_free_1; + } + + on_each_cpu(hardware_enable, NULL, 0, 1); + r = register_cpu_notifier(&kvm_cpu_notifier); + if (r) + goto out_free_2; + register_reboot_notifier(&kvm_reboot_notifier); + + r = sysdev_class_register(&kvm_sysdev_class); + if (r) + goto out_free_3; + + r = sysdev_register(&kvm_sysdev); + if (r) + goto out_free_4; + + /* A kmem cache lets us meet the alignment requirements of fx_save. */ + kvm_vcpu_cache = kmem_cache_create("kvm_vcpu", vcpu_size, + __alignof__(struct kvm_vcpu), + 0, NULL); + if (!kvm_vcpu_cache) { + r = -ENOMEM; + goto out_free_5; + } + + kvm_chardev_ops.owner = module; + + r = misc_register(&kvm_dev); + if (r) { + printk(KERN_ERR "kvm: misc device register failed\n"); + goto out_free; + } + + kvm_preempt_ops.sched_in = kvm_sched_in; + kvm_preempt_ops.sched_out = kvm_sched_out; + + return 0; + +out_free: + kmem_cache_destroy(kvm_vcpu_cache); +out_free_5: + sysdev_unregister(&kvm_sysdev); +out_free_4: + sysdev_class_unregister(&kvm_sysdev_class); +out_free_3: + unregister_reboot_notifier(&kvm_reboot_notifier); + unregister_cpu_notifier(&kvm_cpu_notifier); +out_free_2: + on_each_cpu(hardware_disable, NULL, 0, 1); +out_free_1: + kvm_arch_hardware_unsetup(); +out_free_0: + __free_page(bad_page); +out: + kvm_arch_exit(); + kvm_exit_debug(); +out_fail: + return r; +} +EXPORT_SYMBOL_GPL(kvm_init); + +void kvm_exit(void) +{ + misc_deregister(&kvm_dev); + kmem_cache_destroy(kvm_vcpu_cache); + sysdev_unregister(&kvm_sysdev); + sysdev_class_unregister(&kvm_sysdev_class); + unregister_reboot_notifier(&kvm_reboot_notifier); + unregister_cpu_notifier(&kvm_cpu_notifier); + on_each_cpu(hardware_disable, NULL, 0, 1); + kvm_arch_hardware_unsetup(); + kvm_arch_exit(); + kvm_exit_debug(); + __free_page(bad_page); +} +EXPORT_SYMBOL_GPL(kvm_exit); --- linux-2.6.24.orig/drivers/Kconfig +++ linux-2.6.24/drivers/Kconfig @@ -90,9 +90,5 @@ source "drivers/auxdisplay/Kconfig" -source "drivers/kvm/Kconfig" - source "drivers/uio/Kconfig" - -source "drivers/virtio/Kconfig" endmenu --- linux-2.6.24.orig/drivers/Makefile +++ linux-2.6.24/drivers/Makefile @@ -47,7 +47,6 @@ obj-$(CONFIG_PCCARD) += pcmcia/ obj-$(CONFIG_DIO) += dio/ obj-$(CONFIG_SBUS) += sbus/ -obj-$(CONFIG_KVM) += kvm/ obj-$(CONFIG_ZORRO) += zorro/ obj-$(CONFIG_MAC) += macintosh/ obj-$(CONFIG_ATA_OVER_ETH) += block/aoe/ @@ -77,6 +76,7 @@ obj-$(CONFIG_CPU_FREQ) += cpufreq/ obj-$(CONFIG_CPU_IDLE) += cpuidle/ obj-$(CONFIG_MMC) += mmc/ +obj-$(CONFIG_MSS) += mmc/ obj-$(CONFIG_NEW_LEDS) += leds/ obj-$(CONFIG_INFINIBAND) += infiniband/ obj-$(CONFIG_SGI_SN) += sn/ --- linux-2.6.24.orig/drivers/bluetooth/bt3c_cs.c +++ linux-2.6.24/drivers/bluetooth/bt3c_cs.c @@ -344,7 +344,10 @@ unsigned int iobase; int iir; - BUG_ON(!info->hdev); + if (!info || !info->hdev) { + BT_ERR("Call of irq %d for unknown device", irq); + return IRQ_NONE; + } iobase = info->p_dev->io.BasePort1; --- linux-2.6.24.orig/drivers/bluetooth/dtl1_cs.c +++ linux-2.6.24/drivers/bluetooth/dtl1_cs.c @@ -298,7 +298,10 @@ int boguscount = 0; int iir, lsr; - BUG_ON(!info->hdev); + if (!info || !info->hdev) { + BT_ERR("Call of irq %d for unknown device", irq); + return IRQ_NONE; + } iobase = info->p_dev->io.BasePort1; --- linux-2.6.24.orig/drivers/bluetooth/bcm203x.c +++ linux-2.6.24/drivers/bluetooth/bcm203x.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -42,7 +43,7 @@ #define BT_DBG(D...) #endif -#define VERSION "1.1" +#define VERSION "1.0" static int ignore = 0; @@ -71,7 +72,7 @@ unsigned long state; - struct work_struct work; + struct timer_list timer; struct urb *urb; unsigned char *buffer; @@ -104,7 +105,7 @@ data->state = BCM203X_SELECT_MEMORY; - schedule_work(&data->work); + mod_timer(&data->timer, jiffies + (HZ / 10)); break; case BCM203X_SELECT_MEMORY: @@ -157,10 +158,9 @@ } } -static void bcm203x_work(struct work_struct *work) +static void bcm203x_timer(unsigned long user_data) { - struct bcm203x_data *data = - container_of(work, struct bcm203x_data, work); + struct bcm203x_data *data = (struct bcm203x_data *) user_data; if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0) BT_ERR("Can't submit URB"); @@ -247,11 +247,13 @@ release_firmware(firmware); - INIT_WORK(&data->work, bcm203x_work); + init_timer(&data->timer); + data->timer.function = bcm203x_timer; + data->timer.data = (unsigned long) data; usb_set_intfdata(intf, data); - schedule_work(&data->work); + mod_timer(&data->timer, jiffies + HZ); return 0; } --- linux-2.6.24.orig/drivers/bluetooth/bluecard_cs.c +++ linux-2.6.24/drivers/bluetooth/bluecard_cs.c @@ -503,7 +503,10 @@ unsigned int iobase; unsigned char reg; - BUG_ON(!info->hdev); + if (!info || !info->hdev) { + BT_ERR("Call of irq %d for unknown device", irq); + return IRQ_NONE; + } if (!test_bit(CARD_READY, &(info->hw_state))) return IRQ_HANDLED; --- linux-2.6.24.orig/drivers/bluetooth/btuart_cs.c +++ linux-2.6.24/drivers/bluetooth/btuart_cs.c @@ -294,7 +294,10 @@ int boguscount = 0; int iir, lsr; - BUG_ON(!info->hdev); + if (!info || !info->hdev) { + BT_ERR("Call of irq %d for unknown device", irq); + return IRQ_NONE; + } iobase = info->p_dev->io.BasePort1; --- linux-2.6.24.orig/drivers/bluetooth/hci_usb.c +++ linux-2.6.24/drivers/bluetooth/hci_usb.c @@ -132,6 +132,13 @@ /* Dell laptop with Broadcom chip */ { USB_DEVICE(0x413c, 0x8126), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU }, + /* Dell Wireless 370 */ + { USB_DEVICE(0x413c, 0x8156), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU }, + /* Dell Wireless 410 */ + { USB_DEVICE(0x413c, 0x8152), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU }, + + /* Broadcom 2046 */ + { USB_DEVICE(0x0a5c, 0x2151), .driver_info = HCI_RESET }, /* Microsoft Wireless Transceiver for Bluetooth 2.0 */ { USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET }, @@ -144,6 +151,7 @@ { USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET }, /* RTX Telecom based adapters with buggy SCO support */ + { USB_DEVICE(0x0e5e, 0x6622), .driver_info = HCI_BROKEN_ISOC }, { USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC }, { USB_DEVICE(0x0400, 0x080a), .driver_info = HCI_BROKEN_ISOC }, --- linux-2.6.24.orig/drivers/virtio/virtio.c +++ linux-2.6.24/drivers/virtio/virtio.c @@ -102,9 +102,13 @@ struct virtio_driver *drv = container_of(dev->dev.driver, struct virtio_driver, driver); - dev->config->set_status(dev, dev->config->get_status(dev) - & ~VIRTIO_CONFIG_S_DRIVER); drv->remove(dev); + + /* Driver should have reset device. */ + BUG_ON(dev->config->get_status(dev)); + + /* Acknowledge the device's existence again. */ + add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE); return 0; } @@ -130,6 +134,10 @@ dev->dev.bus = &virtio_bus; sprintf(dev->dev.bus_id, "%u", dev->index); + /* We always start by resetting the device, in case a previous + * driver messed it up. This also tests that code path a little. */ + dev->config->reset(dev); + /* Acknowledge that we've seen the device. */ add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE); @@ -148,55 +156,18 @@ } EXPORT_SYMBOL_GPL(unregister_virtio_device); -int __virtio_config_val(struct virtio_device *vdev, - u8 type, void *val, size_t size) -{ - void *token; - unsigned int len; - - token = vdev->config->find(vdev, type, &len); - if (!token) - return -ENOENT; - - if (len != size) - return -EIO; - - vdev->config->get(vdev, token, val, size); - return 0; -} -EXPORT_SYMBOL_GPL(__virtio_config_val); - -int virtio_use_bit(struct virtio_device *vdev, - void *token, unsigned int len, unsigned int bitnum) -{ - unsigned long bits[16]; - - /* This makes it convenient to pass-through find() results. */ - if (!token) - return 0; - - /* bit not in range of this bitfield? */ - if (bitnum * 8 >= len / 2) - return 0; - - /* Giant feature bitfields are silly. */ - BUG_ON(len > sizeof(bits)); - vdev->config->get(vdev, token, bits, len); - - if (!test_bit(bitnum, bits)) - return 0; - - /* Set acknowledge bit, and write it back. */ - set_bit(bitnum + len * 8 / 2, bits); - vdev->config->set(vdev, token, bits, len); - return 1; -} -EXPORT_SYMBOL_GPL(virtio_use_bit); - static int virtio_init(void) { if (bus_register(&virtio_bus) != 0) panic("virtio bus registration failed"); return 0; } + +static void __exit virtio_exit(void) +{ + bus_unregister(&virtio_bus); +} core_initcall(virtio_init); +module_exit(virtio_exit); + +MODULE_LICENSE("GPL"); --- linux-2.6.24.orig/drivers/virtio/virtio_ring.c +++ linux-2.6.24/drivers/virtio/virtio_ring.c @@ -87,6 +87,8 @@ if (vq->num_free < out + in) { pr_debug("Can't add buf len %i - avail = %i\n", out + in, vq->num_free); + /* We notify *even if* VRING_USED_F_NO_NOTIFY is set here. */ + vq->notify(&vq->vq); END_USE(vq); return -ENOSPC; } @@ -97,16 +99,14 @@ head = vq->free_head; for (i = vq->free_head; out; i = vq->vring.desc[i].next, out--) { vq->vring.desc[i].flags = VRING_DESC_F_NEXT; - vq->vring.desc[i].addr = (page_to_pfn(sg_page(sg))<offset; + vq->vring.desc[i].addr = sg_phys(sg); vq->vring.desc[i].len = sg->length; prev = i; sg++; } for (; in; i = vq->vring.desc[i].next, in--) { vq->vring.desc[i].flags = VRING_DESC_F_NEXT|VRING_DESC_F_WRITE; - vq->vring.desc[i].addr = (page_to_pfn(sg_page(sg))<offset; + vq->vring.desc[i].addr = sg_phys(sg); vq->vring.desc[i].len = sg->length; prev = i; sg++; @@ -171,16 +171,6 @@ vq->num_free++; } -/* FIXME: We need to tell other side about removal, to synchronize. */ -static void vring_shutdown(struct virtqueue *_vq) -{ - struct vring_virtqueue *vq = to_vvq(_vq); - unsigned int i; - - for (i = 0; i < vq->vring.num; i++) - detach_buf(vq, i); -} - static inline bool more_used(const struct vring_virtqueue *vq) { return vq->last_used_idx != vq->vring.used->idx; @@ -220,7 +210,14 @@ return ret; } -static bool vring_restart(struct virtqueue *_vq) +static void vring_disable_cb(struct virtqueue *_vq) +{ + struct vring_virtqueue *vq = to_vvq(_vq); + + vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; +} + +static bool vring_enable_cb(struct virtqueue *_vq) { struct vring_virtqueue *vq = to_vvq(_vq); @@ -232,7 +229,6 @@ vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT; mb(); if (unlikely(more_used(vq))) { - vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; END_USE(vq); return false; } @@ -253,26 +249,34 @@ if (unlikely(vq->broken)) return IRQ_HANDLED; + /* Other side may have missed us turning off the interrupt, + * but we should preserve disable semantic for virtio users. */ + if (unlikely(vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT)) { + pr_debug("virtqueue interrupt after disable for %p\n", vq); + return IRQ_HANDLED; + } + pr_debug("virtqueue callback for %p (%p)\n", vq, vq->vq.callback); - if (vq->vq.callback && !vq->vq.callback(&vq->vq)) - vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; + if (vq->vq.callback) + vq->vq.callback(&vq->vq); return IRQ_HANDLED; } +EXPORT_SYMBOL_GPL(vring_interrupt); static struct virtqueue_ops vring_vq_ops = { .add_buf = vring_add_buf, .get_buf = vring_get_buf, .kick = vring_kick, - .restart = vring_restart, - .shutdown = vring_shutdown, + .disable_cb = vring_disable_cb, + .enable_cb = vring_enable_cb, }; struct virtqueue *vring_new_virtqueue(unsigned int num, struct virtio_device *vdev, void *pages, void (*notify)(struct virtqueue *), - bool (*callback)(struct virtqueue *)) + void (*callback)(struct virtqueue *)) { struct vring_virtqueue *vq; unsigned int i; @@ -311,9 +315,12 @@ return &vq->vq; } +EXPORT_SYMBOL_GPL(vring_new_virtqueue); void vring_del_virtqueue(struct virtqueue *vq) { kfree(to_vvq(vq)); } +EXPORT_SYMBOL_GPL(vring_del_virtqueue); +MODULE_LICENSE("GPL"); --- linux-2.6.24.orig/drivers/virtio/Kconfig +++ linux-2.6.24/drivers/virtio/Kconfig @@ -1,8 +1,35 @@ # Virtio always gets selected by whoever wants it. config VIRTIO - bool + tristate # Similarly the virtio ring implementation. config VIRTIO_RING - bool + tristate depends on VIRTIO + +config VIRTIO_PCI + tristate "PCI driver for virtio devices (EXPERIMENTAL)" + depends on PCI && EXPERIMENTAL + select VIRTIO + select VIRTIO_RING + ---help--- + This drivers provides support for virtio based paravirtual device + drivers over PCI. This requires that your VMM has appropriate PCI + virtio backends. Most QEMU based VMMs should support these devices + (like KVM or Xen). + + Currently, the ABI is not considered stable so there is no guarantee + that this version of the driver will work with your VMM. + + If unsure, say M. + +config VIRTIO_BALLOON + tristate "Virtio balloon driver (EXPERIMENTAL)" + select VIRTIO + select VIRTIO_RING + ---help--- + This driver supports increasing and decreasing the amount + of memory within a KVM guest. + + If unsure, say M. + --- linux-2.6.24.orig/drivers/virtio/Makefile +++ linux-2.6.24/drivers/virtio/Makefile @@ -1,2 +1,4 @@ obj-$(CONFIG_VIRTIO) += virtio.o obj-$(CONFIG_VIRTIO_RING) += virtio_ring.o +obj-$(CONFIG_VIRTIO_PCI) += virtio_pci.o +obj-$(CONFIG_VIRTIO_BALLOON) += virtio_balloon.o --- linux-2.6.24.orig/drivers/virtio/virtio_pci.c +++ linux-2.6.24/drivers/virtio/virtio_pci.c @@ -0,0 +1,450 @@ +/* + * Virtio PCI driver + * + * This module allows virtio devices to be used over a virtual PCI device. + * This can be used with QEMU based VMMs like KVM or Xen. + * + * Copyright IBM Corp. 2007 + * + * Authors: + * Anthony Liguori + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_AUTHOR("Anthony Liguori "); +MODULE_DESCRIPTION("virtio-pci"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("1"); + +/* Our device structure */ +struct virtio_pci_device +{ + struct virtio_device vdev; + struct pci_dev *pci_dev; + + /* the IO mapping for the PCI config space */ + void __iomem *ioaddr; + + /* a list of queues so we can dispatch IRQs */ + spinlock_t lock; + struct list_head virtqueues; +}; + +struct virtio_pci_vq_info +{ + /* the actual virtqueue */ + struct virtqueue *vq; + + /* the number of entries in the queue */ + int num; + + /* the index of the queue */ + int queue_index; + + /* the virtual address of the ring queue */ + void *queue; + + /* the list node for the virtqueues list */ + struct list_head node; +}; + +/* Qumranet donated their vendor ID for devices 0x1000 thru 0x10FF. */ +static struct pci_device_id virtio_pci_id_table[] = { + { 0x1af4, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { 0 }, +}; + +MODULE_DEVICE_TABLE(pci, virtio_pci_id_table); + +/* A PCI device has it's own struct device and so does a virtio device so + * we create a place for the virtio devices to show up in sysfs. I think it + * would make more sense for virtio to not insist on having it's own device. */ +static struct device virtio_pci_root = { + .parent = NULL, + .bus_id = "virtio-pci", +}; + +/* Unique numbering for devices under the kvm root */ +static unsigned int dev_index; + +/* Convert a generic virtio device to our structure */ +static struct virtio_pci_device *to_vp_device(struct virtio_device *vdev) +{ + return container_of(vdev, struct virtio_pci_device, vdev); +} + +/* virtio config->feature() implementation */ +static bool vp_feature(struct virtio_device *vdev, unsigned bit) +{ + struct virtio_pci_device *vp_dev = to_vp_device(vdev); + u32 mask; + + /* Since this function is supposed to have the side effect of + * enabling a queried feature, we simulate that by doing a read + * from the host feature bitmask and then writing to the guest + * feature bitmask */ + mask = ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES); + if (mask & (1 << bit)) { + mask |= (1 << bit); + iowrite32(mask, vp_dev->ioaddr + VIRTIO_PCI_GUEST_FEATURES); + } + + return !!(mask & (1 << bit)); +} + +/* virtio config->get() implementation */ +static void vp_get(struct virtio_device *vdev, unsigned offset, + void *buf, unsigned len) +{ + struct virtio_pci_device *vp_dev = to_vp_device(vdev); + void __iomem *ioaddr = vp_dev->ioaddr + VIRTIO_PCI_CONFIG + offset; + u8 *ptr = buf; + int i; + + for (i = 0; i < len; i++) + ptr[i] = ioread8(ioaddr + i); +} + +/* the config->set() implementation. it's symmetric to the config->get() + * implementation */ +static void vp_set(struct virtio_device *vdev, unsigned offset, + const void *buf, unsigned len) +{ + struct virtio_pci_device *vp_dev = to_vp_device(vdev); + void __iomem *ioaddr = vp_dev->ioaddr + VIRTIO_PCI_CONFIG + offset; + const u8 *ptr = buf; + int i; + + for (i = 0; i < len; i++) + iowrite8(ptr[i], ioaddr + i); +} + +/* config->{get,set}_status() implementations */ +static u8 vp_get_status(struct virtio_device *vdev) +{ + struct virtio_pci_device *vp_dev = to_vp_device(vdev); + return ioread8(vp_dev->ioaddr + VIRTIO_PCI_STATUS); +} + +static void vp_set_status(struct virtio_device *vdev, u8 status) +{ + struct virtio_pci_device *vp_dev = to_vp_device(vdev); + /* We should never be setting status to 0. */ + BUG_ON(status == 0); + return iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS); +} + +static void vp_reset(struct virtio_device *vdev) +{ + struct virtio_pci_device *vp_dev = to_vp_device(vdev); + /* 0 status means a reset. */ + return iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS); +} + +/* the notify function used when creating a virt queue */ +static void vp_notify(struct virtqueue *vq) +{ + struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev); + struct virtio_pci_vq_info *info = vq->priv; + + /* we write the queue's selector into the notification register to + * signal the other end */ + iowrite16(info->queue_index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_NOTIFY); +} + +/* A small wrapper to also acknowledge the interrupt when it's handled. + * I really need an EIO hook for the vring so I can ack the interrupt once we + * know that we'll be handling the IRQ but before we invoke the callback since + * the callback may notify the host which results in the host attempting to + * raise an interrupt that we would then mask once we acknowledged the + * interrupt. */ +static irqreturn_t vp_interrupt(int irq, void *opaque) +{ + struct virtio_pci_device *vp_dev = opaque; + struct virtio_pci_vq_info *info; + irqreturn_t ret = IRQ_NONE; + unsigned long flags; + u8 isr; + + /* reading the ISR has the effect of also clearing it so it's very + * important to save off the value. */ + isr = ioread8(vp_dev->ioaddr + VIRTIO_PCI_ISR); + + /* It's definitely not us if the ISR was not high */ + if (!isr) + return IRQ_NONE; + + /* Configuration change? Tell driver if it wants to know. */ + if (isr & VIRTIO_PCI_ISR_CONFIG) { + struct virtio_driver *drv; + drv = container_of(vp_dev->vdev.dev.driver, + struct virtio_driver, driver); + + if (drv->config_changed) + drv->config_changed(&vp_dev->vdev); + } + + spin_lock_irqsave(&vp_dev->lock, flags); + list_for_each_entry(info, &vp_dev->virtqueues, node) { + if (vring_interrupt(irq, info->vq) == IRQ_HANDLED) + ret = IRQ_HANDLED; + } + spin_unlock_irqrestore(&vp_dev->lock, flags); + + return ret; +} + +/* the config->find_vq() implementation */ +static struct virtqueue *vp_find_vq(struct virtio_device *vdev, unsigned index, + void (*callback)(struct virtqueue *vq)) +{ + struct virtio_pci_device *vp_dev = to_vp_device(vdev); + struct virtio_pci_vq_info *info; + struct virtqueue *vq; + unsigned long flags; + u16 num; + int err; + + /* Select the queue we're interested in */ + iowrite16(index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_SEL); + + /* Check if queue is either not available or already active. */ + num = ioread16(vp_dev->ioaddr + VIRTIO_PCI_QUEUE_NUM); + if (!num || ioread32(vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN)) + return ERR_PTR(-ENOENT); + + /* allocate and fill out our structure the represents an active + * queue */ + info = kmalloc(sizeof(struct virtio_pci_vq_info), GFP_KERNEL); + if (!info) + return ERR_PTR(-ENOMEM); + + info->queue_index = index; + info->num = num; + + info->queue = kzalloc(PAGE_ALIGN(vring_size(num,PAGE_SIZE)), GFP_KERNEL); + if (info->queue == NULL) { + err = -ENOMEM; + goto out_info; + } + + /* activate the queue */ + iowrite32(virt_to_phys(info->queue) >> PAGE_SHIFT, + vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); + + /* create the vring */ + vq = vring_new_virtqueue(info->num, vdev, info->queue, + vp_notify, callback); + if (!vq) { + err = -ENOMEM; + goto out_activate_queue; + } + + vq->priv = info; + info->vq = vq; + + spin_lock_irqsave(&vp_dev->lock, flags); + list_add(&info->node, &vp_dev->virtqueues); + spin_unlock_irqrestore(&vp_dev->lock, flags); + + return vq; + +out_activate_queue: + iowrite32(0, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); + kfree(info->queue); +out_info: + kfree(info); + return ERR_PTR(err); +} + +/* the config->del_vq() implementation */ +static void vp_del_vq(struct virtqueue *vq) +{ + struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev); + struct virtio_pci_vq_info *info = vq->priv; + unsigned long flags; + + spin_lock_irqsave(&vp_dev->lock, flags); + list_del(&info->node); + spin_unlock_irqrestore(&vp_dev->lock, flags); + + vring_del_virtqueue(vq); + + /* Select and deactivate the queue */ + iowrite16(info->queue_index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_SEL); + iowrite32(0, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); + + kfree(info->queue); + kfree(info); +} + +static struct virtio_config_ops virtio_pci_config_ops = { + .feature = vp_feature, + .get = vp_get, + .set = vp_set, + .get_status = vp_get_status, + .set_status = vp_set_status, + .reset = vp_reset, + .find_vq = vp_find_vq, + .del_vq = vp_del_vq, +}; + +/* the PCI probing function */ +static int __devinit virtio_pci_probe(struct pci_dev *pci_dev, + const struct pci_device_id *id) +{ + struct virtio_pci_device *vp_dev; + int err; + + /* We only own devices >= 0x1000 and <= 0x103f: leave the rest. */ + if (pci_dev->device < 0x1000 || pci_dev->device > 0x103f) + return -ENODEV; + + if (pci_dev->revision != VIRTIO_PCI_ABI_VERSION) { + printk(KERN_ERR "virtio_pci: expected ABI version %d, got %d\n", + VIRTIO_PCI_ABI_VERSION, pci_dev->revision); + return -ENODEV; + } + + /* allocate our structure and fill it out */ + vp_dev = kzalloc(sizeof(struct virtio_pci_device), GFP_KERNEL); + if (vp_dev == NULL) + return -ENOMEM; + + snprintf(vp_dev->vdev.dev.bus_id, BUS_ID_SIZE, "virtio%d", dev_index); + vp_dev->vdev.index = dev_index; + dev_index++; + + vp_dev->vdev.dev.parent = &virtio_pci_root; + vp_dev->vdev.config = &virtio_pci_config_ops; + vp_dev->pci_dev = pci_dev; + INIT_LIST_HEAD(&vp_dev->virtqueues); + spin_lock_init(&vp_dev->lock); + + /* enable the device */ + err = pci_enable_device(pci_dev); + if (err) + goto out; + + err = pci_request_regions(pci_dev, "virtio-pci"); + if (err) + goto out_enable_device; + + vp_dev->ioaddr = pci_iomap(pci_dev, 0, 0); + if (vp_dev->ioaddr == NULL) + goto out_req_regions; + + pci_set_drvdata(pci_dev, vp_dev); + + /* we use the subsystem vendor/device id as the virtio vendor/device + * id. this allows us to use the same PCI vendor/device id for all + * virtio devices and to identify the particular virtio driver by + * the subsytem ids */ + vp_dev->vdev.id.vendor = pci_dev->subsystem_vendor; + vp_dev->vdev.id.device = pci_dev->subsystem_device; + + /* register a handler for the queue with the PCI device's interrupt */ + err = request_irq(vp_dev->pci_dev->irq, vp_interrupt, IRQF_SHARED, + vp_dev->vdev.dev.bus_id, vp_dev); + if (err) + goto out_set_drvdata; + + /* finally register the virtio device */ + err = register_virtio_device(&vp_dev->vdev); + if (err) + goto out_req_irq; + + return 0; + +out_req_irq: + free_irq(pci_dev->irq, vp_dev); +out_set_drvdata: + pci_set_drvdata(pci_dev, NULL); + pci_iounmap(pci_dev, vp_dev->ioaddr); +out_req_regions: + pci_release_regions(pci_dev); +out_enable_device: + pci_disable_device(pci_dev); +out: + kfree(vp_dev); + return err; +} + +static void __devexit virtio_pci_remove(struct pci_dev *pci_dev) +{ + struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); + + unregister_virtio_device(&vp_dev->vdev); + free_irq(pci_dev->irq, vp_dev); + pci_set_drvdata(pci_dev, NULL); + pci_iounmap(pci_dev, vp_dev->ioaddr); + pci_release_regions(pci_dev); + pci_disable_device(pci_dev); + kfree(vp_dev); +} + +#ifdef CONFIG_PM +static int virtio_pci_suspend(struct pci_dev *pci_dev, pm_message_t state) +{ + pci_save_state(pci_dev); + pci_set_power_state(pci_dev, PCI_D3hot); + return 0; +} + +static int virtio_pci_resume(struct pci_dev *pci_dev) +{ + pci_restore_state(pci_dev); + pci_set_power_state(pci_dev, PCI_D0); + return 0; +} +#endif + +static struct pci_driver virtio_pci_driver = { + .name = "virtio-pci", + .id_table = virtio_pci_id_table, + .probe = virtio_pci_probe, + .remove = virtio_pci_remove, +#ifdef CONFIG_PM + .suspend = virtio_pci_suspend, + .resume = virtio_pci_resume, +#endif +}; + +static int __init virtio_pci_init(void) +{ + int err; + + err = device_register(&virtio_pci_root); + if (err) + return err; + + err = pci_register_driver(&virtio_pci_driver); + if (err) + device_unregister(&virtio_pci_root); + + return err; +} + +module_init(virtio_pci_init); + +static void __exit virtio_pci_exit(void) +{ + device_unregister(&virtio_pci_root); + pci_unregister_driver(&virtio_pci_driver); +} + +module_exit(virtio_pci_exit); --- linux-2.6.24.orig/drivers/virtio/virtio_balloon.c +++ linux-2.6.24/drivers/virtio/virtio_balloon.c @@ -0,0 +1,285 @@ +/* Virtio balloon implementation, inspired by Dor Loar and Marcelo + * Tosatti's implementations. + * + * Copyright 2008 Rusty Russell IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +//#define DEBUG +#include +#include +#include +#include +#include +#include + +struct virtio_balloon +{ + struct virtio_device *vdev; + struct virtqueue *inflate_vq, *deflate_vq; + + /* Where the ballooning thread waits for config to change. */ + wait_queue_head_t config_change; + + /* The thread servicing the balloon. */ + struct task_struct *thread; + + /* Waiting for host to ack the pages we released. */ + struct completion acked; + + /* Do we have to tell Host *before* we reuse pages? */ + bool tell_host_first; + + /* The pages we've told the Host we're not using. */ + unsigned int num_pages; + struct list_head pages; + + /* The array of pfns we tell the Host about. */ + unsigned int num_pfns; + u32 pfns[256]; +}; + +static struct virtio_device_id id_table[] = { + { VIRTIO_ID_BALLOON, VIRTIO_DEV_ANY_ID }, + { 0 }, +}; + +static void balloon_ack(struct virtqueue *vq) +{ + struct virtio_balloon *vb; + unsigned int len; + + vb = vq->vq_ops->get_buf(vq, &len); + if (vb) + complete(&vb->acked); +} + +static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq) +{ + struct scatterlist sg; + + sg_init_one(&sg, vb->pfns, sizeof(vb->pfns[0]) * vb->num_pfns); + + init_completion(&vb->acked); + + /* We should always be able to add one buffer to an empty queue. */ + if (vq->vq_ops->add_buf(vq, &sg, 1, 0, vb) != 0) + BUG(); + vq->vq_ops->kick(vq); + + /* When host has read buffer, this completes via balloon_ack */ + wait_for_completion(&vb->acked); +} + +static void fill_balloon(struct virtio_balloon *vb, size_t num) +{ + /* We can only do one array worth at a time. */ + num = min(num, ARRAY_SIZE(vb->pfns)); + + for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) { + struct page *page = alloc_page(GFP_HIGHUSER | __GFP_NORETRY); + if (!page) { + if (printk_ratelimit()) + dev_printk(KERN_INFO, &vb->vdev->dev, + "Out of puff! Can't get %zu pages\n", + num); + /* Sleep for at least 1/5 of a second before retry. */ + msleep(200); + break; + } + vb->pfns[vb->num_pfns] = page_to_pfn(page); + totalram_pages--; + vb->num_pages++; + list_add(&page->lru, &vb->pages); + } + + /* Didn't get any? Oh well. */ + if (vb->num_pfns == 0) + return; + + tell_host(vb, vb->inflate_vq); +} + +static void release_pages_by_pfn(const u32 pfns[], unsigned int num) +{ + unsigned int i; + + for (i = 0; i < num; i++) { + __free_page(pfn_to_page(pfns[i])); + totalram_pages++; + } +} + +static void leak_balloon(struct virtio_balloon *vb, size_t num) +{ + struct page *page; + + /* We can only do one array worth at a time. */ + num = min(num, ARRAY_SIZE(vb->pfns)); + + for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) { + page = list_first_entry(&vb->pages, struct page, lru); + list_del(&page->lru); + vb->pfns[vb->num_pfns] = page_to_pfn(page); + vb->num_pages--; + } + + if (vb->tell_host_first) { + tell_host(vb, vb->deflate_vq); + release_pages_by_pfn(vb->pfns, vb->num_pfns); + } else { + release_pages_by_pfn(vb->pfns, vb->num_pfns); + tell_host(vb, vb->deflate_vq); + } +} + +static void virtballoon_changed(struct virtio_device *vdev) +{ + struct virtio_balloon *vb = vdev->priv; + + wake_up(&vb->config_change); +} + +static inline s64 towards_target(struct virtio_balloon *vb) +{ + u32 v; + __virtio_config_val(vb->vdev, + offsetof(struct virtio_balloon_config, num_pages), + &v); + return v - vb->num_pages; +} + +static void update_balloon_size(struct virtio_balloon *vb) +{ + __le32 actual = cpu_to_le32(vb->num_pages); + + vb->vdev->config->set(vb->vdev, + offsetof(struct virtio_balloon_config, actual), + &actual, sizeof(actual)); +} + +static int balloon(void *_vballoon) +{ + struct virtio_balloon *vb = _vballoon; + + set_freezable(); + while (!kthread_should_stop()) { + s64 diff; + + try_to_freeze(); + wait_event_interruptible(vb->config_change, + (diff = towards_target(vb)) != 0 + || kthread_should_stop()); + if (diff > 0) + fill_balloon(vb, diff); + else if (diff < 0) + leak_balloon(vb, -diff); + update_balloon_size(vb); + } + return 0; +} + +static int virtballoon_probe(struct virtio_device *vdev) +{ + struct virtio_balloon *vb; + int err; + + vdev->priv = vb = kmalloc(sizeof(*vb), GFP_KERNEL); + if (!vb) { + err = -ENOMEM; + goto out; + } + + INIT_LIST_HEAD(&vb->pages); + vb->num_pages = 0; + init_waitqueue_head(&vb->config_change); + vb->vdev = vdev; + + /* We expect two virtqueues. */ + vb->inflate_vq = vdev->config->find_vq(vdev, 0, balloon_ack); + if (IS_ERR(vb->inflate_vq)) { + err = PTR_ERR(vb->inflate_vq); + goto out_free_vb; + } + + vb->deflate_vq = vdev->config->find_vq(vdev, 1, balloon_ack); + if (IS_ERR(vb->deflate_vq)) { + err = PTR_ERR(vb->deflate_vq); + goto out_del_inflate_vq; + } + + vb->thread = kthread_run(balloon, vb, "vballoon"); + if (IS_ERR(vb->thread)) { + err = PTR_ERR(vb->thread); + goto out_del_deflate_vq; + } + + vb->tell_host_first + = vdev->config->feature(vdev, VIRTIO_BALLOON_F_MUST_TELL_HOST); + + return 0; + +out_del_deflate_vq: + vdev->config->del_vq(vb->deflate_vq); +out_del_inflate_vq: + vdev->config->del_vq(vb->inflate_vq); +out_free_vb: + kfree(vb); +out: + return err; +} + +static void virtballoon_remove(struct virtio_device *vdev) +{ + struct virtio_balloon *vb = vdev->priv; + + kthread_stop(vb->thread); + + /* There might be pages left in the balloon: free them. */ + while (vb->num_pages) + leak_balloon(vb, vb->num_pages); + + /* Now we reset the device so we can clean up the queues. */ + vdev->config->reset(vdev); + + vdev->config->del_vq(vb->deflate_vq); + vdev->config->del_vq(vb->inflate_vq); + kfree(vb); +} + +static struct virtio_driver virtio_balloon = { + .driver.name = KBUILD_MODNAME, + .driver.owner = THIS_MODULE, + .id_table = id_table, + .probe = virtballoon_probe, + .remove = __devexit_p(virtballoon_remove), + .config_changed = virtballoon_changed, +}; + +static int __init init(void) +{ + return register_virtio_driver(&virtio_balloon); +} + +static void __exit fini(void) +{ + unregister_virtio_driver(&virtio_balloon); +} +module_init(init); +module_exit(fini); + +MODULE_DEVICE_TABLE(virtio, id_table); +MODULE_DESCRIPTION("Virtio balloon driver"); +MODULE_LICENSE("GPL"); --- linux-2.6.24.orig/drivers/ata/ahci.c +++ linux-2.6.24/drivers/ata/ahci.c @@ -85,6 +85,7 @@ board_ahci_ign_iferr = 2, board_ahci_sb600 = 3, board_ahci_mv = 4, + board_ahci_sb700 = 5, /* global controller registers */ HOST_CAP = 0x00, /* host capabilities */ @@ -442,6 +443,16 @@ .udma_mask = ATA_UDMA6, .port_ops = &ahci_ops, }, + /* board_ahci_sb700 */ + { + AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | + AHCI_HFLAG_NO_PMP), + .flags = AHCI_FLAG_COMMON, + .link_flags = AHCI_LFLAG_COMMON, + .pio_mask = 0x1f, /* pio0-4 */ + .udma_mask = ATA_UDMA6, + .port_ops = &ahci_ops, + }, }; static const struct pci_device_id ahci_pci_tbl[] = { @@ -482,12 +493,12 @@ /* ATI */ { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */ - { PCI_VDEVICE(ATI, 0x4390), board_ahci_sb600 }, /* ATI SB700/800 */ - { PCI_VDEVICE(ATI, 0x4391), board_ahci_sb600 }, /* ATI SB700/800 */ - { PCI_VDEVICE(ATI, 0x4392), board_ahci_sb600 }, /* ATI SB700/800 */ - { PCI_VDEVICE(ATI, 0x4393), board_ahci_sb600 }, /* ATI SB700/800 */ - { PCI_VDEVICE(ATI, 0x4394), board_ahci_sb600 }, /* ATI SB700/800 */ - { PCI_VDEVICE(ATI, 0x4395), board_ahci_sb600 }, /* ATI SB700/800 */ + { PCI_VDEVICE(ATI, 0x4390), board_ahci_sb700 }, /* ATI SB700/800 */ + { PCI_VDEVICE(ATI, 0x4391), board_ahci_sb700 }, /* ATI SB700/800 */ + { PCI_VDEVICE(ATI, 0x4392), board_ahci_sb700 }, /* ATI SB700/800 */ + { PCI_VDEVICE(ATI, 0x4393), board_ahci_sb700 }, /* ATI SB700/800 */ + { PCI_VDEVICE(ATI, 0x4394), board_ahci_sb700 }, /* ATI SB700/800 */ + { PCI_VDEVICE(ATI, 0x4395), board_ahci_sb700 }, /* ATI SB700/800 */ /* VIA */ { PCI_VDEVICE(VIA, 0x3349), board_ahci_vt8251 }, /* VIA VT8251 */ @@ -579,6 +590,11 @@ }; +static inline int ahci_zero_nr_ports(u32 cap) +{ + return cap & ~0x1f; +} + static inline int ahci_nr_ports(u32 cap) { return (cap & 0x1f) + 1; @@ -644,6 +660,15 @@ cap &= ~HOST_CAP_PMP; } + if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361 && + port_map != 1) { + dev_printk(KERN_INFO, &pdev->dev, + "JMB361 has only one port, port_map 0x%x -> 0x%x\n", + port_map, 1); + port_map = 1; + cap = ahci_zero_nr_ports(cap); + } + /* * Temporary Marvell 6145 hack: PATA port presence * is asserted through the standard AHCI port @@ -1922,7 +1947,7 @@ void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; u32 ctl; - if (mesg.event == PM_EVENT_SUSPEND) { + if (mesg.event & PM_EVENT_SLEEP) { /* AHCI spec rev1.1 section 8.3.3: * Software must disable interrupts prior to requesting a * transition of the HBA to D3 state. --- linux-2.6.24.orig/drivers/ata/libata-core.c +++ linux-2.6.24/drivers/ata/libata-core.c @@ -103,9 +103,9 @@ module_param_named(fua, libata_fua, int, 0444); MODULE_PARM_DESC(fua, "FUA support (0=off, 1=on)"); -static int ata_ignore_hpa; +static int ata_ignore_hpa = 1; module_param_named(ignore_hpa, ata_ignore_hpa, int, 0644); -MODULE_PARM_DESC(ignore_hpa, "Ignore HPA limit (0=keep BIOS limits, 1=ignore limits, using full disk)"); +MODULE_PARM_DESC(ignore_hpa, "Ignore HPA limit (0=keep BIOS limits, 1=ignore limits, using full disk, default)"); static int libata_dma_mask = ATA_DMA_MASK_ATA|ATA_DMA_MASK_ATAPI|ATA_DMA_MASK_CFA; module_param_named(dma, libata_dma_mask, int, 0444); @@ -947,8 +947,8 @@ if (r_err) *r_err = err; - /* see if device passed diags: if master then continue and warn later */ - if (err == 0 && dev->devno == 0) + /* see if device passed diags: continue and warn later */ + if (err == 0) /* diagnostic fail : do nothing _YET_ */ dev->horkage |= ATA_HORKAGE_DIAGNOSTIC; else if (err == 1) @@ -1936,24 +1936,34 @@ id, sizeof(id[0]) * ATA_ID_WORDS, 0); if (err_mask) { if (err_mask & AC_ERR_NODEV_HINT) { - DPRINTK("ata%u.%d: NODEV after polling detection\n", - ap->print_id, dev->devno); + ata_dev_printk(dev, KERN_DEBUG, + "NODEV after polling detection\n"); return -ENOENT; } - /* Device or controller might have reported the wrong - * device class. Give a shot at the other IDENTIFY if - * the current one is aborted by the device. - */ - if (may_fallback && - (err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) { - may_fallback = 0; + if ((err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) { + /* Device or controller might have reported + * the wrong device class. Give a shot at the + * other IDENTIFY if the current one is + * aborted by the device. + */ + if (may_fallback) { + may_fallback = 0; - if (class == ATA_DEV_ATA) - class = ATA_DEV_ATAPI; - else - class = ATA_DEV_ATA; - goto retry; + if (class == ATA_DEV_ATA) + class = ATA_DEV_ATAPI; + else + class = ATA_DEV_ATA; + goto retry; + } + + /* Control reaches here iff the device aborted + * both flavors of IDENTIFYs which happens + * sometimes with phantom devices. + */ + ata_dev_printk(dev, KERN_DEBUG, + "both IDENTIFYs aborted, assuming NODEV\n"); + return -ENOENT; } rc = -EIO; @@ -2295,19 +2305,8 @@ dev->flags |= ATA_DFLAG_DIPM; } - if (dev->horkage & ATA_HORKAGE_DIAGNOSTIC) { - /* Let the user know. We don't want to disallow opens for - rescue purposes, or in case the vendor is just a blithering - idiot */ - if (print_info) { - ata_dev_printk(dev, KERN_WARNING, -"Drive reports diagnostics failure. This may indicate a drive\n"); - ata_dev_printk(dev, KERN_WARNING, -"fault or invalid emulation. Contact drive vendor for information.\n"); - } - } - - /* limit bridge transfers to udma5, 200 sectors */ + /* Limit PATA drive on SATA cable bridge transfers to udma5, + 200 sectors */ if (ata_dev_knobble(dev)) { if (ata_msg_drv(ap) && print_info) ata_dev_printk(dev, KERN_INFO, @@ -2336,6 +2335,21 @@ if (ap->ops->dev_config) ap->ops->dev_config(dev); + if (dev->horkage & ATA_HORKAGE_DIAGNOSTIC) { + /* Let the user know. We don't want to disallow opens for + rescue purposes, or in case the vendor is just a blithering + idiot. Do this after the dev_config call as some controllers + with buggy firmware may want to avoid reporting false device + bugs */ + + if (print_info) { + ata_dev_printk(dev, KERN_WARNING, +"Drive reports diagnostics failure. This may indicate a drive\n"); + ata_dev_printk(dev, KERN_WARNING, +"fault or invalid emulation. Contact drive vendor for information.\n"); + } + } + if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, "%s: EXIT, drv_stat = 0x%x\n", __FUNCTION__, ata_chk_status(ap)); @@ -3039,7 +3053,7 @@ /* Early MWDMA devices do DMA but don't allow DMA mode setting. Don't fail an MWDMA0 set IFF the device indicates it is in MWDMA0 */ - if (dev->xfer_shift == ATA_SHIFT_MWDMA && + if (dev->xfer_shift == ATA_SHIFT_MWDMA && dev->dma_mode == XFER_MW_DMA_0 && (dev->id[63] >> 8) & 1) err_mask &= ~AC_ERR_DEV; @@ -4144,6 +4158,9 @@ /* NCQ is slow */ { "WDC WD740ADFD-00", NULL, ATA_HORKAGE_NONCQ }, { "WDC WD740ADFD-00NLR1", NULL, ATA_HORKAGE_NONCQ, }, + /* See also: http://lkml.org/lkml/2007/10/17/380 */ + { "WDC WD1500ADFD-0*", NULL, ATA_HORKAGE_NONCQ }, + { "WDC WD5000AAKS-0*", NULL, ATA_HORKAGE_NONCQ }, /* http://thread.gmane.org/gmane.linux.ide/14907 */ { "FUJITSU MHT2060BH", NULL, ATA_HORKAGE_NONCQ }, /* NCQ is broken */ @@ -4159,6 +4176,25 @@ { "HTS541060G9SA00", "MB3OC60D", ATA_HORKAGE_NONCQ, }, { "HTS541080G9SA00", "MB4OC60D", ATA_HORKAGE_NONCQ, }, { "HTS541010G9SA00", "MBZOC60D", ATA_HORKAGE_NONCQ, }, + /* Drives which do spurious command completion */ + { "HTS541680J9SA00", "SB2IC7EP", ATA_HORKAGE_NONCQ, }, + { "HTS541612J9SA00", "SBDIC7JP", ATA_HORKAGE_NONCQ, }, + { "HDT722516DLA380", "V43OA96A", ATA_HORKAGE_NONCQ, }, + { "Hitachi HTS541616J9SA00", "SB4OC70P", ATA_HORKAGE_NONCQ, }, + { "Hitachi HTS542525K9SA00", "BBFOC31P", ATA_HORKAGE_NONCQ, }, + { "HTS722012K9A300", "DCCOC54P", ATA_HORKAGE_NONCQ, }, + { "WDC WD740ADFD-00NLR1", NULL, ATA_HORKAGE_NONCQ, }, + { "WDC WD3200AAJS-00RYA0", "12.01B01", ATA_HORKAGE_NONCQ, }, + { "FUJITSU MHV2080BH", "00840028", ATA_HORKAGE_NONCQ, }, + { "ST9120822AS", "3.CLF", ATA_HORKAGE_NONCQ, }, + { "ST9160821AS", "3.CLF", ATA_HORKAGE_NONCQ, }, + { "ST9160821AS", "3.ALD", ATA_HORKAGE_NONCQ, }, + { "ST9160821AS", "3.CCD", ATA_HORKAGE_NONCQ, }, + { "ST3160812AS", "3.ADJ", ATA_HORKAGE_NONCQ, }, + { "ST980813AS", "3.ADB", ATA_HORKAGE_NONCQ, }, + { "SAMSUNG HD401LJ", "ZZ100-15", ATA_HORKAGE_NONCQ, }, + { "Maxtor 7V300F0", "VA111900", ATA_HORKAGE_NONCQ, }, + { "FUJITSU MHW2160BH PL", "0084001E", ATA_HORKAGE_NONCQ, }, /* devices which puke on READ_NATIVE_MAX */ { "HDS724040KLSA80", "KFAOA20N", ATA_HORKAGE_BROKEN_HPA, }, @@ -7388,7 +7424,7 @@ pci_save_state(pdev); pci_disable_device(pdev); - if (mesg.event == PM_EVENT_SUSPEND) + if (mesg.event & PM_EVENT_SLEEP) pci_set_power_state(pdev, PCI_D3hot); } --- linux-2.6.24.orig/drivers/ata/sata_nv.c +++ linux-2.6.24/drivers/ata/sata_nv.c @@ -1011,14 +1011,20 @@ } if (status & (NV_ADMA_STAT_DONE | - NV_ADMA_STAT_CPBERR)) { - u32 check_commands; + NV_ADMA_STAT_CPBERR | + NV_ADMA_STAT_CMD_COMPLETE)) { + u32 check_commands = notifier_clears[i]; int pos, error = 0; - if (ata_tag_valid(ap->link.active_tag)) - check_commands = 1 << ap->link.active_tag; - else - check_commands = ap->link.sactive; + if (status & NV_ADMA_STAT_CPBERR) { + /* Check all active commands */ + if (ata_tag_valid(ap->link.active_tag)) + check_commands = 1 << + ap->link.active_tag; + else + check_commands = ap-> + link.sactive; + } /** Check CPBs for completed commands */ while ((pos = ffs(check_commands)) && !error) { --- linux-2.6.24.orig/drivers/ata/ata_piix.c +++ linux-2.6.24/drivers/ata/ata_piix.c @@ -700,6 +700,8 @@ { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */ { 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */ { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */ + { 0x24CA, 0x1025, 0x003d }, /* ICH4 on Acer TM290 */ + { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */ /* end marker */ { 0, } }; @@ -1129,7 +1131,7 @@ * cycles and power trying to do something to the sleeping * beauty. */ - if (piix_broken_suspend() && mesg.event == PM_EVENT_SUSPEND) { + if (piix_broken_suspend() && (mesg.event & PM_EVENT_SLEEP)) { pci_save_state(pdev); /* mark its power state as "unknown", since we don't --- linux-2.6.24.orig/drivers/ata/pata_hpt37x.c +++ linux-2.6.24/drivers/ata/pata_hpt37x.c @@ -24,7 +24,7 @@ #include #define DRV_NAME "pata_hpt37x" -#define DRV_VERSION "0.6.9" +#define DRV_VERSION "0.6.11" struct hpt_clock { u8 xfer_speed; @@ -281,7 +281,7 @@ if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33)) mask &= ~ATA_MASK_UDMA; if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5)) - mask &= ~(0x1F << ATA_SHIFT_UDMA); + mask &= ~(0xE0 << ATA_SHIFT_UDMA); } return ata_pci_default_filter(adev, mask); } @@ -297,7 +297,7 @@ { if (adev->class == ATA_DEV_ATA) { if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5)) - mask &= ~ (0x1F << ATA_SHIFT_UDMA); + mask &= ~(0xE0 << ATA_SHIFT_UDMA); } return ata_pci_default_filter(adev, mask); } --- linux-2.6.24.orig/drivers/ata/pata_serverworks.c +++ linux-2.6.24/drivers/ata/pata_serverworks.c @@ -226,7 +226,7 @@ for (i = 0; (p = csb_bad_ata100[i]) != NULL; i++) { if (!strcmp(p, model_num)) - mask &= ~(0x1F << ATA_SHIFT_UDMA); + mask &= ~(0xE0 << ATA_SHIFT_UDMA); } return ata_pci_default_filter(adev, mask); } --- linux-2.6.24.orig/drivers/ata/pata_it821x.c +++ linux-2.6.24/drivers/ata/pata_it821x.c @@ -430,7 +430,7 @@ return ata_qc_issue_prot(qc); } printk(KERN_DEBUG "it821x: can't process command 0x%02X\n", qc->tf.command); - return AC_ERR_INVALID; + return AC_ERR_DEV; } /** @@ -516,6 +516,37 @@ printk("(%dK stripe)", adev->id[146]); printk(".\n"); } + /* This is a controller firmware triggered funny, don't + report the drive faulty! */ + adev->horkage &= ~ATA_HORKAGE_DIAGNOSTIC; +} + +/** + * it821x_ident_hack - Hack identify data up + * @ap: Port + * + * Walk the devices on this firmware driven port and slightly + * mash the identify data to stop us and common tools trying to + * use features not firmware supported. The firmware itself does + * some masking (eg SMART) but not enough. + * + * This is a bit of an abuse of the cable method, but it is the + * only method called at the right time. We could modify the libata + * core specifically for ident hacking but while we have one offender + * it seems better to keep the fallout localised. + */ + +static int it821x_ident_hack(struct ata_port *ap) +{ + struct ata_device *adev; + ata_link_for_each_dev(adev, &ap->link) { + if (ata_dev_enabled(adev)) { + adev->id[84] &= ~(1 << 6); /* No FUA */ + adev->id[85] &= ~(1 << 10); /* No HPA */ + adev->id[76] = 0; /* No NCQ/AN etc */ + } + } + return ata_cable_unknown(ap); } @@ -634,7 +665,7 @@ .thaw = ata_bmdma_thaw, .error_handler = ata_bmdma_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, - .cable_detect = ata_cable_unknown, + .cable_detect = it821x_ident_hack, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, --- linux-2.6.24.orig/drivers/ata/pata_sis.c +++ linux-2.6.24/drivers/ata/pata_sis.c @@ -1006,6 +1006,7 @@ { PCI_VDEVICE(SI, 0x5513), }, /* SiS 5513 */ { PCI_VDEVICE(SI, 0x5518), }, /* SiS 5518 */ { PCI_VDEVICE(SI, 0x1180), }, /* SiS 1180 */ + { PCI_VDEVICE(SI, 0x1180), }, /* SiS 1180 */ { } }; --- linux-2.6.24.orig/drivers/ata/pata_hpt366.c +++ linux-2.6.24/drivers/ata/pata_hpt366.c @@ -27,7 +27,7 @@ #include #define DRV_NAME "pata_hpt366" -#define DRV_VERSION "0.6.1" +#define DRV_VERSION "0.6.2" struct hpt_clock { u8 xfer_speed; @@ -180,9 +180,9 @@ if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33)) mask &= ~ATA_MASK_UDMA; if (hpt_dma_blacklisted(adev, "UDMA3", bad_ata66_3)) - mask &= ~(0x07 << ATA_SHIFT_UDMA); + mask &= ~(0xF8 << ATA_SHIFT_UDMA); if (hpt_dma_blacklisted(adev, "UDMA4", bad_ata66_4)) - mask &= ~(0x0F << ATA_SHIFT_UDMA); + mask &= ~(0xF0 << ATA_SHIFT_UDMA); } return ata_pci_default_filter(adev, mask); } --- linux-2.6.24.orig/drivers/ata/libata-acpi.c +++ linux-2.6.24/drivers/ata/libata-acpi.c @@ -760,7 +760,8 @@ */ ata_link_for_each_dev(dev, &ap->link) { ata_acpi_clear_gtf(dev); - if (ata_dev_get_GTF(dev, NULL) >= 0) + if (ata_dev_enabled(dev) && + ata_dev_get_GTF(dev, NULL) >= 0) dev->flags |= ATA_DFLAG_ACPI_PENDING; } } else { @@ -770,7 +771,8 @@ */ ata_link_for_each_dev(dev, &ap->link) { ata_acpi_clear_gtf(dev); - dev->flags |= ATA_DFLAG_ACPI_PENDING; + if (ata_dev_enabled(dev)) + dev->flags |= ATA_DFLAG_ACPI_PENDING; } } } --- linux-2.6.24.orig/drivers/pci/pci.c +++ linux-2.6.24/drivers/pci/pci.c @@ -536,6 +536,7 @@ case PM_EVENT_PRETHAW: /* REVISIT both freeze and pre-thaw "should" use D0 */ case PM_EVENT_SUSPEND: + case PM_EVENT_HIBERNATE: return PCI_D3hot; default: printk("Unrecognized suspend event %d\n", state.event); --- linux-2.6.24.orig/drivers/pci/quirks.c +++ linux-2.6.24/drivers/pci/quirks.c @@ -187,10 +187,12 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, quirk_vialatency ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8371_1, quirk_vialatency ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_vialatency ); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C691_0, quirk_vialatency ); /* Must restore this on a resume from RAM */ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, quirk_vialatency ); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8371_1, quirk_vialatency ); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_vialatency ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C691_0, quirk_vialatency ); /* * VIA Apollo VP3 needs ETBF on BT848/878 @@ -869,13 +871,13 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb ); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb ); - -static void __devinit quirk_sb600_sata(struct pci_dev *pdev) +static void __devinit quirk_amd_ide_mode(struct pci_dev *pdev) { - /* set sb600 sata to ahci mode */ - if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) { - u8 tmp; + /* set sb600/sb700/sb800 sata to ahci mode */ + u8 tmp; + pci_read_config_byte(pdev, PCI_CLASS_DEVICE, &tmp); + if (tmp == 0x01) { pci_read_config_byte(pdev, 0x40, &tmp); pci_write_config_byte(pdev, 0x40, tmp|1); pci_write_config_byte(pdev, 0x9, 1); @@ -883,10 +885,13 @@ pci_write_config_byte(pdev, 0x40, tmp); pdev->class = PCI_CLASS_STORAGE_SATA_AHCI; + dev_info(&pdev->dev, "set SATA to AHCI mode\n"); } } -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_sb600_sata); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_sb600_sata); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode); /* * Serverworks CSB5 IDE does not fully support native mode @@ -950,6 +955,12 @@ * accesses to the SMBus registers, with potentially bad effects. Thus you * should be very careful when adding new entries: if SMM is accessing the * Intel SMBus, this is a very good reason to leave it hidden. + * + * Likewise, many recent laptops use ACPI for thermal management. If the + * ACPI DSDT code accesses the SMBus, then Linux should not access it + * natively, and keeping the SMBus hidden is the right thing to do. If you + * are about to add an entry in the table below, please first disassemble + * the DSDT and double-check that there is no code accessing the SMBus. */ static int asus_hides_smbus; @@ -1022,11 +1033,6 @@ case 0x12bd: /* HP D530 */ asus_hides_smbus = 1; } - else if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) - switch (dev->subsystem_device) { - case 0x099c: /* HP Compaq nx6110 */ - asus_hides_smbus = 1; - } } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG)) { if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB) switch(dev->subsystem_device) { @@ -1711,10 +1717,89 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, quirk_nvidia_ck804_msi_ht_cap); +/* + * Force enable MSI mapping capability on HT bridges */ +static inline void ht_enable_msi_mapping(struct pci_dev *dev) +{ + int pos, ttl = 48; + + pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); + while (pos && ttl--) { + u8 flags; + + if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, + &flags) == 0) { + dev_info(&dev->dev, "Enabling HT MSI Mapping\n"); + + pci_write_config_byte(dev, pos + HT_MSI_FLAGS, + flags | HT_MSI_FLAGS_ENABLE); + } + pos = pci_find_next_ht_capability(dev, pos, + HT_CAPTYPE_MSI_MAPPING); + } +} + +static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) +{ + struct pci_dev *host_bridge; + int pos, ttl = 48; + + /* + * HT MSI mapping should be disabled on devices that are below + * a non-Hypertransport host bridge. Locate the host bridge... + */ + host_bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)); + if (host_bridge == NULL) { + dev_warn(&dev->dev, + "nv_msi_ht_cap_quirk didn't locate host bridge\n"); + return; + } + + pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE); + if (pos != 0) { + /* Host bridge is to HT */ + ht_enable_msi_mapping(dev); + return; + } + + /* Host bridge is not to HT, disable HT MSI mapping on this device */ + pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); + while (pos && ttl--) { + u8 flags; + + if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, + &flags) == 0) { + dev_info(&dev->dev, "Quirk disabling HT MSI mapping"); + pci_write_config_byte(dev, pos + HT_MSI_FLAGS, + flags & ~HT_MSI_FLAGS_ENABLE); + } + pos = pci_find_next_ht_capability(dev, pos, + HT_CAPTYPE_MSI_MAPPING); + } +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk); + static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev) { dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG; } +static void __devinit quirk_msi_intx_disable_ati_bug(struct pci_dev *dev) +{ + struct pci_dev *p; + + /* SB700 MSI issue will be fixed at HW level from revision A21, + * we need check PCI REVISION ID of SMBus controller to get SB700 + * revision. + */ + p = pci_get_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, + NULL); + if (!p) + return; + + if ((p->revision < 0x3B) && (p->revision >= 0x30)) + dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG; + pci_dev_put(p); +} DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780, quirk_msi_intx_disable_bug); @@ -1735,17 +1820,15 @@ quirk_msi_intx_disable_bug); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4390, - quirk_msi_intx_disable_bug); + quirk_msi_intx_disable_ati_bug); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4391, - quirk_msi_intx_disable_bug); + quirk_msi_intx_disable_ati_bug); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4392, - quirk_msi_intx_disable_bug); + quirk_msi_intx_disable_ati_bug); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4393, - quirk_msi_intx_disable_bug); + quirk_msi_intx_disable_ati_bug); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4394, - quirk_msi_intx_disable_bug); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4395, - quirk_msi_intx_disable_bug); + quirk_msi_intx_disable_ati_bug); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4373, quirk_msi_intx_disable_bug); --- linux-2.6.24.orig/drivers/pci/pci.h +++ linux-2.6.24/drivers/pci/pci.h @@ -39,9 +39,11 @@ #ifdef CONFIG_PCI_MSI void pci_no_msi(void); +void pci_yes_msi(void); extern void pci_msi_init_pci_dev(struct pci_dev *dev); #else static inline void pci_no_msi(void) { } +static inline void pci_yes_msi(void) { } static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } #endif --- linux-2.6.24.orig/drivers/pci/setup-res.c +++ linux-2.6.24/drivers/pci/setup-res.c @@ -158,7 +158,7 @@ } if (ret) { - printk(KERN_ERR "PCI: Failed to allocate %s resource " + printk(KERN_WARNING "PCI: Failed to allocate %s resource " "#%d:%llx@%llx for %s\n", res->flags & IORESOURCE_IO ? "I/O" : "mem", resno, (unsigned long long)size, @@ -196,7 +196,7 @@ } if (ret) { - printk(KERN_ERR "PCI: Failed to allocate %s resource " + printk(KERN_WARNING "PCI: Failed to allocate %s resource " "#%d:%llx@%llx for %s\n", res->flags & IORESOURCE_IO ? "I/O" : "mem", resno, (unsigned long long)(res->end - res->start + 1), --- linux-2.6.24.orig/drivers/hwmon/coretemp.c +++ linux-2.6.24/drivers/hwmon/coretemp.c @@ -368,10 +368,10 @@ for_each_online_cpu(i) { struct cpuinfo_x86 *c = &cpu_data(i); - /* check if family 6, models e, f, 16 */ + /* check if family 6, models 0xe, 0xf, 0x16, 0x17 */ if ((c->cpuid_level < 0) || (c->x86 != 0x6) || !((c->x86_model == 0xe) || (c->x86_model == 0xf) || - (c->x86_model == 0x16))) { + (c->x86_model == 0x16) || (c->x86_model == 0x17))) { /* supported CPU not found, but report the unknown family 6 CPU */ --- linux-2.6.24.orig/drivers/hwmon/hdaps.c +++ linux-2.6.24/drivers/hwmon/hdaps.c @@ -521,10 +521,16 @@ HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T42"), HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T43"), HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T60"), + HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61"), HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X40"), HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X41"), HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60"), + HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61"), + HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61 Tablet"), HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad Z60m"), + HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T61P"), + HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R61"), + HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T61"), { .ident = NULL } }; --- linux-2.6.24.orig/drivers/hwmon/w83781d.c +++ linux-2.6.24/drivers/hwmon/w83781d.c @@ -1380,7 +1380,8 @@ /* Reserve the ISA region */ res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!request_region(res->start, W83781D_EXTENT, "w83781d")) { + if (!request_region(res->start + W83781D_ADDR_REG_OFFSET, 2, + "w83781d")) { err = -EBUSY; goto exit; } @@ -1432,7 +1433,7 @@ device_remove_file(&pdev->dev, &dev_attr_name); kfree(data); exit_release_region: - release_region(res->start, W83781D_EXTENT); + release_region(res->start + W83781D_ADDR_REG_OFFSET, 2); exit: return err; } @@ -1446,7 +1447,7 @@ sysfs_remove_group(&pdev->dev.kobj, &w83781d_group); sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt); device_remove_file(&pdev->dev, &dev_attr_name); - release_region(data->client.addr, W83781D_EXTENT); + release_region(data->client.addr + W83781D_ADDR_REG_OFFSET, 2); kfree(data); return 0; @@ -1820,8 +1821,17 @@ { int val, save, found = 0; - if (!request_region(address, W83781D_EXTENT, "w83781d")) + /* We have to request the region in two parts because some + boards declare base+4 to base+7 as a PNP device */ + if (!request_region(address, 4, "w83781d")) { + pr_debug("w83781d: Failed to request low part of region\n"); return 0; + } + if (!request_region(address + 4, 4, "w83781d")) { + pr_debug("w83781d: Failed to request high part of region\n"); + release_region(address, 4); + return 0; + } #define REALLY_SLOW_IO /* We need the timeouts for at least some W83781D-like @@ -1896,7 +1906,8 @@ val == 0x30 ? "W83782D" : "W83781D", (int)address); release: - release_region(address, W83781D_EXTENT); + release_region(address + 4, 4); + release_region(address, 4); return found; } --- linux-2.6.24.orig/drivers/macintosh/smu.c +++ linux-2.6.24/drivers/macintosh/smu.c @@ -85,6 +85,7 @@ u32 cmd_buf_abs; /* command buffer absolute */ struct list_head cmd_list; struct smu_cmd *cmd_cur; /* pending command */ + int broken_nap; struct list_head cmd_i2c_list; struct smu_i2c_cmd *cmd_i2c_cur; /* pending i2c command */ struct timer_list i2c_timer; @@ -135,6 +136,19 @@ fend = faddr + smu->cmd_buf->length + 2; flush_inval_dcache_range(faddr, fend); + + /* We also disable NAP mode for the duration of the command + * on U3 based machines. + * This is slightly racy as it can be written back to 1 by a sysctl + * but that never happens in practice. There seem to be an issue with + * U3 based machines such as the iMac G5 where napping for the + * whole duration of the command prevents the SMU from fetching it + * from memory. This might be related to the strange i2c based + * mechanism the SMU uses to access memory. + */ + if (smu->broken_nap) + powersave_nap = 0; + /* This isn't exactly a DMA mapping here, I suspect * the SMU is actually communicating with us via i2c to the * northbridge or the CPU to access RAM. @@ -211,6 +225,10 @@ misc = cmd->misc; mb(); cmd->status = rc; + + /* Re-enable NAP mode */ + if (smu->broken_nap) + powersave_nap = 1; bail: /* Start next command if any */ smu_start_cmd(); @@ -461,7 +479,7 @@ if (np == NULL) return -ENODEV; - printk(KERN_INFO "SMU driver %s %s\n", VERSION, AUTHOR); + printk(KERN_INFO "SMU: Driver %s %s\n", VERSION, AUTHOR); if (smu_cmdbuf_abs == 0) { printk(KERN_ERR "SMU: Command buffer not allocated !\n"); @@ -533,6 +551,11 @@ goto fail; } + /* U3 has an issue with NAP mode when issuing SMU commands */ + smu->broken_nap = pmac_get_uninorth_variant() < 4; + if (smu->broken_nap) + printk(KERN_INFO "SMU: using NAP mode workaround\n"); + sys_ctrler = SYS_CTRLER_SMU; return 0; --- linux-2.6.24.orig/drivers/macintosh/via-pmu.c +++ linux-2.6.24/drivers/macintosh/via-pmu.c @@ -2842,7 +2842,7 @@ EXPORT_SYMBOL(pmu_suspend); EXPORT_SYMBOL(pmu_resume); EXPORT_SYMBOL(pmu_unlock); -#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) +#if defined(CONFIG_PPC32) EXPORT_SYMBOL(pmu_enable_irled); EXPORT_SYMBOL(pmu_battery_count); EXPORT_SYMBOL(pmu_batteries); --- linux-2.6.24.orig/drivers/macintosh/mediabay.c +++ linux-2.6.24/drivers/macintosh/mediabay.c @@ -447,6 +447,7 @@ return -ENODEV; } +EXPORT_SYMBOL(check_media_bay_by_base); int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base, int irq, int index) @@ -487,6 +488,7 @@ return -ENODEV; } +EXPORT_SYMBOL(media_bay_set_ide_infos); static void media_bay_step(int i) { @@ -709,7 +711,8 @@ { struct media_bay_info *bay = macio_get_drvdata(mdev); - if (state.event != mdev->ofdev.dev.power.power_state.event && state.event == PM_EVENT_SUSPEND) { + if (state.event != mdev->ofdev.dev.power.power_state.event + && (state.event & PM_EVENT_SLEEP)) { down(&bay->lock); bay->sleeping = 1; set_mb_power(bay, 0); --- linux-2.6.24.orig/drivers/spi/atmel_spi.c +++ linux-2.6.24/drivers/spi/atmel_spi.c @@ -85,6 +85,16 @@ unsigned gpio = (unsigned) spi->controller_data; unsigned active = spi->mode & SPI_CS_HIGH; u32 mr; + int i; + u32 csr; + u32 cpol = (spi->mode & SPI_CPOL) ? SPI_BIT(CPOL) : 0; + + /* Make sure clock polarity is correct */ + for (i = 0; i < spi->master->num_chipselect; i++) { + csr = spi_readl(as, CSR0 + 4 * i); + if ((csr ^ cpol) & SPI_BIT(CPOL)) + spi_writel(as, CSR0 + 4 * i, csr ^ SPI_BIT(CPOL)); + } mr = spi_readl(as, MR); mr = SPI_BFINS(PCS, ~(1 << spi->chip_select), mr); --- linux-2.6.24.orig/drivers/spi/pxa2xx_spi.c +++ linux-2.6.24/drivers/spi/pxa2xx_spi.c @@ -48,13 +48,19 @@ #define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK) #define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0) -/* for testing SSCR1 changes that require SSP restart, basically - * everything except the service and interrupt enables */ -#define SSCR1_CHANGE_MASK (SSCR1_TTELP | SSCR1_TTE | SSCR1_EBCEI | SSCR1_SCFR \ +/* + * for testing SSCR1 changes that require SSP restart, basically + * everything except the service and interrupt enables, the pxa270 developer + * manual says only SSCR1_SCFR, SSCR1_SPH, SSCR1_SPO need to be in this + * list, but the PXA255 dev man says all bits without really meaning the + * service and interrupt enables + */ +#define SSCR1_CHANGE_MASK (SSCR1_TTELP | SSCR1_TTE | SSCR1_SCFR \ | SSCR1_ECRA | SSCR1_ECRB | SSCR1_SCLKDIR \ - | SSCR1_RWOT | SSCR1_TRAIL | SSCR1_PINTE \ - | SSCR1_STRF | SSCR1_EFWR |SSCR1_RFT \ - | SSCR1_TFT | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM) + | SSCR1_SFRMDIR | SSCR1_RWOT | SSCR1_TRAIL \ + | SSCR1_IFS | SSCR1_STRF | SSCR1_EFWR \ + | SSCR1_RFT | SSCR1_TFT | SSCR1_MWDS \ + | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM) #define DEFINE_SSP_REG(reg, off) \ static inline u32 read_##reg(void *p) { return __raw_readl(p + (off)); } \ @@ -961,9 +967,6 @@ if (drv_data->ssp_type == PXA25x_SSP) DCMD(drv_data->tx_channel) |= DCMD_ENDIRQEN; - /* Fix me, need to handle cs polarity */ - drv_data->cs_control(PXA2XX_CS_ASSERT); - /* Clear status and start DMA engine */ cr1 = chip->cr1 | dma_thresh | drv_data->dma_cr1; write_SSSR(drv_data->clear_sr, reg); @@ -973,9 +976,6 @@ /* Ensure we have the correct interrupt handler */ drv_data->transfer_handler = interrupt_transfer; - /* Fix me, need to handle cs polarity */ - drv_data->cs_control(PXA2XX_CS_ASSERT); - /* Clear status */ cr1 = chip->cr1 | chip->threshold | drv_data->int_cr1; write_SSSR(drv_data->clear_sr, reg); @@ -986,16 +986,29 @@ || (read_SSCR1(reg) & SSCR1_CHANGE_MASK) != (cr1 & SSCR1_CHANGE_MASK)) { + /* stop the SSP, and update the other bits */ write_SSCR0(cr0 & ~SSCR0_SSE, reg); if (drv_data->ssp_type != PXA25x_SSP) write_SSTO(chip->timeout, reg); - write_SSCR1(cr1, reg); + /* first set CR1 without interrupt and service enables */ + write_SSCR1(cr1 & SSCR1_CHANGE_MASK, reg); + /* restart the SSP */ write_SSCR0(cr0, reg); + } else { if (drv_data->ssp_type != PXA25x_SSP) write_SSTO(chip->timeout, reg); - write_SSCR1(cr1, reg); } + + /* FIXME, need to handle cs polarity, + * this driver uses struct pxa2xx_spi_chip.cs_control to + * specify a CS handling function, and it ignores most + * struct spi_device.mode[s], including SPI_CS_HIGH */ + drv_data->cs_control(PXA2XX_CS_ASSERT); + + /* after chip select, release the data by enabling service + * requests and interrupts, without changing any mode bits */ + write_SSCR1(cr1, reg); } static void pump_messages(struct work_struct *work) --- linux-2.6.24.orig/drivers/input/serio/i8042-x86ia64io.h +++ linux-2.6.24/drivers/input/serio/i8042-x86ia64io.h @@ -270,6 +270,13 @@ DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"), }, }, + { + .ident = "IBM 2656", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "IBM"), + DMI_MATCH(DMI_PRODUCT_NAME, "2656"), + }, + }, { } }; --- linux-2.6.24.orig/drivers/input/mouse/alps.c +++ linux-2.6.24/drivers/input/mouse/alps.c @@ -54,6 +54,7 @@ { { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */ { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */ + { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude E6500 */ { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FW_BK_1 } /* Dell Vostro 1400 */ }; @@ -421,7 +422,8 @@ static int alps_reconnect(struct psmouse *psmouse) { - psmouse_reset(psmouse); + /* UBUNTU: Causes lockups on resume */ + /* psmouse_reset(psmouse); */ if (alps_hw_init(psmouse, NULL)) return -1; --- linux-2.6.24.orig/drivers/input/mouse/appletouch.c +++ linux-2.6.24/drivers/input/mouse/appletouch.c @@ -62,6 +62,11 @@ #define GEYSER4_ISO_PRODUCT_ID 0x021B #define GEYSER4_JIS_PRODUCT_ID 0x021C +/* Updated codes for MacBook3,1 support */ +#define GEYSER4_HF_ANSI_PRODUCT_ID 0x0229 +#define GEYSER4_HF_ISO_PRODUCT_ID 0x022A +#define GEYSER4_HF_JIS_PRODUCT_ID 0x021B + #define ATP_DEVICE(prod) \ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ USB_DEVICE_ID_MATCH_INT_CLASS | \ @@ -93,6 +98,11 @@ { ATP_DEVICE(GEYSER4_ISO_PRODUCT_ID) }, { ATP_DEVICE(GEYSER4_JIS_PRODUCT_ID) }, + /* Core2 Duo MacBook3,1 */ + { ATP_DEVICE(GEYSER4_HF_ANSI_PRODUCT_ID) }, + { ATP_DEVICE(GEYSER4_HF_ISO_PRODUCT_ID) }, + { ATP_DEVICE(GEYSER4_HF_JIS_PRODUCT_ID) }, + /* Terminating entry */ { } }; @@ -217,7 +227,10 @@ (productId == GEYSER3_JIS_PRODUCT_ID) || (productId == GEYSER4_ANSI_PRODUCT_ID) || (productId == GEYSER4_ISO_PRODUCT_ID) || - (productId == GEYSER4_JIS_PRODUCT_ID); + (productId == GEYSER4_JIS_PRODUCT_ID) || + (productId == GEYSER4_HF_ANSI_PRODUCT_ID) || + (productId == GEYSER4_HF_ISO_PRODUCT_ID) || + (productId == GEYSER4_HF_JIS_PRODUCT_ID); } /* --- linux-2.6.24.orig/drivers/input/joystick/xpad.c +++ linux-2.6.24/drivers/input/joystick/xpad.c @@ -136,6 +136,7 @@ { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, + { 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, { 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, @@ -180,6 +181,7 @@ static struct usb_device_id xpad_table [] = { { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ { USB_DEVICE_INTERFACE_PROTOCOL(0x045e, 0x028e, 1) }, /* X-Box 360 controller */ + { USB_DEVICE_INTERFACE_PROTOCOL(0x1430, 0x4748, 1) }, /* RedOctane Guitar Hero X-plorer */ { } }; --- linux-2.6.24.orig/drivers/mtd/chips/cfi_cmdset_0001.c +++ linux-2.6.24/drivers/mtd/chips/cfi_cmdset_0001.c @@ -669,7 +669,7 @@ /* Someone else might have been playing with it. */ return -EAGAIN; } - + /* Fall through */ case FL_READY: case FL_CFI_QUERY: case FL_JEDEC_QUERY: @@ -729,14 +729,14 @@ chip->state = FL_READY; return 0; + case FL_SHUTDOWN: + /* The machine is rebooting now,so no one can get chip anymore */ + return -EIO; case FL_POINT: /* Only if there's no operation suspended... */ if (mode == FL_READY && chip->oldstate == FL_READY) return 0; - - case FL_SHUTDOWN: - /* The machine is rebooting now,so no one can get chip anymore */ - return -EIO; + /* Fall through */ default: sleep: set_current_state(TASK_UNINTERRUPTIBLE); --- linux-2.6.24.orig/drivers/mtd/devices/block2mtd.c +++ linux-2.6.24/drivers/mtd/devices/block2mtd.c @@ -408,7 +408,6 @@ if (token[1]) { ret = parse_num(&erase_size, token[1]); if (ret) { - kfree(name); parse_err("illegal erase size"); } } --- linux-2.6.24.orig/drivers/pcmcia/cs.c +++ linux-2.6.24/drivers/pcmcia/cs.c @@ -565,7 +565,10 @@ if (!(skt->state & SOCKET_PRESENT)) { skt->state &= ~SOCKET_SUSPEND; - return socket_insert(skt); + /* UBUNTU: This causes problems on resume. Userspace + * scripts take care of this. */ + /* return socket_insert(skt); */ + return 0; } ret = socket_setup(skt, resume_delay); --- linux-2.6.24.orig/drivers/ssb/driver_pcicore.c +++ linux-2.6.24/drivers/ssb/driver_pcicore.c @@ -517,7 +517,7 @@ } else { tmp = ssb_read32(dev, SSB_TPSFLAG); tmp &= SSB_TPSFLAG_BPFLAG; - intvec |= tmp; + intvec |= (1 << tmp); } ssb_write32(pdev, SSB_INTVEC, intvec); } --- linux-2.6.24.orig/drivers/ssb/pci.c +++ linux-2.6.24/drivers/ssb/pci.c @@ -426,6 +426,7 @@ SPEX(crc, SSB_SPROM_REVISION, SSB_SPROM_REVISION_CRC, SSB_SPROM_REVISION_CRC_SHIFT); + if ((bus->chip_id & 0xFF00) == 0x4400) { /* Workaround: The BCM44XX chip has a stupid revision * number stored in the SPROM. @@ -443,6 +444,10 @@ if (out->revision >= 4) goto unsupported; } + if (out->r1.boardflags_lo == 0xFFFF) + out->r1.boardflags_lo = 0; /* per specs */ + if (out->r2.boardflags_hi == 0xFFFF) + out->r2.boardflags_hi = 0; /* per specs */ return 0; unsupported: --- linux-2.6.24.orig/drivers/ssb/main.c +++ linux-2.6.24/drivers/ssb/main.c @@ -879,6 +879,11 @@ return SSB_TMSLOW_REJECT_22; case SSB_IDLOW_SSBREV_23: return SSB_TMSLOW_REJECT_23; + case SSB_IDLOW_SSBREV_24: /* TODO - find the proper REJECT bits */ + case SSB_IDLOW_SSBREV_25: /* same here */ + case SSB_IDLOW_SSBREV_26: /* same here */ + case SSB_IDLOW_SSBREV_27: /* same here */ + return SSB_TMSLOW_REJECT_23; /* this is a guess */ default: WARN_ON(1); } @@ -1032,6 +1037,12 @@ goto out; cc = &bus->chipco; + + if (!cc->dev) + goto out; + if (cc->dev->id.revision < 5) + goto out; + ssb_chipco_set_clockmode(cc, SSB_CLKMODE_SLOW); err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0); if (err) --- linux-2.6.24.orig/drivers/lguest/lguest_device.c +++ linux-2.6.24/drivers/lguest/lguest_device.c @@ -52,57 +52,82 @@ /*D:130 * Device configurations * - * The configuration information for a device consists of a series of fields. - * We don't really care what they are: the Launcher set them up, and the driver - * will look at them during setup. - * - * For us these fields come immediately after that device's descriptor in the - * lguest_devices page. - * - * Each field starts with a "type" byte, a "length" byte, then that number of - * bytes of configuration information. The device descriptor tells us the - * total configuration length so we know when we've reached the last field. */ + * The configuration information for a device consists of one or more + * virtqueues, a feature bitmaks, and some configuration bytes. The + * configuration bytes don't really matter to us: the Launcher sets them up, and + * the driver will look at them during setup. + * + * A convenient routine to return the device's virtqueue config array: + * immediately after the descriptor. */ +static struct lguest_vqconfig *lg_vq(const struct lguest_device_desc *desc) +{ + return (void *)(desc + 1); +} -/* type + length bytes */ -#define FHDR_LEN 2 +/* The features come immediately after the virtqueues. */ +static u8 *lg_features(const struct lguest_device_desc *desc) +{ + return (void *)(lg_vq(desc) + desc->num_vq); +} -/* This finds the first field of a given type for a device's configuration. */ -static void *lg_find(struct virtio_device *vdev, u8 type, unsigned int *len) +/* The config space comes after the two feature bitmasks. */ +static u8 *lg_config(const struct lguest_device_desc *desc) { - struct lguest_device_desc *desc = to_lgdev(vdev)->desc; - int i; + return lg_features(desc) + desc->feature_len * 2; +} - for (i = 0; i < desc->config_len; i += FHDR_LEN + desc->config[i+1]) { - if (desc->config[i] == type) { - /* Mark it used, so Host can know we looked at it, and - * also so we won't find the same one twice. */ - desc->config[i] |= 0x80; - /* Remember, the second byte is the length. */ - *len = desc->config[i+1]; - /* We return a pointer to the field header. */ - return desc->config + i; - } - } +/* The total size of the config page used by this device (incl. desc) */ +static unsigned desc_size(const struct lguest_device_desc *desc) +{ + return sizeof(*desc) + + desc->num_vq * sizeof(struct lguest_vqconfig) + + desc->feature_len * 2 + + desc->config_len; +} - /* Not found: return NULL for failure. */ - return NULL; +/* This tests (and acknowleges) a feature bit. */ +static bool lg_feature(struct virtio_device *vdev, unsigned fbit) +{ + struct lguest_device_desc *desc = to_lgdev(vdev)->desc; + u8 *features; + + /* Obviously if they ask for a feature off the end of our feature + * bitmap, it's not set. */ + if (fbit / 8 > desc->feature_len) + return false; + + /* The feature bitmap comes after the virtqueues. */ + features = lg_features(desc); + if (!(features[fbit / 8] & (1 << (fbit % 8)))) + return false; + + /* We set the matching bit in the other half of the bitmap to tell the + * Host we want to use this feature. We don't use this yet, but we + * could in future. */ + features[desc->feature_len + fbit / 8] |= (1 << (fbit % 8)); + return true; } /* Once they've found a field, getting a copy of it is easy. */ -static void lg_get(struct virtio_device *vdev, void *token, +static void lg_get(struct virtio_device *vdev, unsigned int offset, void *buf, unsigned len) { - /* Check they didn't ask for more than the length of the field! */ - BUG_ON(len > ((u8 *)token)[1]); - memcpy(buf, token + FHDR_LEN, len); + struct lguest_device_desc *desc = to_lgdev(vdev)->desc; + + /* Check they didn't ask for more than the length of the config! */ + BUG_ON(offset + len > desc->config_len); + memcpy(buf, lg_config(desc) + offset, len); } /* Setting the contents is also trivial. */ -static void lg_set(struct virtio_device *vdev, void *token, +static void lg_set(struct virtio_device *vdev, unsigned int offset, const void *buf, unsigned len) { - BUG_ON(len > ((u8 *)token)[1]); - memcpy(token + FHDR_LEN, buf, len); + struct lguest_device_desc *desc = to_lgdev(vdev)->desc; + + /* Check they didn't ask for more than the length of the config! */ + BUG_ON(offset + len > desc->config_len); + memcpy(lg_config(desc) + offset, buf, len); } /* The operations to get and set the status word just access the status field @@ -114,9 +139,20 @@ static void lg_set_status(struct virtio_device *vdev, u8 status) { + BUG_ON(!status); to_lgdev(vdev)->desc->status = status; } +/* To reset the device, we (ab)use the NOTIFY hypercall, with the descriptor + * address of the device. The Host will zero the status and all the + * features. */ +static void lg_reset(struct virtio_device *vdev) +{ + unsigned long offset = (void *)to_lgdev(vdev)->desc - lguest_devices; + + hcall(LHCALL_NOTIFY, (max_pfn<config->find(vdev, VIRTIO_CONFIG_F_VIRTQUEUE, &len); - if (!token) + /* We must have this many virtqueues. */ + if (index >= ldev->desc->num_vq) return ERR_PTR(-ENOENT); lvq = kmalloc(sizeof(*lvq), GFP_KERNEL); if (!lvq) return ERR_PTR(-ENOMEM); - /* Note: we could use a configuration space inside here, just like we - * do for the device. This would allow expansion in future, because - * our configuration system is designed to be expansible. But this is - * way easier. */ - if (len != sizeof(lvq->config)) { - dev_err(&vdev->dev, "Unexpected virtio config len %u\n", len); - err = -EIO; - goto free_lvq; - } - /* Make a copy of the "struct lguest_vqconfig" field. We need a copy - * because the config space might not be aligned correctly. */ - vdev->config->get(vdev, token, &lvq->config, sizeof(lvq->config)); + /* Make a copy of the "struct lguest_vqconfig" entry, which sits after + * the descriptor. We need a copy because the config space might not + * be aligned correctly. */ + memcpy(&lvq->config, lg_vq(ldev->desc)+index, sizeof(lvq->config)); + printk("Mapping virtqueue %i addr %lx\n", index, + (unsigned long)lvq->config.pfn << PAGE_SHIFT); /* Figure out how many pages the ring will take, and map that memory */ lvq->pages = lguest_map((unsigned long)lvq->config.pfn << PAGE_SHIFT, DIV_ROUND_UP(vring_size(lvq->config.num, @@ -259,11 +285,12 @@ /* The ops structure which hooks everything together. */ static struct virtio_config_ops lguest_config_ops = { - .find = lg_find, + .feature = lg_feature, .get = lg_get, .set = lg_set, .get_status = lg_get_status, .set_status = lg_set_status, + .reset = lg_reset, .find_vq = lg_find_vq, .del_vq = lg_del_vq, }; @@ -329,13 +356,14 @@ struct lguest_device_desc *d; /* We start at the page beginning, and skip over each entry. */ - for (i = 0; i < PAGE_SIZE; i += sizeof(*d) + d->config_len) { + for (i = 0; i < PAGE_SIZE; i += desc_size(d)) { d = lguest_devices + i; /* Once we hit a zero, stop. */ if (d->type == 0) break; + printk("Device at %i has size %u\n", i, desc_size(d)); add_lguest_device(d); } } --- linux-2.6.24.orig/drivers/lguest/segments.c +++ linux-2.6.24/drivers/lguest/segments.c @@ -58,7 +58,7 @@ * Protection Fault in the Switcher when it restores a Guest segment register * which tries to use that entry. Then we kill the Guest for causing such a * mess: the message will be "unhandled trap 256". */ -static void fixup_gdt_table(struct lguest *lg, unsigned start, unsigned end) +static void fixup_gdt_table(struct lg_cpu *cpu, unsigned start, unsigned end) { unsigned int i; @@ -71,14 +71,14 @@ /* Segment descriptors contain a privilege level: the Guest is * sometimes careless and leaves this as 0, even though it's * running at privilege level 1. If so, we fix it here. */ - if ((lg->arch.gdt[i].b & 0x00006000) == 0) - lg->arch.gdt[i].b |= (GUEST_PL << 13); + if ((cpu->arch.gdt[i].b & 0x00006000) == 0) + cpu->arch.gdt[i].b |= (GUEST_PL << 13); /* Each descriptor has an "accessed" bit. If we don't set it * now, the CPU will try to set it when the Guest first loads * that entry into a segment register. But the GDT isn't * writable by the Guest, so bad things can happen. */ - lg->arch.gdt[i].b |= 0x00000100; + cpu->arch.gdt[i].b |= 0x00000100; } } @@ -109,31 +109,31 @@ /* This routine sets up the initial Guest GDT for booting. All entries start * as 0 (unusable). */ -void setup_guest_gdt(struct lguest *lg) +void setup_guest_gdt(struct lg_cpu *cpu) { /* Start with full 0-4G segments... */ - lg->arch.gdt[GDT_ENTRY_KERNEL_CS] = FULL_EXEC_SEGMENT; - lg->arch.gdt[GDT_ENTRY_KERNEL_DS] = FULL_SEGMENT; + cpu->arch.gdt[GDT_ENTRY_KERNEL_CS] = FULL_EXEC_SEGMENT; + cpu->arch.gdt[GDT_ENTRY_KERNEL_DS] = FULL_SEGMENT; /* ...except the Guest is allowed to use them, so set the privilege * level appropriately in the flags. */ - lg->arch.gdt[GDT_ENTRY_KERNEL_CS].b |= (GUEST_PL << 13); - lg->arch.gdt[GDT_ENTRY_KERNEL_DS].b |= (GUEST_PL << 13); + cpu->arch.gdt[GDT_ENTRY_KERNEL_CS].b |= (GUEST_PL << 13); + cpu->arch.gdt[GDT_ENTRY_KERNEL_DS].b |= (GUEST_PL << 13); } /*H:650 An optimization of copy_gdt(), for just the three "thead-local storage" * entries. */ -void copy_gdt_tls(const struct lguest *lg, struct desc_struct *gdt) +void copy_gdt_tls(const struct lg_cpu *cpu, struct desc_struct *gdt) { unsigned int i; for (i = GDT_ENTRY_TLS_MIN; i <= GDT_ENTRY_TLS_MAX; i++) - gdt[i] = lg->arch.gdt[i]; + gdt[i] = cpu->arch.gdt[i]; } /*H:640 When the Guest is run on a different CPU, or the GDT entries have * changed, copy_gdt() is called to copy the Guest's GDT entries across to this * CPU's GDT. */ -void copy_gdt(const struct lguest *lg, struct desc_struct *gdt) +void copy_gdt(const struct lg_cpu *cpu, struct desc_struct *gdt) { unsigned int i; @@ -141,21 +141,22 @@ * replaced. See ignored_gdt() above. */ for (i = 0; i < GDT_ENTRIES; i++) if (!ignored_gdt(i)) - gdt[i] = lg->arch.gdt[i]; + gdt[i] = cpu->arch.gdt[i]; } /*H:620 This is where the Guest asks us to load a new GDT (LHCALL_LOAD_GDT). * We copy it from the Guest and tweak the entries. */ -void load_guest_gdt(struct lguest *lg, unsigned long table, u32 num) +void load_guest_gdt(struct lg_cpu *cpu, unsigned long table, u32 num) { + struct lguest *lg = cpu->lg; /* We assume the Guest has the same number of GDT entries as the * Host, otherwise we'd have to dynamically allocate the Guest GDT. */ - if (num > ARRAY_SIZE(lg->arch.gdt)) + if (num > ARRAY_SIZE(cpu->arch.gdt)) kill_guest(lg, "too many gdt entries %i", num); /* We read the whole thing in, then fix it up. */ - __lgread(lg, lg->arch.gdt, table, num * sizeof(lg->arch.gdt[0])); - fixup_gdt_table(lg, 0, ARRAY_SIZE(lg->arch.gdt)); + __lgread(lg, cpu->arch.gdt, table, num * sizeof(cpu->arch.gdt[0])); + fixup_gdt_table(cpu, 0, ARRAY_SIZE(cpu->arch.gdt)); /* Mark that the GDT changed so the core knows it has to copy it again, * even if the Guest is run on the same CPU. */ lg->changed |= CHANGED_GDT; @@ -165,12 +166,13 @@ * Remember that this happens on every context switch, so it's worth * optimizing. But wouldn't it be neater to have a single hypercall to cover * both cases? */ -void guest_load_tls(struct lguest *lg, unsigned long gtls) +void guest_load_tls(struct lg_cpu *cpu, unsigned long gtls) { - struct desc_struct *tls = &lg->arch.gdt[GDT_ENTRY_TLS_MIN]; + struct desc_struct *tls = &cpu->arch.gdt[GDT_ENTRY_TLS_MIN]; + struct lguest *lg = cpu->lg; __lgread(lg, tls, gtls, sizeof(*tls)*GDT_ENTRY_TLS_ENTRIES); - fixup_gdt_table(lg, GDT_ENTRY_TLS_MIN, GDT_ENTRY_TLS_MAX+1); + fixup_gdt_table(cpu, GDT_ENTRY_TLS_MIN, GDT_ENTRY_TLS_MAX+1); /* Note that just the TLS entries have changed. */ lg->changed |= CHANGED_GDT_TLS; } --- linux-2.6.24.orig/drivers/lguest/core.c +++ linux-2.6.24/drivers/lguest/core.c @@ -174,20 +174,22 @@ /*H:030 Let's jump straight to the the main loop which runs the Guest. * Remember, this is called by the Launcher reading /dev/lguest, and we keep * going around and around until something interesting happens. */ -int run_guest(struct lguest *lg, unsigned long __user *user) +int run_guest(struct lg_cpu *cpu, unsigned long __user *user) { + struct lguest *lg = cpu->lg; + /* We stop running once the Guest is dead. */ while (!lg->dead) { /* First we run any hypercalls the Guest wants done. */ - if (lg->hcall) - do_hypercalls(lg); + if (cpu->hcall) + do_hypercalls(cpu); /* It's possible the Guest did a NOTIFY hypercall to the * Launcher, in which case we return from the read() now. */ - if (lg->pending_notify) { - if (put_user(lg->pending_notify, user)) + if (cpu->pending_notify) { + if (put_user(cpu->pending_notify, user)) return -EFAULT; - return sizeof(lg->pending_notify); + return sizeof(cpu->pending_notify); } /* Check for signals */ @@ -195,13 +197,13 @@ return -ERESTARTSYS; /* If Waker set break_out, return to Launcher. */ - if (lg->break_out) + if (cpu->break_out) return -EAGAIN; /* Check if there are any interrupts which can be delivered * now: if so, this sets up the hander to be executed when we * next run the Guest. */ - maybe_do_interrupt(lg); + maybe_do_interrupt(cpu); /* All long-lived kernel loops need to check with this horrible * thing called the freezer. If the Host is trying to suspend, @@ -215,7 +217,7 @@ /* If the Guest asked to be stopped, we sleep. The Guest's * clock timer or LHCALL_BREAK from the Waker will wake us. */ - if (lg->halted) { + if (cpu->halted) { set_current_state(TASK_INTERRUPTIBLE); schedule(); continue; @@ -226,15 +228,17 @@ local_irq_disable(); /* Actually run the Guest until something happens. */ - lguest_arch_run_guest(lg); + lguest_arch_run_guest(cpu); /* Now we're ready to be interrupted or moved to other CPUs */ local_irq_enable(); /* Now we deal with whatever happened to the Guest. */ - lguest_arch_handle_trap(lg); + lguest_arch_handle_trap(cpu); } + if (lg->dead == ERR_PTR(-ERESTART)) + return -ERESTART; /* The Guest is dead => "No such file or directory" */ return -ENOENT; } --- linux-2.6.24.orig/drivers/lguest/lguest_user.c +++ linux-2.6.24/drivers/lguest/lguest_user.c @@ -13,7 +13,7 @@ * LHREQ_BREAK and the value "1" to /dev/lguest to do this. Once the Launcher * has done whatever needs attention, it writes LHREQ_BREAK and "0" to release * the Waker. */ -static int break_guest_out(struct lguest *lg, const unsigned long __user *input) +static int break_guest_out(struct lg_cpu *cpu, const unsigned long __user*input) { unsigned long on; @@ -22,21 +22,21 @@ return -EFAULT; if (on) { - lg->break_out = 1; + cpu->break_out = 1; /* Pop it out of the Guest (may be running on different CPU) */ - wake_up_process(lg->tsk); + wake_up_process(cpu->tsk); /* Wait for them to reset it */ - return wait_event_interruptible(lg->break_wq, !lg->break_out); + return wait_event_interruptible(cpu->break_wq, !cpu->break_out); } else { - lg->break_out = 0; - wake_up(&lg->break_wq); + cpu->break_out = 0; + wake_up(&cpu->break_wq); return 0; } } /*L:050 Sending an interrupt is done by writing LHREQ_IRQ and an interrupt * number to /dev/lguest. */ -static int user_send_irq(struct lguest *lg, const unsigned long __user *input) +static int user_send_irq(struct lg_cpu *cpu, const unsigned long __user *input) { unsigned long irq; @@ -46,7 +46,7 @@ return -EINVAL; /* Next time the Guest runs, the core code will see if it can deliver * this interrupt. */ - set_bit(irq, lg->irqs_pending); + set_bit(irq, cpu->irqs_pending); return 0; } @@ -55,13 +55,21 @@ static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o) { struct lguest *lg = file->private_data; + struct lg_cpu *cpu; + unsigned int cpu_id = *o; /* You must write LHREQ_INITIALIZE first! */ if (!lg) return -EINVAL; + /* Watch out for arbitrary vcpu indexes! */ + if (cpu_id >= lg->nr_cpus) + return -EINVAL; + + cpu = &lg->cpus[cpu_id]; + /* If you're not the task which owns the Guest, go away. */ - if (current != lg->tsk) + if (current != cpu->tsk) return -EPERM; /* If the guest is already dead, we indicate why */ @@ -81,11 +89,49 @@ /* If we returned from read() last time because the Guest notified, * clear the flag. */ - if (lg->pending_notify) - lg->pending_notify = 0; + if (cpu->pending_notify) + cpu->pending_notify = 0; /* Run the Guest until something interesting happens. */ - return run_guest(lg, (unsigned long __user *)user); + return run_guest(cpu, (unsigned long __user *)user); +} + +static int lg_cpu_start(struct lg_cpu *cpu, unsigned id, unsigned long start_ip) +{ + if (id >= NR_CPUS) + return -EINVAL; + + cpu->id = id; + cpu->lg = container_of((cpu - id), struct lguest, cpus[0]); + cpu->lg->nr_cpus++; + init_clockdev(cpu); + + /* We need a complete page for the Guest registers: they are accessible + * to the Guest and we can only grant it access to whole pages. */ + cpu->regs_page = get_zeroed_page(GFP_KERNEL); + if (!cpu->regs_page) + return -ENOMEM; + + /* We actually put the registers at the bottom of the page. */ + cpu->regs = (void *)cpu->regs_page + PAGE_SIZE - sizeof(*cpu->regs); + + /* Now we initialize the Guest's registers, handing it the start + * address. */ + lguest_arch_setup_regs(cpu, start_ip); + + /* Initialize the queue for the waker to wait on */ + init_waitqueue_head(&cpu->break_wq); + + /* We keep a pointer to the Launcher task (ie. current task) for when + * other Guests want to wake this one (inter-Guest I/O). */ + cpu->tsk = current; + + /* We need to keep a pointer to the Launcher's memory map, because if + * the Launcher dies we need to clean it up. If we don't keep a + * reference, it is destroyed before close() is called. */ + cpu->mm = get_task_mm(cpu->tsk); + + return 0; } /*L:020 The initialization write supplies 4 pointer sized (32 or 64 bit) @@ -134,15 +180,10 @@ lg->mem_base = (void __user *)(long)args[0]; lg->pfn_limit = args[1]; - /* We need a complete page for the Guest registers: they are accessible - * to the Guest and we can only grant it access to whole pages. */ - lg->regs_page = get_zeroed_page(GFP_KERNEL); - if (!lg->regs_page) { - err = -ENOMEM; + /* This is the first cpu */ + err = lg_cpu_start(&lg->cpus[0], 0, args[3]); + if (err) goto release_guest; - } - /* We actually put the registers at the bottom of the page. */ - lg->regs = (void *)lg->regs_page + PAGE_SIZE - sizeof(*lg->regs); /* Initialize the Guest's shadow page tables, using the toplevel * address the Launcher gave us. This allocates memory, so can @@ -151,24 +192,6 @@ if (err) goto free_regs; - /* Now we initialize the Guest's registers, handing it the start - * address. */ - lguest_arch_setup_regs(lg, args[3]); - - /* The timer for lguest's clock needs initialization. */ - init_clockdev(lg); - - /* We keep a pointer to the Launcher task (ie. current task) for when - * other Guests want to wake this one (inter-Guest I/O). */ - lg->tsk = current; - /* We need to keep a pointer to the Launcher's memory map, because if - * the Launcher dies we need to clean it up. If we don't keep a - * reference, it is destroyed before close() is called. */ - lg->mm = get_task_mm(lg->tsk); - - /* Initialize the queue for the waker to wait on */ - init_waitqueue_head(&lg->break_wq); - /* We remember which CPU's pages this Guest used last, for optimization * when the same Guest runs on the same CPU twice. */ lg->last_pages = NULL; @@ -182,7 +205,8 @@ return sizeof(args); free_regs: - free_page(lg->regs_page); + /* FIXME: This should be in free_vcpu */ + free_page(lg->cpus[0].regs_page); release_guest: kfree(lg); unlock: @@ -202,30 +226,37 @@ struct lguest *lg = file->private_data; const unsigned long __user *input = (const unsigned long __user *)in; unsigned long req; + struct lg_cpu *uninitialized_var(cpu); + unsigned int cpu_id = *off; if (get_user(req, input) != 0) return -EFAULT; input++; /* If you haven't initialized, you must do that first. */ - if (req != LHREQ_INITIALIZE && !lg) - return -EINVAL; + if (req != LHREQ_INITIALIZE) { + if (!lg || (cpu_id >= lg->nr_cpus)) + return -EINVAL; + cpu = &lg->cpus[cpu_id]; + if (!cpu) + return -EINVAL; + } /* Once the Guest is dead, all you can do is read() why it died. */ if (lg && lg->dead) return -ENOENT; /* If you're not the task which owns the Guest, you can only break */ - if (lg && current != lg->tsk && req != LHREQ_BREAK) + if (lg && current != cpu->tsk && req != LHREQ_BREAK) return -EPERM; switch (req) { case LHREQ_INITIALIZE: return initialize(file, input); case LHREQ_IRQ: - return user_send_irq(lg, input); + return user_send_irq(cpu, input); case LHREQ_BREAK: - return break_guest_out(lg, input); + return break_guest_out(cpu, input); default: return -EINVAL; } @@ -241,6 +272,7 @@ static int close(struct inode *inode, struct file *file) { struct lguest *lg = file->private_data; + unsigned int i; /* If we never successfully initialized, there's nothing to clean up */ if (!lg) @@ -249,19 +281,23 @@ /* We need the big lock, to protect from inter-guest I/O and other * Launchers initializing guests. */ mutex_lock(&lguest_lock); - /* Cancels the hrtimer set via LHCALL_SET_CLOCKEVENT. */ - hrtimer_cancel(&lg->hrt); + /* Free up the shadow page tables for the Guest. */ free_guest_pagetable(lg); - /* Now all the memory cleanups are done, it's safe to release the - * Launcher's memory management structure. */ - mmput(lg->mm); + + for (i = 0; i < lg->nr_cpus; i++) { + /* Cancels the hrtimer set via LHCALL_SET_CLOCKEVENT. */ + hrtimer_cancel(&lg->cpus[i].hrt); + /* We can free up the register page we allocated. */ + free_page(lg->cpus[i].regs_page); + /* Now all the memory cleanups are done, it's safe to release + * the Launcher's memory management structure. */ + mmput(lg->cpus[i].mm); + } /* If lg->dead doesn't contain an error code it will be NULL or a * kmalloc()ed string, either of which is ok to hand to kfree(). */ if (!IS_ERR(lg->dead)) kfree(lg->dead); - /* We can free up the register page we allocated. */ - free_page(lg->regs_page); /* We clear the entire structure, which also marks it as free for the * next user. */ memset(lg, 0, sizeof(*lg)); --- linux-2.6.24.orig/drivers/lguest/interrupts_and_traps.c +++ linux-2.6.24/drivers/lguest/interrupts_and_traps.c @@ -60,41 +60,42 @@ * We set up the stack just like the CPU does for a real interrupt, so it's * identical for the Guest (and the standard "iret" instruction will undo * it). */ -static void set_guest_interrupt(struct lguest *lg, u32 lo, u32 hi, int has_err) +static void set_guest_interrupt(struct lg_cpu *cpu, u32 lo, u32 hi, int has_err) { unsigned long gstack, origstack; u32 eflags, ss, irq_enable; unsigned long virtstack; + struct lguest *lg = cpu->lg; /* There are two cases for interrupts: one where the Guest is already * in the kernel, and a more complex one where the Guest is in * userspace. We check the privilege level to find out. */ - if ((lg->regs->ss&0x3) != GUEST_PL) { + if ((cpu->regs->ss&0x3) != GUEST_PL) { /* The Guest told us their kernel stack with the SET_STACK * hypercall: both the virtual address and the segment */ - virtstack = lg->esp1; - ss = lg->ss1; + virtstack = cpu->esp1; + ss = cpu->ss1; - origstack = gstack = guest_pa(lg, virtstack); + origstack = gstack = guest_pa(cpu, virtstack); /* We push the old stack segment and pointer onto the new * stack: when the Guest does an "iret" back from the interrupt * handler the CPU will notice they're dropping privilege * levels and expect these here. */ - push_guest_stack(lg, &gstack, lg->regs->ss); - push_guest_stack(lg, &gstack, lg->regs->esp); + push_guest_stack(lg, &gstack, cpu->regs->ss); + push_guest_stack(lg, &gstack, cpu->regs->esp); } else { /* We're staying on the same Guest (kernel) stack. */ - virtstack = lg->regs->esp; - ss = lg->regs->ss; + virtstack = cpu->regs->esp; + ss = cpu->regs->ss; - origstack = gstack = guest_pa(lg, virtstack); + origstack = gstack = guest_pa(cpu, virtstack); } /* Remember that we never let the Guest actually disable interrupts, so * the "Interrupt Flag" bit is always set. We copy that bit from the * Guest's "irq_enabled" field into the eflags word: we saw the Guest * copy it back in "lguest_iret". */ - eflags = lg->regs->eflags; + eflags = cpu->regs->eflags; if (get_user(irq_enable, &lg->lguest_data->irq_enabled) == 0 && !(irq_enable & X86_EFLAGS_IF)) eflags &= ~X86_EFLAGS_IF; @@ -103,19 +104,19 @@ * "eflags" word, the old code segment, and the old instruction * pointer. */ push_guest_stack(lg, &gstack, eflags); - push_guest_stack(lg, &gstack, lg->regs->cs); - push_guest_stack(lg, &gstack, lg->regs->eip); + push_guest_stack(lg, &gstack, cpu->regs->cs); + push_guest_stack(lg, &gstack, cpu->regs->eip); /* For the six traps which supply an error code, we push that, too. */ if (has_err) - push_guest_stack(lg, &gstack, lg->regs->errcode); + push_guest_stack(lg, &gstack, cpu->regs->errcode); /* Now we've pushed all the old state, we change the stack, the code * segment and the address to execute. */ - lg->regs->ss = ss; - lg->regs->esp = virtstack + (gstack - origstack); - lg->regs->cs = (__KERNEL_CS|GUEST_PL); - lg->regs->eip = idt_address(lo, hi); + cpu->regs->ss = ss; + cpu->regs->esp = virtstack + (gstack - origstack); + cpu->regs->cs = (__KERNEL_CS|GUEST_PL); + cpu->regs->eip = idt_address(lo, hi); /* There are two kinds of interrupt handlers: 0xE is an "interrupt * gate" which expects interrupts to be disabled on entry. */ @@ -129,9 +130,10 @@ * * maybe_do_interrupt() gets called before every entry to the Guest, to see if * we should divert the Guest to running an interrupt handler. */ -void maybe_do_interrupt(struct lguest *lg) +void maybe_do_interrupt(struct lg_cpu *cpu) { unsigned int irq; + struct lguest *lg = cpu->lg; DECLARE_BITMAP(blk, LGUEST_IRQS); struct desc_struct *idt; @@ -145,7 +147,7 @@ sizeof(blk))) return; - bitmap_andnot(blk, lg->irqs_pending, blk, LGUEST_IRQS); + bitmap_andnot(blk, cpu->irqs_pending, blk, LGUEST_IRQS); /* Find the first interrupt. */ irq = find_first_bit(blk, LGUEST_IRQS); @@ -155,15 +157,15 @@ /* They may be in the middle of an iret, where they asked us never to * deliver interrupts. */ - if (lg->regs->eip >= lg->noirq_start && lg->regs->eip < lg->noirq_end) + if (cpu->regs->eip >= lg->noirq_start && cpu->regs->eip < lg->noirq_end) return; /* If they're halted, interrupts restart them. */ - if (lg->halted) { + if (cpu->halted) { /* Re-enable interrupts. */ if (put_user(X86_EFLAGS_IF, &lg->lguest_data->irq_enabled)) kill_guest(lg, "Re-enabling interrupts"); - lg->halted = 0; + cpu->halted = 0; } else { /* Otherwise we check if they have interrupts disabled. */ u32 irq_enabled; @@ -176,15 +178,15 @@ /* Look at the IDT entry the Guest gave us for this interrupt. The * first 32 (FIRST_EXTERNAL_VECTOR) entries are for traps, so we skip * over them. */ - idt = &lg->arch.idt[FIRST_EXTERNAL_VECTOR+irq]; + idt = &cpu->arch.idt[FIRST_EXTERNAL_VECTOR+irq]; /* If they don't have a handler (yet?), we just ignore it */ if (idt_present(idt->a, idt->b)) { /* OK, mark it no longer pending and deliver it. */ - clear_bit(irq, lg->irqs_pending); + clear_bit(irq, cpu->irqs_pending); /* set_guest_interrupt() takes the interrupt descriptor and a * flag to say whether this interrupt pushes an error code onto * the stack as well: virtual interrupts never do. */ - set_guest_interrupt(lg, idt->a, idt->b, 0); + set_guest_interrupt(cpu, idt->a, idt->b, 0); } /* Every time we deliver an interrupt, we update the timestamp in the @@ -245,19 +247,19 @@ } /* deliver_trap() returns true if it could deliver the trap. */ -int deliver_trap(struct lguest *lg, unsigned int num) +int deliver_trap(struct lg_cpu *cpu, unsigned int num) { /* Trap numbers are always 8 bit, but we set an impossible trap number * for traps inside the Switcher, so check that here. */ - if (num >= ARRAY_SIZE(lg->arch.idt)) + if (num >= ARRAY_SIZE(cpu->arch.idt)) return 0; /* Early on the Guest hasn't set the IDT entries (or maybe it put a * bogus one in): if we fail here, the Guest will be killed. */ - if (!idt_present(lg->arch.idt[num].a, lg->arch.idt[num].b)) + if (!idt_present(cpu->arch.idt[num].a, cpu->arch.idt[num].b)) return 0; - set_guest_interrupt(lg, lg->arch.idt[num].a, lg->arch.idt[num].b, - has_err(num)); + set_guest_interrupt(cpu, cpu->arch.idt[num].a, + cpu->arch.idt[num].b, has_err(num)); return 1; } @@ -309,10 +311,11 @@ * the Guest. * * Which is deeply unfair, because (literally!) it wasn't the Guests' fault. */ -void pin_stack_pages(struct lguest *lg) +void pin_stack_pages(struct lg_cpu *cpu) { unsigned int i; + struct lguest *lg = cpu->lg; /* Depending on the CONFIG_4KSTACKS option, the Guest can have one or * two pages of stack space. */ for (i = 0; i < lg->stack_pages; i++) @@ -320,7 +323,7 @@ * start of the page after the kernel stack. Subtract one to * get back onto the first stack page, and keep subtracting to * get to the rest of the stack pages. */ - pin_page(lg, lg->esp1 - 1 - i * PAGE_SIZE); + pin_page(cpu, cpu->esp1 - 1 - i * PAGE_SIZE); } /* Direct traps also mean that we need to know whenever the Guest wants to use @@ -331,21 +334,21 @@ * * In Linux each process has its own kernel stack, so this happens a lot: we * change stacks on each context switch. */ -void guest_set_stack(struct lguest *lg, u32 seg, u32 esp, unsigned int pages) +void guest_set_stack(struct lg_cpu *cpu, u32 seg, u32 esp, unsigned int pages) { /* You are not allowed have a stack segment with privilege level 0: bad * Guest! */ if ((seg & 0x3) != GUEST_PL) - kill_guest(lg, "bad stack segment %i", seg); + kill_guest(cpu->lg, "bad stack segment %i", seg); /* We only expect one or two stack pages. */ if (pages > 2) - kill_guest(lg, "bad stack pages %u", pages); + kill_guest(cpu->lg, "bad stack pages %u", pages); /* Save where the stack is, and how many pages */ - lg->ss1 = seg; - lg->esp1 = esp; - lg->stack_pages = pages; + cpu->ss1 = seg; + cpu->esp1 = esp; + cpu->lg->stack_pages = pages; /* Make sure the new stack pages are mapped */ - pin_stack_pages(lg); + pin_stack_pages(cpu); } /* All this reference to mapping stacks leads us neatly into the other complex @@ -383,7 +386,7 @@ * * We saw the Guest setting Interrupt Descriptor Table (IDT) entries with the * LHCALL_LOAD_IDT_ENTRY hypercall before: that comes here. */ -void load_guest_idt_entry(struct lguest *lg, unsigned int num, u32 lo, u32 hi) +void load_guest_idt_entry(struct lg_cpu *cpu, unsigned int num, u32 lo, u32 hi) { /* Guest never handles: NMI, doublefault, spurious interrupt or * hypercall. We ignore when it tries to set them. */ @@ -392,13 +395,13 @@ /* Mark the IDT as changed: next time the Guest runs we'll know we have * to copy this again. */ - lg->changed |= CHANGED_IDT; + cpu->lg->changed |= CHANGED_IDT; /* Check that the Guest doesn't try to step outside the bounds. */ - if (num >= ARRAY_SIZE(lg->arch.idt)) - kill_guest(lg, "Setting idt entry %u", num); + if (num >= ARRAY_SIZE(cpu->arch.idt)) + kill_guest(cpu->lg, "Setting idt entry %u", num); else - set_trap(lg, &lg->arch.idt[num], num, lo, hi); + set_trap(cpu->lg, &cpu->arch.idt[num], num, lo, hi); } /* The default entry for each interrupt points into the Switcher routines which @@ -434,14 +437,14 @@ /*H:240 We don't use the IDT entries in the "struct lguest" directly, instead * we copy them into the IDT which we've set up for Guests on this CPU, just * before we run the Guest. This routine does that copy. */ -void copy_traps(const struct lguest *lg, struct desc_struct *idt, +void copy_traps(const struct lg_cpu *cpu, struct desc_struct *idt, const unsigned long *def) { unsigned int i; /* We can simply copy the direct traps, otherwise we use the default * ones in the Switcher: they will return to the Host. */ - for (i = 0; i < ARRAY_SIZE(lg->arch.idt); i++) { + for (i = 0; i < ARRAY_SIZE(cpu->arch.idt); i++) { /* If no Guest can ever override this trap, leave it alone. */ if (!direct_trap(i)) continue; @@ -450,8 +453,8 @@ * Interrupt gates (type 14) disable interrupts as they are * entered, which we never let the Guest do. Not present * entries (type 0x0) also can't go direct, of course. */ - if (idt_type(lg->arch.idt[i].a, lg->arch.idt[i].b) == 0xF) - idt[i] = lg->arch.idt[i]; + if (idt_type(cpu->arch.idt[i].a, cpu->arch.idt[i].b) == 0xF) + idt[i] = cpu->arch.idt[i]; else /* Reset it to the default. */ default_idt_entry(&idt[i], i, def[i]); @@ -470,13 +473,13 @@ * infrastructure to set a callback at that time. * * 0 means "turn off the clock". */ -void guest_set_clockevent(struct lguest *lg, unsigned long delta) +void guest_set_clockevent(struct lg_cpu *cpu, unsigned long delta) { ktime_t expires; if (unlikely(delta == 0)) { /* Clock event device is shutting down. */ - hrtimer_cancel(&lg->hrt); + hrtimer_cancel(&cpu->hrt); return; } @@ -484,25 +487,25 @@ * all the time between now and the timer interrupt it asked for. This * is almost always the right thing to do. */ expires = ktime_add_ns(ktime_get_real(), delta); - hrtimer_start(&lg->hrt, expires, HRTIMER_MODE_ABS); + hrtimer_start(&cpu->hrt, expires, HRTIMER_MODE_ABS); } /* This is the function called when the Guest's timer expires. */ static enum hrtimer_restart clockdev_fn(struct hrtimer *timer) { - struct lguest *lg = container_of(timer, struct lguest, hrt); + struct lg_cpu *cpu = container_of(timer, struct lg_cpu, hrt); /* Remember the first interrupt is the timer interrupt. */ - set_bit(0, lg->irqs_pending); + set_bit(0, cpu->irqs_pending); /* If the Guest is actually stopped, we need to wake it up. */ - if (lg->halted) - wake_up_process(lg->tsk); + if (cpu->halted) + wake_up_process(cpu->tsk); return HRTIMER_NORESTART; } /* This sets up the timer for this Guest. */ -void init_clockdev(struct lguest *lg) +void init_clockdev(struct lg_cpu *cpu) { - hrtimer_init(&lg->hrt, CLOCK_REALTIME, HRTIMER_MODE_ABS); - lg->hrt.function = clockdev_fn; + hrtimer_init(&cpu->hrt, CLOCK_REALTIME, HRTIMER_MODE_ABS); + cpu->hrt.function = clockdev_fn; } --- linux-2.6.24.orig/drivers/lguest/page_tables.c +++ linux-2.6.24/drivers/lguest/page_tables.c @@ -94,10 +94,10 @@ /* These two functions just like the above two, except they access the Guest * page tables. Hence they return a Guest address. */ -static unsigned long gpgd_addr(struct lguest *lg, unsigned long vaddr) +static unsigned long gpgd_addr(struct lg_cpu *cpu, unsigned long vaddr) { unsigned int index = vaddr >> (PGDIR_SHIFT); - return lg->pgdirs[lg->pgdidx].gpgdir + index * sizeof(pgd_t); + return cpu->lg->pgdirs[cpu->cpu_pgd].gpgdir + index * sizeof(pgd_t); } static unsigned long gpte_addr(struct lguest *lg, @@ -200,22 +200,23 @@ * * If we fixed up the fault (ie. we mapped the address), this routine returns * true. Otherwise, it was a real fault and we need to tell the Guest. */ -int demand_page(struct lguest *lg, unsigned long vaddr, int errcode) +int demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode) { pgd_t gpgd; pgd_t *spgd; unsigned long gpte_ptr; pte_t gpte; pte_t *spte; + struct lguest *lg = cpu->lg; /* First step: get the top-level Guest page table entry. */ - gpgd = lgread(lg, gpgd_addr(lg, vaddr), pgd_t); + gpgd = lgread(lg, gpgd_addr(cpu, vaddr), pgd_t); /* Toplevel not present? We can't map it in. */ if (!(pgd_flags(gpgd) & _PAGE_PRESENT)) return 0; /* Now look at the matching shadow entry. */ - spgd = spgd_addr(lg, lg->pgdidx, vaddr); + spgd = spgd_addr(lg, cpu->cpu_pgd, vaddr); if (!(pgd_flags(*spgd) & _PAGE_PRESENT)) { /* No shadow entry: allocate a new shadow PTE page. */ unsigned long ptepage = get_zeroed_page(GFP_KERNEL); @@ -297,19 +298,19 @@ * * This is a quick version which answers the question: is this virtual address * mapped by the shadow page tables, and is it writable? */ -static int page_writable(struct lguest *lg, unsigned long vaddr) +static int page_writable(struct lg_cpu *cpu, unsigned long vaddr) { pgd_t *spgd; unsigned long flags; /* Look at the current top level entry: is it present? */ - spgd = spgd_addr(lg, lg->pgdidx, vaddr); + spgd = spgd_addr(cpu->lg, cpu->cpu_pgd, vaddr); if (!(pgd_flags(*spgd) & _PAGE_PRESENT)) return 0; /* Check the flags on the pte entry itself: it must be present and * writable. */ - flags = pte_flags(*(spte_addr(lg, *spgd, vaddr))); + flags = pte_flags(*(spte_addr(cpu->lg, *spgd, vaddr))); return (flags & (_PAGE_PRESENT|_PAGE_RW)) == (_PAGE_PRESENT|_PAGE_RW); } @@ -317,10 +318,10 @@ /* So, when pin_stack_pages() asks us to pin a page, we check if it's already * in the page tables, and if not, we call demand_page() with error code 2 * (meaning "write"). */ -void pin_page(struct lguest *lg, unsigned long vaddr) +void pin_page(struct lg_cpu *cpu, unsigned long vaddr) { - if (!page_writable(lg, vaddr) && !demand_page(lg, vaddr, 2)) - kill_guest(lg, "bad stack page %#lx", vaddr); + if (!page_writable(cpu, vaddr) && !demand_page(cpu, vaddr, 2)) + kill_guest(cpu->lg, "bad stack page %#lx", vaddr); } /*H:450 If we chase down the release_pgd() code, it looks like this: */ @@ -358,28 +359,28 @@ * * The Guest has a hypercall to throw away the page tables: it's used when a * large number of mappings have been changed. */ -void guest_pagetable_flush_user(struct lguest *lg) +void guest_pagetable_flush_user(struct lg_cpu *cpu) { /* Drop the userspace part of the current page table. */ - flush_user_mappings(lg, lg->pgdidx); + flush_user_mappings(cpu->lg, cpu->cpu_pgd); } /*:*/ /* We walk down the guest page tables to get a guest-physical address */ -unsigned long guest_pa(struct lguest *lg, unsigned long vaddr) +unsigned long guest_pa(struct lg_cpu *cpu, unsigned long vaddr) { pgd_t gpgd; pte_t gpte; /* First step: get the top-level Guest page table entry. */ - gpgd = lgread(lg, gpgd_addr(lg, vaddr), pgd_t); + gpgd = lgread(cpu->lg, gpgd_addr(cpu, vaddr), pgd_t); /* Toplevel not present? We can't map it in. */ if (!(pgd_flags(gpgd) & _PAGE_PRESENT)) - kill_guest(lg, "Bad address %#lx", vaddr); + kill_guest(cpu->lg, "Bad address %#lx", vaddr); - gpte = lgread(lg, gpte_addr(lg, gpgd, vaddr), pte_t); + gpte = lgread(cpu->lg, gpte_addr(cpu->lg, gpgd, vaddr), pte_t); if (!(pte_flags(gpte) & _PAGE_PRESENT)) - kill_guest(lg, "Bad address %#lx", vaddr); + kill_guest(cpu->lg, "Bad address %#lx", vaddr); return pte_pfn(gpte) * PAGE_SIZE | (vaddr & ~PAGE_MASK); } @@ -399,11 +400,12 @@ /*H:435 And this is us, creating the new page directory. If we really do * allocate a new one (and so the kernel parts are not there), we set * blank_pgdir. */ -static unsigned int new_pgdir(struct lguest *lg, +static unsigned int new_pgdir(struct lg_cpu *cpu, unsigned long gpgdir, int *blank_pgdir) { unsigned int next; + struct lguest *lg = cpu->lg; /* We pick one entry at random to throw out. Choosing the Least * Recently Used might be better, but this is easy. */ @@ -413,7 +415,7 @@ lg->pgdirs[next].pgdir = (pgd_t *)get_zeroed_page(GFP_KERNEL); /* If the allocation fails, just keep using the one we have */ if (!lg->pgdirs[next].pgdir) - next = lg->pgdidx; + next = cpu->cpu_pgd; else /* This is a blank page, so there are no kernel * mappings: caller must map the stack! */ @@ -432,21 +434,22 @@ * Now we've seen all the page table setting and manipulation, let's see what * what happens when the Guest changes page tables (ie. changes the top-level * pgdir). This occurs on almost every context switch. */ -void guest_new_pagetable(struct lguest *lg, unsigned long pgtable) +void guest_new_pagetable(struct lg_cpu *cpu, unsigned long pgtable) { int newpgdir, repin = 0; + struct lguest *lg = cpu->lg; /* Look to see if we have this one already. */ newpgdir = find_pgdir(lg, pgtable); /* If not, we allocate or mug an existing one: if it's a fresh one, * repin gets set to 1. */ if (newpgdir == ARRAY_SIZE(lg->pgdirs)) - newpgdir = new_pgdir(lg, pgtable, &repin); + newpgdir = new_pgdir(cpu, pgtable, &repin); /* Change the current pgd index to the new one. */ - lg->pgdidx = newpgdir; + cpu->cpu_pgd = newpgdir; /* If it was completely blank, we map in the Guest kernel stack */ if (repin) - pin_stack_pages(lg); + pin_stack_pages(cpu); } /*H:470 Finally, a routine which throws away everything: all PGD entries in all @@ -468,11 +471,11 @@ * mapping. Since kernel mappings are in every page table, it's easiest to * throw them all away. This traps the Guest in amber for a while as * everything faults back in, but it's rare. */ -void guest_pagetable_clear_all(struct lguest *lg) +void guest_pagetable_clear_all(struct lg_cpu *cpu) { - release_all_pagetables(lg); + release_all_pagetables(cpu->lg); /* We need the Guest kernel stack mapped again. */ - pin_stack_pages(lg); + pin_stack_pages(cpu); } /*:*/ /*M:009 Since we throw away all mappings when a kernel mapping changes, our @@ -590,11 +593,11 @@ { /* We start on the first shadow page table, and give it a blank PGD * page. */ - lg->pgdidx = 0; - lg->pgdirs[lg->pgdidx].gpgdir = pgtable; - lg->pgdirs[lg->pgdidx].pgdir = (pgd_t*)get_zeroed_page(GFP_KERNEL); - if (!lg->pgdirs[lg->pgdidx].pgdir) + lg->pgdirs[0].gpgdir = pgtable; + lg->pgdirs[0].pgdir = (pgd_t *)get_zeroed_page(GFP_KERNEL); + if (!lg->pgdirs[0].pgdir) return -ENOMEM; + lg->cpus[0].cpu_pgd = 0; return 0; } @@ -606,7 +609,7 @@ /* We tell the Guest that it can't use the top 4MB of virtual * addresses used by the Switcher. */ || put_user(4U*1024*1024, &lg->lguest_data->reserve_mem) - || put_user(lg->pgdirs[lg->pgdidx].gpgdir,&lg->lguest_data->pgdir)) + || put_user(lg->pgdirs[0].gpgdir, &lg->lguest_data->pgdir)) kill_guest(lg, "bad guest page %p", lg->lguest_data); /* In flush_user_mappings() we loop from 0 to @@ -634,17 +637,18 @@ * Guest (and not the pages for other CPUs). We have the appropriate PTE pages * for each CPU already set up, we just need to hook them in now we know which * Guest is about to run on this CPU. */ -void map_switcher_in_guest(struct lguest *lg, struct lguest_pages *pages) +void map_switcher_in_guest(struct lg_cpu *cpu, struct lguest_pages *pages) { pte_t *switcher_pte_page = __get_cpu_var(switcher_pte_pages); pgd_t switcher_pgd; pte_t regs_pte; + unsigned long pfn; /* Make the last PGD entry for this Guest point to the Switcher's PTE * page for this CPU (with appropriate flags). */ switcher_pgd = __pgd(__pa(switcher_pte_page) | _PAGE_KERNEL); - lg->pgdirs[lg->pgdidx].pgdir[SWITCHER_PGD_INDEX] = switcher_pgd; + cpu->lg->pgdirs[cpu->cpu_pgd].pgdir[SWITCHER_PGD_INDEX] = switcher_pgd; /* We also change the Switcher PTE page. When we're running the Guest, * we want the Guest's "regs" page to appear where the first Switcher @@ -653,7 +657,8 @@ * CPU's "struct lguest_pages": if we make sure the Guest's register * page is already mapped there, we don't have to copy them out * again. */ - regs_pte = pfn_pte (__pa(lg->regs_page) >> PAGE_SHIFT, __pgprot(_PAGE_KERNEL)); + pfn = __pa(cpu->regs_page) >> PAGE_SHIFT; + regs_pte = pfn_pte(pfn, __pgprot(_PAGE_KERNEL)); switcher_pte_page[(unsigned long)pages/PAGE_SIZE%PTRS_PER_PTE] = regs_pte; } /*:*/ --- linux-2.6.24.orig/drivers/lguest/hypercalls.c +++ linux-2.6.24/drivers/lguest/hypercalls.c @@ -29,8 +29,10 @@ /*H:120 This is the core hypercall routine: where the Guest gets what it wants. * Or gets killed. Or, in the case of LHCALL_CRASH, both. */ -static void do_hcall(struct lguest *lg, struct hcall_args *args) +static void do_hcall(struct lg_cpu *cpu, struct hcall_args *args) { + struct lguest *lg = cpu->lg; + switch (args->arg0) { case LHCALL_FLUSH_ASYNC: /* This call does nothing, except by breaking out of the Guest @@ -41,8 +43,8 @@ * do that. */ kill_guest(lg, "already have lguest_data"); break; - case LHCALL_CRASH: { - /* Crash is such a trivial hypercall that we do it in four + case LHCALL_SHUTDOWN: { + /* Shutdown is such a trivial hypercall that we do it in four * lines right here. */ char msg[128]; /* If the lgread fails, it will call kill_guest() itself; the @@ -50,24 +52,26 @@ __lgread(lg, msg, args->arg1, sizeof(msg)); msg[sizeof(msg)-1] = '\0'; kill_guest(lg, "CRASH: %s", msg); + if (args->arg2 == LGUEST_SHUTDOWN_RESTART) + lg->dead = ERR_PTR(-ERESTART); break; } case LHCALL_FLUSH_TLB: /* FLUSH_TLB comes in two flavors, depending on the * argument: */ if (args->arg1) - guest_pagetable_clear_all(lg); + guest_pagetable_clear_all(cpu); else - guest_pagetable_flush_user(lg); + guest_pagetable_flush_user(cpu); break; /* All these calls simply pass the arguments through to the right * routines. */ case LHCALL_NEW_PGTABLE: - guest_new_pagetable(lg, args->arg1); + guest_new_pagetable(cpu, args->arg1); break; case LHCALL_SET_STACK: - guest_set_stack(lg, args->arg1, args->arg2, args->arg3); + guest_set_stack(cpu, args->arg1, args->arg2, args->arg3); break; case LHCALL_SET_PTE: guest_set_pte(lg, args->arg1, args->arg2, __pte(args->arg3)); @@ -76,22 +80,22 @@ guest_set_pmd(lg, args->arg1, args->arg2); break; case LHCALL_SET_CLOCKEVENT: - guest_set_clockevent(lg, args->arg1); + guest_set_clockevent(cpu, args->arg1); break; case LHCALL_TS: /* This sets the TS flag, as we saw used in run_guest(). */ - lg->ts = args->arg1; + cpu->ts = args->arg1; break; case LHCALL_HALT: /* Similarly, this sets the halted flag for run_guest(). */ - lg->halted = 1; + cpu->halted = 1; break; case LHCALL_NOTIFY: - lg->pending_notify = args->arg1; + cpu->pending_notify = args->arg1; break; default: /* It should be an architecture-specific hypercall. */ - if (lguest_arch_do_hcall(lg, args)) + if (lguest_arch_do_hcall(cpu, args)) kill_guest(lg, "Bad hypercall %li\n", args->arg0); } } @@ -104,10 +108,11 @@ * Guest put them in the ring, but we also promise the Guest that they will * happen before any normal hypercall (which is why we check this before * checking for a normal hcall). */ -static void do_async_hcalls(struct lguest *lg) +static void do_async_hcalls(struct lg_cpu *cpu) { unsigned int i; u8 st[LHCALL_RING_SIZE]; + struct lguest *lg = cpu->lg; /* For simplicity, we copy the entire call status array in at once. */ if (copy_from_user(&st, &lg->lguest_data->hcall_status, sizeof(st))) @@ -119,7 +124,7 @@ /* We remember where we were up to from last time. This makes * sure that the hypercalls are done in the order the Guest * places them in the ring. */ - unsigned int n = lg->next_hcall; + unsigned int n = cpu->next_hcall; /* 0xFF means there's no call here (yet). */ if (st[n] == 0xFF) @@ -127,8 +132,8 @@ /* OK, we have hypercall. Increment the "next_hcall" cursor, * and wrap back to 0 if we reach the end. */ - if (++lg->next_hcall == LHCALL_RING_SIZE) - lg->next_hcall = 0; + if (++cpu->next_hcall == LHCALL_RING_SIZE) + cpu->next_hcall = 0; /* Copy the hypercall arguments into a local copy of * the hcall_args struct. */ @@ -139,7 +144,7 @@ } /* Do the hypercall, same as a normal one. */ - do_hcall(lg, &args); + do_hcall(cpu, &args); /* Mark the hypercall done. */ if (put_user(0xFF, &lg->lguest_data->hcall_status[n])) { @@ -149,23 +154,24 @@ /* Stop doing hypercalls if they want to notify the Launcher: * it needs to service this first. */ - if (lg->pending_notify) + if (cpu->pending_notify) break; } } /* Last of all, we look at what happens first of all. The very first time the * Guest makes a hypercall, we end up here to set things up: */ -static void initialize(struct lguest *lg) +static void initialize(struct lg_cpu *cpu) { + struct lguest *lg = cpu->lg; /* You can't do anything until you're initialized. The Guest knows the * rules, so we're unforgiving here. */ - if (lg->hcall->arg0 != LHCALL_LGUEST_INIT) { - kill_guest(lg, "hypercall %li before INIT", lg->hcall->arg0); + if (cpu->hcall->arg0 != LHCALL_LGUEST_INIT) { + kill_guest(lg, "hypercall %li before INIT", cpu->hcall->arg0); return; } - if (lguest_arch_init_hypercalls(lg)) + if (lguest_arch_init_hypercalls(cpu)) kill_guest(lg, "bad guest page %p", lg->lguest_data); /* The Guest tells us where we're not to deliver interrupts by putting @@ -185,7 +191,7 @@ * first write to a Guest page. This may have caused a copy-on-write * fault, but the old page might be (read-only) in the Guest * pagetable. */ - guest_pagetable_clear_all(lg); + guest_pagetable_clear_all(cpu); } /*H:100 @@ -194,27 +200,27 @@ * Remember from the Guest, hypercalls come in two flavors: normal and * asynchronous. This file handles both of types. */ -void do_hypercalls(struct lguest *lg) +void do_hypercalls(struct lg_cpu *cpu) { /* Not initialized yet? This hypercall must do it. */ - if (unlikely(!lg->lguest_data)) { + if (unlikely(!cpu->lg->lguest_data)) { /* Set up the "struct lguest_data" */ - initialize(lg); + initialize(cpu); /* Hcall is done. */ - lg->hcall = NULL; + cpu->hcall = NULL; return; } /* The Guest has initialized. * * Look in the hypercall ring for the async hypercalls: */ - do_async_hcalls(lg); + do_async_hcalls(cpu); /* If we stopped reading the hypercall ring because the Guest did a * NOTIFY to the Launcher, we want to return now. Otherwise we do * the hypercall. */ - if (!lg->pending_notify) { - do_hcall(lg, lg->hcall); + if (!cpu->pending_notify) { + do_hcall(cpu, cpu->hcall); /* Tricky point: we reset the hcall pointer to mark the * hypercall as "done". We use the hcall pointer rather than * the trap number to indicate a hypercall is pending. @@ -225,7 +231,7 @@ * Launcher, the run_guest() loop will exit without running the * Guest. When it comes back it would try to re-run the * hypercall. */ - lg->hcall = NULL; + cpu->hcall = NULL; } } --- linux-2.6.24.orig/drivers/lguest/lg.h +++ linux-2.6.24/drivers/lguest/lg.h @@ -38,58 +38,71 @@ #define CHANGED_GDT_TLS 4 /* Actually a subset of CHANGED_GDT */ #define CHANGED_ALL 3 -/* The private info the thread maintains about the guest. */ -struct lguest -{ - /* At end of a page shared mapped over lguest_pages in guest. */ - unsigned long regs_page; - struct lguest_regs *regs; - struct lguest_data __user *lguest_data; +struct lguest; + +struct lg_cpu { + unsigned int id; + struct lguest *lg; struct task_struct *tsk; struct mm_struct *mm; /* == tsk->mm, but that becomes NULL on exit */ - u32 pfn_limit; - /* This provides the offset to the base of guest-physical - * memory in the Launcher. */ - void __user *mem_base; - unsigned long kernel_address; + u32 cr2; - int halted; int ts; - u32 next_hcall; u32 esp1; u8 ss1; + unsigned long pending_notify; /* pfn from LHCALL_NOTIFY */ + + /* At end of a page shared mapped over lguest_pages in guest. */ + unsigned long regs_page; + struct lguest_regs *regs; + + int cpu_pgd; /* which pgd this cpu is currently using */ + /* If a hypercall was asked for, this points to the arguments. */ struct hcall_args *hcall; + u32 next_hcall; + + /* Virtual clock device */ + struct hrtimer hrt; /* Do we need to stop what we're doing and return to userspace? */ int break_out; wait_queue_head_t break_wq; + int halted; + + /* Pending virtual interrupts */ + DECLARE_BITMAP(irqs_pending, LGUEST_IRQS); + + struct lg_cpu_arch arch; +}; + +/* The private info the thread maintains about the guest. */ +struct lguest +{ + struct lguest_data __user *lguest_data; + struct lg_cpu cpus[NR_CPUS]; + unsigned int nr_cpus; + + u32 pfn_limit; + /* This provides the offset to the base of guest-physical + * memory in the Launcher. */ + void __user *mem_base; + unsigned long kernel_address; /* Bitmap of what has changed: see CHANGED_* above. */ int changed; struct lguest_pages *last_pages; - /* We keep a small number of these. */ - u32 pgdidx; struct pgdir pgdirs[4]; unsigned long noirq_start, noirq_end; - unsigned long pending_notify; /* pfn from LHCALL_NOTIFY */ unsigned int stack_pages; u32 tsc_khz; /* Dead? */ const char *dead; - - struct lguest_arch arch; - - /* Virtual clock device */ - struct hrtimer hrt; - - /* Pending virtual interrupts */ - DECLARE_BITMAP(irqs_pending, LGUEST_IRQS); }; extern struct mutex lguest_lock; @@ -116,7 +129,7 @@ } while(0) /* (end of memory access helper routines) :*/ -int run_guest(struct lguest *lg, unsigned long __user *user); +int run_guest(struct lg_cpu *cpu, unsigned long __user *user); /* Helper macros to obtain the first 12 or the last 20 bits, this is only the * first step in the migration to the kernel types. pte_pfn is already defined @@ -126,52 +139,53 @@ #define pgd_pfn(x) (pgd_val(x) >> PAGE_SHIFT) /* interrupts_and_traps.c: */ -void maybe_do_interrupt(struct lguest *lg); -int deliver_trap(struct lguest *lg, unsigned int num); -void load_guest_idt_entry(struct lguest *lg, unsigned int i, u32 low, u32 hi); -void guest_set_stack(struct lguest *lg, u32 seg, u32 esp, unsigned int pages); -void pin_stack_pages(struct lguest *lg); +void maybe_do_interrupt(struct lg_cpu *cpu); +int deliver_trap(struct lg_cpu *cpu, unsigned int num); +void load_guest_idt_entry(struct lg_cpu *cpu, unsigned int i, + u32 low, u32 hi); +void guest_set_stack(struct lg_cpu *cpu, u32 seg, u32 esp, unsigned int pages); +void pin_stack_pages(struct lg_cpu *cpu); void setup_default_idt_entries(struct lguest_ro_state *state, const unsigned long *def); -void copy_traps(const struct lguest *lg, struct desc_struct *idt, +void copy_traps(const struct lg_cpu *cpu, struct desc_struct *idt, const unsigned long *def); -void guest_set_clockevent(struct lguest *lg, unsigned long delta); -void init_clockdev(struct lguest *lg); +void guest_set_clockevent(struct lg_cpu *cpu, unsigned long delta); +void init_clockdev(struct lg_cpu *cpu); bool check_syscall_vector(struct lguest *lg); int init_interrupts(void); void free_interrupts(void); /* segments.c: */ void setup_default_gdt_entries(struct lguest_ro_state *state); -void setup_guest_gdt(struct lguest *lg); -void load_guest_gdt(struct lguest *lg, unsigned long table, u32 num); -void guest_load_tls(struct lguest *lg, unsigned long tls_array); -void copy_gdt(const struct lguest *lg, struct desc_struct *gdt); -void copy_gdt_tls(const struct lguest *lg, struct desc_struct *gdt); +void setup_guest_gdt(struct lg_cpu *cpu); +void load_guest_gdt(struct lg_cpu *cpu, unsigned long table, u32 num); +void guest_load_tls(struct lg_cpu *cpu, unsigned long tls_array); +void copy_gdt(const struct lg_cpu *cpu, struct desc_struct *gdt); +void copy_gdt_tls(const struct lg_cpu *cpu, struct desc_struct *gdt); /* page_tables.c: */ int init_guest_pagetable(struct lguest *lg, unsigned long pgtable); void free_guest_pagetable(struct lguest *lg); -void guest_new_pagetable(struct lguest *lg, unsigned long pgtable); +void guest_new_pagetable(struct lg_cpu *cpu, unsigned long pgtable); void guest_set_pmd(struct lguest *lg, unsigned long gpgdir, u32 i); -void guest_pagetable_clear_all(struct lguest *lg); -void guest_pagetable_flush_user(struct lguest *lg); +void guest_pagetable_clear_all(struct lg_cpu *cpu); +void guest_pagetable_flush_user(struct lg_cpu *cpu); void guest_set_pte(struct lguest *lg, unsigned long gpgdir, unsigned long vaddr, pte_t val); -void map_switcher_in_guest(struct lguest *lg, struct lguest_pages *pages); -int demand_page(struct lguest *info, unsigned long cr2, int errcode); -void pin_page(struct lguest *lg, unsigned long vaddr); -unsigned long guest_pa(struct lguest *lg, unsigned long vaddr); +void map_switcher_in_guest(struct lg_cpu *cpu, struct lguest_pages *pages); +int demand_page(struct lg_cpu *cpu, unsigned long cr2, int errcode); +void pin_page(struct lg_cpu *cpu, unsigned long vaddr); +unsigned long guest_pa(struct lg_cpu *cpu, unsigned long vaddr); void page_table_guest_data_init(struct lguest *lg); /* /core.c: */ void lguest_arch_host_init(void); void lguest_arch_host_fini(void); -void lguest_arch_run_guest(struct lguest *lg); -void lguest_arch_handle_trap(struct lguest *lg); -int lguest_arch_init_hypercalls(struct lguest *lg); -int lguest_arch_do_hcall(struct lguest *lg, struct hcall_args *args); -void lguest_arch_setup_regs(struct lguest *lg, unsigned long start); +void lguest_arch_run_guest(struct lg_cpu *cpu); +void lguest_arch_handle_trap(struct lg_cpu *cpu); +int lguest_arch_init_hypercalls(struct lg_cpu *cpu); +int lguest_arch_do_hcall(struct lg_cpu *cpu, struct hcall_args *args); +void lguest_arch_setup_regs(struct lg_cpu *cpu, unsigned long start); /* /switcher.S: */ extern char start_switcher_text[], end_switcher_text[], switch_to_guest[]; @@ -181,7 +195,7 @@ void lguest_device_remove(void); /* hypercalls.c: */ -void do_hypercalls(struct lguest *lg); +void do_hypercalls(struct lg_cpu *cpu); void write_timestamp(struct lguest *lg); /*L:035 --- linux-2.6.24.orig/drivers/lguest/Makefile +++ linux-2.6.24/drivers/lguest/Makefile @@ -19,3 +19,11 @@ @for f in Preparation Guest Drivers Launcher Host Switcher Mastery; do echo "{==- $$f -==}"; make -s $$f; done; echo "{==-==}" Preparation Preparation! Guest Drivers Launcher Host Switcher Mastery: @sh ../../Documentation/lguest/extract $(PREFIX) `find ../../* -name '*.[chS]' -wholename '*lguest*'` +Puppy: + @clear + @printf " __ \n (___()'\`;\n /, /\`\n \\\\\\\"--\\\\\\ \n" + @sleep 2; clear; printf "\n\n Sit!\n\n"; sleep 1; clear + @printf " __ \n ()'\`; \n /\\|\` \n / | \n(/_)_|_ \n" + @sleep 2; clear; printf "\n\n Stand!\n\n"; sleep 1; clear + @printf " __ \n ()'\`; \n /\\|\` \n /._.= \n /| / \n(_\_)_ \n" + @sleep 2; clear; printf "\n\n Good puppy!\n\n"; sleep 1; clear --- linux-2.6.24.orig/drivers/lguest/x86/core.c +++ linux-2.6.24/drivers/lguest/x86/core.c @@ -73,8 +73,9 @@ * since it last ran. We saw this set in interrupts_and_traps.c and * segments.c. */ -static void copy_in_guest_info(struct lguest *lg, struct lguest_pages *pages) +static void copy_in_guest_info(struct lg_cpu *cpu, struct lguest_pages *pages) { + struct lguest *lg = cpu->lg; /* Copying all this data can be quite expensive. We usually run the * same Guest we ran last time (and that Guest hasn't run anywhere else * meanwhile). If that's not the case, we pretend everything in the @@ -90,42 +91,43 @@ pages->state.host_cr3 = __pa(current->mm->pgd); /* Set up the Guest's page tables to see this CPU's pages (and no * other CPU's pages). */ - map_switcher_in_guest(lg, pages); + map_switcher_in_guest(cpu, pages); /* Set up the two "TSS" members which tell the CPU what stack to use * for traps which do directly into the Guest (ie. traps at privilege * level 1). */ - pages->state.guest_tss.esp1 = lg->esp1; - pages->state.guest_tss.ss1 = lg->ss1; + pages->state.guest_tss.esp1 = cpu->esp1; + pages->state.guest_tss.ss1 = cpu->ss1; /* Copy direct-to-Guest trap entries. */ if (lg->changed & CHANGED_IDT) - copy_traps(lg, pages->state.guest_idt, default_idt_entries); + copy_traps(cpu, pages->state.guest_idt, default_idt_entries); /* Copy all GDT entries which the Guest can change. */ if (lg->changed & CHANGED_GDT) - copy_gdt(lg, pages->state.guest_gdt); + copy_gdt(cpu, pages->state.guest_gdt); /* If only the TLS entries have changed, copy them. */ else if (lg->changed & CHANGED_GDT_TLS) - copy_gdt_tls(lg, pages->state.guest_gdt); + copy_gdt_tls(cpu, pages->state.guest_gdt); /* Mark the Guest as unchanged for next time. */ lg->changed = 0; } /* Finally: the code to actually call into the Switcher to run the Guest. */ -static void run_guest_once(struct lguest *lg, struct lguest_pages *pages) +static void run_guest_once(struct lg_cpu *cpu, struct lguest_pages *pages) { /* This is a dummy value we need for GCC's sake. */ unsigned int clobber; + struct lguest *lg = cpu->lg; /* Copy the guest-specific information into this CPU's "struct * lguest_pages". */ - copy_in_guest_info(lg, pages); + copy_in_guest_info(cpu, pages); /* Set the trap number to 256 (impossible value). If we fault while * switching to the Guest (bad segment registers or bug), this will * cause us to abort the Guest. */ - lg->regs->trapnum = 256; + cpu->regs->trapnum = 256; /* Now: we push the "eflags" register on the stack, then do an "lcall". * This is how we change from using the kernel code segment to using @@ -143,7 +145,7 @@ * 0-th argument above, ie "a"). %ebx contains the * physical address of the Guest's top-level page * directory. */ - : "0"(pages), "1"(__pa(lg->pgdirs[lg->pgdidx].pgdir)) + : "0"(pages), "1"(__pa(lg->pgdirs[cpu->cpu_pgd].pgdir)) /* We tell gcc that all these registers could change, * which means we don't have to save and restore them in * the Switcher. */ @@ -161,12 +163,12 @@ /*H:040 This is the i386-specific code to setup and run the Guest. Interrupts * are disabled: we own the CPU. */ -void lguest_arch_run_guest(struct lguest *lg) +void lguest_arch_run_guest(struct lg_cpu *cpu) { /* Remember the awfully-named TS bit? If the Guest has asked to set it * we set it now, so we can trap and pass that trap to the Guest if it * uses the FPU. */ - if (lg->ts) + if (cpu->ts) lguest_set_ts(); /* SYSENTER is an optimized way of doing system calls. We can't allow @@ -180,7 +182,7 @@ /* Now we actually run the Guest. It will return when something * interesting happens, and we can examine its registers to see what it * was doing. */ - run_guest_once(lg, lguest_pages(raw_smp_processor_id())); + run_guest_once(cpu, lguest_pages(raw_smp_processor_id())); /* Note that the "regs" pointer contains two extra entries which are * not really registers: a trap number which says what interrupt or @@ -191,11 +193,11 @@ * bad virtual address. We have to grab this now, because once we * re-enable interrupts an interrupt could fault and thus overwrite * cr2, or we could even move off to a different CPU. */ - if (lg->regs->trapnum == 14) - lg->arch.last_pagefault = read_cr2(); + if (cpu->regs->trapnum == 14) + cpu->arch.last_pagefault = read_cr2(); /* Similarly, if we took a trap because the Guest used the FPU, * we have to restore the FPU it expects to see. */ - else if (lg->regs->trapnum == 7) + else if (cpu->regs->trapnum == 7) math_state_restore(); /* Restore SYSENTER if it's supposed to be on. */ @@ -214,18 +216,19 @@ * When the Guest uses one of these instructions, we get a trap (General * Protection Fault) and come here. We see if it's one of those troublesome * instructions and skip over it. We return true if we did. */ -static int emulate_insn(struct lguest *lg) +static int emulate_insn(struct lg_cpu *cpu) { + struct lguest *lg = cpu->lg; u8 insn; unsigned int insnlen = 0, in = 0, shift = 0; /* The eip contains the *virtual* address of the Guest's instruction: * guest_pa just subtracts the Guest's page_offset. */ - unsigned long physaddr = guest_pa(lg, lg->regs->eip); + unsigned long physaddr = guest_pa(cpu, cpu->regs->eip); /* This must be the Guest kernel trying to do something, not userspace! * The bottom two bits of the CS segment register are the privilege * level. */ - if ((lg->regs->cs & 3) != GUEST_PL) + if ((cpu->regs->cs & 3) != GUEST_PL) return 0; /* Decoding x86 instructions is icky. */ @@ -268,26 +271,27 @@ if (in) { /* Lower bit tells is whether it's a 16 or 32 bit access */ if (insn & 0x1) - lg->regs->eax = 0xFFFFFFFF; + cpu->regs->eax = 0xFFFFFFFF; else - lg->regs->eax |= (0xFFFF << shift); + cpu->regs->eax |= (0xFFFF << shift); } /* Finally, we've "done" the instruction, so move past it. */ - lg->regs->eip += insnlen; + cpu->regs->eip += insnlen; /* Success! */ return 1; } /*H:050 Once we've re-enabled interrupts, we look at why the Guest exited. */ -void lguest_arch_handle_trap(struct lguest *lg) +void lguest_arch_handle_trap(struct lg_cpu *cpu) { - switch (lg->regs->trapnum) { + struct lguest *lg = cpu->lg; + switch (cpu->regs->trapnum) { case 13: /* We've intercepted a General Protection Fault. */ /* Check if this was one of those annoying IN or OUT * instructions which we need to emulate. If so, we just go * back into the Guest after we've done it. */ - if (lg->regs->errcode == 0) { - if (emulate_insn(lg)) + if (cpu->regs->errcode == 0) { + if (emulate_insn(cpu)) return; } break; @@ -301,7 +305,8 @@ * * The errcode tells whether this was a read or a write, and * whether kernel or userspace code. */ - if (demand_page(lg, lg->arch.last_pagefault, lg->regs->errcode)) + if (demand_page(cpu, cpu->arch.last_pagefault, + cpu->regs->errcode)) return; /* OK, it's really not there (or not OK): the Guest needs to @@ -312,14 +317,14 @@ * happen before it's done the LHCALL_LGUEST_INIT hypercall, so * lg->lguest_data could be NULL */ if (lg->lguest_data && - put_user(lg->arch.last_pagefault, &lg->lguest_data->cr2)) + put_user(cpu->arch.last_pagefault, &lg->lguest_data->cr2)) kill_guest(lg, "Writing cr2"); break; case 7: /* We've intercepted a Device Not Available fault. */ /* If the Guest doesn't want to know, we already restored the * Floating Point Unit, so we just continue without telling * it. */ - if (!lg->ts) + if (!cpu->ts) return; break; case 32 ... 255: @@ -332,19 +337,19 @@ case LGUEST_TRAP_ENTRY: /* Our 'struct hcall_args' maps directly over our regs: we set * up the pointer now to indicate a hypercall is pending. */ - lg->hcall = (struct hcall_args *)lg->regs; + cpu->hcall = (struct hcall_args *)cpu->regs; return; } /* We didn't handle the trap, so it needs to go to the Guest. */ - if (!deliver_trap(lg, lg->regs->trapnum)) + if (!deliver_trap(cpu, cpu->regs->trapnum)) /* If the Guest doesn't have a handler (either it hasn't * registered any yet, or it's one of the faults we don't let * it handle), it dies with a cryptic error message. */ kill_guest(lg, "unhandled trap %li at %#lx (%#lx)", - lg->regs->trapnum, lg->regs->eip, - lg->regs->trapnum == 14 ? lg->arch.last_pagefault - : lg->regs->errcode); + cpu->regs->trapnum, cpu->regs->eip, + cpu->regs->trapnum == 14 ? cpu->arch.last_pagefault + : cpu->regs->errcode); } /* Now we can look at each of the routines this calls, in increasing order of @@ -487,17 +492,17 @@ /*H:122 The i386-specific hypercalls simply farm out to the right functions. */ -int lguest_arch_do_hcall(struct lguest *lg, struct hcall_args *args) +int lguest_arch_do_hcall(struct lg_cpu *cpu, struct hcall_args *args) { switch (args->arg0) { case LHCALL_LOAD_GDT: - load_guest_gdt(lg, args->arg1, args->arg2); + load_guest_gdt(cpu, args->arg1, args->arg2); break; case LHCALL_LOAD_IDT_ENTRY: - load_guest_idt_entry(lg, args->arg1, args->arg2, args->arg3); + load_guest_idt_entry(cpu, args->arg1, args->arg2, args->arg3); break; case LHCALL_LOAD_TLS: - guest_load_tls(lg, args->arg1); + guest_load_tls(cpu, args->arg1); break; default: /* Bad Guest. Bad! */ @@ -507,13 +512,14 @@ } /*H:126 i386-specific hypercall initialization: */ -int lguest_arch_init_hypercalls(struct lguest *lg) +int lguest_arch_init_hypercalls(struct lg_cpu *cpu) { u32 tsc_speed; + struct lguest *lg = cpu->lg; /* The pointer to the Guest's "struct lguest_data" is the only * argument. We check that address now. */ - if (!lguest_address_ok(lg, lg->hcall->arg1, sizeof(*lg->lguest_data))) + if (!lguest_address_ok(lg, cpu->hcall->arg1, sizeof(*lg->lguest_data))) return -EFAULT; /* Having checked it, we simply set lg->lguest_data to point straight @@ -521,7 +527,7 @@ * copy_to_user/from_user from now on, instead of lgread/write. I put * this in to show that I'm not immune to writing stupid * optimizations. */ - lg->lguest_data = lg->mem_base + lg->hcall->arg1; + lg->lguest_data = lg->mem_base + cpu->hcall->arg1; /* We insist that the Time Stamp Counter exist and doesn't change with * cpu frequency. Some devious chip manufacturers decided that TSC @@ -548,9 +554,9 @@ * * Most of the Guest's registers are left alone: we used get_zeroed_page() to * allocate the structure, so they will be 0. */ -void lguest_arch_setup_regs(struct lguest *lg, unsigned long start) +void lguest_arch_setup_regs(struct lg_cpu *cpu, unsigned long start) { - struct lguest_regs *regs = lg->regs; + struct lguest_regs *regs = cpu->regs; /* There are four "segment" registers which the Guest needs to boot: * The "code segment" register (cs) refers to the kernel code segment @@ -577,5 +583,5 @@ /* There are a couple of GDT entries the Guest expects when first * booting. */ - setup_guest_gdt(lg); + setup_guest_gdt(cpu); } --- linux-2.6.24.orig/drivers/isdn/capi/capidrv.c +++ linux-2.6.24/drivers/isdn/capi/capidrv.c @@ -2332,13 +2332,14 @@ static void __exit capidrv_exit(void) { - char rev[10]; + char rev[32]; char *p; if ((p = strchr(revision, ':')) != 0) { - strcpy(rev, p + 1); - p = strchr(rev, '$'); - *p = 0; + strncpy(rev, p + 1, sizeof(rev)); + rev[sizeof(rev)-1] = 0; + if ((p = strchr(rev, '$')) != 0) + *p = 0; } else { strcpy(rev, " ??? "); } --- linux-2.6.24.orig/drivers/isdn/i4l/isdn_net.c +++ linux-2.6.24/drivers/isdn/i4l/isdn_net.c @@ -2010,6 +2010,7 @@ ndev->flags = IFF_NOARP|IFF_POINTOPOINT; ndev->type = ARPHRD_ETHER; ndev->addr_len = ETH_ALEN; + ndev->validate_addr = NULL; /* for clients with MPPP maybe higher values better */ ndev->tx_queue_len = 30; --- linux-2.6.24.orig/drivers/infiniband/ulp/srp/ib_srp.c +++ linux-2.6.24/drivers/infiniband/ulp/srp/ib_srp.c @@ -2055,6 +2055,7 @@ &host->target_list, list) { srp_remove_host(target->scsi_host); scsi_remove_host(target->scsi_host); + srp_remove_host(target->scsi_host); srp_disconnect_target(target); ib_destroy_cm_id(target->cm_id); srp_free_target_ib(target); --- linux-2.6.24.orig/drivers/mmc/Kconfig +++ linux-2.6.24/drivers/mmc/Kconfig @@ -2,6 +2,8 @@ # MMC subsystem configuration # +menu "MMC/SD/SDIO support, can only select one arch from MMC and MSS" + menuconfig MMC tristate "MMC/SD card support" depends on HAS_IOMEM @@ -17,7 +19,6 @@ help This is an option for use by developers; most people should say N here. This enables MMC core and driver debugging. - if MMC source "drivers/mmc/core/Kconfig" @@ -27,3 +28,22 @@ source "drivers/mmc/host/Kconfig" endif # MMC + +config MSS + tristate "MSS architecture MMC/SD/SDIO Interface support" + help + MSS is an advanced version of the MMC protocol drivers + which abstracts the control layer to encompass multiple + media card formats. Simply define the protocols you + wish to use (one is MMC for instance, another is SD). + + If you want MSS support, you should say M here and also + to the specific drivers for your MSS interface. + +if MSS + +source "drivers/mmc/mss/Kconfig" + +endif + +endmenu --- linux-2.6.24.orig/drivers/mmc/Makefile +++ linux-2.6.24/drivers/mmc/Makefile @@ -9,4 +9,5 @@ obj-$(CONFIG_MMC) += core/ obj-$(CONFIG_MMC) += card/ obj-$(CONFIG_MMC) += host/ +obj-$(CONFIG_MSS) += mss/ --- linux-2.6.24.orig/drivers/mmc/core/core.c +++ linux-2.6.24/drivers/mmc/core/core.c @@ -496,7 +496,7 @@ * This delay must be at least 74 clock sizes, or 1 ms, or the * time required to reach a stable voltage. */ - mmc_delay(2); + mmc_delay(10); } static void mmc_power_off(struct mmc_host *host) --- linux-2.6.24.orig/drivers/mmc/card/block.c +++ linux-2.6.24/drivers/mmc/card/block.c @@ -46,7 +46,7 @@ #define MMC_SHIFT 3 #define MMC_NUM_MINORS (256 >> MMC_SHIFT) -static unsigned long dev_use[MMC_NUM_MINORS/(8*sizeof(unsigned long))]; +static DECLARE_BITMAP(dev_use,MMC_NUM_MINORS); /* * There is one mmc_blk_data per slot. --- linux-2.6.24.orig/drivers/mmc/mss/sdio_protocol.c +++ linux-2.6.24/drivers/mmc/mss/sdio_protocol.c @@ -0,0 +1,1094 @@ +/* + * sdio_protocol.c - SDIO protocol driver + * + * Copyright (C) 2007 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 only + * for now as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * derived from previous mmc code in Linux kernel + * Copyright (c) 2002 Hewlett-Packard Company + * Copyright (c) 2002 Andrew Christian + * Copyright (c) 2006 Bridge Wu + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/***************************************************************************** + * + * internal functions + * + ****************************************************************************/ + +#define KBPS 1 +#define MBPS 1000 + +static u32 ts_exp[] = { 100*KBPS, 1*MBPS, 10*MBPS, 100*MBPS, 0, 0, 0, 0 }; +static u32 ts_mul[] = { 0, 1000, 1200, 1300, 1500, 2000, 2500, 3000, + 3500, 4000, 4500, 5000, 5500, 6000, 7000, 8000 }; + +static u32 sdio_tran_speed( u8 ts ) +{ + u32 clock = ts_exp[(ts & 0x7)] * ts_mul[(ts & 0x78) >> 3]; + + dbg5("clock :%d", clock); + return clock; +} + +static int sdio_unpack_r1(struct mss_cmd *cmd, struct sdio_response_r1 *r1, struct sdio_card *sdio_card) +{ + u8 *buf = cmd->response; + + //debug(" result in r1: %d\n", request->result); + //if ( request->result ) return request->result; + + sdio_card->errno = SDIO_ERROR_NONE; + r1->cmd = unstuff_bits(buf, 40, 8, 6); + r1->status = unstuff_bits(buf, 8, 32, 6); + + dbg5("status 0x%x", r1->status); + if (R1_STATUS(r1->status)) { + if (r1->status & R1_OUT_OF_RANGE) + sdio_card->errno = SDIO_ERROR_OUT_OF_RANGE; + if (r1->status & R1_COM_CRC_ERROR) + sdio_card->errno = SDIO_ERROR_COM_CRC; + if (r1->status & R1_ILLEGAL_COMMAND) + sdio_card->errno = SDIO_ERROR_ILLEGAL_COMMAND; + if (r1->status & R1_ERROR) + sdio_card->errno = SDIO_ERROR_GENERAL; + } + + if (r1->cmd != cmd->opcode) + sdio_card->errno = SDIO_ERROR_HEADER_MISMATCH; + dbg5("command:0x%x", r1->cmd); + /* This should be last - it's the least dangerous error */ + if (sdio_card->errno != SDIO_ERROR_NONE) + return MSS_ERROR_RESP_UNPACK; + return MSS_ERROR_NONE; +} + + +static int sdio_unpack_r4(struct mss_cmd *cmd, struct sdio_response_r4 *r4, struct sdio_card *sdio_card) +{ + u8 *buf = cmd->response; + + r4->ocr = unstuff_bits(buf, 8, 24, 6); + r4->ready = unstuff_bits(buf, 39, 1, 6); + r4->mem_present = unstuff_bits(buf, 35, 1, 6); + r4->func_num = unstuff_bits(buf, 36, 3, 6); + dbg5("ocr=%08x,ready=%d,mp=%d,fun_num:%d\n", r4->ocr, r4->ready, +r4->mem_present, r4->func_num); + return 0; +} + + +static int sdio_unpack_r5(struct mss_cmd *cmd, struct sdio_response_r5 *r5, struct sdio_card *sdio_card) +{ + u8 *buf = cmd->response; + + sdio_card->errno = SDIO_ERROR_NONE; + r5->cmd = unstuff_bits(buf, 40, 8, 6); + r5->status = unstuff_bits(buf, 16, 8, 6); + r5->data = unstuff_bits(buf, 8, 8, 6); + dbg5("cmd=%d status=%02x,data:%02x", r5->cmd, r5->status, r5->data); + + if (r5->status) { + if (r5->status & R5_OUT_OF_RANGE) + return SDIO_ERROR_OUT_OF_RANGE; + if (r5->status & R5_COM_CRC_ERROR) + return SDIO_ERROR_COM_CRC; + if (r5->status & R5_ILLEGAL_COMMAND) + return SDIO_ERROR_ILLEGAL_COMMAND; + if (r5->status & R5_ERROR) + return SDIO_ERROR_GENERAL; + if (r5->status & R5_FUNCTION_NUMBER) + return SDIO_ERROR_FUNC_NUM; + } + + if (r5->cmd != cmd->opcode) { + return SDIO_ERROR_HEADER_MISMATCH; + } + + return 0; +} + +static u16 sdio_unpack_r6(struct mss_cmd *cmd, struct sdio_response_r6 *r6, struct sdio_card *sdio_card) +{ + u8 *buf = cmd->response; + int errno = SDIO_ERROR_NONE; + + r6->cmd = unstuff_bits(buf, 40, 8, 6); + r6->rca = unstuff_bits(buf, 24, 16, 6); + r6->status = unstuff_bits(buf, 8, 16, 6); + if (R6_STATUS(r6->status)) { + if (r6->status & R6_COM_CRC_ERROR) + errno = SDIO_ERROR_COM_CRC; + if (r6->status & R6_ILLEGAL_COMMAND) + errno = SDIO_ERROR_ILLEGAL_COMMAND; + if (r6->status & R6_ERROR) + errno = SDIO_ERROR_GENERAL; + } + if (r6->cmd != cmd->opcode) + errno = SDIO_ERROR_HEADER_MISMATCH; + sdio_card->errno = errno; + if (errno) + return MSS_ERROR_RESP_UNPACK; + return 0 ; + +} + + +/***************************************************************************** + * + * internal functions + * + ****************************************************************************/ + +/* sdio related function */ +static u32 sdio_make_cmd52_arg(int rw, int fun_num, int raw, int address, int write_data) +{ + u32 ret; + dbg5("rw:%d,fun:%d,raw:%d,address:%d,write_data:%d\n", + rw, fun_num, raw, address, write_data); + ret = (rw << 31) | (fun_num << 28) | (raw << 27) | (address << 9) | write_data; + return ret; +} + +static u32 sdio_make_cmd53_arg(int rw, int fun_num, int block_mode, int op_code, int address, int count) +{ + u32 ret; + dbg5("rw:%d,fun:%d,block_mode:%d,op_code:%d,address:%d,count:%d\n", + rw, fun_num, block_mode, op_code, address, count); + ret = (rw << 31) | (fun_num << 28) | (block_mode << 27) | (op_code << 26) | (address << 9) | count; + return ret; +} + +#define SDIO_FN0_READ_REG(addr) \ + do { \ + arg = sdio_make_cmd52_arg(SDIO_R, 0, 0, addr, 0); \ + ret = mss_send_simple_ll_req(host, llreq, cmd, \ + IO_RW_DIRECT, arg, MSS_RESPONSE_R5, \ + MSS_CMD_SDIO_EN); \ + if (ret) { \ + dbg5("CMD ERROR: ret = %d\n", ret); \ + return ret; \ + } \ + ret = sdio_unpack_r5(cmd, &r5, sdio_card); \ + if (ret) { \ + dbg5("UNPACK ERROR: ret = %d\n", ret); \ + return ret; \ + } \ + } while(0) + +#define SDIO_FN0_WRITE_REG(addr, val) \ + do { \ + arg = sdio_make_cmd52_arg(SDIO_W, 0, 0, addr, val); \ + ret = mss_send_simple_ll_req(host, llreq, cmd, \ + IO_RW_DIRECT, arg, MSS_RESPONSE_R5, \ + MSS_CMD_SDIO_EN); \ + if (ret) { \ + dbg5("CMD ERROR: ret = %d\n", ret); \ + return ret; \ + } \ + ret = sdio_unpack_r5(cmd, &r5, sdio_card); \ + if (ret) { \ + dbg5("UNPACK ERROR: ret = %d\n", ret); \ + return ret; \ + } \ + } while(0) + + +static int sdio_set_bus_width(struct mss_card *card, u8 buswidth) +{ + struct mss_host *host = card->slot->host; + struct sdio_card *sdio_card = card->prot_card; + struct mss_cmd *cmd = &sdio_card->cmd; + struct mss_ll_request *llreq = &sdio_card->llreq; + struct sdio_response_r5 r5; + int ret,arg; + + SDIO_FN0_WRITE_REG(BUS_IF_CTRL, buswidth); + card->bus_width = MSS_BUSWIDTH_4BIT; + + return 0; +} + +static int sdio_set_block_size(struct mss_card *card, u16 size, int func) +{ + struct mss_host *host = card->slot->host; + struct sdio_card *sdio_card = card->prot_card; + struct mss_cmd *cmd = &sdio_card->cmd; + struct mss_ll_request *llreq = &sdio_card->llreq; + struct sdio_response_r5 r5; + int ret,arg; + u8 tmp; + + if (func == 0) { + tmp = size & 0xff; + SDIO_FN0_WRITE_REG(FN0_BLKSZ_1, tmp); + + tmp = (size & 0xff00) >> 8; + SDIO_FN0_WRITE_REG(FN0_BLKSZ_2, tmp); + + sdio_card->cccr.fn0_blksz = size; + } else { + tmp = size & 0xff; + SDIO_FN0_WRITE_REG(FNn_BLKSZ_1(func), tmp); + + tmp = (size & 0xff00) >> 8; + SDIO_FN0_WRITE_REG(FNn_BLKSZ_2(func), tmp); + + sdio_card->fbr[func].fn_blksz = size; + } + + return 0; +} + +static int sdio_io_enable(struct mss_card *card, u8 set_mask) +{ + struct mss_host *host = card->slot->host; + struct sdio_card *sdio_card = card->prot_card; + struct mss_cmd *cmd = &sdio_card->cmd; + struct mss_ll_request *llreq = &sdio_card->llreq; + struct sdio_response_r5 r5; + int ret, arg; + + SDIO_FN0_WRITE_REG(IO_ENABLE, set_mask); + + return 0; +} + +static int sdio_interrupt_enable(struct mss_card *card, u8 set_mask) +{ + struct mss_host *host = card->slot->host; + struct sdio_card *sdio_card = card->prot_card; + struct mss_cmd *cmd = &sdio_card->cmd; + struct mss_ll_request *llreq = &sdio_card->llreq; + struct sdio_response_r5 r5; + int ret, arg; + + SDIO_FN0_WRITE_REG(INT_ENABLE, set_mask); + + return 0; +} + +static int sdio_csa_enable(struct mss_card *card, int func) +{ + struct mss_host *host = card->slot->host; + struct sdio_card *sdio_card = card->prot_card; + struct mss_cmd *cmd = &sdio_card->cmd; + struct mss_ll_request *llreq = &sdio_card->llreq; + struct sdio_response_r5 r5; + int arg; + int ret = 0; + + if(sdio_card->fbr[func].fun_support_csa == 0) + return ret; + + SDIO_FN0_WRITE_REG(FNn_IF_CODE(func), 0x80); + + return 0; +} + + +static int get_sdio_fbr_info(struct mss_card *card, int func) +{ + struct mss_host *host = card->slot->host; + struct sdio_card *sdio_card = card->prot_card; + struct mss_cmd *cmd = &sdio_card->cmd; + struct mss_ll_request *llreq = &sdio_card->llreq; + struct sdio_response_r5 r5; + int ret,arg; + u32 tmp; + + dbg5("get_sdio_fbr_info"); + SDIO_FN0_READ_REG(FNn_IF_CODE(func)); + sdio_card->fbr[func].fun_if_code = r5.data & 0xF; + sdio_card->fbr[func].fun_support_csa = (r5.data >> 6) & 0x1; + sdio_card->fbr[func].fun_csa_enable = (r5.data >> 7) & 0x1; + + SDIO_FN0_READ_REG(FNn_EXT_IF_CODE(func)); + sdio_card->fbr[func].fun_ext_if_code = r5.data; + + SDIO_FN0_READ_REG(FNn_CIS_POINTER_1(func)); + tmp = r5.data; + SDIO_FN0_READ_REG(FNn_CIS_POINTER_2(func)); + tmp |= r5.data << 8; + SDIO_FN0_READ_REG(FNn_CIS_POINTER_3(func)); + tmp |= r5.data << 16; + sdio_card->fbr[func].pfcis = tmp; + + SDIO_FN0_READ_REG(FNn_CSA_POINTER_1(func)); + tmp = r5.data; + SDIO_FN0_READ_REG(FNn_CSA_POINTER_2(func)); + tmp |= r5.data << 8; + SDIO_FN0_READ_REG(FNn_CSA_POINTER_3(func)); + tmp |= r5.data << 16; + sdio_card->fbr[func].pcsa = tmp; + + SDIO_FN0_READ_REG(FNn_BLKSZ_1(func)); + tmp = r5.data; + SDIO_FN0_READ_REG(FNn_BLKSZ_2(func)); + tmp |= r5.data << 8; + sdio_card->fbr[func].fn_blksz = tmp; + + dbg5("func:%d, csa:0x%x, cis:0x%x, blksz:0x%x", func, sdio_card->fbr[func].pcsa, sdio_card->fbr[func].pfcis, sdio_card->fbr[func].fn_blksz); + + return 0; +} + +static int get_sdio_cccr_info(struct mss_card *card) +{ + struct mss_host *host = card->slot->host; + struct sdio_card *sdio_card = card->prot_card; + struct mss_cmd *cmd = &sdio_card->cmd; + struct mss_ll_request *llreq = &sdio_card->llreq; + struct sdio_response_r5 r5; + int ret, arg; + u32 tmp; + + dbg5("get_sdio_cccr_info"); + SDIO_FN0_READ_REG(CCCR_SDIO_REVISION); + sdio_card->cccr.sdiox = (r5.data >> 4) & 0xf; + sdio_card->cccr.cccrx = r5.data & 0xf; + + SDIO_FN0_READ_REG(SD_SPEC_REVISION); + sdio_card->cccr.sdx = r5.data & 0xf; + + SDIO_FN0_READ_REG(IO_ENABLE); + sdio_card->cccr.ioex = r5.data; + + SDIO_FN0_READ_REG(IO_READY); + sdio_card->cccr.iorx = r5.data; + + SDIO_FN0_READ_REG(INT_ENABLE); + sdio_card->cccr.intex = r5.data; + + SDIO_FN0_READ_REG(INT_PENDING); + sdio_card->cccr.intx = r5.data; + + SDIO_FN0_READ_REG(BUS_IF_CTRL); + sdio_card->cccr.buswidth = r5.data & 0x3; + sdio_card->cccr.cd = (r5.data >> 7) & 0x1; + + SDIO_FN0_READ_REG(CARD_CAPABILITY); + sdio_card->cccr.sdc = r5.data & 0x1; + sdio_card->cccr.smb = (r5.data >> 1) & 0x1; + sdio_card->cccr.srw = (r5.data >> 2) & 0x1; + sdio_card->cccr.sbs = (r5.data >> 3) & 0x1; + sdio_card->cccr.s4mi = (r5.data >> 4) & 0x1; + sdio_card->cccr.e4mi = (r5.data >> 5) & 0x1; + sdio_card->cccr.lsc = (r5.data >> 6) & 0x1; + sdio_card->cccr.ls4b = (r5.data >> 7) & 0x1; + + SDIO_FN0_READ_REG(COMMON_CIS_POINTER_1); + tmp = r5.data; + SDIO_FN0_READ_REG(COMMON_CIS_POINTER_2); + tmp |= r5.data << 8; + SDIO_FN0_READ_REG(COMMON_CIS_POINTER_3); + tmp |= r5.data << 16; + sdio_card->cccr.pccis = tmp; + + SDIO_FN0_READ_REG(BUS_SUSPEND); + sdio_card->cccr.bs = r5.data & 0x1; + sdio_card->cccr.br = (r5.data >> 1) & 0x1; + + SDIO_FN0_READ_REG(FUNCTION_SELECT); + sdio_card->cccr.fsx = r5.data & 0xf; + sdio_card->cccr.df = (r5.data >> 7) & 0x1; + + SDIO_FN0_READ_REG(EXEC_FLAGS); + sdio_card->cccr.exx = r5.data; + + SDIO_FN0_READ_REG(READY_FLAGS); + sdio_card->cccr.rfx = r5.data; + + SDIO_FN0_READ_REG(FN0_BLKSZ_1); + tmp = r5.data; + SDIO_FN0_READ_REG(FN0_BLKSZ_2); + tmp |= r5.data << 8; + sdio_card->cccr.fn0_blksz = tmp; + + SDIO_FN0_READ_REG(POWER_CTRL); + sdio_card->cccr.smpc = r5.data & 0x1; + sdio_card->cccr.empc = (r5.data >> 1) & 0x1; + + dbg5("cccr, card capability: low_speed_card:%d" + " low_speed_card_4bit:%d int_bw_block:%d\n" + " suspend/resume:%d read/wait:%d multiblcok:%d direct_cmd:%d\n", + sdio_card->cccr.lsc, sdio_card->cccr.ls4b, + sdio_card->cccr.s4mi, sdio_card->cccr.sbs, + sdio_card->cccr.srw, sdio_card->cccr.smb, sdio_card->cccr.sdc); + dbg5("sdio:%d, sd:%d, cccr:%d, common cis:0x%x\n", sdio_card->cccr.sdiox, sdio_card->cccr.sdx, sdio_card->cccr.cccrx, sdio_card->cccr.pccis); + dbg5("spmc:%d\n", sdio_card->cccr.smpc); + dbg5("ioe:0x%x, ior:0x%x\n", sdio_card->cccr.ioex, sdio_card->cccr.iorx); + return 0; +} + +static int get_sdio_fcis_info(struct mss_card *card, int func) +{ + struct mss_host *host= card->slot->host; + struct sdio_card *sdio_card = card->prot_card; + struct mss_cmd *cmd = &sdio_card->cmd; + struct mss_ll_request *llreq = &sdio_card->llreq; + int ret, arg, tuple_body_len, tuple_type; + struct sdio_response_r5 r5; + u32 addr, next_addr; + u32 tmp; + u16 tmp16; + + dbg5("get_sdio_fcis_info"); + addr = sdio_card->fbr[func].pfcis; + + while(1) { + SDIO_FN0_READ_REG(addr); + tuple_type = r5.data; + + SDIO_FN0_READ_REG(addr + 1); + tuple_body_len = r5.data; + + next_addr = addr + 2 + r5.data; + switch (tuple_type) { + case CISTPL_NULL: + case CISTPL_END: + dbg5("cistpl null/end\n"); + goto finish; + case CISTPL_CHECKSUM: + dbg5("cistpl checksum\n"); + break; + case CISTPL_VERS_1: + dbg5("cistpl vers level 1\n"); + break; + case CISTPL_ALTSTR: + dbg5("cistpl altstr\n"); + break; + case CISTPL_MANFID: + dbg5("cistpl manfid\n"); + break; + case CISTPL_FUNCID: + dbg5("cistpl funcid\n"); + SDIO_FN0_READ_REG(addr + 2); + + if (r5.data != 0x0c) + dbg5("not a sdio card\n"); + else + dbg5(" a sdio card\n"); + + break; + case CISTPL_FUNCE: + /* Type of extended data, should be 1 */ + SDIO_FN0_READ_REG(addr + 2); + if (r5.data == 0x01) + dbg5("1 type extended tuple\n"); + + /* FUNCTION_INFO */ + SDIO_FN0_READ_REG(addr + 3); + sdio_card->fcis[func].func_info = r5.data; + + /* STD_IO_REV */ + SDIO_FN0_READ_REG(addr + 4); + sdio_card->fcis[func].std_io_rev = r5.data; + + /* card psn */ + SDIO_FN0_READ_REG(addr + 5); + tmp = r5.data; + SDIO_FN0_READ_REG(addr + 6); + tmp |= r5.data << 8; + SDIO_FN0_READ_REG(addr + 7); + tmp |= r5.data << 16; + SDIO_FN0_READ_REG(addr + 8); + tmp |= r5.data << 24; + sdio_card->fcis[func].card_psn = tmp; + + /* card csa size */ + SDIO_FN0_READ_REG(addr + 9); + tmp = r5.data; + SDIO_FN0_READ_REG(addr + 10); + tmp |= r5.data << 8; + SDIO_FN0_READ_REG(addr + 11); + tmp |= r5.data << 16; + SDIO_FN0_READ_REG(addr + 12); + tmp |= r5.data << 24; + sdio_card->fcis[func].csa_size = tmp; + + /* csa property */ + SDIO_FN0_READ_REG(addr + 13); + sdio_card->fcis[func].csa_property = r5.data; + + /* max_blk_size */ + SDIO_FN0_READ_REG(addr + 14); + tmp16 = r5.data; + SDIO_FN0_READ_REG(addr + 15); + tmp16 |= r5.data << 8; + sdio_card->fcis[func].max_blk_size = tmp16; + + /* ocr */ + SDIO_FN0_READ_REG(addr + 16); + tmp = r5.data; + SDIO_FN0_READ_REG(addr + 17); + tmp |= r5.data << 8; + SDIO_FN0_READ_REG(addr + 18); + tmp |= r5.data << 16; + SDIO_FN0_READ_REG(addr + 19); + tmp |= r5.data << 24; + sdio_card->fcis[func].ocr = tmp; + + /* pwr */ + SDIO_FN0_READ_REG(addr + 20); + sdio_card->fcis[func].op_min_pwr = r5.data; + + SDIO_FN0_READ_REG(addr + 21); + sdio_card->fcis[func].op_avg_pwr = r5.data; + + SDIO_FN0_READ_REG(addr + 22); + sdio_card->fcis[func].op_max_pwr = r5.data; + + SDIO_FN0_READ_REG(addr + 23); + sdio_card->fcis[func].sb_min_pwr = r5.data; + + SDIO_FN0_READ_REG(addr + 24); + sdio_card->fcis[func].sb_avg_pwr = r5.data; + + SDIO_FN0_READ_REG(addr + 25); + sdio_card->fcis[func].sb_max_pwr = r5.data; + + SDIO_FN0_READ_REG(addr + 26); + tmp16 = r5.data; + SDIO_FN0_READ_REG(addr + 27); + tmp16 |= r5.data << 8; + sdio_card->fcis[func].min_bw = tmp16; + + SDIO_FN0_READ_REG(addr + 28); + tmp16 = r5.data; + SDIO_FN0_READ_REG(addr + 29); + tmp16 |= r5.data << 8; + sdio_card->fcis[func].opt_bw = tmp16; + + // SDIO1.0 is 28, and 1.1 is 36 + if (sdio_card->cccr.sdiox == 0) + break; + SDIO_FN0_READ_REG(addr + 30); + tmp16 = r5.data; + SDIO_FN0_READ_REG(addr + 31); + tmp16 |= r5.data << 8; + sdio_card->fcis[func].enable_timeout_val= tmp16; + break; + case CISTPL_SDIO_STD: + dbg5("sdio std\n"); + break; + case CISTPL_SDIO_EXT: + dbg5("sdio std ext\n"); + break; + default : + dbg5("not supported cis\n"); + } + addr = next_addr; + } +finish: + dbg5("fcis %d\nfunction_info:0x%x std_io_rev:0x%x card_psn:0x%x\n" + "csa_size:0x%x csa_property:0x%x max_blk_size:0x%x\n" + "ocr:0x%x op_min_pwr:0x%x op_avg_pwr:0x%x op_max_pwr:0x%x" + "sb_min_pwr:0x%x sb_avg_pwr:0x%x sb_max_pwr:0x%x" + "min_bw:0x%x opt_bw:0x%x time out:%x\n",func, + sdio_card->fcis[func].func_info, sdio_card->fcis[func].std_io_rev, sdio_card->fcis[func].card_psn, + sdio_card->fcis[func].csa_size, sdio_card->fcis[func].csa_property, sdio_card->fcis[func].max_blk_size, + sdio_card->fcis[func].ocr, sdio_card->fcis[func].op_min_pwr, sdio_card->fcis[func].op_avg_pwr, sdio_card->fcis[func].op_max_pwr, + sdio_card->fcis[func].sb_min_pwr, sdio_card->fcis[func].sb_avg_pwr, sdio_card->fcis[func].sb_max_pwr, + sdio_card->fcis[func].min_bw, sdio_card->fcis[func].opt_bw, sdio_card->fcis[func].enable_timeout_val); + return 0; +} + +static int get_sdio_ccis_info(struct mss_card *card) +{ + struct mss_host *host= card->slot->host; + struct sdio_card *sdio_card = card->prot_card; + struct mss_cmd *cmd = &sdio_card->cmd; + struct mss_ll_request *llreq = &sdio_card->llreq; + int ret, arg, tuple_body_len, tuple_type; + struct sdio_response_r5 r5; + u32 addr, next_addr; + u16 tmp16; + + dbg5("get_sdio_ccis_info"); + addr = sdio_card->cccr.pccis; + while (1) { + SDIO_FN0_READ_REG(addr); + tuple_type = r5.data; + + SDIO_FN0_READ_REG(addr + 1); + tuple_body_len = r5.data; + next_addr = addr + 2 + r5.data; + + switch (tuple_type) { + case CISTPL_NULL: + case CISTPL_END: + dbg5("cistpl null/end\n"); + goto finish; + case CISTPL_CHECKSUM: + dbg5("cistpl checksum\n"); + break; + case CISTPL_VERS_1: + dbg5("cistpl vers level 1\n"); + break; + case CISTPL_ALTSTR: + dbg5("cistpl altstr\n"); + break; + case CISTPL_MANFID: + dbg5("cistpl manfid\n"); + SDIO_FN0_READ_REG(addr + 2); + tmp16 = r5.data; + SDIO_FN0_READ_REG(addr + 3); + tmp16 |= r5.data << 8; + sdio_card->ccis.manufacturer = tmp16; + + SDIO_FN0_READ_REG(addr + 4); + tmp16 = r5.data; + SDIO_FN0_READ_REG(addr + 5); + tmp16 |= r5.data << 8; + sdio_card->ccis.card_id = tmp16; + + break; + case CISTPL_FUNCID: + dbg5("cistpl funcid\n"); + SDIO_FN0_READ_REG(addr + 2); + if (r5.data != 0x0c) + dbg5("not a sdio card\n"); + else + dbg5(" a sdio card\n"); + + break; + case CISTPL_FUNCE: + dbg5("cistpl funce\n"); + SDIO_FN0_READ_REG(addr + 2); + if (r5.data == 0x00) + dbg5("0 type extended tuple\n"); + + SDIO_FN0_READ_REG(addr + 3); + tmp16 = r5.data; + SDIO_FN0_READ_REG(addr + 4); + tmp16 = r5.data << 8; + sdio_card->ccis.fn0_block_size = tmp16; + + SDIO_FN0_READ_REG(addr + 5); + sdio_card->ccis.max_tran_speed = r5.data; + //slot->tran_speed = card->ccis.max_tran_speed; + break; + case CISTPL_SDIO_STD: + dbg5("sdio std\n"); + break; + case CISTPL_SDIO_EXT: + dbg5("sdio std ext\n"); + break; + default: + dbg5("not supported cis\n"); + } + addr = next_addr; + } +finish: + dbg5("ccis:\nmanf:0x%x card_id:0x%x block_size:0x%x\nmax_tran_speed:0x%x\n",sdio_card->ccis.manufacturer, sdio_card->ccis.card_id, sdio_card->ccis.fn0_block_size, sdio_card->ccis.max_tran_speed); + return 0; +} + +/***************************************************************************** + * + * protocol entry functions + * + ****************************************************************************/ + +static int sdio_recognize_card(struct mss_card *card) +{ + struct mss_host *host = card->slot->host; + struct sdio_card *sdio_card = card->prot_card; + struct mss_cmd *cmd = &sdio_card->cmd; + struct mss_ll_request *llreq = &sdio_card->llreq; + struct mss_ios ios; + struct sdio_response_r4 r4; + int ret; + + card->card_type = MSS_UNKNOWN_CARD; + card->state = CARD_STATE_INIT; + card->bus_width = MSS_BUSWIDTH_1BIT; + + memcpy(&ios, &host->ios, sizeof(struct mss_ios)); + ios.clock = host->f_min; + ios.bus_width = MSS_BUSWIDTH_1BIT; + host->ops->set_ios(host, &ios); + + /* check if a sdio card, need not send CMD0 to reset for SDIO card */ + ret = mss_send_simple_ll_req(host, llreq, cmd, IO_SEND_OP_COND, + 0, MSS_RESPONSE_R4, 0); + if (ret) + return ret; + ret = sdio_unpack_r4(cmd, &r4, sdio_card); + if (ret) + return ret; + sdio_card->func_num = r4.func_num; + sdio_card->mem_present = r4.mem_present; + if (!r4.func_num) + return MSS_ERROR_NONE; + /* maybe COMBO_CARD. but we can return SDIO_CARD first, + * in sdio_card_init, we will judge further. + */ + if(r4.ocr & host->vdd) { + card->card_type = MSS_SDIO_CARD; + } else { + printk(KERN_WARNING "uncompatible card\n"); + card->card_type = MSS_UNCOMPATIBLE_CARD; + } + + return MSS_ERROR_NONE; +} + +static int sdio_card_init(struct mss_card *card) +{ + struct mss_host *host = card->slot->host; + struct sdio_card *sdio_card = card->prot_card; + struct mss_cmd *cmd = &sdio_card->cmd; + struct mss_ll_request *llreq = &sdio_card->llreq; + struct sdio_response_r1 r1; + struct sdio_response_r4 r4; + struct sdio_response_r6 r6; + struct mss_ios ios; + int ret, tmp, i; + u8 funcs; + + dbg5("card = %08X\n", (u32)card); + card->state = CARD_STATE_INIT; + card->bus_width = MSS_BUSWIDTH_1BIT; + + memcpy(&ios, &host->ios, sizeof(struct mss_ios)); + ios.clock = host->f_min; + ios.bus_width = MSS_BUSWIDTH_1BIT; + host->ops->set_ios(host, &ios); + + ret = mss_send_simple_ll_req(host, llreq, cmd, IO_SEND_OP_COND, + host->vdd, MSS_RESPONSE_R4, 0); + if (ret) + return ret; + ret = sdio_unpack_r4(cmd, &r4, sdio_card); + if (ret) + return ret; + + while (!r4.ready) { + //mdelay(20); + msleep(15); + ret = mss_send_simple_ll_req(host, llreq, cmd, IO_SEND_OP_COND, + host->vdd, MSS_RESPONSE_R4, 0); + if (ret) + return ret; + ret = sdio_unpack_r4(cmd, &r4, sdio_card); + if (ret) + return ret; + } + + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SET_RELATIVE_ADDR, + 0, MSS_RESPONSE_R6, 0); + if (ret) + return ret; + ret = sdio_unpack_r6(cmd, &r6, sdio_card); + if (ret) + return ret; + sdio_card->state = CARD_STATE_STBY; + sdio_card->rca = r6.rca; + + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SELECT_CARD, + (sdio_card->rca) << 16, MSS_RESPONSE_R1B, 0); + if (ret) + return ret; + ret = sdio_unpack_r1(cmd, &r1, sdio_card); + if (ret) + return ret; + + /** CARD_STATE_CMD */ + //slot->state = CARD_STATE_CMD; + //send CMD53 to let DATA BUS FREE, since bus_suspend not supported, need not to do this + //arg = sdio_make_cmd53_arg(SDIO_READ, 0, 0, 0, 0, 1); + //mss_simple_cmd( dev, IO_RW_EXTENDED, arg, RESPONSE_R5); + + + /** CARD_STATE_TRAN */ + sdio_card->state = CARD_STATE_CMD; + + + ret = get_sdio_cccr_info(card); + if (ret) + return ret; + funcs = sdio_card->func_num; + for(i = 1; i <= funcs; i++) { + ret = get_sdio_fbr_info(card, i); + if (ret) + return ret; + } + + ret = get_sdio_ccis_info(card); + if (ret) + return ret; + for(i = 1; i <= funcs; i++) { + ret = get_sdio_fcis_info(card, i); + if (ret) + return ret; + } + if(host->bus_width == MSS_BUSWIDTH_4BIT + && (!sdio_card->cccr.lsc || sdio_card->cccr.ls4b)) { + host->ios.bus_width = MSS_BUSWIDTH_4BIT; + sdio_set_bus_width(card, 2); + } + + /* enable function */ + tmp = 0; + for(i = 1; i <= funcs; i++) { + tmp |= (1 << i); + } + ret = sdio_io_enable(card, tmp); + if (ret) + return ret; + + /* enable interrupt */ + tmp = 1; + for(i = 1; i <= funcs; i++) { + tmp |= (1 << i); + } + ret = sdio_interrupt_enable(card, tmp); + if (ret) + return ret; + + /* enable card capabilites */ + for (i=1; i <= funcs; i++) { + sdio_csa_enable(card, i); + } + + mss_set_sdio_int(card->slot->host, 1); + + return MSS_ERROR_NONE; +} + +static int sdio_read_write_entry(struct mss_card *card, int action, struct mss_rw_arg *arg, struct mss_rw_result *result) +{ + struct mss_host *host = card->slot->host; + struct sdio_card *sdio_card = card->prot_card; + struct mss_cmd *cmd = &sdio_card->cmd; + struct mss_data *data = &sdio_card->data; + struct mss_ll_request *llreq = &sdio_card->llreq; + struct sdio_response_r5 r5; + struct sdio_response_r1 r1; + int ret; + u32 addr, blkmode, func, rw, rw_count, opcode, clock, cmdarg; + int retries = 4; + + if (sdio_card->state == CARD_STATE_STBY) { + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SELECT_CARD, + sdio_card->rca << 16, MSS_RESPONSE_R1B, 0); + if (ret) + return ret; + ret = sdio_unpack_r1(cmd, &r1, sdio_card); + if (ret) + return ret; + } + + mss_set_clock(host, sdio_tran_speed(sdio_card->ccis.max_tran_speed)); + func = arg->func; + if (func > sdio_card->func_num) + return MSS_ERROR_WRONG_ARG; + + if (arg->block_len == 0) { + blkmode = 0; + } + else { + if (!sdio_card->cccr.smb) + return MSS_ERROR_WRONG_ARG; + dbg5("blkzs:%d, %d\n", arg->block_len, sdio_card->fbr[func].fn_blksz); + if (arg->block_len != sdio_card->fbr[func].fn_blksz) { + ret = sdio_set_block_size(card, arg->block_len, func); + if (ret) + return ret; + } + blkmode = 1; + } + + rw = (action == MSS_READ_MEM) ? 0 : 1; + addr = arg->block; + opcode = (arg->opcode) ? 1 : 0; + rw_count = arg->nob; + + memset(llreq, 0x0, sizeof(struct mss_ll_request)); + memset(cmd, 0x0, sizeof(struct mss_cmd)); + memset(data, 0x0, sizeof(struct mss_data)); + +read_write_entry: + /* deal with request */ + /* if only one byte, then use CMD52 to read*/ + if (!blkmode && rw_count == 1) { + u8 val = (rw) ? arg->val : 0; + dbg5("use CMD52 to transfer data. rw direction: %d", rw); + cmdarg = sdio_make_cmd52_arg(rw, func, opcode, addr, val); + + dbg5("cmdarg :0x%x\n", cmdarg); + ret = mss_send_simple_ll_req(host, llreq, cmd, IO_RW_DIRECT, + cmdarg, MSS_RESPONSE_R5, + MSS_CMD_SDIO_EN); + if (!ret) + ret = sdio_unpack_r5(cmd, &r5, sdio_card); + if (!ret) + result->bytes_xfered = r5.data; + else if (ret && --retries) { + clock = host->ios.clock; + clock = clock >> 1; + if (clock < SDIO_CARD_CLOCK_SLOW && retries == 1) { + clock = SDIO_CARD_CLOCK_SLOW; + mss_set_clock(host, clock); + goto read_write_entry; + } + return ret; + } + dbg5("r5.data:0x%x\n",r5.data); + } + else { + cmdarg= sdio_make_cmd53_arg(rw, func, blkmode, opcode, addr, + rw_count); + MSS_INIT_CMD(cmd, IO_RW_EXTENDED, cmdarg, MSS_CMD_SDIO_EN, + MSS_RESPONSE_R5); + MSS_INIT_DATA(data, rw_count, arg->block_len, + ((rw) ? MSS_DATA_WRITE : MSS_DATA_READ), + arg->sg_len, arg->sg, 0); + llreq->cmd = cmd; + llreq->data = data; + + ret = mss_send_ll_req(host, llreq); + if (!ret) + ret = sdio_unpack_r5(cmd, &r5, sdio_card); + if (ret) { + if (--retries) { + clock = host->ios.clock; + clock = clock >> 1; + if (clock < SDIO_CARD_CLOCK_SLOW + && retries == 1) + clock = SDIO_CARD_CLOCK_SLOW; + mss_set_clock(host, clock); + goto read_write_entry; + } + return ret; + } + + } + return MSS_ERROR_NONE; +} + +/***************************************************************************** + * + * protocol driver interface functions + * + ****************************************************************************/ + +static int sdio_prot_entry(struct mss_card *card, unsigned int action, void *arg, void *result) +{ + int ret; + + dbg5("action = %d\n", action); + if (action != MSS_RECOGNIZE_CARD && card->card_type != MSS_SDIO_CARD) + return MSS_ERROR_WRONG_CARD_TYPE; + switch (action) { + case MSS_RECOGNIZE_CARD: + ret = sdio_recognize_card(card); + break; + case MSS_INIT_CARD: + ret = sdio_card_init(card); + break; + case MSS_READ_MEM: + case MSS_WRITE_MEM: + if (!arg || !result) + return -EINVAL; + ret = sdio_read_write_entry(card, action, arg, result); + break; + case MSS_QUERY_CARD: + ret = MSS_ERROR_NONE; + break; + default: + ret = MSS_ERROR_ACTION_UNSUPPORTED; + break; + } + + return ret; +} + +static int sdio_prot_attach_card(struct mss_card *card) +{ + struct sdio_card *sdio_card; + +#define ALIGN32(x) (((x) + 31) & (~31)) + sdio_card = kzalloc(ALIGN32(sizeof(struct sdio_card)), GFP_KERNEL); + card->prot_card = sdio_card; + if (sdio_card) { + return 0; + } + return -ENOMEM; +} + +static void sdio_prot_detach_card(struct mss_card *card) +{ + kfree(card->prot_card); +} + +static int sdio_prot_get_errno(struct mss_card *card) +{ + struct sdio_card *sdio_card = card->prot_card; + + return sdio_card->errno; +} + +static struct mss_prot_driver sdio_protocol = { + .name = SDIO_PROTOCOL, + .prot_entry = sdio_prot_entry, + .attach_card = sdio_prot_attach_card, + .detach_card = sdio_prot_detach_card, + .get_errno = sdio_prot_get_errno, +}; + +/***************************************************************************** + * + * module init and exit functions + * + ****************************************************************************/ +static int sdio_protocol_init(void) +{ + register_mss_prot_driver(&sdio_protocol); + return 0; +} + +static void sdio_protocol_exit(void) +{ + unregister_mss_prot_driver(&sdio_protocol); +} + + +module_init(sdio_protocol_init); +module_exit(sdio_protocol_exit); + +MODULE_AUTHOR("Bridge Wu"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("SDIO protocol driver"); --- linux-2.6.24.orig/drivers/mmc/mss/mss_core.c +++ linux-2.6.24/drivers/mmc/mss/mss_core.c @@ -0,0 +1,918 @@ +/* + * mss_core.c - MMC/SD/SDIO Core driver + * + * Copyright (C) 2007 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 only + * for now as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * derived from previous mmc code in Linux kernel + * Copyright (c) 2002 Hewlett-Packard Company + * Copyright (c) 2002 Andrew Christian + * Copyright (c) 2006 Bridge Wu + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + + +static LIST_HEAD(mss_protocol_list); +static LIST_HEAD(mss_host_list); + +static void mss_power_up(struct mss_host *host) +{ + struct mss_ios ios; + + memcpy(&ios, &host->ios, sizeof(ios)); + ios.vdd = host->vdd; + ios.chip_select = MSS_CS_NO_CARE; + ios.power_mode = MSS_POWER_UP; + host->ops->set_ios(host, &ios); + + msleep(1); + + ios.clock = host->f_min; + ios.power_mode = MSS_POWER_ON; + host->ops->set_ios(host, &ios); + + msleep(2); +} + +static void mss_power_off(struct mss_host *host) +{ + struct mss_ios ios; + + memcpy(&ios, &host->ios, sizeof(ios)); + ios.clock = 0; + ios.chip_select = MSS_CS_NO_CARE; + ios.power_mode = MSS_POWER_OFF; + host->ops->set_ios(host, &ios); +} + +static void mss_idle_cards(struct mss_host *host) +{ + struct mss_ios ios; + + memcpy(&ios, &host->ios, sizeof(ios)); + ios.chip_select = MSS_CS_HIGH; + host->ops->set_ios(host, &ios); + msleep(1); + ios.chip_select = MSS_CS_NO_CARE; + host->ops->set_ios(host, &ios); + msleep(1); +} + +/* + * Only after card is initialized by protocol and be registed to mmc_bus, the + * state is changed to MSS_CARD_REGISTERED. + */ +static int mmc_bus_match(struct device *dev, struct device_driver *drv) +{ + struct mss_card *card; + + card = container_of(dev, struct mss_card, dev); + + dbg(card->slot, "bus match driver %s", drv->name); + /* when card->state is MSS_CARD_REGISTERED,it is accepted by protocol */ + if (card->prot_driver && (card->state & MSS_CARD_REGISTERED)) + return 1; + dbg(card->slot, "bus match driver %s fail", drv->name); + return 0; +} + +//static int mmc_bus_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) +//{ +// printk(KERN_INFO "*** HOT PLUG ***\n"); +// return 0; +//} + +static int mmc_bus_suspend(struct device * dev, pm_message_t state) +{ + int ret = 0; + struct mss_card *card; + + card = container_of(dev, struct mss_card, dev); + + if (card->state & MSS_CARD_HANDLEIO) + return -EAGAIN; + if (card->state & MSS_CARD_SUSPENDED) + return 0; + + if (dev->driver && dev->driver->suspend) { + ret = dev->driver->suspend(dev, state);//, SUSPEND_DISABLE); + if (ret == 0) + ret = dev->driver->suspend(dev, state);//, SUSPEND_SAVE_STATE); + if (ret == 0) + ret = dev->driver->suspend(dev, state);//, SUSPEND_POWER_DOWN); + } + /* mark MSS_CARD_SUSPEND here */ + card->state |= MSS_CARD_SUSPENDED; + return ret; +} +/* + * card may be removed or replaced by another card from the mmc_bus when it is + * sleeping, and the slot may be inserted a card when it is sleeping. + * The controller resume function need to take care about it. + */ +static int mmc_bus_resume(struct device * dev) +{ + int ret = 0; + struct mss_card *card; + + card = container_of(dev, struct mss_card, dev); + + /* it is new instered card or replaced card */ + if (!(card->state & MSS_CARD_SUSPENDED)) + return 0; + + card->state &= ~MSS_CARD_SUSPENDED; + if (dev->driver && dev->driver->resume) { + ret = dev->driver->resume(dev);//, RESUME_POWER_ON); + if (ret == 0) + ret = dev->driver->resume(dev);//, RESUME_RESTORE_STATE); + if (ret == 0) + ret = dev->driver->resume(dev);//, RESUME_ENABLE); + } + + return ret; +} + +static struct bus_type mmc_bus_type = { + .name = "mmc_bus", + .match = mmc_bus_match, +// .hotplug = mmc_bus_hotplug, + .suspend = mmc_bus_suspend, + .resume = mmc_bus_resume, +}; + +static void mss_card_device_release(struct device *dev) +{ + struct mss_card *card = container_of(dev, struct mss_card, dev); + + kfree(card); +} + +static void mss_claim_host(struct mss_host *host, struct mss_card *card) +{ + DECLARE_WAITQUEUE(wait, current); + unsigned long flags; + + /* + spin_lock_irqsave(&host->lock, flags); + while (host->active_card != NULL) { + spin_unlock_irqrestore(&host->lock, flags); + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&host->wq, &wait); + schedule(); + set_current_state(TASK_RUNNING); + remove_wait_queue(&host->wq, &wait); + spin_lock_irqsave(&host->lock, flags); + } + */ + + spin_lock_irqsave(&host->lock, flags); + while (host->active_card != NULL) { + set_current_state(TASK_UNINTERRUPTIBLE); + spin_unlock_irqrestore(&host->lock, flags); + add_wait_queue(&host->wq, &wait); + schedule(); + remove_wait_queue(&host->wq, &wait); + spin_lock_irqsave(&host->lock, flags); + } + set_current_state(TASK_RUNNING); + host->active_card = card; + spin_unlock_irqrestore(&host->lock, flags); +} + +static void mss_release_host(struct mss_host* host) +{ + unsigned long flags; + + BUG_ON(host->active_card == NULL); + + spin_lock_irqsave(&host->lock, flags); + host->active_card = NULL; + spin_unlock_irqrestore(&host->lock, flags); + + wake_up(&host->wq); + +} + +int mss_card_get(struct mss_card *card) +{ + if ((card->state & MSS_CARD_REMOVING) + || !(card->state & MSS_CARD_REGISTERED)) + return -ENXIO; + if (!get_device(&card->dev)) + return -ENXIO; + return 0; +} + +void mss_card_put(struct mss_card *card) +{ + put_device(&card->dev); +} + +/* + * finish handling a request. + */ +static void mss_finish_request(struct mss_request *req) +{ + struct mss_driver *drv; + struct mss_card *card = req->card; + + drv = container_of(card->dev.driver, struct mss_driver, driver); + if (drv && drv->request_done) + drv->request_done(req); +} + +/* + * Loop all the protocol in the mss_protocol_list, and find one protocol that + * can successful recognize and init the card. + */ +static int mss_attach_protocol(struct mss_card *card) +{ + struct list_head *item; + struct mss_prot_driver *pdrv = NULL; + struct mss_host *host = card->slot->host; + int ret; + + /* loop all the protocol, and find one that match the card */ + list_for_each(item, &mss_protocol_list) { + pdrv = list_entry(item, struct mss_prot_driver, node); + dbg(card->slot, "try protocol:%s", pdrv->name); + + ret = pdrv->attach_card(card); + if (ret) + continue; + dbg(card->slot, "protocol:%s allocate spec card", pdrv->name); + + mss_claim_host(host, card); + ret = pdrv->prot_entry(card, MSS_RECOGNIZE_CARD, NULL, NULL); + mss_release_host(host); + dbg(card->slot, "protocol:%s identy ret:%d, card type:%d\n", pdrv->name, ret, card->card_type); + if (ret) + continue; + switch (card->card_type) { + case MSS_MMC_CARD: + //case MSS_CE_ATA: + case MSS_SD_CARD: + case MSS_SDIO_CARD: + case MSS_COMBO_CARD: + //dbg("identified card type: %d", card_type); + goto identified; + /* + * The card can be recognized, but it deos not fit the + * controller. + */ + case MSS_UNCOMPATIBLE_CARD: + pdrv->detach_card(card); + return MSS_ERROR_NO_PROTOCOL; + /* The card can not be recognized by the protocl */ + case MSS_UNKNOWN_CARD: + pdrv->detach_card(card); + break; + default: + pdrv->detach_card(card); + printk(KERN_WARNING "protocol driver :%s return unknown value when recognize the card\n", pdrv->name); + break; + } + } + + return MSS_ERROR_NO_PROTOCOL; +identified: + card->prot_driver = pdrv; + return 0; +} + +/* Initialize card by the protocol */ +int mss_init_card(struct mss_card *card) +{ + int ret; + struct mss_host *host = card->slot->host; + + if (!card || !card->prot_driver) + return -EINVAL; + mss_claim_host(host, card); + ret = card->prot_driver->prot_entry(card, MSS_INIT_CARD, NULL, NULL); + mss_release_host(host); + + dbg5("return :%d", ret); + return ret; +} + +int mss_query_card(struct mss_card *card) +{ + int ret; + struct mss_host *host = card->slot->host; + + if (!card || !card->prot_driver) + return -EINVAL; + mss_claim_host(host, card); + ret = card->prot_driver->prot_entry(card, MSS_QUERY_CARD, NULL, NULL); + mss_release_host(host); + + return ret; +} + +static int __mss_insert_card(struct mss_card *card) +{ + int ret; + + dbg(card->slot, "attaching protocol"); + /* Step 1: Recognize the card */ + ret = mss_attach_protocol(card); + if (ret) + return ret; + + dbg(card->slot, "protocol%s attached", card->prot_driver->name); + /* Step 2, initialize the card */ + ret = mss_init_card(card); + if (ret) { + goto detach_prot; + } + + dbg(card->slot, "protocol%s inited", card->prot_driver->name); + /* Step 3, register the card to mmc bus */ + card->dev.release = mss_card_device_release; + card->dev.parent = card->slot->host->dev; + /* set bus_id and name */ + snprintf(&card->dev.bus_id[0], sizeof(card->dev.bus_id), "mmc%d%d", + card->slot->host->id, card->slot->id); + card->dev.bus = &mmc_bus_type; + + card->state |= MSS_CARD_REGISTERED; + ret = device_register(&card->dev); /* will call mss_card_probe */ + if (ret) { + ret = MSS_ERROR_REGISTER_CARD; + card->state &= ~MSS_CARD_REGISTERED; + goto detach_prot; + } + dbg(card->slot, "protocol%s registered\n", card->prot_driver->name); + return MSS_ERROR_NONE; + +detach_prot: + card->prot_driver->detach_card(card); + card->prot_driver = NULL; + return ret; +} + +/* + * After knowing a card has been inserted into the slot, this function should + * be invoked. At last, load card driver in card (done by card_driver->probe). + */ +static int mss_insert_card(struct mss_slot *slot) +{ + struct mss_card * card; + int ret; + + BUG_ON(slot->card); + dbg(slot, "card is inserting"); + card = kzalloc(sizeof(struct mss_card), GFP_KERNEL); + if (!card) + return -ENOMEM; + card->slot = slot; + slot->card = card; + + dbg(slot, "allocate card :0x%p", card); + ret = __mss_insert_card(card); + dbg(slot, "insert ret :%d", ret); + if (ret) { + dbg(slot, "free card"); + slot->card = NULL; + kfree(card); + } + return ret; +} + +static int __mss_eject_card(struct mss_card *card) +{ + card->state |= MSS_CARD_REMOVING; + + dbg(card->slot, "card state 0x%x", card->state); + + if (card->prot_driver) { + card->prot_driver->detach_card(card); + card->prot_driver = NULL; + } + if (card->state & MSS_CARD_REGISTERED) { + device_unregister(&(card->dev)); + //card->state &= ~MSS_CARD_REGISTERED; + } + + return 0; +} + +/* + * After knowing a card has been ejected from the slot, this function should + * be invoked. At last, unload card driver in card(done by card_driver->remove). + */ +static int mss_eject_card(struct mss_card *card) +{ + BUG_ON(!card); + + dbg(card->slot, "eject card 0x%x", card); + __mss_eject_card(card); + + card->slot->card = NULL; + card->slot = NULL; + //kfree(card); + + return 0; +} + +unsigned int mss_get_capacity(struct mss_card *card) +{ + int ret; + u32 cap; + + mss_claim_host(card->slot->host, card); + ret = card->prot_driver->prot_entry(card, MSS_GET_CAPACITY, NULL, &cap); + mss_release_host(card->slot->host); + dbg5("get capcacity:0x%x, ret:%d",cap, ret); + if (ret) + cap = 0; + return cap; +} + +int mss_scan_slot(struct work_struct *work) +{ + struct mss_card *card; + struct mss_host *host; + struct mss_slot *slot; + int ret = 0; + + slot = container_of(work, struct mss_slot, card_detect.work); + + card = slot->card; + host = slot->host; + + + printk("begin scan slot, id = %d card_type = %d\n", slot->id, + (card)?(card->card_type):0); + + /* slot has card in it before, and the card is resuming back */ + if (card && (card->state & MSS_CARD_SUSPENDED)) { + dbg(slot, "suspend, card state is 0x%x", card->state); + printk("suspend, card state is 0x%x", card->state); + /* card was ejected when it is suspended */ + if (host->ops->is_slot_empty + && host->ops->is_slot_empty(slot)) { + card->state |= MSS_CARD_REMOVING; + ret = MSS_ERROR_CARD_REMOVING; + } + else { + /* + * if host provides is_slot_empty, and it + * indicates that the card is in slot, then + * we try to init it. + * else, we try to init it directly. Obvisouly + * that if there is no card in the slot, the + * init will fail + */ + dbg(slot, "no is_slot_empty"); + ret = mss_init_card(card); + if (ret) + card->state |= MSS_CARD_INVALID; + } + } + else if (card && (card->state & MSS_CARD_INVALID)) { + + dbg(slot, "2222222222222"); + + card->state &= ~MSS_CARD_INVALID; + ret = mss_eject_card(card); + + if (!host->ops->is_slot_empty + || (host->ops->is_slot_empty && + !host->ops->is_slot_empty(slot))) { + ret = mss_insert_card(slot); + } + + } + /* slot has card in it before, and no suspend happens */ + else if (card && (card->state & MSS_CARD_REGISTERED)) { + dbg(slot, "33333333333"); + + dbg(slot, "register, card state is %d", card->state); + //printk("register, card state is %d", card->state); + if (host->ops->is_slot_empty) { + dbg(slot, "has is_slot_empty"); + /* card has been ejected */ + if (host->ops->is_slot_empty(slot)) + ret = mss_eject_card(card); + } + else { + /* + * We try to send the status query command. + * If card->state has set MSS_CARD_REGISRTEED, + * it indicates that the card has finished + * identification process, and it will response + * the SEND_STATUS command. + */ + dbg(slot, "no is_slot_empty"); + if (mss_query_card(card)) + /* Card has been ejected */ + ret = mss_eject_card(card); + } + } + /* slot has card in it, but the card is not registered */ + else if (card) { + /* This should never be happens, because when insert fail, we will delete the card */ + BUG(); + } + /* slot has no card in it before */ + else if (!card) { + dbg(slot, "no card in it before"); + + mss_power_off(host); + mss_power_up(host); + mss_idle_cards(host); + if (host->ops->is_slot_empty) { + /* slot is not empty */ + if (!host->ops->is_slot_empty(slot)) + ret = mss_insert_card(slot); + } + else { + /* try to insert a card */ + ret = mss_insert_card(slot); + } + } + else { + printk(KERN_ERR "Unexpected situation when scan host:%d" + ", slot:%d, card state:0x%x\n", host->id, + slot->id, card ? card->state : 0x0); + BUG(); + } + + return ret; +} + +void mss_detect_change(struct mss_host *host, unsigned long delay, unsigned int id) +{ + struct mss_slot *slot; + + slot = &host->slots[id]; + + //printk(" enter mss_detect_change(): delay = %d, id = %d, slot = 0x%xi\n", + // delay, id, slot); + + if (delay) + schedule_delayed_work(&slot->card_detect, delay); + else + schedule_work(&slot->card_detect); + + //printk("%s(): done and exit\n", __FUNCTION__); +} + +void mss_scan_host(struct mss_host *host) +{ + struct mss_slot *slot; + int i; + + for (i = 0; i < host->slot_num; i++) { + slot = &host->slots[i]; + mss_scan_slot(&slot->card_detect.work); + } +} + +void mss_force_card_remove(struct mss_card *card) +{ + mss_eject_card(card); +} + +static void mss_wait_done(struct mss_ll_request *llreq) +{ + complete(llreq->done_data); +} + +int mss_send_ll_req(struct mss_host *host, struct mss_ll_request *llreq) +{ + DECLARE_COMPLETION(complete); + + llreq->done = mss_wait_done; + llreq->done_data = &complete; + + llreq->cmd->llreq = llreq; + llreq->cmd->error = MSS_ERROR_NONE; + if (llreq->data) + llreq->cmd->data = llreq->data; +/* if (llreq->data && llreq->stop) { + llreq->stop->llreq = llreq; + llreq->stop->error = 0; + }*/ + host->ops->request(host, llreq); + wait_for_completion(&complete); +/* if (llreq->cmd->error || (llreq->stop && llreq->stop-error))*/ + + return llreq->cmd->error; +} + +int mss_send_simple_ll_req(struct mss_host *host, struct mss_ll_request *llreq, struct mss_cmd *cmd, u32 opcode, u32 arg, u32 rtype, u32 flags) +{ + memset(llreq, 0x0, sizeof(struct mss_ll_request)); + memset(cmd, 0x0, sizeof(struct mss_cmd)); + + cmd->opcode = opcode; + cmd->arg = arg; + cmd->rtype = rtype; + cmd->flags = flags; + + llreq->cmd = cmd; + + return mss_send_ll_req(host, llreq); +} + + +/* + * add controller into mss_host_list + */ +int register_mss_host(struct mss_host *host) +{ + list_add_tail(&host->node, &mss_host_list); + return 0; +} + +/* + * delete controller from mss_controller_list + */ +void unregister_mss_host(struct mss_host *host) +{ + + list_del(&host->node); +} + +/***************************************************************************** + * + * functions for protocol driver + * + ****************************************************************************/ + +/* + * add protocol driver into mss_protocol_list + */ +int register_mss_prot_driver(struct mss_prot_driver *drv) +{ + struct list_head *item; + struct mss_host *host; + struct mss_slot *slot; + int i; + + list_add(&drv->node, &mss_protocol_list); + + list_for_each(item, &mss_host_list) { + host = list_entry(item, struct mss_host, node); + for (i = 0; i < host->slot_num; i++) { + slot = &host->slots[i]; + if (!slot->card) + mss_scan_slot(&slot->card_detect.work); + } + } + return 0; +} + +/* + * delete protocol driver from mss_protocol_list + */ +void unregister_mss_prot_driver(struct mss_prot_driver *drv) +{ + struct mss_slot *slot; + struct list_head *item; + struct mss_host *host; + int i; + + list_del(&drv->node); + + list_for_each(item, &mss_host_list) { + host = list_entry(item, struct mss_host, node); + for (i = 0; i < host->slot_num; i++) { + slot = &host->slots[i]; + if (slot->card && slot->card->prot_driver == drv) + mss_eject_card(slot->card); + } + } + +} + +/***************************************************************************** + * + * interfaces for card driver + * + ****************************************************************************/ + +/* + * register card driver onto MMC bus + */ +int register_mss_driver (struct mss_driver *drv) +{ + drv->driver.bus = &mmc_bus_type; + return driver_register(&drv->driver); /* will call card_driver->probe */ +} + +/* + * unregister card driver from MMC bus + */ +void unregister_mss_driver (struct mss_driver *drv) +{ + driver_unregister(&drv->driver); +} + +/* + * enable SDIO interrupt, used by SDIO application driver + */ +void mss_set_sdio_int(struct mss_host *host, int sdio_en) +{ + struct mss_ios ios; + + dbg5("mss_set_sdio_int = %s", (sdio_en)?"ENABLE":"DISABLE"); + memcpy(&ios, &host->ios, sizeof(ios)); + ios.sdio_int = sdio_en; + host->ops->set_ios(host, &ios); +} + +void mss_set_clock(struct mss_host *host, int clock) +{ + struct mss_ios ios; + + memcpy(&ios, &host->ios, sizeof(ios)); + if (clock > host->f_max) + clock = host->f_max; + else if (clock < host->f_min) + clock = host->f_min; + ios.clock = clock; + host->ops->set_ios(host, &ios); +} + +void mss_set_buswidth(struct mss_host *host, int buswidth) +{ + struct mss_ios ios; + + memcpy(&ios, &host->ios, sizeof(ios)); + ios.bus_width = buswidth; + host->ops->set_ios(host, &ios); +} + +void mss_set_busmode(struct mss_host *host, int busmode) +{ + struct mss_ios ios; + + memcpy(&ios, &host->ios, sizeof(ios)); + ios.bus_mode = busmode; + host->ops->set_ios(host, &ios); +} + +int mss_send_request(struct mss_request *req) +{ + struct mss_host *host; + struct mss_card *card; +// unsigned long flags; + int ret; + + if (!req->card || !req->card->slot) + return -ENODEV; + card = req->card; + host = card->slot->host; + if (req->card->state & MSS_CARD_REMOVING) + return MSS_ERROR_CARD_REMOVING; + card->state |= MSS_CARD_HANDLEIO; + dbg5("claim host"); + mss_claim_host(host, card); + ret = card->prot_driver->prot_entry(card, req->action, req->arg, + req->result); + mss_release_host(host); + dbg5("release host"); + card->state &= ~MSS_CARD_HANDLEIO; + + if (ret) + req->errno = card->prot_driver->get_errno(card); + + return ret; +} + +struct mss_host * mss_alloc_host(unsigned int slot_num, unsigned int id, unsigned int private_size) +{ + struct mss_host *host; + struct mss_slot *slot; + int i = 0, size; + + printk("%s(): enter\n", __FUNCTION__); + + size = sizeof(struct mss_host) + sizeof(struct mss_slot) * slot_num + + private_size; + host = (struct mss_host *)kzalloc(size, GFP_KERNEL); + if (!host) + return NULL; + memset(host, 0x0, size); + host->id = id; + host->slot_num = slot_num; + while(i < slot_num) { + slot = &host->slots[i]; + slot->id = i; + slot->host = host; + INIT_DELAYED_WORK(&slot->card_detect, (void (*)(void *))mss_scan_slot); + i++; + } + host->private = (void *)&host->slots[slot_num]; + host->active_card = NULL; + init_waitqueue_head(&host->wq); + spin_lock_init(&host->lock); + + return host; +} + +void mss_free_host(struct mss_host *host) +{ + kfree(host); +} + +struct mss_host *mss_find_host(int id) +{ + struct list_head *pos; + struct mss_host *host; + + list_for_each(pos, &mss_host_list) { + host = list_entry(pos, struct mss_host, node); + if (host->id == id) + return host; + } + return NULL; +} + +/***************************************************************************** + * + * module init and exit functions + * + ****************************************************************************/ + +static int mss_core_driver_init(void) +{ + return bus_register(&mmc_bus_type); +} + +static void mss_core_driver_exit(void) +{ + bus_unregister(&mmc_bus_type); +} + + +EXPORT_SYMBOL_GPL(mss_detect_change); +EXPORT_SYMBOL_GPL(mss_scan_slot); +EXPORT_SYMBOL_GPL(mss_scan_host); +EXPORT_SYMBOL_GPL(mss_alloc_host); +EXPORT_SYMBOL_GPL(mss_free_host); +EXPORT_SYMBOL_GPL(mss_find_host); +EXPORT_SYMBOL_GPL(mss_force_card_remove); +EXPORT_SYMBOL_GPL(register_mss_host); +EXPORT_SYMBOL_GPL(unregister_mss_host); + +EXPORT_SYMBOL_GPL(register_mss_driver); +EXPORT_SYMBOL_GPL(unregister_mss_driver); +EXPORT_SYMBOL_GPL(mss_send_request); +EXPORT_SYMBOL_GPL(mss_get_capacity); + +EXPORT_SYMBOL_GPL(register_mss_prot_driver); +EXPORT_SYMBOL_GPL(unregister_mss_prot_driver); +EXPORT_SYMBOL_GPL(mss_send_ll_req); +EXPORT_SYMBOL_GPL(mss_send_simple_ll_req); +EXPORT_SYMBOL_GPL(mss_set_sdio_int); +EXPORT_SYMBOL_GPL(mss_set_buswidth); +EXPORT_SYMBOL_GPL(mss_set_clock); +EXPORT_SYMBOL_GPL(mss_set_busmode); +EXPORT_SYMBOL_GPL(mss_card_get); +EXPORT_SYMBOL_GPL(mss_card_put); + +module_init(mss_core_driver_init); +module_exit(mss_core_driver_exit); + +MODULE_AUTHOR("Bridge Wu"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Core driver for MMC/SD/SDIO card"); --- linux-2.6.24.orig/drivers/mmc/mss/Kconfig +++ linux-2.6.24/drivers/mmc/mss/Kconfig @@ -0,0 +1,28 @@ +# +# MMC subsystem configuration +# + +comment "MSS structure support" + + +config MSS_BLOCK + tristate "MSS block device driver" + depends on MSS && BLOCK + default y + help + Say Y here to enable the MMC block device driver support. + This provides a block device driver, which you can use to + mount the filesystem. Almost everyone wishing MMC support + should say Y or M here. + +config MSS_SDHCI + tristate "MSS host controller driver" + depends on PCI && MSS + help + This select the generic Secure Digital Host Controller Interface. + It is used by manufacturers such as Texas Instruments(R), Ricoh(R) + and Toshiba(R). Most controllers found in laptops are of this type. + If you have a controller with this interface, say Y or M here. + + If unsure, say N. + --- linux-2.6.24.orig/drivers/mmc/mss/mss_sdhci.h +++ linux-2.6.24/drivers/mmc/mss/mss_sdhci.h @@ -0,0 +1,248 @@ +/* + * mss_sdhci.h - SD Host Controller interface driver + * + * Copyright (C) 2007 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 only + * for now as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* + * derived from linux/drivers/mmc/sdhci.h + * Copyright (c) 2005 Pierre Ossman + */ + + +/* + * PCI registers + */ +#define MSS_VDD_150 0 +#define MSS_VDD_155 1 +#define MSS_VDD_160 2 +#define MSS_VDD_165 3 +#define MSS_VDD_170 4 +#define MSS_VDD_180 5 +#define MSS_VDD_190 6 +#define MSS_VDD_200 7 +#define MSS_VDD_210 8 +#define MSS_VDD_220 9 +#define MSS_VDD_230 10 +#define MSS_VDD_240 11 +#define MSS_VDD_250 12 +#define MSS_VDD_260 13 +#define MSS_VDD_270 14 +#define MSS_VDD_280 15 +#define MSS_VDD_290 16 +#define MSS_VDD_300 17 +#define MSS_VDD_310 18 +#define MSS_VDD_320 19 +#define MSS_VDD_330 20 +#define MSS_VDD_340 21 +#define MSS_VDD_350 22 +#define MSS_VDD_360 23 + +#define PCI_SDHCI_IFPIO 0x00 +#define PCI_SDHCI_IFDMA 0x01 +#define PCI_SDHCI_IFVENDOR 0x02 + +#define PCI_SLOT_INFO 0x40 /* 8 bits */ +#define PCI_SLOT_INFO_SLOTS(x) ((x >> 4) & 7) +#define PCI_SLOT_INFO_FIRST_BAR_MASK 0x07 + +/* + * Controller registers + */ +#define SDHCI_DMA_ADDRESS 0x00 +#define SDHCI_BLOCK_SIZE 0x04 +#define SDHCI_MAKE_BLKSZ(dma, blksz) (((dma & 0x7) << 12) | (blksz & 0xFFF)) + +#define SDHCI_BLOCK_COUNT 0x06 +#define SDHCI_ARGUMENT 0x08 + +#define SDHCI_TRANSFER_MODE 0x0C +#define SDHCI_TRNS_DMA 0x01 +#define SDHCI_TRNS_BLK_CNT_EN 0x02 +#define SDHCI_TRNS_ACMD12 0x04 +#define SDHCI_TRNS_READ 0x10 +#define SDHCI_TRNS_MULTI 0x20 + +#define SDHCI_COMMAND 0x0E +#define SDHCI_CMD_RESP_MASK 0x03 +#define SDHCI_CMD_CRC 0x08 +#define SDHCI_CMD_INDEX 0x10 +#define SDHCI_CMD_DATA 0x20 + +#define SDHCI_CMD_RESP_NONE 0x00 +#define SDHCI_CMD_RESP_LONG 0x01 +#define SDHCI_CMD_RESP_SHORT 0x02 +#define SDHCI_CMD_RESP_SHORT_BUSY 0x03 + +#define SDHCI_MAKE_CMD(c, f) (((c & 0xff) << 8) | (f & 0xff)) + +#define SDHCI_RESPONSE 0x10 +#define SDHCI_BUFFER 0x20 +#define SDHCI_PRESENT_STATE 0x24 + +#define SDHCI_CMD_INHIBIT 0x00000001 +#define SDHCI_DATA_INHIBIT 0x00000002 +#define SDHCI_DOING_WRITE 0x00000100 +#define SDHCI_DOING_READ 0x00000200 +#define SDHCI_SPACE_AVAILABLE 0x00000400 +#define SDHCI_DATA_AVAILABLE 0x00000800 +#define SDHCI_CARD_PRESENT 0x00010000 +#define SDHCI_WRITE_PROTECT 0x00080000 + +#define SDHCI_HOST_CONTROL 0x28 +#define SDHCI_CTRL_LED 0x01 +#define SDHCI_CTRL_4BITBUS 0x02 +#define SDHCI_CTRL_HISPD 0x04 + +#define SDHCI_POWER_CONTROL 0x29 +#define SDHCI_POWER_ON 0x01 +#define SDHCI_POWER_180 0x0A +#define SDHCI_POWER_300 0x0C +#define SDHCI_POWER_330 0x0E + +#define SDHCI_BLOCK_GAP_CONTROL 0x2A + +#define SDHCI_WALK_UP_CONTROL 0x2B + +#define SDHCI_CLOCK_CONTROL 0x2C +#define SDHCI_DIVIDER_SHIFT 8 +#define SDHCI_CLOCK_CARD_EN 0x0004 +#define SDHCI_CLOCK_INT_STABLE 0x0002 +#define SDHCI_CLOCK_INT_EN 0x0001 + +#define SDHCI_TIMEOUT_CONTROL 0x2E + +#define SDHCI_SOFTWARE_RESET 0x2F +#define SDHCI_RESET_ALL 0x01 +#define SDHCI_RESET_CMD 0x02 +#define SDHCI_RESET_DATA 0x04 + +#define SDHCI_INT_STATUS 0x30 +#define SDHCI_INT_ENABLE 0x34 +#define SDHCI_SIGNAL_ENABLE 0x38 +#define SDHCI_INT_RESPONSE 0x00000001 +#define SDHCI_INT_DATA_END 0x00000002 +#define SDHCI_INT_BLK_GAP 0x00000004 +#define SDHCI_INT_DMA_END 0x00000008 +#define SDHCI_INT_SPACE_AVAIL 0x00000010 +#define SDHCI_INT_DATA_AVAIL 0x00000020 +#define SDHCI_INT_CARD_INSERT 0x00000040 +#define SDHCI_INT_CARD_REMOVE 0x00000080 +#define SDHCI_INT_CARD_INT 0x00000100 +#define SDHCI_INT_ERROR 0x00008000 +#define SDHCI_INT_TIMEOUT 0x00010000 +#define SDHCI_INT_CRC 0x00020000 +#define SDHCI_INT_END_BIT 0x00040000 +#define SDHCI_INT_INDEX 0x00080000 +#define SDHCI_INT_DATA_TIMEOUT 0x00100000 +#define SDHCI_INT_DATA_CRC 0x00200000 +#define SDHCI_INT_DATA_END_BIT 0x00400000 +#define SDHCI_INT_BUS_POWER 0x00800000 +#define SDHCI_INT_ACMD12ERR 0x01000000 + +#define SDHCI_INT_NORMAL_MASK 0x00007FFF +#define SDHCI_INT_ERROR_MASK 0xFFFF8000 + +#define SDHCI_INT_CMD_MASK (SDHCI_INT_RESPONSE | SDHCI_INT_TIMEOUT | \ + SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX) +#define SDHCI_INT_DATA_MASK (SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \ + SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \ + SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \ + SDHCI_INT_DATA_END_BIT) + +#define SDHCI_ACMD12_ERR 0x3C + +/* 3E-3F reserved */ + +#define SDHCI_CAPABILITIES 0x40 +#define SDHCI_TIMEOUT_CLK_MASK 0x0000003F +#define SDHCI_TIMEOUT_CLK_SHIFT 0 +#define SDHCI_TIMEOUT_CLK_UNIT 0x00000080 +#define SDHCI_CLOCK_BASE_MASK 0x00003F00 +#define SDHCI_CLOCK_BASE_SHIFT 8 +#define SDHCI_MAX_BLOCK_MASK 0x00030000 +#define SDHCI_MAX_BLOCK_SHIFT 16 +#define SDHCI_CAN_DO_HISPD 0x00200000 +#define SDHCI_CAN_DO_DMA 0x00400000 +#define SDHCI_CAN_VDD_330 0x01000000 +#define SDHCI_CAN_VDD_300 0x02000000 +#define SDHCI_CAN_VDD_180 0x04000000 + +/* 44-47 reserved for more caps */ + +#define SDHCI_MAX_CURRENT 0x48 + +/* 4C-4F reserved for more max current */ +/* 50-FB reserved */ + +#define SDHCI_SLOT_INT_STATUS 0xFC + +#define SDHCI_HOST_VERSION 0xFE +#define SDHCI_VENDOR_VER_MASK 0xFF00 +#define SDHCI_VENDOR_VER_SHIFT 8 +#define SDHCI_SPEC_VER_MASK 0x00FF +#define SDHCI_SPEC_VER_SHIFT 0 + +#define SDHCI_USE_DMA (1<<0) + +struct sdhci_chip; + +struct sdhci_host { + struct sdhci_chip *chip; + struct mss_host *mmc; /* MMC structure */ + + spinlock_t lock; /* Mutex */ + int flags; /* Host attributes */ + + + unsigned int max_clk; /* Max possible freq (MHz) */ + unsigned int timeout_clk; /* Timeout freq (KHz) */ + unsigned int max_block; /* Max block size (bytes) */ + + unsigned int clock; /* Current clock (MHz) */ + unsigned short power; /* Current voltage */ + + struct mss_ll_request *mrq; /* Current request */ + struct mss_cmd *cmd; /* Current command */ + struct mss_data *data; /* Current data request */ + struct mss_card *card; + + struct scatterlist *cur_sg; /* We're working on this */ + char *mapped_sg; /* This is where it's mapped */ + int num_sg; /* Entries left */ + int offset; /* Offset into current sg */ + int remain; /* Bytes left in current */ + int size; /* Remaining bytes in transfer */ + + char slot_descr[20]; /* Name for reservations */ + int irq; /* Device IRQ */ + int bar; /* PCI BAR index */ + unsigned long addr; /* Bus address */ + void __iomem * ioaddr; /* Mapped address */ + + struct tasklet_struct card_tasklet; /* Tasklet structures */ + struct tasklet_struct finish_tasklet; + + struct timer_list timer; /* Timer for timeouts */ +}; + +struct sdhci_chip { + struct pci_dev *pdev; + unsigned long quirks; + int num_slots; /* Slots on controller */ + struct sdhci_host *hosts[0]; /* Pointers to hosts */ +}; --- linux-2.6.24.orig/drivers/mmc/mss/Makefile +++ linux-2.6.24/drivers/mmc/mss/Makefile @@ -0,0 +1,13 @@ +# +# Makefile for the kernel MSS(mmc/sd/sdio) device drivers. +# + +# Core +obj-$(CONFIG_MSS) += mss_core.o mmc_protocol.o sdio_protocol.o sd_protocol.o + +# Media drivers +obj-$(CONFIG_MSS_BLOCK) += mss_block.o + +# Host drivers +obj-$(CONFIG_MSS_SDHCI) += mss_sdhci.o + --- linux-2.6.24.orig/drivers/mmc/mss/mss_sdhci.c +++ linux-2.6.24/drivers/mmc/mss/mss_sdhci.c @@ -0,0 +1,1778 @@ +/* + * mss_sdhci.c - SD Host Controller interface driver + * + * Copyright (C) 2007 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 only + * for now as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * derived from linux/drivers/mmc/sdhci.c + * Copyright (c) 2005 Pierre Ossman + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "mss_sdhci.h" + + +#define DRIVER_NAME "sdhci" +#define BUGMAIL " " + +#define DBG(f, x...) \ + pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x) + +static unsigned int debug_nodma = 0; +static unsigned int debug_forcedma = 0; +static unsigned int debug_quirks = 0; + +#define SDHCI_QUIRK_CLOCK_BEFORE_RESET (1<<0) +#define SDHCI_QUIRK_FORCE_DMA (1<<1) +/* Controller doesn't like some resets when there is no card inserted. */ +#define SDHCI_QUIRK_NO_CARD_NO_RESET (1<<2) +#define SDHCI_QUIRK_SINGLE_POWER_WRITE (1<<3) + +static const struct pci_device_id pci_ids[] __devinitdata = { + { + .vendor = PCI_VENDOR_ID_RICOH, + .device = PCI_DEVICE_ID_RICOH_R5C822, + .subvendor = PCI_VENDOR_ID_IBM, + .subdevice = PCI_ANY_ID, + .driver_data = SDHCI_QUIRK_CLOCK_BEFORE_RESET | + SDHCI_QUIRK_FORCE_DMA, + }, + + { + .vendor = PCI_VENDOR_ID_RICOH, + .device = PCI_DEVICE_ID_RICOH_R5C822, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = SDHCI_QUIRK_FORCE_DMA | + SDHCI_QUIRK_NO_CARD_NO_RESET, + }, + + { + .vendor = PCI_VENDOR_ID_TI, + .device = PCI_DEVICE_ID_TI_XX21_XX11_SD, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = SDHCI_QUIRK_FORCE_DMA, + }, + + { + .vendor = PCI_VENDOR_ID_ENE, + .device = PCI_DEVICE_ID_ENE_CB712_SD, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE, + }, + + { /* Generic SD host controller */ + PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) + }, + + { /* end: all zeroes */ }, +}; + +MODULE_DEVICE_TABLE(pci, pci_ids); + +static void sdhci_prepare_data(struct sdhci_host *, struct mss_data *); +static void sdhci_finish_data(struct sdhci_host *); + +static void sdhci_send_command(struct sdhci_host *, struct mss_cmd *); +static void sdhci_finish_command(struct sdhci_host *); + +struct proc_dir_entry *dir_sdhci = NULL; + +static inline struct sdhci_host* slot_to_host(struct mss_slot *slot) +{ + return (struct sdhci_host*)(slot->private); +} + +static inline struct sdhci_host* mss_to_host(struct mss_host *mss) +{ + return (struct sdhci_host*)(mss->private); +} + +static void sdhci_dumpregs(struct sdhci_host *host) +{ + printk(KERN_DEBUG DRIVER_NAME ": ============== REGISTER DUMP ==============\n"); + + printk(KERN_DEBUG DRIVER_NAME ": Sys addr: 0x%08x | Version: 0x%08x\n", + readl(host->ioaddr + SDHCI_DMA_ADDRESS), + readw(host->ioaddr + SDHCI_HOST_VERSION)); + printk(KERN_DEBUG DRIVER_NAME ": Blk size: 0x%08x | Blk cnt: 0x%08x\n", + readw(host->ioaddr + SDHCI_BLOCK_SIZE), + readw(host->ioaddr + SDHCI_BLOCK_COUNT)); + printk(KERN_DEBUG DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n", + readl(host->ioaddr + SDHCI_ARGUMENT), + readw(host->ioaddr + SDHCI_TRANSFER_MODE)); + printk(KERN_DEBUG DRIVER_NAME ": Present: 0x%08x | Host ctl: 0x%08x\n", + readl(host->ioaddr + SDHCI_PRESENT_STATE), + readb(host->ioaddr + SDHCI_HOST_CONTROL)); + printk(KERN_DEBUG DRIVER_NAME ": Power: 0x%08x | Blk gap: 0x%08x\n", + readb(host->ioaddr + SDHCI_POWER_CONTROL), + readb(host->ioaddr + SDHCI_BLOCK_GAP_CONTROL)); + printk(KERN_DEBUG DRIVER_NAME ": Wake-up: 0x%08x | Clock: 0x%08x\n", + readb(host->ioaddr + SDHCI_WALK_UP_CONTROL), + readw(host->ioaddr + SDHCI_CLOCK_CONTROL)); + printk(KERN_DEBUG DRIVER_NAME ": Timeout: 0x%08x | Int stat: 0x%08x\n", + readb(host->ioaddr + SDHCI_TIMEOUT_CONTROL), + readl(host->ioaddr + SDHCI_INT_STATUS)); + printk(KERN_DEBUG DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n", + readl(host->ioaddr + SDHCI_INT_ENABLE), + readl(host->ioaddr + SDHCI_SIGNAL_ENABLE)); + printk(KERN_DEBUG DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n", + readw(host->ioaddr + SDHCI_ACMD12_ERR), + readw(host->ioaddr + SDHCI_SLOT_INT_STATUS)); + printk(KERN_DEBUG DRIVER_NAME ": Caps: 0x%08x | Max curr: 0x%08x\n", + readl(host->ioaddr + SDHCI_CAPABILITIES), + readl(host->ioaddr + SDHCI_MAX_CURRENT)); + + printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n"); +} + +#ifdef CONFIG_PROC_FS +static int sdhci_read_proc(char* page, char** start, off_t off, int count, int* eof, void* data) { +int len = 0; +struct sdhci_host *host=(struct sdhci_host *)data; + + if (host == NULL) goto done; + + len += sprintf(page+len, DRIVER_NAME ": ============== REGISTER DUMP ==============\n"); + + len += sprintf(page+len, DRIVER_NAME ": Sys addr: 0x%08x | Version: 0x%08x\n", + readl(host->ioaddr + SDHCI_DMA_ADDRESS), + readw(host->ioaddr + SDHCI_HOST_VERSION)); + len += sprintf(page+len, DRIVER_NAME ": Blk size: 0x%08x | Blk cnt: 0x%08x\n", + readw(host->ioaddr + SDHCI_BLOCK_SIZE), + readw(host->ioaddr + SDHCI_BLOCK_COUNT)); + len += sprintf(page+len, DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n", + readl(host->ioaddr + SDHCI_ARGUMENT), + readw(host->ioaddr + SDHCI_TRANSFER_MODE)); + len += sprintf(page+len, DRIVER_NAME ": Present: 0x%08x | Host ctl: 0x%08x\n", + readl(host->ioaddr + SDHCI_PRESENT_STATE), + readb(host->ioaddr + SDHCI_HOST_CONTROL)); + len += sprintf(page+len, DRIVER_NAME ": Power: 0x%08x | Blk gap: 0x%08x\n", + readb(host->ioaddr + SDHCI_POWER_CONTROL), + readb(host->ioaddr + SDHCI_BLOCK_GAP_CONTROL)); + len += sprintf(page+len, DRIVER_NAME ": Wake-up: 0x%08x | Clock: 0x%08x\n", + readb(host->ioaddr + SDHCI_WALK_UP_CONTROL), + readw(host->ioaddr + SDHCI_CLOCK_CONTROL)); + len += sprintf(page+len, DRIVER_NAME ": Timeout: 0x%08x | Int stat: 0x%08x\n", + readb(host->ioaddr + SDHCI_TIMEOUT_CONTROL), + readl(host->ioaddr + SDHCI_INT_STATUS)); + len += sprintf(page+len, DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n", + readl(host->ioaddr + SDHCI_INT_ENABLE), + readl(host->ioaddr + SDHCI_SIGNAL_ENABLE)); + len += sprintf(page+len, DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n", + readw(host->ioaddr + SDHCI_ACMD12_ERR), + readw(host->ioaddr + SDHCI_SLOT_INT_STATUS)); + len += sprintf(page+len, DRIVER_NAME ": Caps: 0x%08x | Max curr: 0x%08x\n", + readl(host->ioaddr + SDHCI_CAPABILITIES), + readl(host->ioaddr + SDHCI_MAX_CURRENT)); + + len += sprintf(page+len, DRIVER_NAME ": ===========================================\n"); + +done: + *eof = 1; + return len; +} +#endif + +/*****************************************************************************\ + * * + * Low level functions * + * * +\*****************************************************************************/ + +static void sdhci_reset(struct sdhci_host *host, u8 mask) +{ + unsigned long timeout; + + if (host->chip->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) { + if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & + SDHCI_CARD_PRESENT)) + return; + } + + writeb(mask, host->ioaddr + SDHCI_SOFTWARE_RESET); + + if (mask & SDHCI_RESET_ALL) + host->clock = 0; + + /* Wait max 100 ms */ + timeout = 100; + + /* hw clears the bit when it's done */ + while (readb(host->ioaddr + SDHCI_SOFTWARE_RESET) & mask) { + if (timeout == 0) { + printk(KERN_ERR "mmchost: Reset 0x%x never completed.\n", (int)mask); + sdhci_dumpregs(host); + return; + } + timeout--; + mdelay(1); + } +} + +static void sdhci_init(struct sdhci_host *host) +{ + u32 intmask; + + sdhci_reset(host, SDHCI_RESET_ALL); + + intmask = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT | + SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX | + SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT | + SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT | + SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | + SDHCI_INT_DMA_END | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE; + + writel(intmask, host->ioaddr + SDHCI_INT_ENABLE); + writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE); +} + +static void sdhci_activate_led(struct sdhci_host *host) +{ + u8 ctrl; + + ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL); + ctrl |= SDHCI_CTRL_LED; + writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); +} + +static void sdhci_deactivate_led(struct sdhci_host *host) +{ + u8 ctrl; + + ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL); + ctrl &= ~SDHCI_CTRL_LED; + writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); +} + +/*****************************************************************************\ + * * + * Core functions * + * * +\*****************************************************************************/ + +static inline char* sdhci_sg_to_buffer(struct sdhci_host* host) +{ + return page_address(host->cur_sg->page) + host->cur_sg->offset; +} + +static inline int sdhci_next_sg(struct sdhci_host* host) +{ + /* Skip to next SG entry. */ + host->cur_sg++; + host->num_sg--; + + /* Any entries left? */ + if (host->num_sg > 0) { + host->offset = 0; + host->remain = host->cur_sg->length; + } + + return host->num_sg; +} + +static void sdhci_read_block_pio(struct sdhci_host *host) +{ + int blksize, chunk_remain; + u32 data; + char *buffer; + int size; + + + blksize = host->data->blksz; + chunk_remain = 0; + data = 0; + + buffer = sdhci_sg_to_buffer(host) + host->offset; + + while (blksize) { + if (chunk_remain == 0) { + data = readl(host->ioaddr + SDHCI_BUFFER); + chunk_remain = min(blksize, 4); + } + + size = min(host->size, host->remain); + size = min(size, chunk_remain); + + chunk_remain -= size; + blksize -= size; + host->offset += size; + host->remain -= size; + host->size -= size; + while (size) { + *buffer = data & 0xFF; + buffer++; + data >>= 8; + size--; + } + + if (host->remain == 0) { + if (sdhci_next_sg(host) == 0) { + BUG_ON(blksize != 0); + return; + } + buffer = sdhci_sg_to_buffer(host); + } + } +} + +static void sdhci_write_block_pio(struct sdhci_host *host) +{ + int blksize, chunk_remain; + u32 data; + char *buffer; + int bytes, size; + + + blksize = host->data->blksz; + chunk_remain = 4; + data = 0; + + bytes = 0; + buffer = sdhci_sg_to_buffer(host) + host->offset; + + while (blksize) { + size = min(host->size, host->remain); + size = min(size, chunk_remain); + + chunk_remain -= size; + blksize -= size; + host->offset += size; + host->remain -= size; + host->size -= size; + while (size) { + data >>= 8; + data |= (u32)*buffer << 24; + buffer++; + size--; + } + + if (chunk_remain == 0) { + writel(data, host->ioaddr + SDHCI_BUFFER); + chunk_remain = min(blksize, 4); + } + + if (host->remain == 0) { + if (sdhci_next_sg(host) == 0) { + BUG_ON(blksize != 0); + return; + } + buffer = sdhci_sg_to_buffer(host); + } + } +} + +static void sdhci_transfer_pio(struct sdhci_host *host) +{ + u32 mask; + + BUG_ON(!host->data); + + if (host->size == 0) + return; + + if (host->data->flags & MSS_DATA_READ) + mask = SDHCI_DATA_AVAILABLE; + else + mask = SDHCI_SPACE_AVAILABLE; + + while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) { + if (host->data->flags & MSS_DATA_READ) + sdhci_read_block_pio(host); + else + sdhci_write_block_pio(host); + + if (host->size == 0) + break; + + BUG_ON(host->num_sg == 0); + } + + DBG("PIO transfer complete.\n"); +} + + +static void sdhci_prepare_data(struct sdhci_host *host, struct mss_data *data) +{ + u8 count; + unsigned target_timeout, current_timeout; + + WARN_ON(host->data); + + if (data == NULL) + return; + + DBG("blksz %04x blks %04x flags %08x\n", + data->blksz, data->blocks, data->flags); + DBG("tsac %d ms\n", data->timeout_ns / 1000000); + + /* Sanity checks */ + BUG_ON(data->blksz * data->blocks > 524288); + //BUG_ON(data->blksz > host->mmc->max_blk_size); + BUG_ON(data->blocks > 65535); + + /* timeout in us */ + target_timeout = data->timeout_ns / 1000; + + /* + * Figure out needed cycles. + * We do this in steps in order to fit inside a 32 bit int. + * The first step is the minimum timeout, which will have a + * minimum resolution of 6 bits: + * (1) 2^13*1000 > 2^22, + * (2) host->timeout_clk < 2^16 + * => + * (1) / (2) > 2^6 + */ + count = 0; + current_timeout = (1 << 13) * 1000 / host->timeout_clk; + while (current_timeout < target_timeout) { + count++; + current_timeout <<= 1; + if (count >= 0xF) + break; + } + + if (count >= 0xF) { + printk(KERN_WARNING "mmchost: Too large timeout requested!\n"); + count = 0xE; + } + + if (count == 0) count = 0x8; /* add by feng for SD memory timeout issue */ + writeb(count, host->ioaddr + SDHCI_TIMEOUT_CONTROL); + + if (host->flags & SDHCI_USE_DMA) { + int count; + + count = pci_map_sg(host->chip->pdev, data->sg, data->sg_len, + (data->flags & MSS_DATA_READ)?PCI_DMA_FROMDEVICE:PCI_DMA_TODEVICE); + BUG_ON(count != 1); + + writel(sg_dma_address(data->sg), host->ioaddr + SDHCI_DMA_ADDRESS); + } else { + host->size = data->blksz * data->blocks; + + host->cur_sg = data->sg; + host->num_sg = data->sg_len; + + host->offset = 0; + host->remain = host->cur_sg->length; + } + + + /* We do not handle DMA boundaries, so set it to max (512 KiB) */ + writew(SDHCI_MAKE_BLKSZ(7, data->blksz), + host->ioaddr + SDHCI_BLOCK_SIZE); + writew(data->blocks, host->ioaddr + SDHCI_BLOCK_COUNT); +} + +static void sdhci_set_transfer_mode(struct sdhci_host *host, + struct mss_data *data) +{ + u16 mode; + + WARN_ON(host->data); + + if (data == NULL) + return; + + mode = SDHCI_TRNS_BLK_CNT_EN; + if (data->blocks > 1) + mode |= SDHCI_TRNS_MULTI; + if (data->flags & MSS_DATA_READ) + mode |= SDHCI_TRNS_READ; + if (host->flags & SDHCI_USE_DMA) + mode |= SDHCI_TRNS_DMA; + + writew(mode, host->ioaddr + SDHCI_TRANSFER_MODE); +} + +static void sdhci_finish_data(struct sdhci_host *host) +{ + struct mss_data *data; + struct mss_cmd *cmd; + u16 blocks; + + BUG_ON(!host->data); + BUG_ON(!host->mrq->cmd); + + data = host->data; + cmd = host->mrq->cmd; + host->data = NULL; + + if (host->flags & SDHCI_USE_DMA) { + pci_unmap_sg(host->chip->pdev, data->sg, data->sg_len, + (data->flags & MSS_DATA_READ)?PCI_DMA_FROMDEVICE:PCI_DMA_TODEVICE); + } + + /* + * Controller doesn't count down when in single block mode. + */ + if ((data->blocks == 1) && (cmd->error == MSS_ERROR_NONE)) + blocks = 0; + else + blocks = readw(host->ioaddr + SDHCI_BLOCK_COUNT); + data->bytes_xfered = data->blksz * (data->blocks - blocks); + + if ((cmd->error == MSS_ERROR_NONE) && blocks) { + printk(KERN_ERR "mmchost: Controller signalled completion even " + "though there were blocks left. Please report this " + "to " BUGMAIL ".\n"); + cmd->error = MSS_ERROR_CRC; + } else if (host->size != 0) { + printk(KERN_ERR "mmchost: %d bytes were left untransferred. " + "Please report this to " BUGMAIL ".\n", host->size); + cmd->error = MSS_ERROR_CRC; + } + + DBG("Ending data transfer (%d bytes)\n", data->bytes_xfered); + + tasklet_schedule(&host->finish_tasklet); +} + +static void sdhci_send_command(struct sdhci_host *host, struct mss_cmd *cmd) +{ + unsigned long flags; + u32 mask; + unsigned long timeout; + + WARN_ON(host->cmd); + + DBG("Sending cmd (%x)\n", cmd->opcode); + + /* Wait max 10 ms */ + timeout = 10; + + mask = SDHCI_CMD_INHIBIT; + + if ((cmd->data != NULL) || (cmd->rtype == MSS_RESPONSE_R1B)) + mask |= SDHCI_DATA_INHIBIT; + + while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) { + if (timeout == 0) { + printk(KERN_ERR "mmchost: Controller never released " + "inhibit bit(s).\n"); + sdhci_dumpregs(host); + cmd->error = MSS_ERROR_CRC; + tasklet_schedule(&host->finish_tasklet); + return; + } + timeout--; + mdelay(1); + } + + mod_timer(&host->timer, jiffies + 10 * HZ); + + host->cmd = cmd; + + sdhci_prepare_data(host, cmd->data); + + writel(cmd->arg, host->ioaddr + SDHCI_ARGUMENT); + + sdhci_set_transfer_mode(host, cmd->data); + + + switch (cmd->rtype) { + case MSS_RESPONSE_NONE: + flags = SDHCI_CMD_RESP_NONE; + break; + case MSS_RESPONSE_R1: + flags = SDHCI_CMD_RESP_SHORT | SDHCI_CMD_CRC | SDHCI_CMD_INDEX; + break; + case MSS_RESPONSE_R1B: + flags = SDHCI_CMD_RESP_SHORT_BUSY | SDHCI_CMD_CRC | SDHCI_CMD_INDEX; + break; + case MSS_RESPONSE_R2_CID: + case MSS_RESPONSE_R2_CSD: + flags = SDHCI_CMD_RESP_LONG | SDHCI_CMD_CRC; + break; + case MSS_RESPONSE_R3: + flags = SDHCI_CMD_RESP_SHORT; + break; + case MSS_RESPONSE_R6: + flags = SDHCI_CMD_RESP_SHORT | SDHCI_CMD_CRC; + break; + default: + flags = SDHCI_CMD_RESP_SHORT; + } + + if (cmd->data) + flags |= SDHCI_CMD_DATA; + DBG("SEND CMD=%08X, ARG=%08X\n", + SDHCI_MAKE_CMD(cmd->opcode, flags), cmd->arg); + writew(SDHCI_MAKE_CMD(cmd->opcode, flags), + host->ioaddr + SDHCI_COMMAND); +} + +static void sdhci_finish_command(struct sdhci_host *host) +{ + int i; + u32 *rp; + + BUG_ON(host->cmd == NULL); + + if (host->cmd->rtype != MSS_RESPONSE_NONE) { + switch (host->cmd->rtype) { + case MSS_RESPONSE_R2_CID: + case MSS_RESPONSE_R2_CSD: + case MSS_RESPONSE_R3: + host->cmd->response[0] = 0x3f; + break; + case MSS_RESPONSE_R6: + case MSS_RESPONSE_R1: + case MSS_RESPONSE_R1B: + default: + host->cmd->response[0] = host->cmd->opcode; + } + rp = (u32 *)&host->cmd->response[1]; + if ((host->cmd->rtype == MSS_RESPONSE_R2_CID)|| + (host->cmd->rtype == MSS_RESPONSE_R2_CSD)) { + /* CRC is stripped so we need to do some shifting. */ + for (i = 0; i < 4; i++, rp++) { + *rp = readl(host->ioaddr + + SDHCI_RESPONSE + (3-i)*4) << 8; + if (i != 3) + *rp |= readb(host->ioaddr + + SDHCI_RESPONSE + (3-i)*4-1); + //*rp = BYTE_REVERSE(*rp); + *rp = ___arch__swab32(*rp); + } + } else { + *rp = readl(host->ioaddr + SDHCI_RESPONSE); + //*rp = BYTE_REVERSE(*rp); + *rp = ___arch__swab32(*rp); + } + } + + host->cmd->error = MSS_ERROR_NONE; + + DBG("Ending cmd (%x)\n", host->cmd->opcode); + + if (host->cmd->data) + host->data = host->cmd->data; + else + tasklet_schedule(&host->finish_tasklet); + + host->cmd = NULL; +} + +static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) +{ + int div; + //u8 ctrl; + u16 clk; + unsigned long timeout; + + if (clock == host->clock) + return; + + writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL); + + + /* + ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL); + if (clock > 25000000) + ctrl |= SDHCI_CTRL_HISPD; + else + ctrl &= ~SDHCI_CTRL_HISPD; + writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); + */ + + if (clock == 0) + goto out; + + for (div = 1;div < 256;div *= 2) { + if ((host->max_clk / div) <= clock) + break; + } + div >>= 1; + + clk = div << SDHCI_DIVIDER_SHIFT; + clk |= SDHCI_CLOCK_INT_EN; + writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL); + + /* Wait max 10 ms */ + timeout = 10; + while (!((clk = readw(host->ioaddr + SDHCI_CLOCK_CONTROL)) + & SDHCI_CLOCK_INT_STABLE)) { + if (timeout == 0) { + printk(KERN_ERR "mmchost: Internal clock never estabilised.\n"); + sdhci_dumpregs(host); + return; + } + timeout--; + mdelay(1); + } + + clk |= SDHCI_CLOCK_CARD_EN; + writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL); + +out: + host->clock = clock; +} + +static void sdhci_set_power(struct sdhci_host *host, unsigned short power) +{ + u8 pwr; + int i; + + /* feng: modify ulong to ushort for 2.6.21 porting */ + if (power != (unsigned short)-1) { + for(i = 0; (i < 16)&&!(power&1); i++) power >>= 1; + power = i; + } + DBG("set power to %d\n", power); + + + if (host->power == power) + return; + + if (power == (unsigned short)-1) { + writeb(0, host->ioaddr + SDHCI_POWER_CONTROL); + goto out; + } + + /* + * Spec says that we should clear the power reg before setting + * a new value. Some controllers don't seem to like this though. + */ + if (!(host->chip->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE)) + writeb(0, host->ioaddr + SDHCI_POWER_CONTROL); + + pwr = SDHCI_POWER_ON; + + /* + switch (power) { + case MSS_VDD_170: + case MSS_VDD_180: + case MSS_VDD_190: + pwr |= SDHCI_POWER_180; + break; + case MSS_VDD_290: + case MSS_VDD_300: + case MSS_VDD_310: + pwr |= SDHCI_POWER_300; + break; + case MSS_VDD_320: + case MSS_VDD_330: + case MSS_VDD_340: + pwr |= SDHCI_POWER_330; + break; + default: + // mask by feng, temply masked it for debug + //BUG(); + } + */ + + /* added for temp use */ + pwr |= SDHCI_POWER_330; + + writeb(pwr, host->ioaddr + SDHCI_POWER_CONTROL); + +out: + host->power = power; + +} + +/*****************************************************************************\ + * * + * MMC callbacks * + * * +\*****************************************************************************/ + +static void sdhci_request(struct mss_host *mmc, struct mss_ll_request *mrq) +{ + struct sdhci_host *host; + unsigned long flags; + + host = mss_to_host(mmc); + if (mmc->active_card != NULL) + host->card = mmc->active_card; + + spin_lock_irqsave(&host->lock, flags); + + WARN_ON(host->mrq != NULL); + + sdhci_activate_led(host); + + host->mrq = mrq; + + if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) { + host->mrq->cmd->error = MSS_ERROR_TIMEOUT; + tasklet_schedule(&host->finish_tasklet); + } else + sdhci_send_command(host, mrq->cmd); + + mmiowb(); + spin_unlock_irqrestore(&host->lock, flags); +} + +static void sdhci_set_ios(struct mss_host *mmc, struct mss_ios *ios) +{ + struct sdhci_host *host; + unsigned long flags; + u8 ctrl; + u32 intmask; + host = mss_to_host(mmc); + + DBG("clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n", + ios->clock, ios->bus_mode, ios->power_mode, + ios->chip_select, ios->vdd, ios->bus_width); + + spin_lock_irqsave(&host->lock, flags); + + /* + * Reset the chip on each power off. + * Should clear out any weird states. + */ + if (ios->power_mode == MSS_POWER_OFF) { + writel(0, host->ioaddr + SDHCI_SIGNAL_ENABLE); + sdhci_init(host); + } + + sdhci_set_clock(host, ios->clock); + + if (ios->power_mode == MSS_POWER_OFF) + sdhci_set_power(host, -1); + else + sdhci_set_power(host, ios->vdd); + + ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL); + if (ios->bus_width == MSS_BUSWIDTH_4BIT) + ctrl |= SDHCI_CTRL_4BITBUS; + else + ctrl &= ~SDHCI_CTRL_4BITBUS; + + /* temply masked by feng + if (ios->timing == MMC_TIMING_SD_HS) + ctrl |= SDHCI_CTRL_HISPD; + else + ctrl &= ~SDHCI_CTRL_HISPD; + */ + + writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); + mmiowb(); + + + if (ios->sdio_int == MSS_SDIO_INT_EN) { + intmask = readl(host->ioaddr + SDHCI_SIGNAL_ENABLE); + intmask |= SDHCI_INT_CARD_INT; + writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE); + + intmask = readl(host->ioaddr + SDHCI_INT_ENABLE); + intmask |= SDHCI_INT_CARD_INT; + writel(intmask, host->ioaddr + SDHCI_INT_ENABLE); + } else { + intmask = readl(host->ioaddr + SDHCI_SIGNAL_ENABLE); + intmask &= ~(SDHCI_INT_CARD_INT); + writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE); + + intmask = readl(host->ioaddr + SDHCI_INT_ENABLE); + intmask &= ~(SDHCI_INT_CARD_INT); + writel(intmask, host->ioaddr + SDHCI_INT_ENABLE); + } + + + memcpy(&host->mmc->ios, ios, sizeof(struct mss_ios)); + spin_unlock_irqrestore(&host->lock, flags); +} + +/* +static int sdhci_slot_is_wp(struct mss_slot *slot) +{ + struct sdhci_host *host; + int present; + + host = slot_to_host(slot); + present = readl(host->ioaddr + SDHCI_PRESENT_STATE); + return !(present & SDHCI_WRITE_PROTECT); +} + +static int sdhci_slot_is_empty(struct mss_slot *slot) +{ + struct sdhci_host *host; + int present; + + host = slot_to_host(slot); + present = readl(host->ioaddr + SDHCI_PRESENT_STATE); + return !(present & SDHCI_CARD_PRESENT); +} + +static int sdhci_mss_slot_is_wp(struct mss_slot *slot) +{ + struct sdhci_host *host; + int result; + unsigned long flags; + + host = slot_to_host(slot); + spin_lock_irqsave(&host->lock, flags); + result = sdhci_slot_is_wp(slot); + spin_unlock_irqrestore(&host->lock, flags); + return result; +} + +static int sdhci_mss_slot_is_empty(struct mss_slot *slot) +{ + struct sdhci_host *host; + int result; + unsigned long flags; + + host = slot_to_host(slot); + spin_lock_irqsave(&host->lock, flags); + result = sdhci_slot_is_empty(slot); + spin_unlock_irqrestore(&host->lock, flags); + return result; +} +*/ + +static u32 sdhci_get_cur_state(struct mss_slot *slot) +{ + struct sdhci_host *host; + u32 state; + unsigned long flags; + + host = slot_to_host(slot); + spin_lock_irqsave(&host->lock, flags); + state = readl(host->ioaddr + SDHCI_PRESENT_STATE); + spin_unlock_irqrestore(&host->lock, flags); + return state; +} + +static int sdhci_mss_slot_is_wp(struct mss_slot *slot) +{ + return !( sdhci_get_cur_state(slot) & SDHCI_WRITE_PROTECT); +} + +static int sdhci_mss_slot_is_empty(struct mss_slot *slot) +{ + return !( sdhci_get_cur_state(slot) & SDHCI_CARD_PRESENT); +} + + +static struct mss_host_ops sdhci_ops = { + .request = sdhci_request, + .set_ios = sdhci_set_ios, + .is_slot_empty = sdhci_mss_slot_is_empty, + .is_slot_wp = sdhci_mss_slot_is_wp, +}; + +/*****************************************************************************\ + * * + * Tasklets * + * * +\*****************************************************************************/ + +static void sdhci_tasklet_card(unsigned long param) +{ + struct sdhci_host *host; + unsigned long flags; + + host = (struct sdhci_host*)param; + + spin_lock_irqsave(&host->lock, flags); + + if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) { + if (host->mrq) { + printk(KERN_ERR "mmchost: Card removed during transfer!\n"); + printk(KERN_ERR "mmchost: Resetting controller.\n"); + + sdhci_reset(host, SDHCI_RESET_CMD); + sdhci_reset(host, SDHCI_RESET_DATA); + + host->mrq->cmd->error = MSS_ERROR_CRC; + tasklet_schedule(&host->finish_tasklet); + } + } + + spin_unlock_irqrestore(&host->lock, flags); + + + mss_detect_change(host->mmc, msecs_to_jiffies(500), 0); + //mmc_detect_change(host->mmc, msecs_to_jiffies(500)); + +} + +static void sdhci_tasklet_finish(unsigned long param) +{ + struct sdhci_host *host; + unsigned long flags; + struct mss_ll_request *mrq; + host = (struct sdhci_host*)param; + + spin_lock_irqsave(&host->lock, flags); + + del_timer(&host->timer); + + mrq = host->mrq; + + DBG("Ending request, cmd (%x)\n", mrq->cmd->opcode); + + /* + * The controller needs a reset of internal state machines + * upon error conditions. + */ + + if (mrq->cmd->error != MSS_ERROR_NONE) { + //if ((mrq->cmd->error != MSS_ERROR_NONE) || + // (mrq->data && ((mrq->data->error != MSS_ERROR_NONE) || + // (mrq->data->stop && (mrq->data->stop->error != MSS_ERROR_NONE))))) { + + /* Some controllers need this kick or reset won't work here */ + if (host->chip->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) { + unsigned int clock; + + /* This is to force an update */ + clock = host->clock; + host->clock = 0; + sdhci_set_clock(host, clock); + } + + /* Spec says we should do both at the same time, but Ricoh + controllers do not like that. */ + sdhci_reset(host, SDHCI_RESET_CMD); + sdhci_reset(host, SDHCI_RESET_DATA); + } + + +// printk(KERN_EMERG "%%%%%%%%%%%%%host->cmd = NULL; host->data = NULL %%%%%%%%%%%%%%%%%%%%\n"); + host->cmd = NULL; + host->data = NULL; + + sdhci_deactivate_led(host); + + mmiowb(); + spin_unlock_irqrestore(&host->lock, flags); + + host->mrq->done(host->mrq); + host->mrq = NULL; +} + +static void sdhci_timeout_timer(unsigned long data) +{ + struct sdhci_host *host; + unsigned long flags; + + host = (struct sdhci_host*)data; + + spin_lock_irqsave(&host->lock, flags); + + + + if (host->data) { + host->mrq->cmd->error = MSS_ERROR_TIMEOUT; + sdhci_finish_data(host); + } else { + if (host->cmd) + host->cmd->error = MSS_ERROR_TIMEOUT; + else + host->mrq->cmd->error = MSS_ERROR_TIMEOUT; + + tasklet_schedule(&host->finish_tasklet); + } + + mmiowb(); + spin_unlock_irqrestore(&host->lock, flags); +} + +/*****************************************************************************\ + * * + * Interrupt handling * + * * +\*****************************************************************************/ + +static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) +{ + BUG_ON(intmask == 0); + + if (!host->cmd) { + printk(KERN_ERR "mmchost: Got command interrupt even though no " + "command operation was in progress.\n"); + sdhci_dumpregs(host); + return; + } + + if (intmask & SDHCI_INT_RESPONSE) + sdhci_finish_command(host); + else { + if (intmask & SDHCI_INT_TIMEOUT) + host->cmd->error = MSS_ERROR_TIMEOUT; + else if (intmask & SDHCI_INT_CRC) + host->cmd->error = MSS_ERROR_CRC; + else if (intmask & (SDHCI_INT_END_BIT | SDHCI_INT_INDEX)) + host->cmd->error = MSS_ERROR_CRC; + else + host->cmd->error = MSS_ERROR_CRC; + + tasklet_schedule(&host->finish_tasklet); + } +} + +static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) +{ + BUG_ON(intmask == 0); + + if (!host->data) { + /* + * A data end interrupt is sent together with the response + * for the stop command. + */ + if (intmask & SDHCI_INT_DATA_END) + return; + + printk(KERN_ERR "mmchost: Got data interrupt even though no " + "data operation was in progress.\n"); + sdhci_dumpregs(host); + + return; + } + + if (intmask & SDHCI_INT_DATA_TIMEOUT) + host->mrq->cmd->error = MSS_ERROR_TIMEOUT; + else if (intmask & SDHCI_INT_DATA_CRC) + host->mrq->cmd->error = MSS_ERROR_CRC; + else if (intmask & SDHCI_INT_DATA_END_BIT) + host->mrq->cmd->error = MSS_ERROR_CRC; + + if (host->mrq->cmd->error != MSS_ERROR_NONE) + sdhci_finish_data(host); + else { + if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL)) + sdhci_transfer_pio(host); + + if (intmask & SDHCI_INT_DATA_END) + sdhci_finish_data(host); + } +} + +/* static irqreturn_t sdhci_irq(int irq, void *dev_id, struct pt_regs *regs) */ +static irqreturn_t sdhci_irq(int irq, void *dev_id) +{ + irqreturn_t result; + struct sdhci_host* host = dev_id; + u32 intmask; + struct mss_driver *drv; + struct mss_card *card; + u32 imask; + + spin_lock(&host->lock); + + intmask = readl(host->ioaddr + SDHCI_INT_STATUS); + + if (!intmask || intmask == 0xffffffff) { + result = IRQ_NONE; + goto out; + } + + DBG("*** %s got interrupt: 0x%08x\n", host->slot_descr, intmask); + + if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) { + writel(intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE), + host->ioaddr + SDHCI_INT_STATUS); + tasklet_schedule(&host->card_tasklet); + } + + intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE); + + if (intmask & SDHCI_INT_CMD_MASK) { + writel(intmask & SDHCI_INT_CMD_MASK, + host->ioaddr + SDHCI_INT_STATUS); + sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK); + } + + if (intmask & SDHCI_INT_DATA_MASK) { + writel(intmask & SDHCI_INT_DATA_MASK, + host->ioaddr + SDHCI_INT_STATUS); + sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK); + } + + /* previous sdhci.c has no code for card interrupt handling */ + if (intmask & SDHCI_INT_CARD_INT) { + /* disable the card interrupt */ + imask = readl(host->ioaddr + SDHCI_INT_ENABLE); + imask &= ~(SDHCI_INT_CARD_INT); + writel(imask, host->ioaddr + SDHCI_INT_ENABLE); + + /* send the card interrupt to the SDIO app driver */ + card = host->card; + if (card) + drv = container_of(card->dev.driver, struct mss_driver, driver); + if (card && drv && (drv->sdio_int_handler != NULL)) + drv->sdio_int_handler(card); + } + + + intmask &= ~(SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK); + + if (intmask & SDHCI_INT_BUS_POWER) { + printk(KERN_ERR "mmchost: Card is consuming too much power!\n"); + writel(SDHCI_INT_BUS_POWER, host->ioaddr + SDHCI_INT_STATUS); + } + + intmask &= SDHCI_INT_BUS_POWER; + + if (intmask) { + printk(KERN_ERR "mmchost: Unexpected interrupt 0x%08x.\n", intmask); + sdhci_dumpregs(host); + + writel(intmask, host->ioaddr + SDHCI_INT_STATUS); + } + + result = IRQ_HANDLED; + + + mmiowb(); +out: + spin_unlock(&host->lock); + + return result; +} + +/*****************************************************************************\ + * * + * Suspend/resume * + * * +\*****************************************************************************/ + +#ifdef CONFIG_PM + +static int sdhci_suspend (struct pci_dev *pdev, pm_message_t state) +{ + struct sdhci_chip *chip; + int i, ret; + + chip = pci_get_drvdata(pdev); + if (!chip) + return 0; + + DBG("Suspending...\n"); + + pci_save_state(pdev); + pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); + + for (i = 0;i < chip->num_slots;i++) { + if (!chip->hosts[i]) + continue; + free_irq(chip->hosts[i]->irq, chip->hosts[i]); + } + + pci_disable_device(pdev); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); + + return 0; +} + +static int sdhci_resume (struct pci_dev *pdev) +{ + struct sdhci_chip *chip; + int i, ret; + + chip = pci_get_drvdata(pdev); + if (!chip) + return 0; + + DBG("Resuming...\n"); + + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + ret = pci_enable_device(pdev); + if (ret) + return ret; + + for (i = 0;i < chip->num_slots;i++) { + if (!chip->hosts[i]) + continue; + if (chip->hosts[i]->flags & SDHCI_USE_DMA) + pci_set_master(pdev); + ret = request_irq(chip->hosts[i]->irq, sdhci_irq, + IRQF_SHARED, chip->hosts[i]->slot_descr, + chip->hosts[i]); + if (ret) + return ret; + sdhci_init(chip->hosts[i]); + mmiowb(); + } + + return 0; +} + +#else /* CONFIG_PM */ + +#define sdhci_suspend NULL +#define sdhci_resume NULL + +#endif /* CONFIG_PM */ + +/*****************************************************************************\ + * * + * Device probing/removal * + * * +\*****************************************************************************/ + +static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) +{ + int ret; + unsigned int version; + struct sdhci_chip *chip; + struct mss_host *mmc; + struct sdhci_host *host; +#ifdef CONFIG_PROC_FS + struct proc_dir_entry *proc_sdhci = NULL; + char pbuf[50]; +#endif + u8 first_bar; + unsigned int caps; + + u32 tmpval; + + + chip = pci_get_drvdata(pdev); + BUG_ON(!chip); + + ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &first_bar); + if (ret) + return ret; + first_bar &= PCI_SLOT_INFO_FIRST_BAR_MASK; + + if (first_bar > 5) { + printk(KERN_ERR DRIVER_NAME ": Invalid first BAR. Aborting.\n"); + return -ENODEV; + } + + if (!(pci_resource_flags(pdev, first_bar + slot) & IORESOURCE_MEM)) { + printk(KERN_ERR DRIVER_NAME ": BAR is not iomem. Aborting.\n"); + return -ENODEV; + } + + tmpval = pci_resource_len(pdev, first_bar + slot); + + if (pci_resource_len(pdev, first_bar + slot) != 0x100) { + printk(KERN_ERR DRIVER_NAME ": Invalid iomem size. " + "You may experience problems.\n"); + } + + if ((pdev->class & 0x0000FF) == PCI_SDHCI_IFVENDOR) { + printk(KERN_ERR DRIVER_NAME ": Vendor specific interface. Aborting.\n"); + return -ENODEV; + } + + if ((pdev->class & 0x0000FF) > PCI_SDHCI_IFVENDOR) { + printk(KERN_ERR DRIVER_NAME ": Unknown interface. Aborting.\n"); + return -ENODEV; + } + + //DBG("starting mss alloc process\n"); + + mmc = mss_alloc_host(1, 0, sizeof(struct sdhci_host)); + if (!mmc) + return -ENOMEM; + + host = mss_to_host(mmc); + host->mmc = mmc; + + host->chip = chip; + chip->hosts[slot] = host; + + mmc->slots->private = host; + host->card = NULL; + host->bar = first_bar + slot; + + host->addr = pci_resource_start(pdev, host->bar); + host->irq = pdev->irq; + + + snprintf(host->slot_descr, 20, "sdhci:slot%d", slot); + ret = pci_request_region(pdev, host->bar, host->slot_descr); + if (ret) + goto free; + + host->ioaddr = ioremap_nocache(host->addr, + pci_resource_len(pdev, host->bar)); + if (!host->ioaddr) { + ret = -ENOMEM; + goto release; + } + + sdhci_reset(host, SDHCI_RESET_ALL); + + version = readw(host->ioaddr + SDHCI_HOST_VERSION); + version = (version & SDHCI_SPEC_VER_MASK) >> SDHCI_SPEC_VER_SHIFT; + if (version != 0) { + printk(KERN_ERR "%s: Unknown controller version (%d). " + "You may experience problems.\n", host->slot_descr, + version); + } + + caps = readl(host->ioaddr + SDHCI_CAPABILITIES); + + /*on R5C832 controller we just assume the DMA is supported. It is a work round to fix the silicon bug*/ + // caps &= ~SDHCI_CAN_DO_DMA; + + if (debug_nodma) + DBG("DMA forced off\n"); + else if (debug_forcedma) { + DBG("DMA forced on\n"); + host->flags |= SDHCI_USE_DMA; + } else if (chip->quirks & SDHCI_QUIRK_FORCE_DMA) + host->flags |= SDHCI_USE_DMA; + /* mask the check point for some DMA capable SDIO controller + reporting wrong information to PCI, and "caps" should be + enough for judging DMA capability */ + /* else if ((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA) + DBG("Controller doesn't have DMA interface\n"); */ + else if (!(caps & SDHCI_CAN_DO_DMA)) + DBG("Controller doesn't have DMA capability\n"); + else + host->flags |= SDHCI_USE_DMA; + + if (host->flags & SDHCI_USE_DMA) { + if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { + printk(KERN_WARNING "%s: No suitable DMA available. " + "Falling back to PIO.\n", host->slot_descr); + host->flags &= ~SDHCI_USE_DMA; + } + } + + if (host->flags & SDHCI_USE_DMA) + pci_set_master(pdev); + else /* XXX: Hack to get MMC layer to avoid highmem */ + pdev->dma_mask = 0; + + host->max_clk = + (caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT; + if (host->max_clk == 0) { + printk(KERN_ERR "%s: Hardware doesn't specify base clock " + "frequency.\n", host->slot_descr); + ret = -ENODEV; + goto unmap; + } + host->max_clk *= 1000000; + + host->timeout_clk = + (caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT; + if (host->timeout_clk == 0) { + printk(KERN_ERR "%s: Hardware doesn't specify timeout clock " + "frequency.\n", host->slot_descr); + ret = -ENODEV; + goto unmap; + } + if (caps & SDHCI_TIMEOUT_CLK_UNIT) + host->timeout_clk *= 1000; + + host->max_block = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT; + if (host->max_block >= 3) { + printk(KERN_ERR "%s: Invalid maximum block size.\n", + host->slot_descr); + ret = -ENODEV; + goto unmap; + } + host->max_block = 512 << host->max_block; + + + /* Set host parameters. */ + mmc->ops = &sdhci_ops; + mmc->f_min = host->max_clk / 256; + mmc->f_max = host->max_clk; + mmc->dev = &pdev->dev; + mmc->vdd = 0; + + if (caps & SDHCI_CAN_VDD_330) { + mmc->vdd |= MSS_VDD_32_33|MSS_VDD_33_34; + } else if (caps & SDHCI_CAN_VDD_300) { + mmc->vdd |= MSS_VDD_29_30|MSS_VDD_30_31; + } else if (caps & SDHCI_CAN_VDD_180) { + mmc->vdd |= MSS_VDD_170_195; + } + mmc->ios.vdd = mmc->vdd; + + if (mmc->vdd == 0) { + printk(KERN_ERR "%s: Hardware doesn't report any " + "support voltages.\n", host->slot_descr); + ret = -ENODEV; + goto unmap; + } + mmc->bus_width = MSS_BUSWIDTH_4BIT; + + spin_lock_init(&host->lock); + + /* + * Maximum number of segments. Hardware cannot do scatter lists. + */ + if (host->flags & SDHCI_USE_DMA) + mmc->max_hw_segs = 1; + else + mmc->max_hw_segs = 16; + mmc->max_phys_segs = 16; + + /* + * Maximum number of sectors in one transfer. Limited by DMA boundary + * size (512KiB), which means (512 KiB/512=) 1024 entries. + */ + mmc->max_sectors = 1024; + + /* + * Maximum segment size. Could be one segment with the maximum number + * of sectors. + */ + mmc->max_seg_size = mmc->max_sectors * 512; + + /* + * Init tasklets. + */ + tasklet_init(&host->card_tasklet, + sdhci_tasklet_card, (unsigned long)host); + tasklet_init(&host->finish_tasklet, + sdhci_tasklet_finish, (unsigned long)host); + + setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host); + + ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED, + host->slot_descr, host); + if (ret) + goto untasklet; + + sdhci_init(host); + mmiowb(); + + register_mss_host(mmc); + + printk(KERN_INFO "mmchost: SDHCI at 0x%08lx irq %d %s\n", + host->addr, host->irq, + (host->flags & SDHCI_USE_DMA)?"DMA":"PIO"); + + + mss_detect_change(host->mmc, msecs_to_jiffies(500), 0); + + +#ifdef CONFIG_PROC_FS + if (dir_sdhci) { + sprintf(pbuf, "%s.%d", pci_name(pdev), slot); + if ((proc_sdhci = create_proc_entry(pbuf, S_IRUSR | S_IRGRP | S_IROTH, dir_sdhci)) != NULL) + { + proc_sdhci->read_proc = sdhci_read_proc; + proc_sdhci->data = host; + } + } +#endif + return 0; + +untasklet: + tasklet_kill(&host->card_tasklet); + tasklet_kill(&host->finish_tasklet); +unmap: + iounmap(host->ioaddr); +release: + pci_release_region(pdev, host->bar); +free: + mss_free_host(mmc); + return ret; +} + +static void sdhci_remove_slot(struct pci_dev *pdev, int slot) +{ + struct sdhci_chip *chip; + struct mss_host *mmc; + struct sdhci_host *host; + struct mss_slot *mslot; + +#ifdef CONFIG_PROC_FS + char pbuf[50]; +#endif + + chip = pci_get_drvdata(pdev); + host = chip->hosts[slot]; + mmc = host->mmc; + + mslot = &mmc->slots[slot]; + if (mslot->card) + mss_force_card_remove(mslot->card); + + unregister_mss_host(mmc); + chip->hosts[slot] = NULL; + + sdhci_reset(host, SDHCI_RESET_ALL); + + free_irq(host->irq, host); + + del_timer_sync(&host->timer); + + tasklet_kill(&host->card_tasklet); + tasklet_kill(&host->finish_tasklet); + + iounmap(host->ioaddr); + + pci_release_region(pdev, host->bar); + +#ifdef CONFIG_PROC_FS + if (dir_sdhci) { + sprintf(pbuf, "%s.%d", pci_name(pdev), slot); + remove_proc_entry(pbuf, dir_sdhci); + } +#endif + mss_free_host(mmc); +} + +static int __devinit sdhci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + int ret, i; + u8 slots, rev; + struct sdhci_chip *chip; + + + BUG_ON(pdev == NULL); + BUG_ON(ent == NULL); + + pci_read_config_byte(pdev, PCI_CLASS_REVISION, &rev); + + printk(KERN_INFO DRIVER_NAME + ": SDHCI controller found at %s [%04x:%04x] (rev %x)\n", + pci_name(pdev), (int)pdev->vendor, (int)pdev->device, + (int)rev); + + ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &slots); + if (ret) + return ret; + + slots = PCI_SLOT_INFO_SLOTS(slots) + 1; + if (slots == 0) + return -ENODEV; + + ret = pci_enable_device(pdev); + if (ret) + return ret; + + chip = kzalloc(sizeof(struct sdhci_chip) + + sizeof(struct sdhci_host*) * slots, GFP_KERNEL); + if (!chip) { + ret = -ENOMEM; + goto err; + } + + chip->pdev = pdev; + chip->quirks = ent->driver_data; + + if (debug_quirks) + chip->quirks = debug_quirks; + + chip->num_slots = slots; + pci_set_drvdata(pdev, chip); + + for (i = 0;i < slots;i++) { + ret = sdhci_probe_slot(pdev, i); + if (ret) { + for (i--;i >= 0;i--) + sdhci_remove_slot(pdev, i); + goto free; + } + } + + return 0; + +free: + pci_set_drvdata(pdev, NULL); + kfree(chip); +err: + pci_disable_device(pdev); + return ret; +} + +static void __devexit sdhci_remove(struct pci_dev *pdev) +{ + int i; + struct sdhci_chip *chip; + + chip = pci_get_drvdata(pdev); + + if (chip) { + for (i = 0;i < chip->num_slots;i++) + sdhci_remove_slot(pdev, i); + + pci_set_drvdata(pdev, NULL); + + kfree(chip); + } + + pci_disable_device(pdev); +} + +static struct pci_driver sdhci_driver = { + .name = DRIVER_NAME, + .id_table = pci_ids, + .probe = sdhci_probe, + .remove = __devexit_p(sdhci_remove), + .suspend = sdhci_suspend, + .resume = sdhci_resume, +}; + +/*****************************************************************************\ + * * + * Driver init/exit * + * * +\*****************************************************************************/ + +static int __init sdhci_drv_init(void) +{ + printk(KERN_INFO DRIVER_NAME + ": Secure Digital Host Controller Interface driver\n"); + printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n"); + + + +#ifdef CONFIG_PROC_FS + if ((dir_sdhci = proc_mkdir("sdhci", NULL)) == NULL) + printk(KERN_WARNING "SDHCI failed to create proc interface\n"); +#endif + return pci_register_driver(&sdhci_driver); +} + +static void __exit sdhci_drv_exit(void) +{ + pci_unregister_driver(&sdhci_driver); +#ifdef CONFIG_PROC_FS + if (dir_sdhci) { + remove_proc_entry("sdhci", NULL); + dir_sdhci = NULL; + } +#endif +} + +module_init(sdhci_drv_init); +module_exit(sdhci_drv_exit); + +module_param(debug_nodma, uint, 0444); +module_param(debug_forcedma, uint, 0444); +module_param(debug_quirks, uint, 0444); + +MODULE_AUTHOR("Pierre Ossman "); +MODULE_DESCRIPTION("Secure Digital Host Controller Interface driver"); +MODULE_LICENSE("GPL"); + +MODULE_PARM_DESC(debug_nodma, "Forcefully disable DMA transfers. (default 0)"); +MODULE_PARM_DESC(debug_forcedma, "Forcefully enable DMA transfers. (default 0)"); +MODULE_PARM_DESC(debug_quirks, "Force certain quirks."); --- linux-2.6.24.orig/drivers/mmc/mss/mmc_protocol.c +++ linux-2.6.24/drivers/mmc/mss/mmc_protocol.c @@ -0,0 +1,1049 @@ +/* + * mmc_protocol.c - MMC protocol driver + * + * Copyright (C) 2007 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 only + * for now as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * derived from previous mmc code in Linux kernel + * Copyright (c) 2002 Hewlett-Packard Company + * Copyright (c) 2002 Andrew Christian + * Copyright (c) 2006 Bridge Wu + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* internal functions */ + +#define KBPS 1 +#define MBPS 1000 + +static u32 ts_exp[] = { 100*KBPS, 1*MBPS, 10*MBPS, 100*MBPS, 0, 0, 0, 0 }; +static u32 ts_mul[] = { 0, 1000, 1200, 1300, 1500, 2000, 2500, 3000, + 3500, 4000, 4500, 5000, 5500, 6000, 7000, 8000 }; + +static u32 mmc_tran_speed(u8 ts) +{ + u32 clock = ts_exp[(ts & 0x7)] * ts_mul[(ts & 0x78) >> 3]; + + return clock; +} + +static int mmc_unpack_r1(struct mss_cmd *cmd, struct mmc_response_r1 *r1, struct mmc_card *mmc_card) +{ + u8 *buf = cmd->response; + + mmc_card->errno = MMC_ERROR_NONE; + r1->cmd = unstuff_bits(buf, 40, 8, 6); + r1->status = unstuff_bits(buf, 8, 32, 6); + + if (R1_STATUS(r1->status)) { + if (r1->status & R1_OUT_OF_RANGE) + mmc_card->errno = MMC_ERROR_OUT_OF_RANGE; + if (r1->status & R1_ADDRESS_ERROR) + mmc_card->errno = MMC_ERROR_ADDRESS; + if (r1->status & R1_BLOCK_LEN_ERROR) + mmc_card->errno = MMC_ERROR_BLOCK_LEN; + if (r1->status & R1_ERASE_SEQ_ERROR) + mmc_card->errno = MMC_ERROR_ERASE_SEQ; + if (r1->status & R1_ERASE_PARAM) + mmc_card->errno = MMC_ERROR_ERASE_PARAM; + if (r1->status & R1_WP_VIOLATION) + mmc_card->errno = MMC_ERROR_WP_VIOLATION; + if (r1->status & R1_LOCK_UNLOCK_FAILED) + mmc_card->errno = MMC_ERROR_LOCK_UNLOCK_FAILED; + if (r1->status & R1_COM_CRC_ERROR) + mmc_card->errno = MMC_ERROR_COM_CRC; + if (r1->status & R1_ILLEGAL_COMMAND) + mmc_card->errno = MMC_ERROR_ILLEGAL_COMMAND; + if (r1->status & R1_CARD_ECC_FAILED) + mmc_card->errno = MMC_ERROR_CARD_ECC_FAILED; + if (r1->status & R1_CC_ERROR) + mmc_card->errno = MMC_ERROR_CC; + if (r1->status & R1_ERROR) + mmc_card->errno = MMC_ERROR_GENERAL; + if (r1->status & R1_UNDERRUN) + mmc_card->errno = MMC_ERROR_UNDERRUN; + if (r1->status & R1_OVERRUN) + mmc_card->errno = MMC_ERROR_OVERRUN; + if (r1->status & R1_CID_CSD_OVERWRITE) + mmc_card->errno = MMC_ERROR_CID_CSD_OVERWRITE; + } + + if (buf[0] != cmd->opcode) + mmc_card->errno = MMC_ERROR_HEADER_MISMATCH; + /* This should be last - it's the least dangerous error */ + if (R1_CURRENT_STATE(r1->status) != mmc_card->state ) { + dbg5("state dismatch:r1->status:%x,state:%x\n",R1_CURRENT_STATE(r1->status),mmc_card->state); + mmc_card->errno = MMC_ERROR_STATE_MISMATCH; + } + dbg5("mmc card error %d", mmc_card->errno); + if (mmc_card->errno) + return MSS_ERROR_RESP_UNPACK; + return 0; +} + +static int mmc_unpack_r3(struct mss_cmd *cmd, struct mmc_response_r3 *r3, struct mmc_card *mmc_card) +{ + u8 *buf = cmd->response; + + mmc_card->errno = MMC_ERROR_NONE; + r3->cmd = unstuff_bits(buf, 40, 8, 6); + r3->ocr = unstuff_bits(buf, 8, 32, 6); + + if (r3->cmd != 0x3f) { + mmc_card->errno = MMC_ERROR_HEADER_MISMATCH; + return MSS_ERROR_RESP_UNPACK; + } + return 0; +} + +/** + * Fast I/O, support for CEATA devices. + */ +static int mmc_unpack_r4( struct mss_cmd *cmd, struct mmc_response_r4 *r4, struct mmc_card *mmc_card) +{ + u8 *buf = cmd->response; + + mmc_card->errno = MMC_ERROR_NONE; + + r4->cmd = unstuff_bits(buf, 40, 8, 6); + r4->rca = unstuff_bits(buf, 24, 16, 6); + r4->status = unstuff_bits(buf, 23, 1, 6); + r4->reg_addr = unstuff_bits(buf, 16, 7, 6); + r4->read_reg_contents = unstuff_bits(buf, 8, 8, 6); + + if (r4->cmd != 0x27) { + mmc_card->errno = MMC_ERROR_HEADER_MISMATCH; + return MSS_ERROR_RESP_UNPACK; + } + return 0 ; +} + +/** + * Interrupt request. not supported temporarily. + */ +static int mmc_unpack_r5(struct mss_cmd *cmd, struct mmc_response_r5 *r5, struct mmc_card *mmc_card) +{ + u8 *buf = cmd->response; + + mmc_card->errno = MMC_ERROR_NONE; + + r5->cmd = unstuff_bits(buf, 40, 8, 6); + r5->rca = unstuff_bits(buf, 24, 16, 6); + r5->irq_data = unstuff_bits(buf, 8, 16, 6); + + if (r5->cmd != 0x28) { + mmc_card->errno = MMC_ERROR_HEADER_MISMATCH; + return MSS_ERROR_RESP_UNPACK; + } + return 0 ; +} + +static int mmc_unpack_cid(struct mss_cmd *cmd, struct mmc_cid *cid, struct mmc_card *mmc_card) +{ + u8 *buf = cmd->response; + + mmc_card->errno = MMC_ERROR_NONE; + if (buf[0] != 0x3f) { + mmc_card->errno = MMC_ERROR_HEADER_MISMATCH; + return MSS_ERROR_RESP_UNPACK; + } + buf = buf + 1; + + cid->mid = unstuff_bits(buf, 120, 8, 16); + cid->oid = unstuff_bits(buf, 104, 16, 16); + cid->pnm[0] = unstuff_bits(buf, 96, 8, 16); + cid->pnm[1] = unstuff_bits(buf, 88, 8, 16); + cid->pnm[2] = unstuff_bits(buf, 80, 8, 16); + cid->pnm[3] = unstuff_bits(buf, 72, 8, 16); + cid->pnm[4] = unstuff_bits(buf, 64, 8, 16); + cid->pnm[5] = unstuff_bits(buf, 56, 8, 16); + cid->pnm[6] = 0; + cid->prv = unstuff_bits(buf, 48, 8, 16); + cid->psn = unstuff_bits(buf, 16, 32, 16); + cid->mdt = unstuff_bits(buf, 8, 8, 16); + + return 0; +} + +static int mmc_unpack_csd(struct mss_cmd *cmd, struct mmc_csd *csd, struct mmc_card *mmc_card) +{ + u8 *buf = cmd->response; + + mmc_card->errno = MMC_ERROR_NONE; + if (buf[0] != 0x3f) { + mmc_card->errno = MMC_ERROR_HEADER_MISMATCH; + return MSS_ERROR_RESP_UNPACK; + } + buf = buf + 1; + + csd->csd_structure = unstuff_bits(buf, 126, 2, 16); + csd->spec_vers = unstuff_bits(buf, 122, 4, 16); + csd->taac = unstuff_bits(buf, 112, 8, 16); + csd->nsac = unstuff_bits(buf, 104, 8, 16); + csd->tran_speed = unstuff_bits(buf, 96, 8, 16); + csd->ccc = unstuff_bits(buf, 84, 12, 16);; + csd->read_bl_len = unstuff_bits(buf, 80, 4, 16); + csd->read_bl_partial = unstuff_bits(buf, 79, 1, 16); + csd->write_blk_misalign = unstuff_bits(buf, 78, 1, 16); + csd->read_blk_misalign = unstuff_bits(buf, 77, 1, 16); + csd->dsr_imp = unstuff_bits(buf, 76, 1, 16); + csd->c_size = unstuff_bits(buf, 62, 12, 16); + csd->vdd_r_curr_min = unstuff_bits(buf, 59, 3, 16); + csd->vdd_r_curr_max = unstuff_bits(buf, 56, 3, 16); + csd->vdd_w_curr_min = unstuff_bits(buf, 53, 3, 16); + csd->vdd_w_curr_max = unstuff_bits(buf, 50, 3, 16); + csd->c_size_mult = unstuff_bits(buf, 47, 3, 16); + switch (csd->csd_structure ) { + case CSD_STRUCT_1_0: + case CSD_STRUCT_1_1: + csd->erase.v22.sector_size = + unstuff_bits(buf, 42, 5, 16); + csd->erase.v22.erase_grp_size = + unstuff_bits(buf, 37, 5, 6); + break; + case CSD_STRUCT_1_2: + default: + csd->erase.v31.erase_grp_size = + unstuff_bits(buf, 42, 5, 16); + csd->erase.v31.erase_grp_mult = + unstuff_bits(buf, 37, 5, 16);; + break; + } + csd->wp_grp_size = unstuff_bits(buf, 32, 5, 16); + csd->wp_grp_enable = unstuff_bits(buf, 31, 1, 16); + csd->default_ecc = unstuff_bits(buf, 29, 2, 16); + csd->r2w_factor = unstuff_bits(buf, 26, 3, 16); + csd->write_bl_len = unstuff_bits(buf, 22, 4, 16); + csd->write_bl_partial = unstuff_bits(buf, 21, 1, 16); + csd->file_format_grp = unstuff_bits(buf, 16, 1, 16); + csd->copy = unstuff_bits(buf, 14, 1, 16); + csd->perm_write_protect = unstuff_bits(buf, 13, 1, 16); + csd->tmp_write_protect = unstuff_bits(buf, 12, 1, 16); + csd->file_format = unstuff_bits(buf, 10, 2, 16); + csd->ecc = unstuff_bits(buf, 8, 2, 16); + + printk(" csd_structure=%d spec_vers=%d taac=%02x nsac=%02x tran_speed=%02x\n" + " ccc=%04x read_bl_len=%d read_bl_partial=%d write_blk_misalign=%d\n" + " read_blk_misalign=%d dsr_imp=%d c_size=%d vdd_r_curr_min=%d\n" + " vdd_r_curr_max=%d vdd_w_curr_min=%d vdd_w_curr_max=%d c_size_mult=%d\n" + " wp_grp_size=%d wp_grp_enable=%d default_ecc=%d r2w_factor=%d\n" + " write_bl_len=%d write_bl_partial=%d file_format_grp=%d copy=%d\n" + " perm_write_protect=%d tmp_write_protect=%d file_format=%d ecc=%d\n", + csd->csd_structure, csd->spec_vers, + csd->taac, csd->nsac, csd->tran_speed, + csd->ccc, csd->read_bl_len, + csd->read_bl_partial, csd->write_blk_misalign, + csd->read_blk_misalign, csd->dsr_imp, + csd->c_size, csd->vdd_r_curr_min, + csd->vdd_r_curr_max, csd->vdd_w_curr_min, + csd->vdd_w_curr_max, csd->c_size_mult, + csd->wp_grp_size, csd->wp_grp_enable, + csd->default_ecc, csd->r2w_factor, + csd->write_bl_len, csd->write_bl_partial, + csd->file_format_grp, csd->copy, + csd->perm_write_protect, csd->tmp_write_protect, + csd->file_format, csd->ecc); + switch ( csd->csd_structure ) { + case CSD_STRUCT_1_0: + case CSD_STRUCT_1_1: + printk(" V22 sector_size=%d erase_grp_size=%d\n", + csd->erase.v22.sector_size, + csd->erase.v22.erase_grp_size); + break; + case CSD_STRUCT_1_2: + default: + printk(" V31 erase_grp_size=%d erase_grp_mult=%d\n", + csd->erase.v31.erase_grp_size, + csd->erase.v31.erase_grp_mult); + break; + + } + + return MSS_ERROR_NONE; +} + +static int mmc_unpack_ext_csd(u8 *buf, struct mmc_ext_csd *ext_csd) +{ + ext_csd->s_cmd_set = buf[504]; + ext_csd->sec_count = ((u32)buf[212]) << 24 | ((u32)buf[213]) << 16 | ((u32)buf[214]) << 8 | ((u32)buf[215]) ; + ext_csd->min_perf_w_8_52 = buf[210]; + ext_csd->min_perf_r_8_52 = buf[209]; + ext_csd->min_perf_w_26_4_52 = buf[208]; + ext_csd->min_perf_r_26_4_52 = buf[207]; + ext_csd->min_perf_w_4_26 = buf[206]; + ext_csd->min_perf_r_4_26 = buf[205]; + ext_csd->pwr_cl_26_360 = buf[203]; + ext_csd->pwr_cl_52_360 = buf[202]; + ext_csd->pwr_cl_26_195 = buf[201]; + ext_csd->pwr_cl_52_195 = buf[200]; + ext_csd->card_type = buf[196]; + ext_csd->csd_structure = buf[194]; + ext_csd->ext_csd_rev = buf[192]; + ext_csd->cmd_set = buf[191]; + ext_csd->cmd_set_rev = buf[189]; + ext_csd->power_class = buf[187]; + ext_csd->hs_timing = buf[185]; + ext_csd->erased_mem_cont = buf[183]; + + return 0; +} + +/** + * The blocks requested by the kernel may or may not match what we can do. + * Unfortunately, filesystems play fast and loose with block sizes, so we're + * stuck with this . + */ +static void mmc_fix_request_block_len(struct mss_card *card, int action, struct mss_rw_arg *arg) +{ + u16 block_len = 0; + struct mmc_card *mmc_card = card->prot_card; + struct mss_host *host = card->slot->host; + + switch(action) { + case MSS_DATA_READ: + block_len = 1 << mmc_card->csd.read_bl_len; + break; + case MSS_DATA_WRITE: + block_len = 1 << mmc_card->csd.write_bl_len; + break; + default: + return; + } + if (host->high_capacity && mmc_card->access_mode == MMC_ACCESS_MODE_SECTOR) + block_len = 512; + if (block_len < arg->block_len) { + int scale = arg->block_len / block_len; + arg->block_len = block_len; + arg->block *= scale; + arg->nob *= scale; + } +} + + +/***************************************************************************** + * + * protocol entry functions + * + ****************************************************************************/ + +static u32 mmc_make_cmd6_arg(u8 access, u8 index, u8 value, u8 cmdset) +{ + u32 ret; + ret = (access << 24) | (index << 16) | (value << 8) | cmdset; + return ret; +} + +static int mmc_get_status(struct mss_card *card, u32 *status) +{ + struct mmc_response_r1 r1; + struct mmc_card *mmc_card = card->prot_card; + struct mss_host *host = card->slot->host; + struct mss_ll_request *llreq = &mmc_card->llreq; + struct mss_cmd *cmd = &mmc_card->cmd; + int clock, ret, retries = 4; + + clock = mmc_tran_speed(mmc_card->csd.tran_speed); + mss_set_clock(card->slot->host, clock); + while (retries--) { + dbg5("rety"); + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_SEND_STATUS, + mmc_card->rca << 16, MSS_RESPONSE_R1, 0); + dbg5("retry ret :%d", ret); + if (ret && !retries) + return ret; + else if (!ret) { + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + if (ret) { + if (mmc_card->errno==MMC_ERROR_STATE_MISMATCH) { + mmc_card->state = + R1_CURRENT_STATE(r1.status); + mmc_card->errno = MMC_ERROR_NONE; + } + else + return ret; + } + else + break; + } + + clock = host->ios.clock; + clock = clock >> 1; + if (clock < MMC_CARD_CLOCK_SLOW || retries == 1) + clock = MMC_CARD_CLOCK_SLOW; + mss_set_clock(host, clock); + } + + *status = r1.status; + + return MSS_ERROR_NONE; +} + +static int mmc_recognize_card(struct mss_card *card) +{ + struct mmc_response_r3 r3; + struct mmc_card *mmc_card = card->prot_card; + struct mss_ios ios; + struct mss_host *host = card->slot->host; + struct mss_ll_request *llreq = &mmc_card->llreq; + struct mss_cmd *cmd = &mmc_card->cmd; + int ret; + u32 ocr = host->vdd; + + mmc_card->state = CARD_STATE_IDLE; + card->bus_width = MSS_BUSWIDTH_1BIT; + card->card_type = MSS_UNKNOWN_CARD; + + memcpy(&ios, &host->ios, sizeof(struct mss_ios)); + ios.bus_mode = MSS_BUSMODE_OPENDRAIN; + ios.clock = host->f_min; + ios.bus_width = MSS_BUSWIDTH_1BIT; + host->ops->set_ios(host, &ios); + + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_GO_IDLE_STATE, 0, + MSS_RESPONSE_NONE, MSS_CMD_INIT); + dbg2(card->slot, card->prot_driver, "Sending GO_IDLE cmd, ret:%d\n", ret); + if (ret) + return ret; + if (host->high_capacity) + ocr |= MMC_ACCESS_MODE_SECTOR; + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_SEND_OP_COND, ocr, + MSS_RESPONSE_R3, 0); + dbg2(card->slot, card->prot_driver, "Sending SEND_OP_COND cmd, arg:0x%x\n, ret:%d", ocr, ret); + if (ret) + return ret; + + ret = mmc_unpack_r3(cmd, &r3, mmc_card); + dbg2(card->slot, card->prot_driver, "unapck ret %d, SEND_OP_COND ocr:0x%x", ret, r3.ocr); + if (!ret) { + if (r3.ocr & host->vdd) { + card->card_type = MSS_MMC_CARD; + } else { + printk(KERN_WARNING "uncompatible card\n"); + card->card_type = MSS_UNCOMPATIBLE_CARD; + } + return ret; + } + card->card_type = MSS_UNKNOWN_CARD; + + return MSS_ERROR_NONE; +} + +static int mmc_card_init(struct mss_card *card) +{ + struct mmc_response_r3 r3; + struct mmc_response_r1 r1; + struct mmc_cid cid; + struct mmc_card *mmc_card = card->prot_card; + struct mss_ios ios; + struct mss_host *host; + struct mss_ll_request *llreq = &mmc_card->llreq; + struct mss_cmd *cmd = &mmc_card->cmd; + struct mss_data *data = &mmc_card->data; + int ret; + u8 *g_buffer; + u32 ocr, arg, bus_width; + struct scatterlist sg; + + host = card->slot->host; + ocr = host->vdd; + + mmc_card->state = CARD_STATE_IDLE; + card->bus_width = MSS_BUSWIDTH_1BIT; + + memcpy(&ios, &host->ios, sizeof(struct mss_ios)); + ios.bus_mode = MSS_BUSMODE_OPENDRAIN; + ios.bus_width = MSS_BUSWIDTH_1BIT; + ios.clock = host->f_min; + host->ops->set_ios(host, &ios); + + dbg2(card->slot, card->prot_driver, "Sending GO_IDLE cmd, ret:%d\n", ret); + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_GO_IDLE_STATE, 0, + MSS_RESPONSE_NONE, MSS_CMD_INIT); + if (ret) + return ret; + + if (host->high_capacity) + ocr |= MMC_ACCESS_MODE_SECTOR; + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_SEND_OP_COND, ocr, + MSS_RESPONSE_R3, 0); + dbg2(card->slot, card->prot_driver, "Sending SEND_OP_COND cmd, arg:0x%x\n, ret:%d", ocr, ret); + if (ret) + return ret; + + ret = mmc_unpack_r3(cmd, &r3, mmc_card); + dbg2(card->slot, card->prot_driver, "unapck ret %d, SEND_OP_COND ocr:0x%x", ret, r3.ocr); + if (ret) { + //printk(KERN_ERR "failed SEND_OP_COND error=%d (%s) \n", ret, mmc_result_to_string(ret)); + return ret; + } + + while (!(r3.ocr & MMC_CARD_BUSY)) { + //mdelay(20); + msleep(15); + dbg2(card->slot, card->prot_driver, "card is busy after SNED_OP_COND"); + ret = mss_send_simple_ll_req(host, llreq, cmd, + MMC_SEND_OP_COND, ocr, MSS_RESPONSE_R3, 0); + dbg2(card->slot, card->prot_driver, "Sending SEND_OP_COND cmd, arg:0x%x\n, ret:%d", ocr, ret); + if (ret) + return ret; + ret = mmc_unpack_r3(cmd, &r3, mmc_card); + dbg2(card->slot, card->prot_driver, "unapck ret %d, SEND_OP_COND ocr:0x%x", ret, r3.ocr); + if (ret) { + //printk(KERN_ERR ": failed SEND_OP_COND error=%d (%s) \n", retval, mmc_result_to_string(retval) ); + return ret; + } + } + + mmc_card->vdd = r3.ocr & MMC_VDD_MASK; + mmc_card->access_mode = r3.ocr & MMC_ACCESS_MODE_MASK; + mmc_card->state = CARD_STATE_READY; + + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_ALL_SEND_CID, 0, + MSS_RESPONSE_R2_CID, 0); + dbg2(card->slot, card->prot_driver, "Sending MMC_ALL_SEND_CID cmd, arg:0x%x\n, ret:%d", 0, ret); + if (ret) + return ret; + + memset(&cid, 0x0, sizeof(struct mmc_cid)); + ret = mmc_unpack_cid(cmd, &cid, mmc_card); + if (ret) + return ret; + + /* Not first init */ + if (mmc_card->cid.mid != 0) { + /* Card is changed */ + if (mmc_card->cid.mid != cid.mid || mmc_card->cid.oid != cid.oid + || mmc_card->cid.prv != cid.prv + || mmc_card->cid.psn != cid.psn + || mmc_card->cid.mdt != cid.mdt + || memcmp(mmc_card->cid.pnm, cid.pnm, 6)) + return MSS_ERROR_MISMATCH_CARD; + } + else + memcpy(&mmc_card->cid, &cid, sizeof(struct mmc_cid)); + + mmc_card->state = CARD_STATE_IDENT; + + mss_set_busmode(host, MSS_BUSMODE_PUSHPULL); + + mmc_card->rca = MMC_SLOT_RCA(card->slot); + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_SET_RELATIVE_ADDR, + mmc_card->rca << 16, MSS_RESPONSE_R1, 0); + dbg2(card->slot, card->prot_driver, "Sending SET_REL_ADDR cmd, arg:0x%x\n, ret:%d", mmc_card->rca << 16, ret); + if (ret) + return ret; + + //mss_simple_cmd(dev, MMC_SET_RELATIVE_ADDR, (dev->slot->rca) << 16, RESPONSE_R1, buffer); + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + if (ret) { + //printk(KERN_INFO "MMC: unable to SET_RELATIVE_ADDR error=%d (%s)\n", retval, mmc_result_to_string(retval) ); + return ret; + } + mmc_card->state = CARD_STATE_STBY; + + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_SEND_CSD, + mmc_card->rca << 16, MSS_RESPONSE_R2_CSD, 0); + dbg2(card->slot, card->prot_driver, "Sending MMC_SEND_CSD cmd, arg:0x%x\n, ret:%d", mmc_card->rca << 16, ret); + if (ret) + return ret; + ret = mmc_unpack_csd(cmd, &mmc_card->csd, mmc_card); + if (ret) { + //printk(KERN_INFO "MMC: unable to SEND_CSD error=%d (%s)\n", retval, mmc_result_to_string(retval) ); + return ret; + } + + /* + * if it is MMC4.x-compatible card and how many bits are working. + */ + if (mmc_card->csd.spec_vers != CSD_SPEC_VERS_4 + || host->mmc_spec != MSS_MMC_SPEC_40_42) + goto exit; + + g_buffer = mmc_card->buf;//kmalloc(512, GFP_KERNEL); + /*if (!g_buffer) + return -ENOMEM; */ + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_SELECT_CARD, + mmc_card->rca << 16, MSS_RESPONSE_R1B, 0); + if (ret) + return ret; + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + if (ret) + return ret; + mmc_card->state = CARD_STATE_TRAN; + + /* + * set 1-bus mode in init. arg:access=0b11, arg:index=0xb7, arg:value=0 + * or CMD8 will not be responded with 1-bit/controller and 4-bit/card + * dev->bus_mode should be MSS_1_BIT before next command + * buffer = NULL; + */ + arg = mmc_make_cmd6_arg(0x3, 0xb7, 0, 0); + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_SWITCH, arg, + MSS_RESPONSE_R1B, 0); + if (ret) + return ret; + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + if (ret) + return ret; + + card->bus_width = MSS_BUSWIDTH_1BIT; + mss_set_buswidth(host, MSS_BUSWIDTH_1BIT); + + sg.page = virt_to_page(g_buffer); + sg.offset = offset_in_page(g_buffer); + sg.length = 512; + + memset(llreq, 0x0, sizeof(struct mss_ll_request)); + memset(cmd, 0x0, sizeof(struct mss_cmd)); + memset(data, 0x0, sizeof(struct mss_data)); + MSS_INIT_CMD(cmd, MMC_SEND_EXT_CSD, 0, 0, MSS_RESPONSE_R1); + MSS_INIT_DATA(data, 1, 512, MSS_DATA_READ, 1, &sg, 0); + llreq->cmd = cmd; + llreq->data = data; + + ret = mss_send_ll_req(host, &mmc_card->llreq); + if (ret) + return ret; + ret = mmc_unpack_ext_csd(g_buffer, &mmc_card->ext_csd); + if (ret) + return ret; + + /* + * use CMD19/CMD14 (BUSTEST_W/BUSTEST_R) to test supported bus mode. + */ + memset(g_buffer, 0xFF, 512); + bus_width = host->bus_width; + if (bus_width == MSS_BUSWIDTH_1BIT) + goto exit; + else if (bus_width == MSS_BUSWIDTH_4BIT) { + card->bus_width = MSS_BUSWIDTH_4BIT; + g_buffer[0] = 0xa5; /* 0b10100101 */ + g_buffer[1] = 0xFF; /* 0b11111111 */ + } + else if (bus_width == MSS_BUSWIDTH_8BIT) { + card->bus_width = MSS_BUSWIDTH_8BIT; + g_buffer[0] = 0xaa; /* 0b10101010 */ + g_buffer[1] = 0x55; /* 0b01010101 */ + } + else + goto exit; + + mss_set_buswidth(host, bus_width); + + memset(llreq, 0x0, sizeof(struct mss_ll_request)); + memset(cmd, 0x0, sizeof(struct mss_cmd)); + memset(data, 0x0, sizeof(struct mss_data)); + MSS_INIT_CMD(cmd, MMC_BUSTEST_W, 0, 0, MSS_RESPONSE_R1); + MSS_INIT_DATA(data, 1, 512, MSS_DATA_WRITE, 1, &sg, 0); + llreq->cmd = cmd; + llreq->data = data; + + ret = mss_send_ll_req(host, &mmc_card->llreq); + if (ret) + return ret; + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + if (ret) + return ret; + + mmc_card->state = CARD_STATE_BTST; + memset(g_buffer, 0xFF, 512); + + memset(llreq, 0x0, sizeof(struct mss_ll_request)); + memset(cmd, 0x0, sizeof(struct mss_cmd)); + memset(data, 0x0, sizeof(struct mss_data)); + MSS_INIT_CMD(cmd, MMC_BUSTEST_R, 0, 0, MSS_RESPONSE_R1); + MSS_INIT_DATA(data, 1, 512, MSS_DATA_READ, 1, &sg, 0); + llreq->cmd = cmd; + llreq->data = data; + + ret = mss_send_ll_req(host, &mmc_card->llreq); + if (ret) + return ret; + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + if (ret) + return ret; + + if ((g_buffer[0] == 0x55/*0b01010101*/) && + (g_buffer[1] == 0xaa/*0b10101010*/)) { + mmc_card->bus_width = MSS_BUSWIDTH_8BIT; + } + else if (g_buffer[0] == 0x5a /*0b01011010*/) { + mmc_card->bus_width = MSS_BUSWIDTH_4BIT; + } + else { + mmc_card->bus_width = MSS_BUSWIDTH_1BIT; + } + + mmc_card->state = CARD_STATE_TRAN; + + arg = mmc_make_cmd6_arg(0x3, 0xb7, mmc_card->bus_width, 0); + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_SWITCH, arg, + MSS_RESPONSE_R1B, 0); + if (ret) + return ret; + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + if (ret) + return ret; + + card->bus_width = mmc_card->bus_width; + /** + * use CMD6 to set high speed mode. arg:access=0b11, arg:index=0xb9, + * arg:value=1 according to card/controller high speed timing + * high speed mode for MMC-4.x compatible card. + */ + if (host->high_speed == MSS_HIGH_SPEED) { + mmc_make_cmd6_arg(0x3, 0xb9, 1, 0); + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_SWITCH, arg, + MSS_RESPONSE_R1B, 0); + if (ret) + return ret; + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + if (ret) + return ret; + memcpy(&ios, &host->ios, sizeof(struct mss_ios)); + ios.high_speed = MSS_HIGH_SPEED; + ios.clock = MMC_CARD_CLOCK_FAST; + host->ops->set_ios(host, &ios); + if (host->ios.high_speed != MSS_HIGH_SPEED) { + u32 clock = mmc_tran_speed(mmc_card->csd.tran_speed); + mss_set_clock(host, clock); + } + } + else { + /* change to the highest speed in normal mode */ + u32 clock = mmc_tran_speed(mmc_card->csd.tran_speed); + mss_set_clock(host, clock); + } + + /** + * use CMD6 to set power class. arg:access=0b11, arg:index=0xbb, + * arg:value=card power class code according to card/controller supported + * power class. We read value from PWL_CL_ff_vvv and set it to POWER_CLASS + * according to supported voltage and clock rate. + */ + + /* Deselect the card */ + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_SELECT_CARD, 0, + MSS_RESPONSE_R1B, 0); + if (ret) + return ret; + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + if (ret) + return ret; + mmc_card->state = CARD_STATE_STBY; + +exit: + return MSS_ERROR_NONE; +} + +static int mmc_read_write_entry(struct mss_card *card, int action, struct mss_rw_arg *arg, struct mss_rw_result *result) +{ + struct mmc_card *mmc_card = card->prot_card; + struct mss_host *host; + struct mss_ios ios; + struct mmc_response_r1 r1; + struct mss_ll_request *llreq = &mmc_card->llreq; + struct mss_cmd *cmd = &mmc_card->cmd; + struct mss_data *data = &mmc_card->data; + int ret, retries = 4, clock; + u32 status = 0; + int access_mode_sector = 0; + u32 cmdarg, blklen, opcode, flags; + + host = card->slot->host; + + ret = mmc_get_status(card, &status); + if (ret) + return ret; + + if (status & R1_CARD_IS_LOCKED) + return MSS_ERROR_LOCKED; + + if (action == MSS_WRITE_MEM && host->ops->is_slot_wp && + host->ops->is_slot_wp(card->slot)) + return MSS_ERROR_WP; + + if (mmc_card->state == CARD_STATE_STBY) { + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_SELECT_CARD, + mmc_card->rca << 16, MSS_RESPONSE_R1, 0); + if (ret) + return ret; + dbg5("select card cmd return ret:%d\n", ret); + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + if (ret) + return ret; + } + mmc_card->state = CARD_STATE_TRAN; + + mmc_fix_request_block_len(card, action, arg); + access_mode_sector = (mmc_card->access_mode == MMC_ACCESS_MODE_SECTOR) + && host->high_capacity; + memcpy(&ios, &host->ios, sizeof(struct mss_ios)); + if (access_mode_sector) { + ios.access_mode = MSS_ACCESS_MODE_SECTOR; + cmdarg = arg->block; + blklen = 512; + } + else { + if (arg->block_len != mmc_card->block_len) { + ret = mss_send_simple_ll_req(host, llreq, cmd, + MMC_SET_BLOCKLEN, arg->block_len, + MSS_RESPONSE_R1, 0); + if (ret) + return ret; + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + if (ret) + return ret; + mmc_card->block_len = arg->block_len; + } + cmdarg = arg->block * arg->block_len; + blklen = arg->block_len; + } + + if (mmc_card->csd.spec_vers == CSD_SPEC_VERS_4 && host->high_speed) { + ios.high_speed = MSS_HIGH_SPEED; + ios.clock = MMC_CARD_CLOCK_FAST; + } + else { + ios.clock = mmc_tran_speed(mmc_card->csd.tran_speed); + } + host->ops->set_ios(host, &ios); + + memset(llreq, 0x0, sizeof(struct mss_ll_request)); + memset(cmd, 0x0, sizeof(struct mss_cmd)); + memset(data, 0x0, sizeof(struct mss_data)); + llreq->cmd = cmd; + llreq->data = data; + +read_write_entry: + if (arg->nob > 1) { + if (action == MSS_READ_MEM) { + opcode = MMC_READ_MULTIPLE_BLOCK; + flags = MSS_DATA_READ | MSS_DATA_MULTI; + } + else { + opcode = MMC_WRITE_MULTIPLE_BLOCK; + flags = MSS_DATA_WRITE | MSS_DATA_MULTI; + } + + MSS_INIT_CMD(cmd, opcode, cmdarg, 0, MSS_RESPONSE_R1); + MSS_INIT_DATA(data, arg->nob, blklen, flags, arg->sg_len, + arg->sg, 0); + + ret = mss_send_ll_req(host, &mmc_card->llreq); + if (!ret) + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + + mmc_card->state = (action == MSS_WRITE_MEM) ? CARD_STATE_RCV + : CARD_STATE_DATA; + + if (ret) { + mss_send_simple_ll_req(host, llreq, cmd, + MMC_STOP_TRANSMISSION, 0, + (action == MSS_WRITE_MEM) ? + MSS_RESPONSE_R1B : MSS_RESPONSE_R1, 0); + mmc_card->state = CARD_STATE_TRAN; + + if (--retries) { + clock = host->ios.clock; + clock = clock >> 1; + if (clock < MMC_CARD_CLOCK_SLOW && retries == 1) + clock = MMC_CARD_CLOCK_SLOW; + mss_set_clock(host, clock); + goto read_write_entry; + } + return ret; + } + ret = mss_send_simple_ll_req(host, llreq, cmd, + MMC_STOP_TRANSMISSION, 0, + (action == MSS_WRITE_MEM) ? + MSS_RESPONSE_R1B : MSS_RESPONSE_R1, 0); + if (ret) + return ret; + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + mmc_card->state = CARD_STATE_TRAN; + + if (ret && (mmc_card->errno != MMC_ERROR_OUT_OF_RANGE)) + return ret; + } else { + if (action == MSS_READ_MEM) { + opcode = MMC_READ_SINGLE_BLOCK; + flags = MSS_DATA_READ; + } + else { + opcode = MMC_WRITE_BLOCK; + flags = MSS_DATA_WRITE; + } + MSS_INIT_CMD(cmd, opcode, cmdarg, 0, MSS_RESPONSE_R1); + MSS_INIT_DATA(data, arg->nob, blklen, flags, arg->sg_len, + arg->sg, 0); + + ret = mss_send_ll_req(host, &mmc_card->llreq); + if (!ret) + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + if (ret) { + if (--retries) { + clock = host->ios.clock; + clock = clock >> 1; + if (clock < MMC_CARD_CLOCK_SLOW && retries == 1) + clock = MMC_CARD_CLOCK_SLOW; + mss_set_clock(host, clock); + goto read_write_entry; + } + return ret; + } + } + /* Deselect the card */ + /*mmc_simple_ll_req(host, mmc_card, MMC_SELECT_CARD, + 0, MSS_RESPONSE_NONE, 0); + if (ret) + return ret; + ret = mmc_unpack_r1(&mmc_card->cmd, &r1, mmc_card); + mmc_card->state = CARD_STATE_STBY;*/ + if (ret) + return ret; + result->bytes_xfered = data->bytes_xfered; + + return MSS_ERROR_NONE; +} + +/* count by 512 bytes */ +static int mmc_get_capacity(struct mss_card *card, u32 *size) +{ + int c_size = 0; + int c_size_mult = 0; + struct mmc_card *mmc_card = card->prot_card; + struct mss_host *host = card->slot->host; + + if (mmc_card->access_mode == MMC_ACCESS_MODE_SECTOR && host->high_capacity) + *size = mmc_card->ext_csd.sec_count; + else { + c_size = mmc_card->csd.c_size; + c_size_mult = mmc_card->csd.c_size_mult; + *size = (c_size + 1) + << (2 + c_size_mult + mmc_card->csd.read_bl_len - 9); + } + dbg5("the capacity :0x%x", *size); + return MSS_ERROR_NONE; +} + + +/***************************************************************************** + * + * protocol driver interface functions + * + ****************************************************************************/ + +static int mmc_prot_entry(struct mss_card *card, unsigned int action, void *arg, void *result) +{ + u32 status; + int ret; + + if (action != MSS_RECOGNIZE_CARD && card->card_type != MSS_MMC_CARD) + return MSS_ERROR_WRONG_CARD_TYPE; + switch (action) { + case MSS_RECOGNIZE_CARD: + ret = mmc_recognize_card(card); + break; + case MSS_INIT_CARD: + ret = mmc_card_init(card); + break; + case MSS_READ_MEM: + case MSS_WRITE_MEM: + if (!arg) + return -EINVAL; + ret = mmc_read_write_entry(card, action, arg, result); + break; + case MSS_QUERY_CARD: + ret = mmc_get_status(card, &status); + break; + case MSS_GET_CAPACITY: + ret = mmc_get_capacity(card, result); + break; + default: + ret = MSS_ERROR_ACTION_UNSUPPORTED; + break; + } + //dbg("mmc protocol entry exit, ret: %d, action: %d\n", ret, action); + return ret; +} + +static int mmc_prot_attach_card(struct mss_card *card) +{ + struct mmc_card *mmc_card; + +#define ALIGN32(x) (((x) + 31) & (~31)) + mmc_card = kzalloc(ALIGN32(ALIGN32(sizeof(struct mmc_card))) + 512, + GFP_KERNEL); + card->prot_card = mmc_card; + if (mmc_card) { + mmc_card->buf = (char *)ALIGN32((unsigned int)&mmc_card[1]); + return 0; + } + return -ENOMEM; +} + +static void mmc_prot_detach_card(struct mss_card *card) +{ + kfree(card->prot_card); +} + +static int mmc_prot_get_errno(struct mss_card *card) +{ + struct mmc_card *mmc_card = card->prot_card; + return mmc_card->errno; +} + +static struct mss_prot_driver mmc_protocol = { + .name = MMC_PROTOCOL, + .prot_entry = mmc_prot_entry, + .attach_card = mmc_prot_attach_card, + .detach_card = mmc_prot_detach_card, + .get_errno = mmc_prot_get_errno, +}; + +static int mmc_protocol_init(void) +{ + register_mss_prot_driver(&mmc_protocol); + return 0; +} + +static void mmc_protocol_exit(void) +{ + unregister_mss_prot_driver(&mmc_protocol); +} + + +module_init(mmc_protocol_init); +module_exit(mmc_protocol_exit); + +MODULE_AUTHOR("Bridge Wu"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MMC protocol driver"); --- linux-2.6.24.orig/drivers/mmc/mss/mss_block.c +++ linux-2.6.24/drivers/mmc/mss/mss_block.c @@ -0,0 +1,555 @@ +/* + * mss_block.c - MMC/SD Card driver (block device driver) + * + * Copyright (C) 2007 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 only + * for now as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * derived from previous mmc code in Linux kernel + * Copyright (c) 2002 Hewlett-Packard Company + * Copyright (c) 2002 Andrew Christian + * Copyright (c) 2006 Bridge Wu + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include + +#include + +#define MSS_SHIFT 3 +#define MSS_SECTOR_SIZE (512) + +static int major; + +struct mss_disk { + struct request_queue *queue; + struct gendisk *disk; + struct mss_card *card; + struct class_device cdev; + + u32 flags; /* for suspend/resume */ +#define MSS_QUEUE_SUSPENDED (1 << 1) +#define MSS_QUEUE_EXIT (1 << 0) + struct completion thread_complete; + struct semaphore thread_sem; + wait_queue_head_t thread_wq; + spinlock_t request_lock; + struct scatterlist *sg; + struct request *req; +}; + +#define MSS_NUM_MINORS (256 << MSS_SHIFT) + +static unsigned long dev_use[MSS_NUM_MINORS/8*sizeof(unsigned long)]; + +static DECLARE_MUTEX(md_ref_mutex); + +static struct mss_disk *mss_disk_get(struct gendisk *disk) +{ + struct mss_disk *md; + + down(&md_ref_mutex); + md = disk->private_data; + if (md) { + if (mss_card_get(md->card) == 0) + class_device_get(&md->cdev); + else + md = NULL; + } + up(&md_ref_mutex); + + return md; +} + +static void mss_disk_put(struct mss_disk *md) +{ + struct mss_card *card = md->card; + + down(&md_ref_mutex); + class_device_put(&md->cdev); + mss_card_put(card); + up(&md_ref_mutex); +} + +static void mss_disk_release(struct class_device *cdev) +{ + struct mss_disk *md = container_of(cdev, struct mss_disk, cdev); + struct gendisk *disk = md->disk; + + /* Release the minor number */ + __clear_bit(disk->first_minor >> MSS_SHIFT, dev_use); + + put_disk(md->disk); + + /* Terminate the request handler thread */ + md->flags |= MSS_QUEUE_EXIT; + wake_up(&md->thread_wq); + wait_for_completion(&md->thread_complete); + + kfree(md->sg); + md->sg = NULL; + + blk_cleanup_queue(md->queue); + + put_device(&md->card->dev); + md->card = NULL; + kfree(md); +} + +static struct class mss_disk_class = { + .name = "mss disk", + .owner = THIS_MODULE, + .release = mss_disk_release, + //.class_dev_attrs = mss_disk_attrs, +}; + +static int mss_media_transfer(struct mss_disk *md, struct request *req) +{ + struct mss_request mreq; + struct mss_rw_arg marg; + struct mss_rw_result mres; + int ret; + + memset(&mreq, 0x0, sizeof(mreq)); + memset(&marg, 0x0, sizeof(marg)); + memset(&mres, 0x0, sizeof(marg)); + + mreq.arg = &marg; + mreq.result = &mres; + mreq.card = md->card; + do { + if (rq_data_dir(req) == READ) + mreq.action = MSS_READ_MEM; + else + mreq.action = MSS_WRITE_MEM; + + marg.nob = req->nr_sectors; + /* FIXME */ + marg.block_len = MSS_SECTOR_SIZE; + marg.block = req->sector; + marg.sg = md->sg; + marg.sg_len = blk_rq_map_sg(req->q, req, marg.sg); + + ret = mss_send_request(&mreq); + if (ret) + goto err; + dbg5("successful, bytes transfer :%x\n", mres.bytes_xfered); + ret = end_that_request_chunk(req, 1, mres.bytes_xfered); + if (!ret) { + add_disk_randomness(md->disk); + blkdev_dequeue_request(req); + end_that_request_last(req, 0); + } + } while (ret); + + return 1; +err: + dbg5("error, bytes transfer :%x\n", mres.bytes_xfered); + do { + ret = end_that_request_chunk(req, 0, + req->current_nr_sectors << 9); + } while (ret); + + add_disk_randomness(md->disk); + blkdev_dequeue_request(req); + end_that_request_last(req, 0); + + return 0; +} + +static int mss_queue_thread(void *d) +{ + struct mss_disk *md = d; + DECLARE_WAITQUEUE(wait, current); + + current->flags |= PF_MEMALLOC; + + daemonize("mmcqd%d", md->disk->first_minor >> MSS_SHIFT); + + complete(&md->thread_complete); + + down(&md->thread_sem); + add_wait_queue(&md->thread_wq, &wait); + do { + struct request *req = NULL; + + + /* masked by Feng */ + /* try_to_freeze(); */ + spin_lock_irq(&md->request_lock); + set_current_state(TASK_INTERRUPTIBLE); + if (!blk_queue_plugged(md->queue)) + md->req = req = elv_next_request(md->queue); + spin_unlock_irq(&md->request_lock); + + if (!req) { + if (md->flags & MSS_QUEUE_EXIT) + break; + up(&md->thread_sem); + schedule(); + down(&md->thread_sem); + continue; + } + set_current_state(TASK_RUNNING); + + mss_media_transfer(md, req); + } while (1); + remove_wait_queue(&md->thread_wq, &wait); + up(&md->thread_sem); + + complete_and_exit(&md->thread_complete, 0); + return 0; +} + +static int mss_media_preq(struct request_queue *q, struct request *req) +{ + struct mss_disk *md = q->queuedata; + if (!md || !md->card || + (md->card->state & (MSS_CARD_REMOVING | MSS_CARD_INVALID))) { + return BLKPREP_KILL; + } + return BLKPREP_OK; +} + + +/** + * mss_media_request + * @q: request queue + * + * entry function to request handling of MMC/SD block device driver. + * handle a request from request queue generated by upper layer. + */ +static void mss_media_request(request_queue_t *q) +{ + struct mss_disk *md = q->queuedata; + + if (md && !md->req) + wake_up(&md->thread_wq); +} + + +static int mss_blk_open(struct inode *inode, struct file *filp) +{ + struct gendisk *disk = inode->i_bdev->bd_disk; + struct mss_disk *md; + + md = mss_disk_get(disk); + if (!md) + return -ENXIO; + + if ((filp->f_mode & FMODE_WRITE) && (md->card->state & MSS_CARD_WP)) + return -EROFS; + /* FIXME check media change */ + check_disk_change(inode->i_bdev); + return 0; +} + +static int mss_blk_release(struct inode *inode, struct file *filep) +{ + struct gendisk *disk = inode->i_bdev->bd_disk; + struct mss_disk *md = disk->private_data; + + mss_disk_put(md); + return 0; +} + +static struct block_device_operations mss_bdops = { + .open = mss_blk_open, + .release = mss_blk_release, + //.media_changed = mss_media_changed, + //.revalidate_disk = mss_media_revalidate_disk, + .owner = THIS_MODULE, +}; + +/***************************************************************************** + * + * device driver functions + * + ****************************************************************************/ + +/** + * mss_card_probe + * @dev: device + * + * probe method to initialize block device. + * initialize mss_block_device, set capacity, load block driver(add_disk). + * + * invoked by bus_match (invoked by device_register or driver_register) + * must have device and driver, or this function cannot be invoked. + */ +static int mss_blk_probe(struct device *dev) +{ + struct mss_disk *md; + struct mss_card *card; + struct mss_host *host; + int devidx, ret = 0; + u64 limit = BLK_BOUNCE_HIGH; + + dbg5("read to probe card"); + devidx = find_first_zero_bit(dev_use, MSS_NUM_MINORS); + if (devidx >= MSS_NUM_MINORS) { + printk(KERN_ERR "can not find available minors"); + return -ENOSPC; + } + __set_bit(devidx, dev_use); + + card = container_of(dev, struct mss_card, dev); + + host = card->slot->host; + if (card->card_type != MSS_MMC_CARD && card->card_type != MSS_SD_CARD) { + printk(KERN_ERR "card(slot%d, host%d) is not memory card\n", + card->slot->id, host->id); + ret = -ENOTBLK; + goto clear_bit; + } + + md = kzalloc(sizeof(*md), GFP_KERNEL); + if (!md) { + printk(KERN_ERR "card(slot%d, host%d) alloc block_dev failed!" + "\n", card->slot->id, host->id); + ret = -ENOMEM; + goto clear_bit; + } + md->card = card; + md->disk = alloc_disk(1 << MSS_SHIFT); + if (md->disk == NULL) { + printk(KERN_ERR "card(slot%d, host%d) alloc disk failed!\n", + card->slot->id, host->id); + ret = -ENOMEM; + goto free_data; + } + md->disk->major = major; + md->disk->first_minor = devidx << MSS_SHIFT; + md->disk->fops = &mss_bdops; + md->disk->driverfs_dev = &card->dev; + md->disk->private_data = md; +// sprintf(md->disk->devfs_name, "mssblk%d", devidx); + sprintf(md->disk->disk_name, "mss/blk%d", devidx); + + class_device_initialize(&md->cdev); + md->cdev.dev = &card->dev; + md->cdev.class = &mss_disk_class; + strncpy(md->cdev.class_id, card->dev.bus_id, BUS_ID_SIZE); + ret = class_device_add(&md->cdev); + if (ret) { + goto free_disk; + } + get_device(&card->dev); + + spin_lock_init(&md->request_lock); + md->queue = blk_init_queue(mss_media_request, &md->request_lock); + if (!md->queue) { + ret = -ENOMEM; + goto remove_cdev; + } + if (host->dev->dma_mask && *host->dev->dma_mask) + limit = *host->dev->dma_mask; + + blk_queue_prep_rq(md->queue, mss_media_preq); + blk_queue_bounce_limit(md->queue, limit); + blk_queue_max_sectors(md->queue, host->max_sectors); + blk_queue_max_phys_segments(md->queue, host->max_phys_segs); + blk_queue_max_hw_segments(md->queue, host->max_hw_segs); + blk_queue_max_segment_size(md->queue, host->max_seg_size); + + md->queue->queuedata = md; + + md->sg = kmalloc(sizeof(struct scatterlist) * host->max_phys_segs, + GFP_KERNEL); + if (!md->sg) { + ret = -ENOMEM; + goto clean_queue; + } + + init_completion(&md->thread_complete); + init_waitqueue_head(&md->thread_wq); + init_MUTEX(&md->thread_sem); + + ret = kernel_thread(mss_queue_thread, md, CLONE_KERNEL); + if (ret < 0) { + goto free_sg; + } + wait_for_completion(&md->thread_complete); + init_completion(&md->thread_complete); + + md->disk->queue = md->queue; + dev_set_drvdata(dev, md); + blk_queue_hardsect_size(md->queue, MSS_SECTOR_SIZE); + set_capacity(md->disk, mss_get_capacity(card)/(MSS_SECTOR_SIZE/512) - 4); + add_disk(md->disk); + return 0; + +free_sg: + kfree(md->sg); +clean_queue: + blk_cleanup_queue(md->queue); +remove_cdev: + class_device_del(&md->cdev); + put_device(&card->dev); +free_disk: + put_disk(md->disk); +free_data: + kfree(md); +clear_bit: + __clear_bit(devidx, dev_use); + + return ret; +} + +/** + * mss_card_remove + * @dev: device + * + * remove method to remove block device. + * invoked by device_unregister or driver_unregister. + */ +static int mss_blk_remove(struct device *dev) +{ + struct mss_disk *md; + struct mss_card *card; + + card = container_of(dev, struct mss_card, dev); + md = dev_get_drvdata(dev); + + class_device_del(&md->cdev); + del_gendisk(md->disk); + md->disk->queue = NULL; + + down(&md_ref_mutex); + dev_set_drvdata(dev, NULL); + class_device_put(&md->cdev); + up(&md_ref_mutex); + + return 0; +} + +/** + * mss_card_suspend + * @dev: device + * @state: suspend state + * @level: suspend level + * + * card specific suspend. + * invoke blk_stop_queue to suspend request queue. + */ +static int mss_blk_suspend(struct device *dev, pm_message_t state)//, u32 level) +{ + struct mss_disk *md; + struct mss_card *card; + unsigned long flags; + + card = container_of(dev, struct mss_card, dev); + md = dev_get_drvdata(dev); + + if (!(md->flags & MSS_QUEUE_SUSPENDED)) { + md->flags |= MSS_QUEUE_SUSPENDED; + spin_lock_irqsave(&md->request_lock, flags); + blk_stop_queue(md->queue); + spin_unlock_irqrestore(&md->request_lock, flags); + } + + return 0; +} + +/** + * mss_card_resume + * @dev: device + * @level: suspend level + * + * card specific resume. + * invoke blk_start_queue to resume request queue. + */ +static int mss_blk_resume(struct device *dev)//, u32 level) +{ + struct mss_disk *md; + struct mss_card *card; + unsigned long flags; + + card = container_of(dev, struct mss_card, dev); + md = dev_get_drvdata(dev); + + if (md->flags & MSS_QUEUE_SUSPENDED) { + md->flags &= ~MSS_QUEUE_SUSPENDED; + spin_lock_irqsave(&md->request_lock, flags); + blk_start_queue(md->queue); + spin_unlock_irqrestore(&md->request_lock, flags); + } + + return 0; +} + +static struct mss_driver mss_block_driver = { + .driver = { + .name = "MMC_SD Block Driver", + .probe = mss_blk_probe, + .remove = mss_blk_remove, + .suspend = mss_blk_suspend, + .resume = mss_blk_resume, + }, +}; + +/***************************************************************************** + * + * module init and exit functions + * + ****************************************************************************/ +static int mss_card_driver_init(void) +{ + int ret = -ENOMEM; + + ret = register_blkdev(major, "mmc"); + if (ret < 0) { + printk(KERN_ERR "Unable to get major %d for MMC media: %d\n", + major, ret); + return ret; + } + if (major == 0) + major = ret; + + dbg5("Get major number :%d\n", major); +// devfs_mk_dir("mmc"); + + class_register(&mss_disk_class); + return register_mss_driver(&mss_block_driver); +} + +static void mss_card_driver_exit(void) +{ + unregister_mss_driver(&mss_block_driver); +// devfs_remove("mmc"); + unregister_blkdev(major, "mmc"); + class_unregister(&mss_disk_class); +} + + +module_init(mss_card_driver_init); +module_exit(mss_card_driver_exit); + +MODULE_AUTHOR("Bridge Wu"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Block device driver for MMC/SD card"); --- linux-2.6.24.orig/drivers/mmc/mss/sd_protocol.c +++ linux-2.6.24/drivers/mmc/mss/sd_protocol.c @@ -0,0 +1,1100 @@ +/* + * sd_protocol.c - SD protocol driver + * + * Copyright (C) 2007 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 only + * for now as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * derived from previous mmc code in Linux kernel + * Copyright (c) 2002 Hewlett-Packard Company + * Copyright (c) 2002 Andrew Christian + * Copyright (c) 2006 Bridge Wu + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define KBPS 1 +#define MBPS 1000 + +static u32 ts_exp[] = { 100*KBPS, 1*MBPS, 10*MBPS, 100*MBPS, 0, 0, 0, 0 }; +static u32 ts_mul[] = { 0, 1000, 1200, 1300, 1500, 2000, 2500, 3000, + 3500, 4000, 4500, 5000, 5500, 6000, 7000, 8000 }; + +static u32 sd_tran_speed(u8 ts) +{ + u32 clock = ts_exp[(ts & 0x7)] * ts_mul[(ts & 0x78) >> 3]; + + dbg5("clock :%d", clock); + return clock; +} + + +static int sd_unpack_r1(struct mss_cmd *cmd, struct sd_response_r1 *r1, struct sd_card *sd_card) +{ + u8 *buf = cmd->response; + + //debug(" result in r1: %d\n", request->result); + //if ( request->result ) return request->result; + + sd_card->errno = SD_ERROR_NONE; + r1->cmd = unstuff_bits(buf, 40, 8, 6); + r1->status = unstuff_bits(buf, 8, 32, 6); + + dbg5("status 0x%x", r1->status); + if (R1_STATUS(r1->status)) { + if (r1->status & R1_OUT_OF_RANGE) + sd_card->errno = SD_ERROR_OUT_OF_RANGE; + if (r1->status & R1_ADDRESS_ERROR) + sd_card->errno = SD_ERROR_ADDRESS; + if (r1->status & R1_BLOCK_LEN_ERROR) + sd_card->errno = SD_ERROR_BLOCK_LEN; + if (r1->status & R1_ERASE_SEQ_ERROR) + sd_card->errno = SD_ERROR_ERASE_SEQ; + if (r1->status & R1_ERASE_PARAM) + sd_card->errno = SD_ERROR_ERASE_PARAM; + if (r1->status & R1_WP_VIOLATION) + sd_card->errno = SD_ERROR_WP_VIOLATION; + if (r1->status & R1_LOCK_UNLOCK_FAILED) + sd_card->errno = SD_ERROR_LOCK_UNLOCK_FAILED; + if (r1->status & R1_COM_CRC_ERROR) + sd_card->errno = SD_ERROR_COM_CRC; + if (r1->status & R1_ILLEGAL_COMMAND) + sd_card->errno = SD_ERROR_ILLEGAL_COMMAND; + if (r1->status & R1_CARD_ECC_FAILED) + sd_card->errno = SD_ERROR_CARD_ECC_FAILED; + if (r1->status & R1_CC_ERROR) + sd_card->errno = SD_ERROR_CC; + if (r1->status & R1_ERROR) + sd_card->errno = SD_ERROR_GENERAL; + if (r1->status & R1_CID_CSD_OVERWRITE) + sd_card->errno = SD_ERROR_CID_CSD_OVERWRITE; + } + if (r1->status & R1_AKE_SEQ_ERROR) + sd_card->errno = SD_ERROR_CID_CSD_OVERWRITE; + + if (r1->cmd != cmd->opcode) + sd_card->errno = SD_ERROR_HEADER_MISMATCH; + dbg5("command:0x%x", r1->cmd); + /* This should be last - it's the least dangerous error */ + if (R1_CURRENT_STATE(r1->status) != sd_card->state ) { + dbg5("state dismatch:r1->status:%x,state:%x\n",R1_CURRENT_STATE(r1->status),sd_card->state); + sd_card->errno = SD_ERROR_STATE_MISMATCH; + } + dbg5("sd card error %d", sd_card->errno); + if (sd_card->errno) + return MSS_ERROR_RESP_UNPACK; + return 0; +} + +static int sd_unpack_r3(struct mss_cmd *cmd, struct sd_response_r3 *r3, struct sd_card *sd_card) +{ + u8 *buf = cmd->response; + + sd_card->errno = SD_ERROR_NONE; + r3->cmd = unstuff_bits(buf, 40, 8, 6); + r3->ocr = unstuff_bits(buf, 8, 32, 6); + dbg5("ocr=0x%x", r3->ocr); + + if (r3->cmd != 0x3f) { + sd_card->errno = SD_ERROR_HEADER_MISMATCH; + return MSS_ERROR_RESP_UNPACK; + } + return 0; +} + +static int sd_unpack_r6(struct mss_cmd *cmd, struct sd_response_r6 *r6, struct sd_card *sd_card) +{ + u8 *buf = cmd->response; + int errno = SD_ERROR_NONE; + + r6->cmd = unstuff_bits(buf, 40, 8, 6); + r6->rca = unstuff_bits(buf, 24, 16, 6); + r6->status = unstuff_bits(buf, 8, 16, 6); + if (R6_STATUS(r6->status)) { + if (r6->status & R6_COM_CRC_ERROR) + errno = SD_ERROR_COM_CRC; + if (r6->status & R6_ILLEGAL_COMMAND) + errno = SD_ERROR_ILLEGAL_COMMAND; + if (r6->status & R6_ERROR) + errno = SD_ERROR_CC; + } + if (r6->cmd != cmd->opcode) + errno = SD_ERROR_HEADER_MISMATCH; + /* This should be last - it's the least dangerous error */ + if (R1_CURRENT_STATE(r6->status) != sd_card->state) + errno = SD_ERROR_STATE_MISMATCH; + sd_card->errno = errno; + if (errno) + return MSS_ERROR_RESP_UNPACK; + return 0 ; +} + +static int sd_unpack_cid(struct mss_cmd *cmd, struct sd_cid *cid, struct sd_card *sd_card) +{ + u8 *buf = cmd->response; + + sd_card->errno = SD_ERROR_NONE; + if (buf[0] != 0x3f) { + sd_card->errno = SD_ERROR_HEADER_MISMATCH; + return MSS_ERROR_RESP_UNPACK; + } + buf = buf + 1; + + cid->mid = unstuff_bits(buf, 120, 8, 16); + cid->oid = unstuff_bits(buf, 104, 16, 16); + cid->pnm[0] = unstuff_bits(buf, 96, 8, 16); + cid->pnm[1] = unstuff_bits(buf, 88, 8, 16); + cid->pnm[2] = unstuff_bits(buf, 80, 8, 16); + cid->pnm[3] = unstuff_bits(buf, 72, 8, 16); + cid->pnm[4] = unstuff_bits(buf, 64, 8, 16); + cid->pnm[5] = 0; + cid->prv = unstuff_bits(buf, 56, 8, 16); + cid->psn = unstuff_bits(buf, 24, 32, 16); + cid->mdt = unstuff_bits(buf, 8, 12, 16); +/* + DEBUG(" mid=%d oid=%d pnm=%s prv=%d.%d psn=%08x mdt=%d/%d\n", + cid->mid, cid->oid, cid->pnm, + (cid->prv>>4), (cid->prv&0xf), + cid->psn, cid->mdt&&0xf, ((cid->mdt>>4)&0xff)+2000); +*/ + + return 0; +} + +static int sd_unpack_csd(struct mss_cmd *cmd, struct sd_csd *csd, struct sd_card *sd_card) +{ + u8 *buf = cmd->response; + + sd_card->errno = SD_ERROR_NONE; + if (buf[0] != 0x3f) { + sd_card->errno = SD_ERROR_HEADER_MISMATCH; + return MSS_ERROR_RESP_UNPACK; + } + buf = buf + 1; + + csd->csd_structure = unstuff_bits(buf, 126, 2, 16); + csd->taac = unstuff_bits(buf, 112, 8, 16); + csd->nsac = unstuff_bits(buf, 104, 8, 16); + csd->tran_speed = unstuff_bits(buf, 96, 8, 16); + csd->ccc = unstuff_bits(buf, 84, 12, 16); + csd->read_bl_len = unstuff_bits(buf, 80, 4, 16); + csd->read_bl_partial = unstuff_bits(buf, 79, 1, 16); + csd->write_blk_misalign = unstuff_bits(buf, 78, 1, 16); + csd->read_blk_misalign = unstuff_bits(buf, 77, 1, 16); + csd->dsr_imp = unstuff_bits(buf, 76, 1, 16); + if (csd->csd_structure == 0) { + csd->csd.csd1.c_size = unstuff_bits(buf, 62, 12, 16); + csd->csd.csd1.vdd_r_curr_min = unstuff_bits(buf, 59, 3, 16); + csd->csd.csd1.vdd_r_curr_max = unstuff_bits(buf, 56, 3, 16); + csd->csd.csd1.vdd_w_curr_min = unstuff_bits(buf, 53, 3, 16); + csd->csd.csd1.vdd_w_curr_max = unstuff_bits(buf, 50, 3, 16); + csd->csd.csd1.c_size_mult = unstuff_bits(buf, 47, 3, 16); + } + else if (csd->csd_structure == 1) { + csd->csd.csd2.c_size = unstuff_bits(buf, 48, 22, 16); + } + csd->erase_blk_en = unstuff_bits(buf, 46, 1, 16); + csd->sector_size = unstuff_bits(buf, 39, 7, 16); + csd->wp_grp_size = unstuff_bits(buf, 32, 7, 16); + csd->wp_grp_enable = unstuff_bits(buf, 31, 1, 16); + csd->r2w_factor = unstuff_bits(buf, 26, 3, 16); + csd->write_bl_len = unstuff_bits(buf, 22, 4, 16); + csd->write_bl_partial = unstuff_bits(buf, 21, 1, 16); + csd->file_format_grp = unstuff_bits(buf, 15, 1, 16); + csd->copy = unstuff_bits(buf, 14, 1, 16); + csd->perm_write_protect = unstuff_bits(buf, 13, 1, 16); + csd->tmp_write_protect = unstuff_bits(buf, 12, 1, 16); + csd->file_format = unstuff_bits(buf, 10, 2, 16); + + if (csd->csd_structure == 0) { + dbg5(" csd_structure=%d taac=%02x nsac=%02x tran_speed=%02x\n" + " ccc=%04x read_bl_len=%d read_bl_partial=%d write_blk_misalign=%d\n" + " read_blk_misalign=%d dsr_imp=%d c_size=%d vdd_r_curr_min=%d\n" + " vdd_r_curr_max=%d vdd_w_curr_min=%d vdd_w_curr_max=%d c_size_mult=%d\n" + " erase_blk_en=%d sector_size=%d wp_grp_size=%d wp_grp_enable=%d r2w_factor=%d\n" + " write_bl_len=%d write_bl_partial=%d file_format_grp=%d copy=%d\n" + " perm_write_protect=%d tmp_write_protect=%d file_format=%d\n", + csd->csd_structure,csd->taac, csd->nsac, csd->tran_speed, + csd->ccc, csd->read_bl_len, + csd->read_bl_partial, csd->write_blk_misalign, + csd->read_blk_misalign, csd->dsr_imp, + csd->csd.csd1.c_size, csd->csd.csd1.vdd_r_curr_min, + csd->csd.csd1.vdd_r_curr_max, csd->csd.csd1.vdd_w_curr_min, + csd->csd.csd1.vdd_w_curr_max, csd->csd.csd1.c_size_mult, + csd->erase_blk_en,csd->sector_size, + csd->wp_grp_size, csd->wp_grp_enable, + csd->r2w_factor, + csd->write_bl_len, csd->write_bl_partial, + csd->file_format_grp, csd->copy, + csd->perm_write_protect, csd->tmp_write_protect, + csd->file_format); + } + else if (csd->csd_structure == 1) { + dbg5(" csd_structure=%d taac=%02x nsac=%02x tran_speed=%02x\n" + " ccc=%04x read_bl_len=%d read_bl_partial=%d write_blk_misalign=%d\n" + " read_blk_misalign=%d dsr_imp=%d c_size=%d\n" + " erase_blk_en=%d sector_size=%d wp_grp_size=%d wp_grp_enable=%d r2w_factor=%d\n" + " write_bl_len=%d write_bl_partial=%d file_format_grp=%d copy=%d\n" + " perm_write_protect=%d tmp_write_protect=%d file_format=%d\n", + csd->csd_structure,csd->taac, csd->nsac, csd->tran_speed, + csd->ccc, csd->read_bl_len, + csd->read_bl_partial, csd->write_blk_misalign, + csd->read_blk_misalign, csd->dsr_imp, + csd->csd.csd2.c_size, + csd->erase_blk_en,csd->sector_size, + csd->wp_grp_size, csd->wp_grp_enable, + csd->r2w_factor, + csd->write_bl_len, csd->write_bl_partial, + csd->file_format_grp, csd->copy, + csd->perm_write_protect, csd->tmp_write_protect, + csd->file_format); + } + + return 0; +} + +static int sd_unpack_swfuncstatus(char *buf, struct sw_func_status *status) +{ + int i; + + buf += 34; + for (i = 0; i < 5; i++) { + status->func_busy[i] = buf[0] << 8 | buf[1]; + buf += 2; + } + buf += 1; + for (i = 0; i <= 5; i = i + 2) { + status->group_status[i] = buf[0] & 0xFF; + status->group_status[(i + 1)] = (buf[0] >> 4) & 0xFF; + buf += 1; + } + + for (i = 0; i <= 5; i++) { + status->func_support[i] = buf[0] << 8 | buf[1]; + buf += 2; + } + + status->current_consumption = buf[0] << 8 | buf[1]; + + return 0; +} + +static int sd_unpack_r7(struct mss_cmd *cmd, struct sd_response_r7 *r7, u16 arg, struct sd_card *sd_card) +{ + u8 *buf = cmd->response; + + r7->cmd = unstuff_bits(buf, 40, 8, 6); + r7->ver = unstuff_bits(buf, 20, 20, 6); + r7->vca = unstuff_bits(buf, 16, 4, 6); + r7->pattern = unstuff_bits(buf, 8, 8, 6); + +/* if ((r7->cmd | r7->ver | r7->vca | r7->pattern) == 0) + return MSS_NO_RESPONSE;*/ + if (r7->cmd != SD_SEND_IF_COND || r7->ver != 0 + || (r7->vca | r7->pattern) != arg) { + sd_card->errno = SD_ERROR_HEADER_MISMATCH; + return MSS_ERROR_RESP_UNPACK; + } + return 0; +} + +static int sd_unpack_scr(u8 *buf, struct sd_scr *scr) +{ + scr->scr_structure = unstuff_bits(buf, 60, 4, 8); + scr->sd_spec = unstuff_bits(buf, 56, 4, 8); + scr->data_stat_after_erase = unstuff_bits(buf, 55, 1, 8); + scr->sd_security = unstuff_bits(buf, 52, 3, 8); + scr->sd_bus_width = unstuff_bits(buf, 48, 4, 8); + scr->init = 1; + + dbg5("scr_stru:%d, spec:%d, sata:%d, security:%d, bus:%d", scr->scr_structure, scr->sd_spec, scr->data_stat_after_erase, scr->sd_security, scr->sd_bus_width); + return 0; +} + +static int sd_get_status(struct mss_card *card, int *status) +{ + struct sd_response_r1 r1; + struct sd_card *sd_card = card->prot_card; + struct mss_host *host = card->slot->host; + int clock, ret, retries = 4; + + clock = sd_tran_speed(sd_card->csd.tran_speed); + mss_set_clock(card->slot->host, clock); + while (retries--) { + dbg5("rety"); + ret = mss_send_simple_ll_req(host, &sd_card->llreq, + &sd_card->cmd, SD_SEND_STATUS, + sd_card->rca << 16, MSS_RESPONSE_R1, 0); + dbg5("retry ret :%d", ret); + if (ret && !retries) + return ret; + else if (!ret) { + ret = sd_unpack_r1(&sd_card->cmd, &r1, sd_card); + if (ret) { + if (sd_card->errno == SD_ERROR_STATE_MISMATCH) { + sd_card->state = R1_CURRENT_STATE(r1.status); + sd_card->errno = SD_ERROR_NONE; + } + else + return ret; + } + else + break; + } + + clock = host->ios.clock; + clock = clock >> 1; + if (clock < SD_CARD_CLOCK_SLOW || retries == 1) + clock = SD_CARD_CLOCK_SLOW; + mss_set_clock(host, clock); + } + + *status = r1.status; + + return MSS_ERROR_NONE; +} + +/** + * The blocks requested by the kernel may or may not match what we can do. + * Unfortunately, filesystems play fast and loose with block sizes, so we're + * stuck with this. + */ +static void sd_fix_request_block_len(struct mss_card *card, int action, struct mss_rw_arg *arg) +{ + u16 block_len = 0; + struct sd_card *sd_card = card->prot_card; + struct mss_host *host = card->slot->host; + + switch(action) { + case MSS_DATA_READ: + block_len = 1 << sd_card->csd.read_bl_len; + break; + case MSS_DATA_WRITE: + block_len = 1 << sd_card->csd.write_bl_len; + break; + default: + return; + } + if (host->high_capacity && (sd_card->ocr & SD_OCR_CCS)) + block_len = 512; + if (block_len < arg->block_len) { + int scale = arg->block_len / block_len; + arg->block_len = block_len; + arg->block *= scale; + arg->nob *= scale; + } +} + +static int sd_send_cmd6(struct mss_card *card, struct sw_func_status *status, int mode, u32 funcs) +{ + struct sd_response_r1 r1; + struct sd_card *sd_card = card->prot_card; + struct mss_ll_request *llreq = &sd_card->llreq; + struct mss_cmd *cmd = &sd_card->cmd; + struct mss_data *data = &sd_card->data; + struct mss_host *host= card->slot->host; + struct scatterlist sg; + char *g_buffer = sd_card->buf; + int ret; + /* Set the argumens for CMD6. */ + /* [31]: Mode + * [30:24]: reserved (all 0s) + * [23:20]: group 6 + * [19:16]: group 5 + * [15:12]: group 4 + * [11:8]: group 3 + * [7:4]: group 2 + * [3:0]: group 1 + */ + sg.page = virt_to_page(g_buffer); + sg.offset = offset_in_page(g_buffer); + sg.length = 8; + + memset(llreq, 0x0, sizeof(struct mss_ll_request)); + memset(cmd, 0x0, sizeof(struct mss_cmd)); + memset(data, 0x0, sizeof(struct mss_data)); + MSS_INIT_CMD(cmd, SD_SW_FUNC, (funcs | ((mode & 0x1) << 31)), 0, + MSS_RESPONSE_R1); + MSS_INIT_DATA(data, 1, 32, MSS_DATA_READ, 1, &sg, 0); + llreq->cmd = cmd; + llreq->data = data; + + ret = mss_send_ll_req(host, llreq); + if (ret) + return ret; + ret = sd_unpack_r1(cmd, &r1, sd_card); + if (ret) + return ret; + sd_unpack_swfuncstatus(g_buffer, status); + + return 0; +} + +/***************************************************************************** + * + * protocol entry functions + * + ****************************************************************************/ + +static int sd_recognize_card(struct mss_card *card) +{ + struct sd_response_r1 r1; + struct sd_response_r3 r3; + struct sd_response_r7 r7; + int ret; + struct sd_card *sd_card = (struct sd_card *)card->prot_card; + struct mss_ios ios; + struct mss_host *host = card->slot->host; + struct mss_ll_request *llreq = &sd_card->llreq; + struct mss_cmd *cmd = &sd_card->cmd; + + card->state = CARD_STATE_IDLE; + card->bus_width = MSS_BUSWIDTH_1BIT; + + memcpy(&ios, &host->ios, sizeof(struct mss_ios)); + ios.bus_mode = MSS_BUSMODE_OPENDRAIN; + ios.clock = host->f_min; + ios.bus_width = MSS_BUSWIDTH_1BIT; + host->ops->set_ios(host, &ios); + + card->card_type = MSS_UNKNOWN_CARD; + + ret = mss_send_simple_ll_req(host, llreq, cmd, + SD_GO_IDLE_STATE, 0, MSS_RESPONSE_NONE, MSS_CMD_INIT); + if (ret) + return ret; + if (host->sd_spec == MSS_SD_SPEC_20) { + if (!(host->vdd & MSS_VDD_27_36)) + return MSS_ERROR_NO_PROTOCOL; + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SEND_IF_COND, + 0x1AA, MSS_RESPONSE_R7, 0); + if (ret == MSS_ERROR_TIMEOUT) + goto next; + else if (ret) + return ret; + ret = sd_unpack_r7(cmd, &r7, 0x1AA, sd_card); + if (!ret) { + sd_card->ver = MSS_SD_SPEC_20; + goto next; + } + else + return ret; + } +next: + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_APP_CMD, 0, + MSS_RESPONSE_R1, 0); + if (ret) + return ret; + ret = sd_unpack_r1(cmd, &r1, sd_card); + if (ret) + return ret; + + + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SD_SEND_OP_COND, 0, + MSS_RESPONSE_R3, 0); + if (ret) + return ret; + ret = sd_unpack_r3(cmd, &r3, sd_card); + if (ret) + return ret; + + if (r3.ocr & host->vdd) { + card->card_type = MSS_SD_CARD; + sd_card->ver = MSS_SD_SPEC_20; + } + else + card->card_type = MSS_UNCOMPATIBLE_CARD; + + return MSS_ERROR_NONE; +} + + +/** + * sd_card_init + * @dev: mss_card_device + * + * return value: 0: success, -1: failed + */ +static int sd_card_init(struct mss_card *card) +{ + struct sd_response_r1 r1; + struct sd_response_r3 r3; + struct sd_response_r6 r6; + struct sd_response_r7 r7; + struct sd_cid cid; + int ret; + struct sd_card * sd_card= (struct sd_card *)card->prot_card; + struct mss_ios ios; + struct mss_host *host = card->slot->host; + struct mss_ll_request *llreq = &sd_card->llreq; + struct mss_cmd *cmd = &sd_card->cmd; + int hcs = 0; + + sd_card->state = CARD_STATE_IDLE; + card->bus_width = MSS_BUSWIDTH_1BIT; + sd_card->rca = 0; + + memcpy(&ios, &host->ios, sizeof(struct mss_ios)); + ios.bus_mode = MSS_BUSMODE_OPENDRAIN; + ios.bus_width = MSS_BUSWIDTH_1BIT; + ios.clock = host->f_min; + host->ops->set_ios(host, &ios); + + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_GO_IDLE_STATE, 0, + MSS_RESPONSE_NONE, MSS_CMD_INIT); + if (ret) + return ret; + /* + * We have to send cmd 8 to 2.0 card. It will tell the card that the + * host support 2.0 spec. + */ + if (sd_card->ver == MSS_SD_SPEC_20 && host->sd_spec == MSS_SD_SPEC_20) { + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SEND_IF_COND, + 0x1AA, MSS_RESPONSE_R7, 0); + if (ret) + return ret; + ret = sd_unpack_r7(cmd, &r7, 0x1AA, sd_card); + if (ret) + return ret; + if (host->high_capacity) + hcs = 1; + } + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_APP_CMD, 0, + MSS_RESPONSE_R1, 0); + if (ret) + return ret; + ret = sd_unpack_r1(cmd, &r1, sd_card); + if (ret) + return ret; + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SD_SEND_OP_COND, + hcs << 30 | host->vdd, MSS_RESPONSE_R3, 0); + if (ret) + return ret; + ret = sd_unpack_r3(cmd, &r3, sd_card); + if (ret) + return ret; + while (!(r3.ocr & SD_OCR_CARD_BUSY)) { + //mdelay(20); + msleep(15); + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_APP_CMD, 0, + MSS_RESPONSE_R1, 0); + if (ret) + return ret; + ret = sd_unpack_r1(cmd, &r1, sd_card); + if (ret) + return ret; + + ret = mss_send_simple_ll_req(host, llreq, cmd, + SD_SD_SEND_OP_COND, hcs << 30 | host->vdd, + MSS_RESPONSE_R3, 0); + if (ret) + return ret; + ret = sd_unpack_r3(cmd, &r3, sd_card); + if (ret) + return ret; + } + memcpy(&sd_card->ocr, &r3.ocr, sizeof(r3.ocr)); + sd_card->state = CARD_STATE_READY; + + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_ALL_SEND_CID, 0, + MSS_RESPONSE_R2_CID, 0); + if (ret) + return ret; + + memset(&cid, 0x0, sizeof(struct sd_cid)); + ret = sd_unpack_cid(cmd, &cid, sd_card); + if (ret) + return ret; + + if (sd_card->cid.mid != 0) { + if (sd_card->cid.mid != cid.mid || sd_card->cid.oid != cid.oid + || sd_card->cid.prv != cid.prv + || sd_card->cid.psn != cid.psn + || sd_card->cid.mdt != cid.mdt + || memcmp(sd_card->cid.pnm, cid.pnm, 6)) + return MSS_ERROR_MISMATCH_CARD; + + if (memcmp(&cid, &sd_card->cid, sizeof(struct sd_cid))) + return MSS_ERROR_MISMATCH_CARD; + } + else + memcpy(&sd_card->cid, &cid, sizeof(struct sd_cid)); + + sd_card->state = CARD_STATE_IDENT; + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SEND_RELATIVE_ADDR, + 0, MSS_RESPONSE_R6, 0); + if (ret) + return ret; + ret = sd_unpack_r6(cmd, &r6, sd_card); + if (ret) + return ret; + sd_card->state = CARD_STATE_STBY; + sd_card->rca = r6.rca; + + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SEND_CSD, + sd_card->rca << 16, MSS_RESPONSE_R2_CSD, 0); + if (ret) + return ret; + ret = sd_unpack_csd(cmd, &sd_card->csd, sd_card); + if (ret) + return ret; + + if (host->ops->is_slot_wp && host->ops->is_slot_wp(card->slot)) + card->state |= MSS_CARD_WP; + + return MSS_ERROR_NONE; +} + +static int sd_read_write_entry(struct mss_card *card, int action, struct mss_rw_arg *arg, struct mss_rw_result *result) +{ + struct sd_response_r1 r1; + struct mss_host *host = card->slot->host; + struct mss_ios ios; + int ret, retries = 4; + struct sd_card *sd_card = (struct sd_card *)card->prot_card; + struct mss_ll_request *llreq = &sd_card->llreq; + struct mss_cmd *cmd = &sd_card->cmd; + struct mss_data *data = &sd_card->data; + struct scatterlist sg; + char *g_buffer = sd_card->buf; + int status; + u32 clock; + u32 cmdarg, blklen, opcode, flags; + + dbg5("block:%d, nob:%d, blok_len:%d", arg->block, arg->nob, arg->block_len); + ret = sd_get_status(card, &status); + if (ret) + return ret; + + if (status & R1_CARD_IS_LOCKED) + return MSS_ERROR_LOCKED; + + if (action == MSS_WRITE_MEM && host->ops->is_slot_wp && + host->ops->is_slot_wp(card->slot)) + return MSS_ERROR_WP; + + if (sd_card->state == CARD_STATE_STBY) { + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SELECT_CARD, + sd_card->rca << 16, MSS_RESPONSE_R1B, 0); + if (ret) + return ret; + ret = sd_unpack_r1(cmd, &r1, sd_card); + if (ret) + return ret; + } + sd_card->state = CARD_STATE_TRAN; + + sd_fix_request_block_len(card, action, arg); + + + if (!sd_card->scr.init) { + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_APP_CMD, + sd_card->rca << 16, MSS_RESPONSE_R1, 0); + if (ret) + return ret; + + sg.page = virt_to_page(g_buffer); + sg.offset = offset_in_page(g_buffer); + sg.length = 8; + + memset(llreq, 0x0, sizeof(struct mss_ll_request)); + memset(cmd, 0x0, sizeof(struct mss_cmd)); + memset(data, 0x0, sizeof(struct mss_data)); + MSS_INIT_CMD(cmd, SD_SEND_SCR, 0, 0, MSS_RESPONSE_R1); + MSS_INIT_DATA(data, 1, 8, MSS_DATA_READ, 1, &sg, 0); + llreq->cmd = cmd; + llreq->data = data; + + ret = mss_send_ll_req(host, llreq); + if (ret) + return ret; + ret = sd_unpack_scr(g_buffer, &sd_card->scr); + if (ret) + return ret; + } + if (sd_card->scr.sd_bus_width == SCR_BUSWIDTH_1BIT) { + mss_set_buswidth(host, MSS_BUSWIDTH_1BIT); + card->bus_width = MSS_BUSWIDTH_1BIT; + } + else { + if (card->bus_width == MSS_BUSWIDTH_1BIT + && host->bus_width == MSS_BUSWIDTH_4BIT) { + mss_set_buswidth(host, MSS_BUSWIDTH_4BIT); + card->bus_width = MSS_BUSWIDTH_4BIT; + ret = mss_send_simple_ll_req(host, llreq, cmd, + SD_APP_CMD, sd_card->rca << 16, + MSS_RESPONSE_R1, 0); + if (ret) + return ret; + ret = sd_unpack_r1(cmd, &r1, sd_card); + if (ret) + return ret; + ret = mss_send_simple_ll_req(host, llreq, cmd, + SD_SET_BUS_WIDTH, 0x2, MSS_RESPONSE_R1, + 0); + if (ret) + return ret; + ret = sd_unpack_r1(cmd, &r1, sd_card); + if (ret) + return ret; + card->bus_width = MSS_BUSWIDTH_4BIT; + } + } + memset(llreq, 0x0, sizeof(struct mss_ll_request)); + memset(cmd, 0x0, sizeof(struct mss_cmd)); + memset(data, 0x0, sizeof(struct mss_data)); + + memcpy(&ios, &host->ios, sizeof(struct mss_ios)); + if ((sd_card->ocr & SD_OCR_CCS) && host->high_capacity) { + ios.access_mode = MSS_ACCESS_MODE_SECTOR; + cmdarg = arg->block; + blklen = 512; + } + else { + if (arg->block_len != sd_card->block_len) { + ret = mss_send_simple_ll_req(host, llreq, cmd, + SD_SET_BLOCKLEN, arg->block_len, + MSS_RESPONSE_R1, 0); + if (ret) + return ret; + ret = sd_unpack_r1(cmd, &r1, sd_card); + if (ret) + return ret; + sd_card->block_len = arg->block_len; + } + cmdarg = arg->block * arg->block_len; + blklen = arg->block_len; + } + ios.clock = sd_tran_speed(sd_card->csd.tran_speed); + host->ops->set_ios(host, &ios); + + llreq->cmd = cmd; + llreq->data = data; + +read_write_entry: + + if (arg->nob > 1) { + if (action == MSS_READ_MEM) { + opcode = SD_READ_MULTIPLE_BLOCK; + flags = MSS_DATA_READ | MSS_DATA_MULTI; + } + else { + opcode = SD_WRITE_MULTIPLE_BLOCK; + flags = MSS_DATA_WRITE | MSS_DATA_MULTI; + } + + MSS_INIT_CMD(cmd, opcode, cmdarg, 0, MSS_RESPONSE_R1); + MSS_INIT_DATA(data, arg->nob, blklen, flags, arg->sg_len, + arg->sg, 0); + + ret = mss_send_ll_req(host, llreq); + if (!ret) + ret = sd_unpack_r1(cmd, &r1, sd_card); + sd_card->state = (action == MSS_WRITE_MEM) ? CARD_STATE_RCV : CARD_STATE_DATA; + if (ret) { + mss_send_simple_ll_req(host, llreq, cmd, + SD_STOP_TRANSMISSION, 0, + (action == MSS_WRITE_MEM) ? + MSS_RESPONSE_R1B : MSS_RESPONSE_R1, 0); + sd_card->state = CARD_STATE_TRAN; + if (--retries) { + clock = host->ios.clock; + clock = clock >> 1; + if (clock < SD_CARD_CLOCK_SLOW && retries == 1) + clock = SD_CARD_CLOCK_SLOW; + mss_set_clock(host, clock); + goto read_write_entry; + } + return ret; + } + ret = mss_send_simple_ll_req(host, llreq, cmd, + SD_STOP_TRANSMISSION, 0, + (action == MSS_WRITE_MEM) ? + MSS_RESPONSE_R1B : MSS_RESPONSE_R1, 0); + if (ret) + return ret; + ret = sd_unpack_r1(cmd, &r1, sd_card); + sd_card->state = CARD_STATE_TRAN; + if (ret && (sd_card->errno != SD_ERROR_OUT_OF_RANGE)) + return ret; + } else { + if (action == MSS_READ_MEM) { + opcode = SD_READ_SINGLE_BLOCK; + flags = MSS_DATA_READ; + } + else { + opcode = SD_WRITE_BLOCK; + flags = MSS_DATA_WRITE; + } + MSS_INIT_CMD(cmd, opcode, cmdarg, 0, MSS_RESPONSE_R1); + MSS_INIT_DATA(data, arg->nob, blklen, flags, arg->sg_len, + arg->sg, 0); + + ret = mss_send_ll_req(host, llreq); + if (!ret) + ret = sd_unpack_r1(cmd, &r1, sd_card); + if (ret) { + if (--retries) { + clock = host->ios.clock; + clock = clock >> 1; + if (clock < SD_CARD_CLOCK_SLOW && retries == 1) + clock = SD_CARD_CLOCK_SLOW; + mss_set_clock(host, clock); + goto read_write_entry; + } + return ret; + } + } + /* Deselect the card */ + /*mmc_simple_ll_req(host, mmc_card, MMC_SELECT_CARD, + 0, MSS_RESPONSE_NONE, 0); + if (ret) + return ret; + ret = mmc_unpack_r1(&mmc_card->cmd, &r1, mmc_card); + mmc_card->state = CARD_STATE_STBY;*/ + if (ret) + return ret; + result->bytes_xfered = data->bytes_xfered; + + return MSS_ERROR_NONE; +} + +static int sd_query_function(struct mss_card *card, struct io_swfunc_request *r, struct sw_func_status *status) +{ + struct sd_card *sd_card = card->prot_card; + int i; + u32 arg = 0; + + if (card->slot->host->sd_spec != MSS_SD_SPEC_20 + || sd_card->ver != MSS_SD_SPEC_20) + return MSS_ERROR_ACTION_UNSUPPORTED; + for (i = 5; i > 0; i--) { + arg |= ((r->args[i] & 0xF) << (i << 2)); + } + return sd_send_cmd6(card, status, 0, arg); +} + +static int sd_sw_function(struct mss_card *card, struct io_swfunc_request *r) +{ + int ret, i; + u32 arg = 0; + struct sw_func_status status; + struct sd_card *sd_card = card->prot_card; + + if (card->slot->host->sd_spec != MSS_SD_SPEC_20 + || sd_card->ver != MSS_SD_SPEC_20) + return MSS_ERROR_ACTION_UNSUPPORTED; + for (i = 0; i < 6; i++) { + if (r->args[i] >= 0xF) { + goto switch_err; + } + } + /* Step 1: CMD6(mode = 0, func = 0xF(Don't Care) */ + ret = sd_send_cmd6(card, &status, 0, 0xFFFFFF); + if (ret) + goto switch_err; + + /* Step 2: Any Switch ? */ + for (i = 0; i < 6; i++) { + if (!((status.func_support[i]) & (0x1 << (r->args[i])))) + goto switch_err; + } + + for (i = 0; i < 6; i++) { + if (status.group_status[i] != r->args[i]) { + break; + } + } + if (i == 6) + return 0; + + /* Step 3: CMD6(mode = 0, func= funcX */ + for (i = 5; i > 0; i--) { + arg |= ((r->args[i]) << (i << 2)); + } + ret = sd_send_cmd6(card, &status, 0, arg); + if (ret) + goto switch_err; + if (status.current_consumption > r->current_acceptable) { + goto switch_err; + } + for (i = 0; i < 6; i++) { + if (status.group_status[i] != r->args[i]) { + goto switch_err; + } + } + ret = sd_send_cmd6(card, &status, 1, arg); + if (ret) + goto switch_err; + for (i = 0; i < 6; i++) { + if (status.group_status[i] != r->args[i]) { + goto switch_err; + } + } + return 0; +switch_err: + sd_card->errno = SD_ERROR_SWFUNC; + return MSS_ERROR_ACTION_UNSUPPORTED; +} +/* count by 512 bytes */ +static int sd_get_capacity(struct mss_card *card, u32 *size) +{ + struct sd_card *sd_card = card->prot_card; + int c_size = 0; + int c_size_mult = 0; + int blk_len = 0; + + if (sd_card->csd.csd_structure == 0) { + c_size = sd_card->csd.csd.csd1.c_size; + c_size_mult = sd_card->csd.csd.csd1.c_size_mult; + blk_len = sd_card->csd.read_bl_len - 9; + } + /* (csize + 1) * 512 * 1024 bytes */ + else if (sd_card->csd.csd_structure == 1) { + c_size = sd_card->csd.csd.csd2.c_size; + c_size_mult = 7; + blk_len = 2; + } + *size = (c_size + 1) << (2 + c_size_mult + blk_len); + return MSS_ERROR_NONE; +} + + + +/***************************************************************************** + * + * protocol driver interface functions + * + ****************************************************************************/ +static int sd_prot_entry(struct mss_card *card, unsigned int action, void *arg, void *result) +{ + int ret; + u32 status; + + if (action != MSS_RECOGNIZE_CARD && card->card_type != MSS_SD_CARD) + return MSS_ERROR_WRONG_CARD_TYPE; + switch (action) { + case MSS_RECOGNIZE_CARD: + ret = sd_recognize_card(card); + break; + case MSS_INIT_CARD: + ret = sd_card_init(card); + break; + case MSS_READ_MEM: + case MSS_WRITE_MEM: + if (!arg || !result) + return -EINVAL; + ret = sd_read_write_entry(card, action, arg, result); + break; + /* + case MSS_LOCK_UNLOCK: + ret = sd_lock_unlock_entry(dev); + break; + */ + case MSS_SD_QUERY_FUNC: + if (!arg || !result) + return -EINVAL; + ret = sd_query_function(card, arg, result); + break; + case MSS_SD_SW_FUNC: + if (!arg) + return -EINVAL; + ret = sd_sw_function(card, arg); + break; + case MSS_QUERY_CARD: + ret = sd_get_status(card, &status); + break; + case MSS_GET_CAPACITY: + ret = sd_get_capacity(card, result); + break; + default: + ret = MSS_ERROR_ACTION_UNSUPPORTED; + break; + } + return ret; +} + +static int sd_prot_attach_card(struct mss_card *card) +{ + struct sd_card *sd_card; + +#define ALIGN32(x) (((x) + 31) & (~31)) + sd_card = kzalloc(ALIGN32(ALIGN32(sizeof(struct sd_card))) + 512, + GFP_KERNEL); + card->prot_card = sd_card; + if (sd_card) { + sd_card->buf = (char *)ALIGN32((unsigned int)&sd_card[1]); + return 0; + } + return -ENOMEM; +} + +static void sd_prot_detach_card(struct mss_card *card) +{ + kfree(card->prot_card); +} + +static int sd_prot_get_errno(struct mss_card *card) +{ + struct sd_card *sd_card = card->prot_card; + + return sd_card->errno; +} + +static struct mss_prot_driver sd_protocol = { + .name = SD_PROTOCOL, + .prot_entry = sd_prot_entry, + .attach_card = sd_prot_attach_card, + .detach_card = sd_prot_detach_card, + .get_errno = sd_prot_get_errno, +}; + +/***************************************************************************** + * + * module init and exit functions + * + ****************************************************************************/ +static int sd_protocol_init(void) +{ + register_mss_prot_driver(&sd_protocol); + return 0; +} + +static void sd_protocol_exit(void) +{ + unregister_mss_prot_driver(&sd_protocol); +} + + +module_init(sd_protocol_init); +module_exit(sd_protocol_exit); + +MODULE_AUTHOR("Bridge Wu"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("SD protocol driver"); --- linux-2.6.24.orig/drivers/net/sis190.c +++ linux-2.6.24/drivers/net/sis190.c @@ -1632,13 +1632,18 @@ static int sis190_get_mac_addr(struct pci_dev *pdev, struct net_device *dev) { - u8 from; + int rc; + + rc = sis190_get_mac_addr_from_eeprom(pdev, dev); + if (rc < 0) { + u8 reg; - pci_read_config_byte(pdev, 0x73, &from); + pci_read_config_byte(pdev, 0x73, ®); - return (from & 0x00000001) ? - sis190_get_mac_addr_from_apc(pdev, dev) : - sis190_get_mac_addr_from_eeprom(pdev, dev); + if (reg & 0x00000001) + rc = sis190_get_mac_addr_from_apc(pdev, dev); + } + return rc; } static void sis190_set_speed_auto(struct net_device *dev) --- linux-2.6.24.orig/drivers/net/macb.c +++ linux-2.6.24/drivers/net/macb.c @@ -148,7 +148,7 @@ if (phydev->duplex) reg |= MACB_BIT(FD); - if (phydev->speed) + if (phydev->speed == SPEED_100) reg |= MACB_BIT(SPD); macb_writel(bp, NCFGR, reg); @@ -1257,6 +1257,8 @@ if (dev) { bp = netdev_priv(dev); + if (bp->phy_dev) + phy_disconnect(bp->phy_dev); mdiobus_unregister(&bp->mii_bus); kfree(bp->mii_bus.irq); unregister_netdev(dev); --- linux-2.6.24.orig/drivers/net/pppol2tp.c +++ linux-2.6.24/drivers/net/pppol2tp.c @@ -302,14 +302,14 @@ struct pppol2tp_session *session; struct hlist_node *walk; - read_lock(&tunnel->hlist_lock); + read_lock_bh(&tunnel->hlist_lock); hlist_for_each_entry(session, walk, session_list, hlist) { if (session->tunnel_addr.s_session == session_id) { - read_unlock(&tunnel->hlist_lock); + read_unlock_bh(&tunnel->hlist_lock); return session; } } - read_unlock(&tunnel->hlist_lock); + read_unlock_bh(&tunnel->hlist_lock); return NULL; } @@ -320,14 +320,14 @@ { struct pppol2tp_tunnel *tunnel = NULL; - read_lock(&pppol2tp_tunnel_list_lock); + read_lock_bh(&pppol2tp_tunnel_list_lock); list_for_each_entry(tunnel, &pppol2tp_tunnel_list, list) { if (tunnel->stats.tunnel_id == tunnel_id) { - read_unlock(&pppol2tp_tunnel_list_lock); + read_unlock_bh(&pppol2tp_tunnel_list_lock); return tunnel; } } - read_unlock(&pppol2tp_tunnel_list_lock); + read_unlock_bh(&pppol2tp_tunnel_list_lock); return NULL; } @@ -342,10 +342,11 @@ static void pppol2tp_recv_queue_skb(struct pppol2tp_session *session, struct sk_buff *skb) { struct sk_buff *skbp; + struct sk_buff *tmp; u16 ns = PPPOL2TP_SKB_CB(skb)->ns; - spin_lock(&session->reorder_q.lock); - skb_queue_walk(&session->reorder_q, skbp) { + spin_lock_bh(&session->reorder_q.lock); + skb_queue_walk_safe(&session->reorder_q, skbp, tmp) { if (PPPOL2TP_SKB_CB(skbp)->ns > ns) { __skb_insert(skb, skbp->prev, skbp, &session->reorder_q); PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG, @@ -360,7 +361,7 @@ __skb_queue_tail(&session->reorder_q, skb); out: - spin_unlock(&session->reorder_q.lock); + spin_unlock_bh(&session->reorder_q.lock); } /* Dequeue a single skb. @@ -371,10 +372,9 @@ int length = PPPOL2TP_SKB_CB(skb)->length; struct sock *session_sock = NULL; - /* We're about to requeue the skb, so unlink it and return resources + /* We're about to requeue the skb, so return resources * to its current owner (a socket receive buffer). */ - skb_unlink(skb, &session->reorder_q); skb_orphan(skb); tunnel->stats.rx_packets++; @@ -442,7 +442,7 @@ * expect to send up next, dequeue it and any other * in-sequence packets behind it. */ - spin_lock(&session->reorder_q.lock); + spin_lock_bh(&session->reorder_q.lock); skb_queue_walk_safe(&session->reorder_q, skb, tmp) { if (time_after(jiffies, PPPOL2TP_SKB_CB(skb)->expires)) { session->stats.rx_seq_discards++; @@ -469,13 +469,18 @@ goto out; } } - spin_unlock(&session->reorder_q.lock); + __skb_unlink(skb, &session->reorder_q); + + /* Process the skb. We release the queue lock while we + * do so to let other contexts process the queue. + */ + spin_unlock_bh(&session->reorder_q.lock); pppol2tp_recv_dequeue_skb(session, skb); - spin_lock(&session->reorder_q.lock); + spin_lock_bh(&session->reorder_q.lock); } out: - spin_unlock(&session->reorder_q.lock); + spin_unlock_bh(&session->reorder_q.lock); } /* Internal receive frame. Do the real work of receiving an L2TP data frame @@ -766,14 +771,18 @@ err = 0; skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, flags & MSG_DONTWAIT, &err); - if (skb) { - err = memcpy_toiovec(msg->msg_iov, (unsigned char *) skb->data, - skb->len); - if (err < 0) - goto do_skb_free; - err = skb->len; - } -do_skb_free: + if (!skb) + goto end; + + if (len > skb->len) + len = skb->len; + else if (len < skb->len) + msg->msg_flags |= MSG_TRUNC; + + err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, len); + if (likely(err == 0)) + err = len; + kfree_skb(skb); end: return err; @@ -1058,7 +1067,7 @@ /* Get routing info from the tunnel socket */ dst_release(skb->dst); - skb->dst = sk_dst_get(sk_tun); + skb->dst = dst_clone(__sk_dst_get(sk_tun)); skb_orphan(skb); skb->sk = sk_tun; @@ -1106,7 +1115,7 @@ PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, "%s: closing all sessions...\n", tunnel->name); - write_lock(&tunnel->hlist_lock); + write_lock_bh(&tunnel->hlist_lock); for (hash = 0; hash < PPPOL2TP_HASH_SIZE; hash++) { again: hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) { @@ -1126,7 +1135,7 @@ * disappear as we're jumping between locks. */ sock_hold(sk); - write_unlock(&tunnel->hlist_lock); + write_unlock_bh(&tunnel->hlist_lock); lock_sock(sk); if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) { @@ -1148,11 +1157,11 @@ * list so we are guaranteed to make forward * progress. */ - write_lock(&tunnel->hlist_lock); + write_lock_bh(&tunnel->hlist_lock); goto again; } } - write_unlock(&tunnel->hlist_lock); + write_unlock_bh(&tunnel->hlist_lock); } /* Really kill the tunnel. @@ -1161,9 +1170,9 @@ static void pppol2tp_tunnel_free(struct pppol2tp_tunnel *tunnel) { /* Remove from socket list */ - write_lock(&pppol2tp_tunnel_list_lock); + write_lock_bh(&pppol2tp_tunnel_list_lock); list_del_init(&tunnel->list); - write_unlock(&pppol2tp_tunnel_list_lock); + write_unlock_bh(&pppol2tp_tunnel_list_lock); atomic_dec(&pppol2tp_tunnel_count); kfree(tunnel); @@ -1239,9 +1248,9 @@ /* Delete the session socket from the * hash */ - write_lock(&tunnel->hlist_lock); + write_lock_bh(&tunnel->hlist_lock); hlist_del_init(&session->hlist); - write_unlock(&tunnel->hlist_lock); + write_unlock_bh(&tunnel->hlist_lock); atomic_dec(&pppol2tp_session_count); } @@ -1386,9 +1395,9 @@ /* Add tunnel to our list */ INIT_LIST_HEAD(&tunnel->list); - write_lock(&pppol2tp_tunnel_list_lock); + write_lock_bh(&pppol2tp_tunnel_list_lock); list_add(&tunnel->list, &pppol2tp_tunnel_list); - write_unlock(&pppol2tp_tunnel_list_lock); + write_unlock_bh(&pppol2tp_tunnel_list_lock); atomic_inc(&pppol2tp_tunnel_count); /* Bump the reference count. The tunnel context is deleted @@ -1593,11 +1602,11 @@ sk->sk_user_data = session; /* Add session to the tunnel's hash list */ - write_lock(&tunnel->hlist_lock); + write_lock_bh(&tunnel->hlist_lock); hlist_add_head(&session->hlist, pppol2tp_session_id_hash(tunnel, session->tunnel_addr.s_session)); - write_unlock(&tunnel->hlist_lock); + write_unlock_bh(&tunnel->hlist_lock); atomic_inc(&pppol2tp_session_count); @@ -2199,7 +2208,7 @@ int next = 0; int i; - read_lock(&tunnel->hlist_lock); + read_lock_bh(&tunnel->hlist_lock); for (i = 0; i < PPPOL2TP_HASH_SIZE; i++) { hlist_for_each_entry(session, walk, &tunnel->session_hlist[i], hlist) { if (curr == NULL) { @@ -2217,7 +2226,7 @@ } } out: - read_unlock(&tunnel->hlist_lock); + read_unlock_bh(&tunnel->hlist_lock); if (!found) session = NULL; @@ -2228,13 +2237,13 @@ { struct pppol2tp_tunnel *tunnel = NULL; - read_lock(&pppol2tp_tunnel_list_lock); + read_lock_bh(&pppol2tp_tunnel_list_lock); if (list_is_last(&curr->list, &pppol2tp_tunnel_list)) { goto out; } tunnel = list_entry(curr->list.next, struct pppol2tp_tunnel, list); out: - read_unlock(&pppol2tp_tunnel_list_lock); + read_unlock_bh(&pppol2tp_tunnel_list_lock); return tunnel; } --- linux-2.6.24.orig/drivers/net/slip.c +++ linux-2.6.24/drivers/net/slip.c @@ -463,9 +463,14 @@ /* 20 sec timeout not reached */ goto out; } - printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name, - (sl->tty->driver->chars_in_buffer(sl->tty) || sl->xleft) ? - "bad line quality" : "driver error"); + { + int cib = 0; + if (sl->tty->driver->chars_in_buffer) + cib = sl->tty->driver->chars_in_buffer(sl->tty); + printk(KERN_WARNING "%s: transmit timed out, %s?\n", + dev->name, (cib || sl->xleft) ? + "bad line quality" : "driver error"); + } sl->xleft = 0; sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); sl_unlock(sl); @@ -834,6 +839,8 @@ if(!capable(CAP_NET_ADMIN)) return -EPERM; + if (!tty->driver->write) + return -EOPNOTSUPP; /* RTnetlink lock is misused here to serialize concurrent opens of slip channels. There are better ways, but it is --- linux-2.6.24.orig/drivers/net/ppp_async.c +++ linux-2.6.24/drivers/net/ppp_async.c @@ -158,6 +158,9 @@ struct asyncppp *ap; int err; + if (!tty->driver->write) + return -EOPNOTSUPP; + err = -ENOMEM; ap = kzalloc(sizeof(*ap), GFP_KERNEL); if (!ap) --- linux-2.6.24.orig/drivers/net/sungem.c +++ linux-2.6.24/drivers/net/sungem.c @@ -910,7 +910,7 @@ * rx ring - must call napi_disable(), which * schedule_timeout()'s if polling is already disabled. */ - work_done += gem_rx(gp, budget); + work_done += gem_rx(gp, budget - work_done); if (work_done >= budget) return work_done; --- linux-2.6.24.orig/drivers/net/tehuti.c +++ linux-2.6.24/drivers/net/tehuti.c @@ -625,6 +625,12 @@ s_firmLoad[i] = CPU_CHIP_SWAP32(s_firmLoad[i]); } +static int bdx_range_check(struct bdx_priv *priv, u32 offset) +{ + return (offset > (u32) (BDX_REGS_SIZE / priv->nic->port_num)) ? + -EINVAL : 0; +} + static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd) { struct bdx_priv *priv = ndev->priv; @@ -643,9 +649,15 @@ DBG("%d 0x%x 0x%x\n", data[0], data[1], data[2]); } + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + switch (data[0]) { case BDX_OP_READ: + error = bdx_range_check(priv, data[1]); + if (error < 0) + return error; data[2] = READ_REG(priv, data[1]); DBG("read_reg(0x%x)=0x%x (dec %d)\n", data[1], data[2], data[2]); @@ -655,6 +667,9 @@ break; case BDX_OP_WRITE: + error = bdx_range_check(priv, data[1]); + if (error < 0) + return error; WRITE_REG(priv, data[1], data[2]); DBG("write_reg(0x%x, 0x%x)\n", data[1], data[2]); break; --- linux-2.6.24.orig/drivers/net/Kconfig +++ linux-2.6.24/drivers/net/Kconfig @@ -3064,6 +3064,7 @@ tristate "Virtio network driver (EXPERIMENTAL)" depends on EXPERIMENTAL && VIRTIO ---help--- - This is the virtual network driver for lguest. Say Y or M. + This is the virtual network driver for virtio. It can be used with + lguest or QEMU based VMMs (like KVM or Xen). Say Y or M. endif # NETDEVICES --- linux-2.6.24.orig/drivers/net/plip.c +++ linux-2.6.24/drivers/net/plip.c @@ -903,17 +903,18 @@ struct net_local *nl; struct plip_local *rcv; unsigned char c0; + unsigned long flags; nl = netdev_priv(dev); rcv = &nl->rcv_data; - spin_lock_irq (&nl->lock); + spin_lock_irqsave (&nl->lock, flags); c0 = read_status(dev); if ((c0 & 0xf8) != 0xc0) { if ((dev->irq != -1) && (net_debug > 1)) printk(KERN_DEBUG "%s: spurious interrupt\n", dev->name); - spin_unlock_irq (&nl->lock); + spin_unlock_irqrestore (&nl->lock, flags); return; } @@ -942,7 +943,7 @@ break; } - spin_unlock_irq(&nl->lock); + spin_unlock_irqrestore(&nl->lock, flags); } static int --- linux-2.6.24.orig/drivers/net/ppp_synctty.c +++ linux-2.6.24/drivers/net/ppp_synctty.c @@ -207,6 +207,9 @@ struct syncppp *ap; int err; + if (!tty->driver->write) + return -EOPNOTSUPP; + ap = kzalloc(sizeof(*ap), GFP_KERNEL); err = -ENOMEM; if (!ap) --- linux-2.6.24.orig/drivers/net/sunvnet.c +++ linux-2.6.24/drivers/net/sunvnet.c @@ -201,15 +201,9 @@ struct sk_buff *skb; int err; - err = -EMSGSIZE; - if (unlikely(len < ETH_ZLEN || len > ETH_FRAME_LEN)) { - dev->stats.rx_length_errors++; - goto out_dropped; - } - skb = alloc_and_align_skb(dev, len); err = -ENOMEM; - if (unlikely(!skb)) { + if (!skb) { dev->stats.rx_missed_errors++; goto out_dropped; } @@ -219,7 +213,7 @@ err = ldc_copy(port->vio.lp, LDC_COPY_IN, skb->data, copy_len, 0, cookies, ncookies); - if (unlikely(err < 0)) { + if (err < 0) { dev->stats.rx_frame_errors++; goto out_free_skb; } --- linux-2.6.24.orig/drivers/net/virtio_net.c +++ linux-2.6.24/drivers/net/virtio_net.c @@ -24,6 +24,13 @@ #include #include +static int napi_weight = 128; +module_param(napi_weight, int, 0444); + +static int csum = 1, gso = 1; +module_param(csum, bool, 0444); +module_param(gso, bool, 0444); + /* FIXME: MTU in config. */ #define MAX_PACKET_LEN (ETH_HLEN+ETH_DATA_LEN) @@ -52,13 +59,14 @@ sg_init_one(sg, skb_vnet_hdr(skb), sizeof(struct virtio_net_hdr)); } -static bool skb_xmit_done(struct virtqueue *rvq) +static void skb_xmit_done(struct virtqueue *svq) { - struct virtnet_info *vi = rvq->vdev->priv; + struct virtnet_info *vi = svq->vdev->priv; - /* In case we were waiting for output buffers. */ + /* Suppress further interrupts. */ + svq->vq_ops->disable_cb(svq); + /* We were waiting for more output buffers. */ netif_wake_queue(vi->dev); - return true; } static void receive_skb(struct net_device *dev, struct sk_buff *skb, @@ -83,28 +91,16 @@ if (hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) { pr_debug("Needs csum!\n"); - skb->ip_summed = CHECKSUM_PARTIAL; - skb->csum_start = hdr->csum_start; - skb->csum_offset = hdr->csum_offset; - if (skb->csum_start > skb->len - 2 - || skb->csum_offset > skb->len - 2) { - if (net_ratelimit()) - printk(KERN_WARNING "%s: csum=%u/%u len=%u\n", - dev->name, skb->csum_start, - skb->csum_offset, skb->len); + if (!skb_partial_csum_set(skb,hdr->csum_start,hdr->csum_offset)) goto frame_err; - } } if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) { pr_debug("GSO!\n"); - switch (hdr->gso_type) { + switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { case VIRTIO_NET_HDR_GSO_TCPV4: skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; break; - case VIRTIO_NET_HDR_GSO_TCPV4_ECN: - skb_shinfo(skb)->gso_type = SKB_GSO_TCP_ECN; - break; case VIRTIO_NET_HDR_GSO_UDP: skb_shinfo(skb)->gso_type = SKB_GSO_UDP; break; @@ -118,6 +114,9 @@ goto frame_err; } + if (hdr->gso_type & VIRTIO_NET_HDR_GSO_ECN) + skb_shinfo(skb)->gso_type |= SKB_GSO_TCP_ECN; + skb_shinfo(skb)->gso_size = hdr->gso_size; if (skb_shinfo(skb)->gso_size == 0) { if (net_ratelimit()) @@ -170,12 +169,14 @@ vi->rvq->vq_ops->kick(vi->rvq); } -static bool skb_recv_done(struct virtqueue *rvq) +static void skb_recv_done(struct virtqueue *rvq) { struct virtnet_info *vi = rvq->vdev->priv; - netif_rx_schedule(vi->dev, &vi->napi); - /* Suppress further interrupts. */ - return false; + /* Schedule NAPI, Suppress further interrupts if successful. */ + if (netif_rx_schedule_prep(vi->dev, &vi->napi)) { + rvq->vq_ops->disable_cb(rvq); + __netif_rx_schedule(vi->dev, &vi->napi); + } } static int virtnet_poll(struct napi_struct *napi, int budget) @@ -201,9 +202,12 @@ /* Out of packets? */ if (received < budget) { netif_rx_complete(vi->dev, napi); - if (unlikely(!vi->rvq->vq_ops->restart(vi->rvq)) - && netif_rx_reschedule(vi->dev, napi)) + if (unlikely(!vi->rvq->vq_ops->enable_cb(vi->rvq)) + && napi_schedule_prep(napi)) { + vi->rvq->vq_ops->disable_cb(vi->rvq); + __netif_rx_schedule(vi->dev, napi); goto again; + } } return received; @@ -236,8 +240,6 @@ pr_debug("%s: xmit %p %s\n", dev->name, skb, print_mac(mac, dest)); - free_old_xmit_skbs(vi); - /* Encode metadata header at front. */ hdr = skb_vnet_hdr(skb); if (skb->ip_summed == CHECKSUM_PARTIAL) { @@ -250,10 +252,9 @@ } if (skb_is_gso(skb)) { + hdr->hdr_len = skb_transport_header(skb) - skb->data; hdr->gso_size = skb_shinfo(skb)->gso_size; - if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN) - hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4_ECN; - else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) + if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4; else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6; @@ -261,19 +262,34 @@ hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP; else BUG(); + if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN) + hdr->gso_type |= VIRTIO_NET_HDR_GSO_ECN; } else { hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE; - hdr->gso_size = 0; + hdr->gso_size = hdr->hdr_len = 0; } vnet_hdr_to_sg(sg, skb); num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; __skb_queue_head(&vi->send, skb); + +again: + /* Free up any pending old buffers before queueing new ones. */ + free_old_xmit_skbs(vi); err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); if (err) { pr_debug("%s: virtio not prepared to send\n", dev->name); - skb_unlink(skb, &vi->send); netif_stop_queue(dev); + + /* Activate callback for using skbs: if this returns false it + * means some were used in the meantime. */ + if (unlikely(!vi->svq->vq_ops->enable_cb(vi->svq))) { + vi->svq->vq_ops->disable_cb(vi->svq); + netif_start_queue(dev); + goto again; + } + __skb_unlink(skb, &vi->send); + return NETDEV_TX_BUSY; } vi->svq->vq_ops->kick(vi->svq); @@ -281,49 +297,46 @@ return 0; } -static int virtnet_open(struct net_device *dev) +#ifdef CONFIG_NET_POLL_CONTROLLER +static void virtnet_netpoll(struct net_device *dev) { struct virtnet_info *vi = netdev_priv(dev); - try_fill_recv(vi); + napi_schedule(&vi->napi); +} +#endif - /* If we didn't even get one input buffer, we're useless. */ - if (vi->num == 0) - return -ENOMEM; +static int virtnet_open(struct net_device *dev) +{ + struct virtnet_info *vi = netdev_priv(dev); napi_enable(&vi->napi); + + /* If all buffers were filled by other side before we napi_enabled, we + * won't get another interrupt, so process any outstanding packets + * now. virtnet_poll wants re-enable the queue, so we disable here. + * We synchronize against interrupts via NAPI_STATE_SCHED */ + if (netif_rx_schedule_prep(dev, &vi->napi)) { + vi->rvq->vq_ops->disable_cb(vi->rvq); + __netif_rx_schedule(dev, &vi->napi); + } return 0; } static int virtnet_close(struct net_device *dev) { struct virtnet_info *vi = netdev_priv(dev); - struct sk_buff *skb; napi_disable(&vi->napi); - /* networking core has neutered skb_xmit_done/skb_recv_done, so don't - * worry about races vs. get(). */ - vi->rvq->vq_ops->shutdown(vi->rvq); - while ((skb = __skb_dequeue(&vi->recv)) != NULL) { - kfree_skb(skb); - vi->num--; - } - vi->svq->vq_ops->shutdown(vi->svq); - while ((skb = __skb_dequeue(&vi->send)) != NULL) - kfree_skb(skb); - - BUG_ON(vi->num != 0); return 0; } static int virtnet_probe(struct virtio_device *vdev) { int err; - unsigned int len; struct net_device *dev; struct virtnet_info *vi; - void *token; /* Allocate ourselves a network device with room for our info */ dev = alloc_etherdev(sizeof(struct virtnet_info)); @@ -331,50 +344,48 @@ return -ENOMEM; /* Set up network device as normal. */ - ether_setup(dev); dev->open = virtnet_open; dev->stop = virtnet_close; dev->hard_start_xmit = start_xmit; dev->features = NETIF_F_HIGHDMA; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = virtnet_netpoll; +#endif SET_NETDEV_DEV(dev, &vdev->dev); /* Do we support "hardware" checksums? */ - token = vdev->config->find(vdev, VIRTIO_CONFIG_NET_F, &len); - if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_NO_CSUM)) { + if (csum && vdev->config->feature(vdev, VIRTIO_NET_F_CSUM)) { /* This opens up the world of extra features. */ dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; - if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_TSO4)) - dev->features |= NETIF_F_TSO; - if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_UFO)) - dev->features |= NETIF_F_UFO; - if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_TSO4_ECN)) - dev->features |= NETIF_F_TSO_ECN; - if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_TSO6)) - dev->features |= NETIF_F_TSO6; + if (gso && vdev->config->feature(vdev, VIRTIO_NET_F_GSO)) { + dev->features |= NETIF_F_TSO | NETIF_F_UFO + | NETIF_F_TSO_ECN | NETIF_F_TSO6; + } } /* Configuration may specify what MAC to use. Otherwise random. */ - token = vdev->config->find(vdev, VIRTIO_CONFIG_NET_MAC_F, &len); - if (token) { - dev->addr_len = len; - vdev->config->get(vdev, token, dev->dev_addr, len); + if (vdev->config->feature(vdev, VIRTIO_NET_F_MAC)) { + vdev->config->get(vdev, + offsetof(struct virtio_net_config, mac), + dev->dev_addr, dev->addr_len); } else random_ether_addr(dev->dev_addr); /* Set up our device-specific information */ vi = netdev_priv(dev); - netif_napi_add(dev, &vi->napi, virtnet_poll, 16); + netif_napi_add(dev, &vi->napi, virtnet_poll, napi_weight); vi->dev = dev; vi->vdev = vdev; + vdev->priv = vi; /* We expect two virtqueues, receive then send. */ - vi->rvq = vdev->config->find_vq(vdev, skb_recv_done); + vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done); if (IS_ERR(vi->rvq)) { err = PTR_ERR(vi->rvq); goto free; } - vi->svq = vdev->config->find_vq(vdev, skb_xmit_done); + vi->svq = vdev->config->find_vq(vdev, 1, skb_xmit_done); if (IS_ERR(vi->svq)) { err = PTR_ERR(vi->svq); goto free_recv; @@ -389,10 +400,21 @@ pr_debug("virtio_net: registering device failed\n"); goto free_send; } + + /* Last of all, set up some receive buffers. */ + try_fill_recv(vi); + + /* If we didn't even get one input buffer, we're useless. */ + if (vi->num == 0) { + err = -ENOMEM; + goto unregister; + } + pr_debug("virtnet: registered device %s\n", dev->name); - vdev->priv = vi; return 0; +unregister: + unregister_netdev(dev); free_send: vdev->config->del_vq(vi->svq); free_recv: @@ -405,6 +427,20 @@ static void virtnet_remove(struct virtio_device *vdev) { struct virtnet_info *vi = vdev->priv; + struct sk_buff *skb; + + /* Stop all the virtqueues. */ + vdev->config->reset(vdev); + + /* Free our skbs in send and recv queues, if any. */ + while ((skb = __skb_dequeue(&vi->recv)) != NULL) { + kfree_skb(skb); + vi->num--; + } + while ((skb = __skb_dequeue(&vi->send)) != NULL) + kfree_skb(skb); + + BUG_ON(vi->num != 0); vdev->config->del_vq(vi->svq); vdev->config->del_vq(vi->rvq); --- linux-2.6.24.orig/drivers/net/dl2k.h +++ linux-2.6.24/drivers/net/dl2k.h @@ -388,8 +388,8 @@ MII_MSSR_CFG_RES = 0x4000, MII_MSSR_LOCAL_RCV_STATUS = 0x2000, MII_MSSR_REMOTE_RCVR = 0x1000, - MII_MSSR_LP_1000BT_HD = 0x0800, - MII_MSSR_LP_1000BT_FD = 0x0400, + MII_MSSR_LP_1000BT_FD = 0x0800, + MII_MSSR_LP_1000BT_HD = 0x0400, MII_MSSR_IDLE_ERR_COUNT = 0x00ff, }; --- linux-2.6.24.orig/drivers/net/forcedeth.c +++ linux-2.6.24/drivers/net/forcedeth.c @@ -5666,3 +5666,5 @@ module_init(init_nic); module_exit(exit_nic); + + --- linux-2.6.24.orig/drivers/net/sky2.c +++ linux-2.6.24/drivers/net/sky2.c @@ -119,6 +119,7 @@ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) }, /* 88E8038 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) }, /* 88E8039 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4354) }, /* 88E8040 */ + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4355) }, /* 88E8040T */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4356) }, /* 88EC033 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4357) }, /* 88E8042 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x435A) }, /* 88E8048 */ @@ -3324,7 +3325,7 @@ default: gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); - gm_phy_write(hw, port, PHY_MARV_LED_OVER, + gm_phy_write(hw, port, PHY_MARV_LED_OVER, on ? PHY_M_LED_ALL : 0); } } @@ -4312,10 +4313,14 @@ if (!hw) return 0; + del_timer_sync(&hw->watchdog_timer); + cancel_work_sync(&hw->restart_work); + for (i = 0; i < hw->ports; i++) { struct net_device *dev = hw->dev[i]; struct sky2_port *sky2 = netdev_priv(dev); + netif_device_detach(dev); if (netif_running(dev)) sky2_down(dev); @@ -4366,6 +4371,8 @@ for (i = 0; i < hw->ports; i++) { struct net_device *dev = hw->dev[i]; + + netif_device_attach(dev); if (netif_running(dev)) { err = sky2_up(dev); if (err) { --- linux-2.6.24.orig/drivers/net/r8169.c +++ linux-2.6.24/drivers/net/r8169.c @@ -1139,6 +1139,10 @@ { 0x7cf00000, 0x34000000, RTL_GIGA_MAC_VER_13 }, { 0x7cf00000, 0x34200000, RTL_GIGA_MAC_VER_16 }, { 0x7c800000, 0x34000000, RTL_GIGA_MAC_VER_16 }, + /* 8102EL */ + { 0x7c800000, 0x24800000, RTL_GIGA_MAC_VER_16 }, + /* 8102E */ + { 0x7c800000, 0x34800000, RTL_GIGA_MAC_VER_16 }, /* FIXME: where did these entries come from ? -- FR */ { 0xfc800000, 0x38800000, RTL_GIGA_MAC_VER_15 }, { 0xfc800000, 0x30800000, RTL_GIGA_MAC_VER_14 }, @@ -1299,6 +1303,21 @@ rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); } +static void rtl8101_hw_phy_config(void __iomem *ioaddr) +{ + struct phy_reg phy_reg_init[] = { + { 0x1f, 0x0000 }, + { 0x11, mdio_read(ioaddr,0x11) | 0x1000 }, + { 0x19, mdio_read(ioaddr,0x19) | 0x2000 }, + { 0x1f, 0x0003 }, + { 0x08, 0x441D }, + { 0x01, 0x9100 }, + { 0x1f, 0x0000 } + }; + + rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); +} + static void rtl_hw_phy_config(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -1316,6 +1335,9 @@ case RTL_GIGA_MAC_VER_04: rtl8169sb_hw_phy_config(ioaddr); break; + case RTL_GIGA_MAC_VER_13: + case RTL_GIGA_MAC_VER_16: + rtl8101_hw_phy_config(ioaddr); case RTL_GIGA_MAC_VER_18: rtl8168cp_hw_phy_config(ioaddr); break; @@ -1438,8 +1460,10 @@ rtl_hw_phy_config(dev); - dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); - RTL_W8(0x82, 0x01); + if (tp->mac_version <= RTL_GIGA_MAC_VER_06) { + dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); + RTL_W8(0x82, 0x01); + } pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40); @@ -1617,6 +1641,7 @@ SET_NETDEV_DEV(dev, &pdev->dev); tp = netdev_priv(dev); tp->dev = dev; + tp->pci_dev = pdev; tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT); /* enable device (incl. PCI PM wakeup and hotplug setup) */ @@ -1776,8 +1801,14 @@ dev->poll_controller = rtl8169_netpoll; #endif + /* Ubuntu temporary workaround for bug #76489, disable + * NETIF_F_TSO by default for RTL8111/8168B chipsets. + * People can re-enable if required */ + if (tp->mac_version == RTL_GIGA_MAC_VER_11 + || tp->mac_version == RTL_GIGA_MAC_VER_12) + dev->features &= ~NETIF_F_TSO; + tp->intr_mask = 0xffff; - tp->pci_dev = pdev; tp->mmio_addr = ioaddr; tp->align = cfg->align; tp->hw_start = cfg->hw_start; --- linux-2.6.24.orig/drivers/net/cxgb3/t3_hw.c +++ linux-2.6.24/drivers/net/cxgb3/t3_hw.c @@ -1730,7 +1730,6 @@ MC7_INTR_MASK}, {A_MC5_DB_INT_ENABLE, MC5_INTR_MASK}, {A_ULPRX_INT_ENABLE, ULPRX_INTR_MASK}, - {A_TP_INT_ENABLE, 0x3bfffff}, {A_PM1_TX_INT_ENABLE, PMTX_INTR_MASK}, {A_PM1_RX_INT_ENABLE, PMRX_INTR_MASK}, {A_CIM_HOST_INT_ENABLE, CIM_INTR_MASK}, @@ -1740,6 +1739,8 @@ adapter->slow_intr_mask = PL_INTR_MASK; t3_write_regs(adapter, intr_en_avp, ARRAY_SIZE(intr_en_avp), 0); + t3_write_reg(adapter, A_TP_INT_ENABLE, + adapter->params.rev >= T3_REV_C ? 0x2bfffff : 0x3bfffff); if (adapter->params.rev > 0) { t3_write_reg(adapter, A_CPL_INTR_ENABLE, --- linux-2.6.24.orig/drivers/net/wireless/ipw2200.c +++ linux-2.6.24/drivers/net/wireless/ipw2200.c @@ -8912,6 +8912,8 @@ range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; + range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE; + IPW_DEBUG_WX("GET Range\n"); return 0; } --- linux-2.6.24.orig/drivers/net/wireless/orinoco_cs.c +++ linux-2.6.24/drivers/net/wireless/orinoco_cs.c @@ -11,6 +11,7 @@ */ #define DRIVER_NAME "orinoco_cs" +#define OVERLAP_DRIVER_NAME "orinoco_cs_overlap" #define PFX DRIVER_NAME ": " #include @@ -440,66 +441,93 @@ " (David Gibson , " "Pavel Roskin , et al)"; -static struct pcmcia_device_id orinoco_cs_ids[] = { +/* + * PCMCIA IDs that are also defined in hostap_cs. + */ +static struct pcmcia_device_id orinoco_overlap_cs_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), /* SonicWALL Long Range Wireless Card */ PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), /* Sohoware NCP110, Philips 802.11b */ - PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), /* AnyPoint(TM) Wireless II PC Card */ PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), /* 3Com AirConnect PCI 777A */ PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), /* PROXIM RangeLAN-DS/LAN PC CARD */ PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), /* Compaq WL100 11 Mbps Wireless Adapter */ + PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), /* Samsung SWL2000-N 11Mb/s WLAN Card */ + PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), /* Linksys WPC11 Version 2.5 */ + PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), /* Linksys WPC11 Version 3 */ + PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), /* Compaq HNW-100 11 Mbps Wireless Adapter */ + PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */ + PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */ + PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), /* Safeway 802.11b, ZCOMAX AirRunner/XI-300 */ + PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), /* D-Link DCF660, Sandisk Connect SDWCFB-000 */ + + PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18), + PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf), + + PCMCIA_DEVICE_PROD_ID123("Intersil", "PRISM Freedom PCMCIA Adapter", "ISL37100P", 0x4b801a17, 0xf222ec2d, 0x630d52b2), + + PCMCIA_DEVICE_PROD_ID12("Addtron", "AWP-100 Wireless PCMCIA", 0xe6ec52ce, 0x08649af2), + PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", 0x71b18589, 0xf144e3ac), + PCMCIA_DEVICE_PROD_ID12("D", "Link DWL-650 11Mbps WLAN Card", 0x71b18589, 0xb6f1b0ab), + PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0), + PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2532W-B EliteConnect Wireless Adapter", 0xc4f8b18b, 0x196bd757), + PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a), + PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-PCM-L11G", 0x2decece3, 0xf57ca4b3), + PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18), + PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b), + PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77), + PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395), + PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee), + PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f), + + PCMCIA_DEVICE_NULL, +}; + +static struct pcmcia_driver orinoco_overlap_driver = { + .owner = THIS_MODULE, + .drv = { + .name = OVERLAP_DRIVER_NAME, + }, + .probe = orinoco_cs_probe, + .remove = orinoco_cs_detach, + .id_table = orinoco_overlap_cs_ids, + .suspend = orinoco_cs_suspend, + .resume = orinoco_cs_resume, +}; + +static struct pcmcia_device_id orinoco_cs_ids[] = { + PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), /* AnyPoint(TM) Wireless II PC Card */ PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), /* Lucent Orinoco and old Intersil */ PCMCIA_DEVICE_MANF_CARD(0x016b, 0x0001), /* Ericsson WLAN Card C11 */ PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a), /* Nortel Networks eMobility 802.11 Wireless Adapter */ PCMCIA_DEVICE_MANF_CARD(0x01ff, 0x0008), /* Intermec MobileLAN 11Mbps 802.11b WLAN Card */ - PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), /* Samsung SWL2000-N 11Mb/s WLAN Card */ PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002), /* AirWay 802.11 Adapter (PCMCIA) */ PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001), /* ARtem Onair */ PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305), /* Buffalo WLI-PCM-S11 */ - PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), /* Linksys WPC11 Version 2.5 */ - PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), /* Linksys WPC11 Version 3 */ - PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), /* Compaq HNW-100 11 Mbps Wireless Adapter */ PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), /* Linksys WCF12 Wireless CompactFlash Card */ - PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */ PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002), /* SpeedStream SS1021 Wireless Adapter */ PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001), /* PLANEX RoadLannerWave GW-NS11H */ - PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */ PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), /* Adaptec Ultra Wireless ANW-8030 */ PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0008), /* CONTEC FLEXSCAN/FX-DDS110-PCC */ PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), /* Conceptronic CON11Cpro, EMTAC A2424i */ - PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), /* Safeway 802.11b, ZCOMAX AirRunner/XI-300 */ - PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), /* D-Link DCF660, Sandisk Connect SDWCFB-000 */ + PCMCIA_DEVICE_PROD_ID12(" ", "IEEE 802.11 Wireless LAN/PC Card", 0x3b6e20c8, 0xefccafe9), PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3), PCMCIA_DEVICE_PROD_ID12("ACTIONTEC", "PRISM Wireless LAN PC Card", 0x393089da, 0xa71e69d5), - PCMCIA_DEVICE_PROD_ID12("Addtron", "AWP-100 Wireless PCMCIA", 0xe6ec52ce, 0x08649af2), PCMCIA_DEVICE_PROD_ID123("AIRVAST", "IEEE 802.11b Wireless PCMCIA Card", "HFA3863", 0xea569531, 0x4bcb9645, 0x355cb092), - PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f), PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842), PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e), PCMCIA_DEVICE_PROD_ID12("Avaya Communication", "Avaya Wireless PC Card", 0xd8a43b78, 0x0d341169), PCMCIA_DEVICE_PROD_ID12("BENQ", "AWL100 PCMCIA ADAPTER", 0x35dadc74, 0x01f7fedb), - PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-PCM-L11G", 0x2decece3, 0xf57ca4b3), - PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18), PCMCIA_DEVICE_PROD_ID12("Cabletron", "RoamAbout 802.11 DS", 0x32d445f5, 0xedeffd90), - PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b), PCMCIA_DEVICE_PROD_ID123("corega", "WL PCCL-11", "ISL37300P", 0x0a21501a, 0x59868926, 0xc9049a39), PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584), PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9), PCMCIA_DEVICE_PROD_ID12("corega_K.K.", "Wireless_LAN_PCCB-11", 0x29e33311, 0xee7a27ae), - PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", 0x71b18589, 0xf144e3ac), - PCMCIA_DEVICE_PROD_ID12("D", "Link DWL-650 11Mbps WLAN Card", 0x71b18589, 0xb6f1b0ab), PCMCIA_DEVICE_PROD_ID12("D-Link Corporation", "D-Link DWL-650H 11Mbps WLAN Adapter", 0xef544d24, 0xcd8ea916), PCMCIA_DEVICE_PROD_ID12("Digital Data Communications", "WPC-0100", 0xfdd73470, 0xe0b6f146), PCMCIA_DEVICE_PROD_ID12("ELSA", "AirLancer MC-11", 0x4507a33a, 0xef54f0e3), PCMCIA_DEVICE_PROD_ID12("HyperLink", "Wireless PC Card 11Mbps", 0x56cc3f1a, 0x0bcf220c), - PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0), PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless 2011 LAN PC Card", 0x816cc815, 0x07f58077), - PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18), - PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77), - PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf), - PCMCIA_DEVICE_PROD_ID123("Intersil", "PRISM Freedom PCMCIA Adapter", "ISL37100P", 0x4b801a17, 0xf222ec2d, 0x630d52b2), PCMCIA_DEVICE_PROD_ID12("LeArtery", "SYNCBYAIR 11Mbps Wireless LAN PC Card", 0x7e3b326a, 0x49893e92), - PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395), PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/IEEE", 0x23eb9949, 0xc562e72a), PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11", 0x481e0094, 0x7360e410), PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11G", 0x481e0094, 0xf57ca4b3), @@ -516,11 +544,8 @@ PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PC CARD HARMONY 80211B", 0xc6536a5e, 0x090c3cd9), PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PCI CARD HARMONY 80211B", 0xc6536a5e, 0x9f494e26), PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "11Mbps WLAN Card", 0x43d74cb4, 0x579bd91b), - PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2532W-B EliteConnect Wireless Adapter", 0xc4f8b18b, 0x196bd757), - PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a), PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e), PCMCIA_DEVICE_PROD_ID123("The Linksys Group, Inc.", "Instant Wireless Network PC Card", "ISL37300P", 0xa5f472c2, 0x590eb502, 0xc9049a39), - PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee), PCMCIA_DEVICE_NULL, }; MODULE_DEVICE_TABLE(pcmcia, orinoco_cs_ids); @@ -537,18 +562,39 @@ .resume = orinoco_cs_resume, }; +static int orinoco_driver_registered = 0; +static int orinoco_overlap_driver_registered = 0; + static int __init init_orinoco_cs(void) { + int status; + printk(KERN_DEBUG "%s\n", version); - return pcmcia_register_driver(&orinoco_driver); + status = pcmcia_register_driver(&orinoco_driver); + if (status >= 0) + orinoco_driver_registered = 1; + + status = pcmcia_register_driver(&orinoco_overlap_driver); + if (status >= 0) + orinoco_overlap_driver_registered = 1; + + return status; } static void __exit exit_orinoco_cs(void) { - pcmcia_unregister_driver(&orinoco_driver); + if (orinoco_overlap_driver_registered) { + pcmcia_unregister_driver(&orinoco_overlap_driver); + orinoco_overlap_driver_registered = 0; + } + + if (orinoco_driver_registered) { + pcmcia_unregister_driver(&orinoco_driver); + orinoco_driver_registered = 0; + } } module_init(init_orinoco_cs); --- linux-2.6.24.orig/drivers/net/wireless/strip.c +++ linux-2.6.24/drivers/net/wireless/strip.c @@ -802,7 +802,8 @@ struct ktermios old_termios = *(tty->termios); tty->termios->c_cflag &= ~CBAUD; /* Clear the old baud setting */ tty->termios->c_cflag |= baudcode; /* Set the new baud setting */ - tty->driver->set_termios(tty, &old_termios); + if (tty->driver->set_termios) + tty->driver->set_termios(tty, &old_termios); } /* --- linux-2.6.24.orig/drivers/net/wireless/hostap/hostap_info.c +++ linux-2.6.24/drivers/net/wireless/hostap/hostap_info.c @@ -238,6 +238,7 @@ wrqu.data.length = 0; wrqu.data.flags = 0; wireless_send_event(local->dev, SIOCGIWSCAN, &wrqu, NULL); + wireless_send_event(local->ddev, SIOCGIWSCAN, &wrqu, NULL); /* Allow SIOCGIWSCAN handling to occur since we have received * scanning result */ @@ -450,8 +451,10 @@ * frames and can confuse wpa_supplicant about the current association * status. */ - if (connected || local->prev_linkstatus_connected) + if (connected || local->prev_linkstatus_connected) { wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL); + wireless_send_event(local->ddev, SIOCGIWAP, &wrqu, NULL); + } local->prev_linkstatus_connected = connected; } --- linux-2.6.24.orig/drivers/net/wireless/hostap/hostap_ioctl.c +++ linux-2.6.24/drivers/net/wireless/hostap/hostap_ioctl.c @@ -1089,6 +1089,9 @@ range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; + if (local->sta_fw_ver >= PRISM2_FW_VER(1,3,1)) + range->scan_capa = IW_SCAN_CAPA_ESSID; + return 0; } --- linux-2.6.24.orig/drivers/net/wireless/hostap/hostap_hw.c +++ linux-2.6.24/drivers/net/wireless/hostap/hostap_hw.c @@ -3434,6 +3434,7 @@ memset(&wrqu, 0, sizeof(wrqu)); wrqu.ap_addr.sa_family = ARPHRD_ETHER; wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL); + wireless_send_event(local->ddev, SIOCGIWAP, &wrqu, NULL); /* Disable hardware and firmware */ prism2_hw_shutdown(dev, 0); --- linux-2.6.24.orig/drivers/net/wireless/hostap/hostap_main.c +++ linux-2.6.24/drivers/net/wireless/hostap/hostap_main.c @@ -1106,6 +1106,7 @@ (u8 *) &reason, 2); memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL); + wireless_send_event(local->ddev, SIOCGIWAP, &wrqu, NULL); return ret; } --- linux-2.6.24.orig/drivers/net/wireless/b43legacy/xmit.c +++ linux-2.6.24/drivers/net/wireless/b43legacy/xmit.c @@ -606,7 +606,7 @@ tmp = hw->count; status.frame_count = (tmp >> 4); status.rts_count = (tmp & 0x0F); - tmp = hw->flags; + tmp = hw->flags << 1; status.supp_reason = ((tmp & 0x1C) >> 2); status.pm_indicated = !!(tmp & 0x80); status.intermediate = !!(tmp & 0x40); --- linux-2.6.24.orig/drivers/net/wireless/b43legacy/main.c +++ linux-2.6.24/drivers/net/wireless/b43legacy/main.c @@ -1500,6 +1500,7 @@ } if (!fw->initvals) { switch (dev->phy.type) { + case B43legacy_PHYTYPE_B: case B43legacy_PHYTYPE_G: if ((rev >= 5) && (rev <= 10)) filename = "b0g0initvals5"; @@ -1517,6 +1518,7 @@ } if (!fw->initvals_band) { switch (dev->phy.type) { + case B43legacy_PHYTYPE_B: case B43legacy_PHYTYPE_G: if ((rev >= 5) && (rev <= 10)) filename = "b0g0bsinitvals5"; --- linux-2.6.24.orig/drivers/net/wireless/b43legacy/leds.c +++ linux-2.6.24/drivers/net/wireless/b43legacy/leds.c @@ -256,7 +256,7 @@ continue; #endif /* CONFIG_B43LEGACY_DEBUG */ default: - B43legacy_BUG_ON(1); + break; }; if (led->activelow) --- linux-2.6.24.orig/drivers/net/wireless/b43/dma.c +++ linux-2.6.24/drivers/net/wireless/b43/dma.c @@ -165,7 +165,7 @@ addrhi = (((u64) dmaaddr >> 32) & ~SSB_DMA_TRANSLATION_MASK); addrext = (((u64) dmaaddr >> 32) & SSB_DMA_TRANSLATION_MASK) >> SSB_DMA_TRANSLATION_SHIFT; - addrhi |= ssb_dma_translation(ring->dev->dev); + addrhi |= (ssb_dma_translation(ring->dev->dev) << 1); if (slot == ring->nr_slots - 1) ctl0 |= B43_DMA64_DCTL0_DTABLEEND; if (start) @@ -426,9 +426,21 @@ static int alloc_ringmemory(struct b43_dmaring *ring) { struct device *dev = ring->dev->dev->dev; + gfp_t flags = GFP_KERNEL; + /* The specs call for 4K buffers for 30- and 32-bit DMA with 4K + * alignment and 8K buffers for 64-bit DMA with 8K alignment. Testing + * has shown that 4K is sufficient for the latter as long as the buffer + * does not cross an 8K boundary. + * + * For unknown reasons - possibly a hardware error - the BCM4311 rev + * 02, which uses 64-bit DMA, needs the ring buffer in very low memory, + * which accounts for the GFP_DMA flag below. + */ + if (ring->dma64) + flags |= GFP_DMA; ring->descbase = dma_alloc_coherent(dev, B43_DMA_RINGMEMSIZE, - &(ring->dmabase), GFP_KERNEL); + &(ring->dmabase), flags); if (!ring->descbase) { b43err(ring->dev->wl, "DMA ringmemory allocation failed\n"); return -ENOMEM; @@ -483,7 +495,7 @@ return 0; } -/* Reset the RX DMA channel */ +/* Reset the TX DMA channel */ int b43_dmacontroller_tx_reset(struct b43_wldev *dev, u16 mmio_base, int dma64) { int i; @@ -647,7 +659,7 @@ b43_dma_write(ring, B43_DMA64_TXRINGHI, ((ringbase >> 32) & ~SSB_DMA_TRANSLATION_MASK) - | trans); + | (trans << 1)); } else { u32 ringbase = (u32) (ring->dmabase); @@ -680,8 +692,9 @@ b43_dma_write(ring, B43_DMA64_RXRINGHI, ((ringbase >> 32) & ~SSB_DMA_TRANSLATION_MASK) - | trans); - b43_dma_write(ring, B43_DMA64_RXINDEX, 200); + | (trans << 1)); + b43_dma_write(ring, B43_DMA64_RXINDEX, ring->nr_slots * + sizeof(struct b43_dmadesc64)); } else { u32 ringbase = (u32) (ring->dmabase); @@ -695,11 +708,12 @@ b43_dma_write(ring, B43_DMA32_RXRING, (ringbase & ~SSB_DMA_TRANSLATION_MASK) | trans); - b43_dma_write(ring, B43_DMA32_RXINDEX, 200); + b43_dma_write(ring, B43_DMA32_RXINDEX, ring->nr_slots * + sizeof(struct b43_dmadesc32)); } } - out: +out: return err; } --- linux-2.6.24.orig/drivers/net/wireless/b43/main.c +++ linux-2.6.24/drivers/net/wireless/b43/main.c @@ -101,6 +101,9 @@ SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 7), SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 9), SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 10), + SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 11), + SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 13), + SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 15), SSB_DEVTABLE_END }; @@ -3079,7 +3082,7 @@ unsupported = 1; break; case B43_PHYTYPE_G: - if (phy_rev > 8) + if (phy_rev > 9) unsupported = 1; break; default: @@ -3739,7 +3742,7 @@ have_gphy = 0; switch (dev->phy.type) { case B43_PHYTYPE_A: - have_aphy = 1; + have_aphy = 0; break; case B43_PHYTYPE_B: have_bphy = 1; @@ -3850,8 +3853,16 @@ return err; } +#define IS_PDEV(pdev, _vendor, _device, _subvendor, _subdevice) ( \ + (pdev->vendor == PCI_VENDOR_ID_##_vendor) && \ + (pdev->device == _device) && \ + (pdev->subsystem_vendor == PCI_VENDOR_ID_##_subvendor) && \ + (pdev->subsystem_device == _subdevice) ) + static void b43_sprom_fixup(struct ssb_bus *bus) { + struct pci_dev *pdev; + /* boardflags workarounds */ if (bus->boardinfo.vendor == SSB_BOARDVENDOR_DELL && bus->chip_id == 0x4301 && bus->boardinfo.rev == 0x74) @@ -3859,6 +3870,15 @@ if (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE && bus->boardinfo.type == 0x4E && bus->boardinfo.rev > 0x40) bus->sprom.r1.boardflags_lo |= B43_BFL_PACTRL; + if (bus->bustype == SSB_BUSTYPE_PCI) { + pdev = bus->host_pci; + if (IS_PDEV(pdev, BROADCOM, 0x4318, ASUSTEK, 0x100F) || + IS_PDEV(pdev, BROADCOM, 0x4320, DELL, 0x0003) || + IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0015) || + IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0014) || + IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0013)) + bus->sprom.r1.boardflags_lo &= ~B43_BFL_BTCOEXIST; + } /* Handle case when gain is not set in sprom */ if (bus->sprom.r1.antenna_gain_a == 0xFF) --- linux-2.6.24.orig/drivers/net/wireless/b43/phy.c +++ linux-2.6.24/drivers/net/wireless/b43/phy.c @@ -933,7 +933,7 @@ for (i = 0; i < B43_TAB_SIGMASQR_SIZE; i++) b43_ofdmtab_write16(dev, 0x5000, i, b43_tab_sigmasqr1[i]); - else if ((phy->rev > 2) && (phy->rev <= 8)) + else if ((phy->rev > 2) && (phy->rev <= 9)) for (i = 0; i < B43_TAB_SIGMASQR_SIZE; i++) b43_ofdmtab_write16(dev, 0x5000, i, b43_tab_sigmasqr2[i]); --- linux-2.6.24.orig/drivers/net/e1000/e1000_main.c +++ linux-2.6.24/drivers/net/e1000/e1000_main.c @@ -218,6 +218,10 @@ MODULE_PARM_DESC(copybreak, "Maximum size of packet that is copied to a new buffer on receive"); +static int eeprom_bad_csum_allow __read_mostly = 0; +module_param(eeprom_bad_csum_allow, int, 0); +MODULE_PARM_DESC(eeprom_bad_csum_allow, "Allow bad EEPROM checksums"); + static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state); static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev); @@ -1001,16 +1005,19 @@ goto err_eeprom; } - /* before reading the EEPROM, reset the controller to - * put the device in a known good starting state */ + if (e1000_validate_eeprom_checksum(&adapter->hw) < 0) { + /* before reading the EEPROM, reset the controller to + * put the device in a known good starting state */ - e1000_reset_hw(&adapter->hw); + e1000_reset_hw(&adapter->hw); - /* make sure the EEPROM is good */ + /* make sure the EEPROM is good */ - if (e1000_validate_eeprom_checksum(&adapter->hw) < 0) { - DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n"); - goto err_eeprom; + if (e1000_validate_eeprom_checksum(&adapter->hw) < 0) { + DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n"); + if (!eeprom_bad_csum_allow) + goto err_eeprom; + } } /* copy the MAC address out of the EEPROM */ --- linux-2.6.24.orig/drivers/net/pcmcia/smc91c92_cs.c +++ linux-2.6.24/drivers/net/pcmcia/smc91c92_cs.c @@ -559,8 +559,16 @@ /* Read the station address from the CIS. It is stored as the last (fourth) string in the Version 1 Version/ID tuple. */ - if (link->prod_id[3]) { - station_addr = link->prod_id[3]; + tuple->DesiredTuple = CISTPL_VERS_1; + if (first_tuple(link, tuple, parse) != CS_SUCCESS) { + rc = -1; + goto free_cfg_mem; + } + /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */ + if (next_tuple(link, tuple, parse) != CS_SUCCESS) + first_tuple(link, tuple, parse); + if (parse->version_1.ns > 3) { + station_addr = parse->version_1.str + parse->version_1.ofs[3]; if (cvt_ascii_address(dev, station_addr) == 0) { rc = 0; goto free_cfg_mem; --- linux-2.6.24.orig/drivers/net/irda/irtty-sir.c +++ linux-2.6.24/drivers/net/irda/irtty-sir.c @@ -64,7 +64,9 @@ IRDA_ASSERT(priv != NULL, return -1;); IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -1;); - return priv->tty->driver->chars_in_buffer(priv->tty); + if (priv->tty->driver->chars_in_buffer) + return priv->tty->driver->chars_in_buffer(priv->tty); + return 0; } /* Wait (sleep) until underlaying hardware finished transmission --- linux-2.6.24.orig/drivers/net/irda/nsc-ircc.c +++ linux-2.6.24/drivers/net/irda/nsc-ircc.c @@ -149,7 +149,7 @@ static chipio_t pnp_info; static const struct pnp_device_id nsc_ircc_pnp_table[] = { { .id = "NSC6001", .driver_data = 0 }, - { .id = "IBM0071", .driver_data = 0 }, + { .id = "IBM0071", .driver_data = 1 }, { } }; @@ -928,6 +928,9 @@ * On my box, cfg_base is in the PnP descriptor of the * motherboard. Oh well... Jean II */ + if (id->driver_data == 1) + dongle_id = 0x9; + if (pnp_port_valid(dev, 0) && !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) pnp_info.fir_base = pnp_port_start(dev, 0); --- linux-2.6.24.orig/drivers/net/wan/x25_asy.c +++ linux-2.6.24/drivers/net/wan/x25_asy.c @@ -283,6 +283,10 @@ static void x25_asy_timeout(struct net_device *dev) { struct x25_asy *sl = (struct x25_asy*)(dev->priv); + int cib = 0; + + if (sl->tty->driver->chars_in_buffer) + cib = sl->tty->driver->chars_in_buffer(sl->tty); spin_lock(&sl->lock); if (netif_queue_stopped(dev)) { @@ -290,8 +294,7 @@ * 14 Oct 1994 Dmitry Gorodchanin. */ printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name, - (sl->tty->driver->chars_in_buffer(sl->tty) || sl->xleft) ? - "bad line quality" : "driver error"); + (cib || sl->xleft) ? "bad line quality" : "driver error"); sl->xleft = 0; sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); x25_asy_unlock(sl); @@ -561,6 +564,9 @@ return -EEXIST; } + if (!tty->driver->write) + return -EOPNOTSUPP; + /* OK. Find a free X.25 channel to use. */ if ((sl = x25_asy_alloc()) == NULL) { return -ENFILE; --- linux-2.6.24.orig/drivers/net/wan/sbni.c +++ linux-2.6.24/drivers/net/wan/sbni.c @@ -1317,7 +1317,7 @@ break; case SIOCDEVRESINSTATS : - if( current->euid != 0 ) /* root only */ + if (!capable(CAP_NET_ADMIN)) return -EPERM; memset( &nl->in_stats, 0, sizeof(struct sbni_in_stats) ); break; @@ -1334,7 +1334,7 @@ break; case SIOCDEVSHWSTATE : - if( current->euid != 0 ) /* root only */ + if (!capable(CAP_NET_ADMIN)) return -EPERM; spin_lock( &nl->lock ); @@ -1355,7 +1355,7 @@ #ifdef CONFIG_SBNI_MULTILINE case SIOCDEVENSLAVE : - if( current->euid != 0 ) /* root only */ + if (!capable(CAP_NET_ADMIN)) return -EPERM; if (copy_from_user( slave_name, ifr->ifr_data, sizeof slave_name )) @@ -1370,7 +1370,7 @@ return enslave( dev, slave_dev ); case SIOCDEVEMANSIPATE : - if( current->euid != 0 ) /* root only */ + if (!capable(CAP_NET_ADMIN)) return -EPERM; return emancipate( dev ); --- linux-2.6.24.orig/drivers/net/hamradio/mkiss.c +++ linux-2.6.24/drivers/net/hamradio/mkiss.c @@ -530,6 +530,7 @@ static int ax_xmit(struct sk_buff *skb, struct net_device *dev) { struct mkiss *ax = netdev_priv(dev); + int cib = 0; if (!netif_running(dev)) { printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name); @@ -545,10 +546,11 @@ /* 20 sec timeout not reached */ return 1; } + if (ax->tty->driver->chars_in_buffer) + cib = ax->tty->driver->chars_in_buffer(ax->tty); printk(KERN_ERR "mkiss: %s: transmit timed out, %s?\n", dev->name, - (ax->tty->driver->chars_in_buffer(ax->tty) || ax->xleft) ? - "bad line quality" : "driver error"); + cib || ax->xleft ? "bad line quality" : "driver error"); ax->xleft = 0; clear_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags); @@ -737,6 +739,8 @@ if (!capable(CAP_NET_ADMIN)) return -EPERM; + if (!tty->driver->write) + return -EOPNOTSUPP; dev = alloc_netdev(sizeof(struct mkiss), "ax%d", ax_setup); if (!dev) { --- linux-2.6.24.orig/drivers/net/hamradio/6pack.c +++ linux-2.6.24/drivers/net/hamradio/6pack.c @@ -601,6 +601,8 @@ if (!capable(CAP_NET_ADMIN)) return -EPERM; + if (!tty->driver->write) + return -EOPNOTSUPP; dev = alloc_netdev(sizeof(struct sixpack), "sp%d", sp_setup); if (!dev) { --- linux-2.6.24.orig/drivers/net/tulip/media.c +++ linux-2.6.24/drivers/net/tulip/media.c @@ -519,10 +519,11 @@ /* Enable autonegotiation: some boards default to off. */ if (tp->default_port == 0) { new_bmcr = mii_reg0 | BMCR_ANENABLE; - if (new_bmcr != mii_reg0) { - new_bmcr |= BMCR_ANRESTART; - ane_switch = 1; - } + /* DM9161E PHY seems to need to restart + * autonegotiation even if it defaults to enabled. + */ + new_bmcr |= BMCR_ANRESTART; + ane_switch = 1; } /* ...or disable nway, if forcing media */ else { --- linux-2.6.24.orig/drivers/net/tulip/tulip_core.c +++ linux-2.6.24/drivers/net/tulip/tulip_core.c @@ -230,8 +230,12 @@ { 0x1259, 0xa120, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x11F6, 0x9881, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMPEX9881 }, { 0x8086, 0x0039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, I21145 }, + /* Ubuntu: On non-sparc, this seems to be handled better by the + * dmfe driver. */ +#ifdef __sparc__ { 0x1282, 0x9100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X }, { 0x1282, 0x9102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X }, +#endif { 0x1113, 0x1216, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x1113, 0x1217, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 }, { 0x1113, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, @@ -394,6 +398,11 @@ goto media_picked; } } + if (tp->chip_id == PCI_ULI5261_ID || tp->chip_id == PCI_ULI5263_ID) { + for (i = tp->mtable->leafcount - 1; i >= 0; i--) + if (tulip_media_cap[tp->mtable->mleaf[i].media] & MediaIsMII) + goto media_picked; + } /* Start sensing first non-full-duplex media. */ for (i = tp->mtable->leafcount - 1; (tulip_media_cap[tp->mtable->mleaf[i].media] & MediaAlwaysFD) && i > 0; i--) --- linux-2.6.24.orig/drivers/net/tulip/tulip.h +++ linux-2.6.24/drivers/net/tulip/tulip.h @@ -37,7 +37,10 @@ #define TULIP_BAR 0 /* CBIO */ #endif - +#ifndef PCI_ULI5261_ID +#define PCI_ULI5261_ID 0x526110B9 /* ULi M5261 ID*/ +#define PCI_ULI5263_ID 0x526310B9 /* ULi M5263 ID*/ +#endif struct tulip_chip_table { char *chip_name; --- linux-2.6.24.orig/drivers/net/e1000e/netdev.c +++ linux-2.6.24/drivers/net/e1000e/netdev.c @@ -1686,6 +1686,9 @@ else rctl |= E1000_RCTL_LPE; + /* Enable hardware CRC frame stripping */ + rctl |= E1000_RCTL_SECRC; + /* Setup buffer sizes */ rctl &= ~E1000_RCTL_SZ_4096; rctl |= E1000_RCTL_BSEX; @@ -1751,9 +1754,6 @@ /* Enable Packet split descriptors */ rctl |= E1000_RCTL_DTYP_PS; - - /* Enable hardware CRC frame stripping */ - rctl |= E1000_RCTL_SECRC; psrctl |= adapter->rx_ps_bsize0 >> E1000_PSRCTL_BSIZE0_SHIFT; --- linux-2.6.24.orig/drivers/net/usb/pegasus.c +++ linux-2.6.24/drivers/net/usb/pegasus.c @@ -1289,6 +1289,24 @@ } } +static int pegasus_blacklisted(struct usb_device *udev) +{ + struct usb_device_descriptor *udd = &udev->descriptor; + + /* Special quirk to keep the driver from handling the Belkin Bluetooth + * dongle which happens to have the same ID. + */ + if (udd->idVendor == VENDOR_BELKIN && udd->idProduct == 0x0121) { + if (udd->bDeviceClass == USB_CLASS_WIRELESS_CONTROLLER) { + if (udd->bDeviceProtocol == 1) { + return 1; + } + } + } + + return 0; +} + static int pegasus_probe(struct usb_interface *intf, const struct usb_device_id *id) { @@ -1300,6 +1318,12 @@ DECLARE_MAC_BUF(mac); usb_get_dev(dev); + + if (pegasus_blacklisted(dev)) { + res = -ENODEV; + goto out; + } + net = alloc_etherdev(sizeof(struct pegasus)); if (!net) { dev_err(&intf->dev, "can't allocate %s\n", "device"); --- linux-2.6.24.orig/drivers/net/usb/rndis_host.c +++ linux-2.6.24/drivers/net/usb/rndis_host.c @@ -499,6 +499,14 @@ net->hard_header_len += sizeof (struct rndis_data_hdr); dev->hard_mtu = net->mtu + net->hard_header_len; + dev->maxpacket = usb_maxpacket(dev->udev, dev->out, 1); + if (dev->maxpacket == 0) { + if (netif_msg_probe(dev)) + dev_dbg(&intf->dev, "dev->maxpacket can't be 0\n"); + retval = -EINVAL; + goto fail_and_release; + } + dev->rx_urb_size = dev->hard_mtu + (dev->maxpacket + 1); dev->rx_urb_size &= ~(dev->maxpacket - 1); u.init->max_transfer_size = cpu_to_le32(dev->rx_urb_size); --- linux-2.6.24.orig/drivers/net/usb/asix.c +++ linux-2.6.24/drivers/net/usb/asix.c @@ -1437,6 +1437,10 @@ // Belkin F5D5055 USB_DEVICE(0x050d, 0x5055), .driver_info = (unsigned long) &ax88178_info, +}, { + // Apple USB Ethernet Adapter + USB_DEVICE(0x05ac, 0x1402), + .driver_info = (unsigned long) &ax88772_info, }, { }, // END }; --- linux-2.6.24.orig/drivers/net/bonding/bond_main.c +++ linux-2.6.24/drivers/net/bonding/bond_main.c @@ -4883,14 +4883,16 @@ down_write(&bonding_rwsem); /* Check to see if the bond already exists. */ - list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) - if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) { - printk(KERN_ERR DRV_NAME + if (name) { + list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) + if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) { + printk(KERN_ERR DRV_NAME ": cannot add bond %s; it already exists\n", - name); - res = -EPERM; - goto out_rtnl; - } + name); + res = -EPERM; + goto out_rtnl; + } + } bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "", ether_setup); --- linux-2.6.24.orig/drivers/block/Kconfig +++ linux-2.6.24/drivers/block/Kconfig @@ -429,6 +429,7 @@ tristate "Virtio block driver (EXPERIMENTAL)" depends on EXPERIMENTAL && VIRTIO ---help--- - This is the virtual block driver for lguest. Say Y or M. + This is the virtual block driver for virtio. It can be used with + lguest or QEMU based VMMs (like KVM or Xen). Say Y or M. endif # BLK_DEV --- linux-2.6.24.orig/drivers/block/virtio_blk.c +++ linux-2.6.24/drivers/block/virtio_blk.c @@ -7,8 +7,10 @@ #include #define VIRTIO_MAX_SG (3+MAX_PHYS_SEGMENTS) +#define PART_BITS 4 + +static int major, index; -static unsigned char virtblk_index = 'a'; struct virtio_blk { spinlock_t lock; @@ -36,7 +38,7 @@ struct virtio_blk_inhdr in_hdr; }; -static bool blk_done(struct virtqueue *vq) +static void blk_done(struct virtqueue *vq) { struct virtio_blk *vblk = vq->vdev->priv; struct virtblk_req *vbr; @@ -65,7 +67,6 @@ /* In case queue is stopped waiting for more buffers. */ blk_start_queue(vblk->disk->queue); spin_unlock_irqrestore(&vblk->lock, flags); - return true; } static bool do_req(struct request_queue *q, struct virtio_blk *vblk, @@ -153,20 +154,37 @@ (void __user *)data); } +/* We provide getgeo only to please some old bootloader/partitioning tools */ +static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) +{ + /* some standard values, similar to sd */ + geo->heads = 1 << 6; + geo->sectors = 1 << 5; + geo->cylinders = get_capacity(bd->bd_disk) >> 11; + return 0; +} + static struct block_device_operations virtblk_fops = { - .ioctl = virtblk_ioctl, - .owner = THIS_MODULE, + .ioctl = virtblk_ioctl, + .owner = THIS_MODULE, + .getgeo = virtblk_getgeo, }; +static int index_to_minor(int index) +{ + return index << PART_BITS; +} + static int virtblk_probe(struct virtio_device *vdev) { struct virtio_blk *vblk; - int err, major; - void *token; - unsigned int len; + int err; u64 cap; u32 v; + if (index_to_minor(index) >= 1 << MINORBITS) + return -ENOSPC; + vdev->priv = vblk = kmalloc(sizeof(*vblk), GFP_KERNEL); if (!vblk) { err = -ENOMEM; @@ -178,7 +196,7 @@ vblk->vdev = vdev; /* We expect one virtqueue, for output. */ - vblk->vq = vdev->config->find_vq(vdev, blk_done); + vblk->vq = vdev->config->find_vq(vdev, 0, blk_done); if (IS_ERR(vblk->vq)) { err = PTR_ERR(vblk->vq); goto out_free_vblk; @@ -190,17 +208,11 @@ goto out_free_vq; } - major = register_blkdev(0, "virtblk"); - if (major < 0) { - err = major; - goto out_mempool; - } - /* FIXME: How many partitions? How long is a piece of string? */ - vblk->disk = alloc_disk(1 << 4); + vblk->disk = alloc_disk(1 << PART_BITS); if (!vblk->disk) { err = -ENOMEM; - goto out_unregister_blkdev; + goto out_mempool; } vblk->disk->queue = blk_init_queue(do_virtblk_request, &vblk->lock); @@ -209,22 +221,33 @@ goto out_put_disk; } - sprintf(vblk->disk->disk_name, "vd%c", virtblk_index++); + if (index < 26) { + sprintf(vblk->disk->disk_name, "vd%c", 'a' + index % 26); + } else if (index < (26 + 1) * 26) { + sprintf(vblk->disk->disk_name, "vd%c%c", + 'a' + index / 26 - 1, 'a' + index % 26); + } else { + const unsigned int m1 = (index / 26 - 1) / 26 - 1; + const unsigned int m2 = (index / 26 - 1) % 26; + const unsigned int m3 = index % 26; + sprintf(vblk->disk->disk_name, "vd%c%c%c", + 'a' + m1, 'a' + m2, 'a' + m3); + } + vblk->disk->major = major; - vblk->disk->first_minor = 0; + vblk->disk->first_minor = index_to_minor(index); vblk->disk->private_data = vblk; vblk->disk->fops = &virtblk_fops; + vblk->disk->driverfs_dev = &vdev->dev; + index++; /* If barriers are supported, tell block layer that queue is ordered */ - token = vdev->config->find(vdev, VIRTIO_CONFIG_BLK_F, &len); - if (virtio_use_bit(vdev, token, len, VIRTIO_BLK_F_BARRIER)) + if (vdev->config->feature(vdev, VIRTIO_BLK_F_BARRIER)) blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL); - err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_CAPACITY, &cap); - if (err) { - dev_err(&vdev->dev, "Bad/missing capacity in config\n"); - goto out_cleanup_queue; - } + /* Host must always specify the capacity. */ + __virtio_config_val(vdev, offsetof(struct virtio_blk_config, capacity), + &cap); /* If capacity is too big, truncate with warning. */ if ((sector_t)cap != cap) { @@ -234,31 +257,25 @@ } set_capacity(vblk->disk, cap); - err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_SIZE_MAX, &v); + /* Host can optionally specify maximum segment size and number of + * segments. */ + err = virtio_config_val(vdev, VIRTIO_BLK_F_SIZE_MAX, + offsetof(struct virtio_blk_config, size_max), + &v); if (!err) blk_queue_max_segment_size(vblk->disk->queue, v); - else if (err != -ENOENT) { - dev_err(&vdev->dev, "Bad SIZE_MAX in config\n"); - goto out_cleanup_queue; - } - err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_SEG_MAX, &v); + err = virtio_config_val(vdev, VIRTIO_BLK_F_SEG_MAX, + offsetof(struct virtio_blk_config, seg_max), + &v); if (!err) blk_queue_max_hw_segments(vblk->disk->queue, v); - else if (err != -ENOENT) { - dev_err(&vdev->dev, "Bad SEG_MAX in config\n"); - goto out_cleanup_queue; - } add_disk(vblk->disk); return 0; -out_cleanup_queue: - blk_cleanup_queue(vblk->disk->queue); out_put_disk: put_disk(vblk->disk); -out_unregister_blkdev: - unregister_blkdev(major, "virtblk"); out_mempool: mempool_destroy(vblk->pool); out_free_vq: @@ -274,12 +291,16 @@ struct virtio_blk *vblk = vdev->priv; int major = vblk->disk->major; + /* Nothing should be pending. */ BUG_ON(!list_empty(&vblk->reqs)); + + /* Stop all the virtqueues. */ + vdev->config->reset(vdev); + blk_cleanup_queue(vblk->disk->queue); put_disk(vblk->disk); unregister_blkdev(major, "virtblk"); mempool_destroy(vblk->pool); - /* There should be nothing in the queue now, so no need to shutdown */ vdev->config->del_vq(vblk->vq); kfree(vblk); } @@ -299,11 +320,15 @@ static int __init init(void) { + major = register_blkdev(0, "virtblk"); + if (major < 0) + return major; return register_virtio_driver(&virtio_blk); } static void __exit fini(void) { + unregister_blkdev(major, "virtblk"); unregister_virtio_driver(&virtio_blk); } module_init(init); --- linux-2.6.24.orig/drivers/block/ub.c +++ linux-2.6.24/drivers/block/ub.c @@ -657,7 +657,6 @@ if ((cmd = ub_get_cmd(lun)) == NULL) return -1; memset(cmd, 0, sizeof(struct ub_scsi_cmd)); - sg_init_table(cmd->sgv, UB_MAX_REQ_SG); blkdev_dequeue_request(rq); @@ -668,6 +667,7 @@ /* * get scatterlist from block layer */ + sg_init_table(&urq->sgv[0], UB_MAX_REQ_SG); n_elem = blk_rq_map_sg(lun->disk->queue, rq, &urq->sgv[0]); if (n_elem < 0) { /* Impossible, because blk_rq_map_sg should not hit ENOMEM. */ --- linux-2.6.24.orig/drivers/video/fb_defio.c +++ linux-2.6.24/drivers/video/fb_defio.c @@ -88,6 +88,17 @@ .page_mkwrite = fb_deferred_io_mkwrite, }; +static int fb_deferred_io_set_page_dirty(struct page *page) +{ + if (!PageDirty(page)) + SetPageDirty(page); + return 0; +} + +static const struct address_space_operations fb_deferred_io_aops = { + .set_page_dirty = fb_deferred_io_set_page_dirty, +}; + static int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma) { vma->vm_ops = &fb_deferred_io_vm_ops; @@ -137,6 +148,14 @@ } EXPORT_SYMBOL_GPL(fb_deferred_io_init); +void fb_deferred_io_open(struct fb_info *info, + struct inode *inode, + struct file *file) +{ + file->f_mapping->a_ops = &fb_deferred_io_aops; +} +EXPORT_SYMBOL_GPL(fb_deferred_io_open); + void fb_deferred_io_cleanup(struct fb_info *info) { struct fb_deferred_io *fbdefio = info->fbdefio; --- linux-2.6.24.orig/drivers/video/chipsfb.c +++ linux-2.6.24/drivers/video/chipsfb.c @@ -459,7 +459,7 @@ if (state.event == pdev->dev.power.power_state.event) return 0; - if (state.event != PM_EVENT_SUSPEND) + if (!(state.event & PM_EVENT_SLEEP)) goto done; acquire_console_sem(); --- linux-2.6.24.orig/drivers/video/fbmem.c +++ linux-2.6.24/drivers/video/fbmem.c @@ -1315,6 +1315,10 @@ if (res) module_put(info->fbops->owner); } +#ifdef CONFIG_FB_DEFERRED_IO + if (info->fbdefio) + fb_deferred_io_open(info, inode, file); +#endif return res; } @@ -1521,6 +1525,7 @@ static void __exit fbmem_exit(void) { + remove_proc_entry("fb", NULL); class_destroy(fb_class); unregister_chrdev(FB_MAJOR, "fb"); } --- linux-2.6.24.orig/drivers/video/Kconfig +++ linux-2.6.24/drivers/video/Kconfig @@ -629,8 +629,8 @@ If unsure, say N. config FB_VESA - bool "VESA VGA graphics support" - depends on (FB = y) && X86 + tristate "VESA VGA graphics support" + depends on FB && X86 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT --- linux-2.6.24.orig/drivers/video/vesafb.c +++ linux-2.6.24/drivers/video/vesafb.c @@ -28,6 +28,12 @@ #define dac_reg (0x3c8) #define dac_val (0x3c9) +struct vesafb_info +{ + u32 pseudo_palette[256]; + int mtrr_hdl; +}; + /* --------------------------------------------------------------------- */ static struct fb_var_screeninfo vesafb_defined __initdata = { @@ -47,16 +53,37 @@ .accel = FB_ACCEL_NONE, }; +#ifndef MODULE static int inverse __read_mostly; +#endif static int mtrr __read_mostly; /* disable mtrr */ static int vram_remap __initdata; /* Set amount of memory to be used */ static int vram_total __initdata; /* Set total amount of memory */ static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */ +static int redraw __read_mostly; static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */ +static int ywrap __read_mostly; static void (*pmi_start)(void) __read_mostly; static void (*pmi_pal) (void) __read_mostly; static int depth __read_mostly; static int vga_compat __read_mostly; + +module_param(redraw, bool, 0); +module_param(ypan, bool, 0); +module_param(ywrap, bool, 0); +module_param_named(vgapal, pmi_setpal, invbool, 0); +MODULE_PARM_DESC(vgapal, "Use VGA for setting palette (default)"); +module_param_named(pmipal, pmi_setpal, bool, 0); +MODULE_PARM_DESC(pmipal, "Use PMI for setting palette"); +module_param(mtrr, bool, 0); +MODULE_PARM_DESC(mtrr, "Enable MTRR support (default)"); +module_param_named(nomtrr, mtrr, invbool, 0); +MODULE_PARM_DESC(nomtrr, "Disable MTRR support"); +module_param(vram_remap, int, 0); +MODULE_PARM_DESC(vram_remap, "Set total amount of memory to be used"); +module_param(vram_total, int, 0); +MODULE_PARM_DESC(vram_total, "Total amount of memory"); + /* --------------------------------------------------------------------- */ static int vesafb_pan_display(struct fb_var_screeninfo *var, @@ -183,6 +210,7 @@ .fb_imageblit = cfb_imageblit, }; +#ifndef MODULE static int __init vesafb_setup(char *options) { char *this_opt; @@ -216,6 +244,7 @@ } return 0; } +#endif static int __init vesafb_probe(struct platform_device *dev) { @@ -463,8 +492,28 @@ return err; } +static int __exit vesafb_remove(struct platform_device *device) +{ + struct fb_info *info = dev_get_drvdata(&device->dev); + + unregister_framebuffer(info); +#ifdef CONFIG_MTRR + { + struct vesafb_info *vfb_info = (struct vesafb_info *) info->par; + if (vfb_info->mtrr_hdl >= 0) + mtrr_del(vfb_info->mtrr_hdl, 0, 0); + } +#endif + iounmap(info->screen_base); + framebuffer_release(info); + release_mem_region(vesafb_fix.smem_start, vesafb_fix.smem_len); + + return 0; +} + static struct platform_driver vesafb_driver = { .probe = vesafb_probe, + .remove = vesafb_remove, .driver = { .name = "vesafb", }, @@ -475,11 +524,18 @@ static int __init vesafb_init(void) { int ret; +#ifndef MODULE char *option = NULL; /* ignore error return of fb_get_options */ fb_get_options("vesafb", &option); vesafb_setup(option); +#else + if (redraw) + ypan = 0; + if (ywrap) + ypan = 2; +#endif ret = platform_driver_register(&vesafb_driver); if (!ret) { @@ -498,6 +554,14 @@ return ret; } + +static void __exit vesafb_exit(void) +{ + platform_device_unregister(vesafb_device); + platform_driver_unregister(&vesafb_driver); +} + module_init(vesafb_init); +module_exit(vesafb_exit); MODULE_LICENSE("GPL"); --- linux-2.6.24.orig/drivers/video/nvidia/nvidia.c +++ linux-2.6.24/drivers/video/nvidia/nvidia.c @@ -1048,7 +1048,7 @@ acquire_console_sem(); par->pm_state = mesg.event; - if (mesg.event == PM_EVENT_SUSPEND) { + if (mesg.event & PM_EVENT_SLEEP) { fb_set_suspend(info, 1); nvidiafb_blank(FB_BLANK_POWERDOWN, info); nvidia_write_regs(par, &par->SavedReg); --- linux-2.6.24.orig/drivers/scsi/scsi_lib.c +++ linux-2.6.24/drivers/scsi/scsi_lib.c @@ -298,7 +298,6 @@ page = sg_page(sg); off = sg->offset; len = sg->length; - data_len += len; while (len > 0 && data_len > 0) { /* --- linux-2.6.24.orig/drivers/scsi/gdth.h +++ linux-2.6.24/drivers/scsi/gdth.h @@ -915,6 +915,7 @@ struct gdth_cmndinfo { /* per-command private info */ int index; int internal_command; /* don't call scsi_done */ + gdth_cmd_str *internal_cmd_str; /* crier for internal messages*/ dma_addr_t sense_paddr; /* sense dma-addr */ unchar priority; int timeout; --- linux-2.6.24.orig/drivers/scsi/sd.c +++ linux-2.6.24/drivers/scsi/sd.c @@ -907,6 +907,7 @@ unsigned int xfer_size = SCpnt->request_bufflen; unsigned int good_bytes = result ? 0 : xfer_size; u64 start_lba = SCpnt->request->sector; + u64 end_lba = SCpnt->request->sector + (xfer_size / 512); u64 bad_lba; struct scsi_sense_hdr sshdr; int sense_valid = 0; @@ -945,26 +946,23 @@ goto out; if (xfer_size <= SCpnt->device->sector_size) goto out; - switch (SCpnt->device->sector_size) { - case 256: + if (SCpnt->device->sector_size < 512) { + /* only legitimate sector_size here is 256 */ start_lba <<= 1; - break; - case 512: - break; - case 1024: - start_lba >>= 1; - break; - case 2048: - start_lba >>= 2; - break; - case 4096: - start_lba >>= 3; - break; - default: - /* Print something here with limiting frequency. */ - goto out; - break; + end_lba <<= 1; + } else { + /* be careful ... don't want any overflows */ + u64 factor = SCpnt->device->sector_size / 512; + do_div(start_lba, factor); + do_div(end_lba, factor); } + + if (bad_lba < start_lba || bad_lba >= end_lba) + /* the bad lba was reported incorrectly, we have + * no idea where the error is + */ + goto out; + /* This computation should always be done in terms of * the resolution of the device's medium. */ @@ -1815,8 +1813,7 @@ goto done; } - if (mesg.event == PM_EVENT_SUSPEND && - sdkp->device->manage_start_stop) { + if ((mesg.event & PM_EVENT_SLEEP) && sdkp->device->manage_start_stop) { sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); ret = sd_start_stop_device(sdkp, 0); } --- linux-2.6.24.orig/drivers/scsi/ips.c +++ linux-2.6.24/drivers/scsi/ips.c @@ -1580,7 +1580,7 @@ METHOD_TRACE("ips_make_passthru", 1); scsi_for_each_sg(SC, sg, scsi_sg_count(SC), i) - length += sg[i].length; + length += sg->length; if (length < sizeof (ips_passthru_t)) { /* wrong size */ @@ -6842,13 +6842,10 @@ if (request_irq(ha->irq, do_ipsintr, IRQF_SHARED, ips_name, ha)) { IPS_PRINTK(KERN_WARNING, ha->pcidev, "Unable to install interrupt handler\n"); - scsi_host_put(sh); - return -1; + goto err_out_sh; } kfree(oldha); - ips_sh[index] = sh; - ips_ha[index] = ha; /* Store away needed values for later use */ sh->io_port = ha->io_addr; @@ -6867,10 +6864,21 @@ sh->max_channel = ha->nbus - 1; sh->can_queue = ha->max_cmds - 1; - scsi_add_host(sh, NULL); + if (scsi_add_host(sh, &ha->pcidev->dev)) + goto err_out; + + ips_sh[index] = sh; + ips_ha[index] = ha; + scsi_scan_host(sh); return 0; + +err_out: + free_irq(ha->pcidev->irq, ha); +err_out_sh: + scsi_host_put(sh); + return -1; } /*---------------------------------------------------------------------------*/ --- linux-2.6.24.orig/drivers/scsi/mesh.c +++ linux-2.6.24/drivers/scsi/mesh.c @@ -1759,6 +1759,7 @@ switch (mesg.event) { case PM_EVENT_SUSPEND: + case PM_EVENT_HIBERNATE: case PM_EVENT_FREEZE: break; default: --- linux-2.6.24.orig/drivers/scsi/gdth.c +++ linux-2.6.24/drivers/scsi/gdth.c @@ -160,7 +160,7 @@ static void gdth_clear_events(void); static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, - char *buffer, ushort count, int to_buffer); + char *buffer, ushort count); static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp); static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive); @@ -183,7 +183,6 @@ unsigned int cmd, unsigned long arg); static void gdth_flush(gdth_ha_str *ha); -static int gdth_halt(struct notifier_block *nb, ulong event, void *buf); static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)); static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp, struct gdth_cmndinfo *cmndinfo); @@ -418,12 +417,6 @@ #include "gdth_proc.h" #include "gdth_proc.c" -/* notifier block to get a notify on system shutdown/halt/reboot */ -static struct notifier_block gdth_notifier = { - gdth_halt, NULL, 0 -}; -static int notifier_disabled = 0; - static gdth_ha_str *gdth_find_ha(int hanum) { gdth_ha_str *ha; @@ -446,8 +439,8 @@ for (i=0; icmndinfo[i].index == 0) { priv = &ha->cmndinfo[i]; - priv->index = i+1; memset(priv, 0, sizeof(*priv)); + priv->index = i+1; break; } } @@ -494,7 +487,6 @@ gdth_ha_str *ha = shost_priv(sdev->host); Scsi_Cmnd *scp; struct gdth_cmndinfo cmndinfo; - struct scatterlist one_sg; DECLARE_COMPLETION_ONSTACK(wait); int rval; @@ -508,13 +500,10 @@ /* use request field to save the ptr. to completion struct. */ scp->request = (struct request *)&wait; scp->timeout_per_command = timeout*HZ; - sg_init_one(&one_sg, gdtcmd, sizeof(*gdtcmd)); - gdth_set_sglist(scp, &one_sg); - gdth_set_sg_count(scp, 1); - gdth_set_bufflen(scp, sizeof(*gdtcmd)); scp->cmd_len = 12; memcpy(scp->cmnd, cmnd, 12); cmndinfo.priority = IOCTL_PRI; + cmndinfo.internal_cmd_str = gdtcmd; cmndinfo.internal_command = 1; TRACE(("__gdth_execute() cmd 0x%x\n", scp->cmnd[0])); @@ -2355,7 +2344,7 @@ * buffers, kmap_atomic() as needed. */ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, - char *buffer, ushort count, int to_buffer) + char *buffer, ushort count) { ushort cpcount,i, max_sg = gdth_sg_count(scp); ushort cpsum,cpnow; @@ -2381,10 +2370,7 @@ } local_irq_save(flags); address = kmap_atomic(sg_page(sl), KM_BIO_SRC_IRQ) + sl->offset; - if (to_buffer) - memcpy(buffer, address, cpnow); - else - memcpy(address, buffer, cpnow); + memcpy(address, buffer, cpnow); flush_dcache_page(sg_page(sl)); kunmap_atomic(address, KM_BIO_SRC_IRQ); local_irq_restore(flags); @@ -2438,7 +2424,7 @@ strcpy(inq.vendor,ha->oem_name); sprintf(inq.product,"Host Drive #%02d",t); strcpy(inq.revision," "); - gdth_copy_internal_data(ha, scp, (char*)&inq, sizeof(gdth_inq_data), 0); + gdth_copy_internal_data(ha, scp, (char*)&inq, sizeof(gdth_inq_data)); break; case REQUEST_SENSE: @@ -2448,7 +2434,7 @@ sd.key = NO_SENSE; sd.info = 0; sd.add_length= 0; - gdth_copy_internal_data(ha, scp, (char*)&sd, sizeof(gdth_sense_data), 0); + gdth_copy_internal_data(ha, scp, (char*)&sd, sizeof(gdth_sense_data)); break; case MODE_SENSE: @@ -2460,7 +2446,7 @@ mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16; mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8; mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff); - gdth_copy_internal_data(ha, scp, (char*)&mpd, sizeof(gdth_modep_data), 0); + gdth_copy_internal_data(ha, scp, (char*)&mpd, sizeof(gdth_modep_data)); break; case READ_CAPACITY: @@ -2470,7 +2456,7 @@ else rdc.last_block_no = cpu_to_be32(ha->hdr[t].size-1); rdc.block_length = cpu_to_be32(SECTOR_SIZE); - gdth_copy_internal_data(ha, scp, (char*)&rdc, sizeof(gdth_rdcap_data), 0); + gdth_copy_internal_data(ha, scp, (char*)&rdc, sizeof(gdth_rdcap_data)); break; case SERVICE_ACTION_IN: @@ -2482,7 +2468,7 @@ rdc16.last_block_no = cpu_to_be64(ha->hdr[t].size-1); rdc16.block_length = cpu_to_be32(SECTOR_SIZE); gdth_copy_internal_data(ha, scp, (char*)&rdc16, - sizeof(gdth_rdcap16_data), 0); + sizeof(gdth_rdcap16_data)); } else { scp->result = DID_ABORT << 16; } @@ -2852,6 +2838,7 @@ static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) { register gdth_cmd_str *cmdp; + struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); int cmd_index; cmdp= ha->pccb; @@ -2860,7 +2847,7 @@ if (ha->type==GDT_EISA && ha->cmd_cnt>0) return 0; - gdth_copy_internal_data(ha, scp, (char *)cmdp, sizeof(gdth_cmd_str), 1); + *cmdp = *cmndinfo->internal_cmd_str; cmdp->RequestBuffer = scp; /* search free command index */ @@ -3793,6 +3780,8 @@ gdth_ha_str *ha; ulong flags; + BUG_ON(list_empty(&gdth_instances)); + ha = list_first_entry(&gdth_instances, gdth_ha_str, list); spin_lock_irqsave(&ha->smp_lock, flags); @@ -4668,45 +4657,6 @@ } } -/* shutdown routine */ -static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) -{ - gdth_ha_str *ha; -#ifndef __alpha__ - gdth_cmd_str gdtcmd; - char cmnd[MAX_COMMAND_SIZE]; -#endif - - if (notifier_disabled) - return NOTIFY_OK; - - TRACE2(("gdth_halt() event %d\n",(int)event)); - if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF) - return NOTIFY_DONE; - - notifier_disabled = 1; - printk("GDT-HA: Flushing all host drives .. "); - list_for_each_entry(ha, &gdth_instances, list) { - gdth_flush(ha); - -#ifndef __alpha__ - /* controller reset */ - memset(cmnd, 0xff, MAX_COMMAND_SIZE); - gdtcmd.BoardNode = LOCALBOARD; - gdtcmd.Service = CACHESERVICE; - gdtcmd.OpCode = GDT_RESET; - TRACE2(("gdth_halt(): reset controller %d\n", ha->hanum)); - gdth_execute(ha->shost, &gdtcmd, cmnd, 10, NULL); -#endif - } - printk("Done.\n"); - -#ifdef GDTH_STATISTICS - del_timer(&gdth_timer); -#endif - return NOTIFY_OK; -} - /* configure lun */ static int gdth_slave_configure(struct scsi_device *sdev) { @@ -4838,6 +4788,9 @@ if (error) goto out_free_coal_stat; list_add_tail(&ha->list, &gdth_instances); + + scsi_scan_host(shp); + return 0; out_free_coal_stat: @@ -4965,6 +4918,9 @@ if (error) goto out_free_coal_stat; list_add_tail(&ha->list, &gdth_instances); + + scsi_scan_host(shp); + return 0; out_free_ccb_phys: @@ -5102,6 +5058,9 @@ if (error) goto out_free_coal_stat; list_add_tail(&ha->list, &gdth_instances); + + scsi_scan_host(shp); + return 0; out_free_coal_stat: @@ -5132,13 +5091,13 @@ scsi_remove_host(shp); + gdth_flush(ha); + if (ha->sdev) { scsi_free_host_dev(ha->sdev); ha->sdev = NULL; } - gdth_flush(ha); - if (shp->irq) free_irq(shp->irq,ha); @@ -5164,6 +5123,24 @@ scsi_host_put(shp); } +static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) +{ + gdth_ha_str *ha; + + TRACE2(("gdth_halt() event %d\n", (int)event)); + if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF) + return NOTIFY_DONE; + + list_for_each_entry(ha, &gdth_instances, list) + gdth_flush(ha); + + return NOTIFY_OK; +} + +static struct notifier_block gdth_notifier = { + gdth_halt, NULL, 0 +}; + static int __init gdth_init(void) { if (disable) { @@ -5226,7 +5203,6 @@ add_timer(&gdth_timer); #endif major = register_chrdev(0,"gdth", &gdth_fops); - notifier_disabled = 0; register_reboot_notifier(&gdth_notifier); gdth_polling = FALSE; return 0; @@ -5236,14 +5212,15 @@ { gdth_ha_str *ha; - list_for_each_entry(ha, &gdth_instances, list) - gdth_remove_one(ha); + unregister_chrdev(major, "gdth"); + unregister_reboot_notifier(&gdth_notifier); #ifdef GDTH_STATISTICS - del_timer(&gdth_timer); + del_timer_sync(&gdth_timer); #endif - unregister_chrdev(major,"gdth"); - unregister_reboot_notifier(&gdth_notifier); + + list_for_each_entry(ha, &gdth_instances, list) + gdth_remove_one(ha); } module_init(gdth_init); --- linux-2.6.24.orig/drivers/scsi/advansys.c +++ linux-2.6.24/drivers/scsi/advansys.c @@ -566,7 +566,7 @@ ASC_SCSI_BIT_ID_TYPE unit_not_ready; ASC_SCSI_BIT_ID_TYPE queue_full_or_busy; ASC_SCSI_BIT_ID_TYPE start_motor; - uchar overrun_buf[ASC_OVERRUN_BSIZE] __aligned(8); + uchar *overrun_buf; dma_addr_t overrun_dma; uchar scsi_reset_wait; uchar chip_no; @@ -6439,7 +6439,7 @@ i += 2; len += 2; } else { - unsigned char off = buf[i] * 2; + unsigned int off = buf[i] * 2; unsigned short word = (buf[off + 1] << 8) | buf[off]; AdvWriteWordAutoIncLram(iop_base, word); len += 2; @@ -13833,6 +13833,12 @@ */ if (ASC_NARROW_BOARD(boardp)) { ASC_DBG(2, "AscInitAsc1000Driver()\n"); + + asc_dvc_varp->overrun_buf = kzalloc(ASC_OVERRUN_BSIZE, GFP_KERNEL); + if (!asc_dvc_varp->overrun_buf) { + ret = -ENOMEM; + goto err_free_wide_mem; + } warn_code = AscInitAsc1000Driver(asc_dvc_varp); if (warn_code || asc_dvc_varp->err_code) { @@ -13840,8 +13846,10 @@ "warn 0x%x, error 0x%x\n", asc_dvc_varp->init_state, warn_code, asc_dvc_varp->err_code); - if (asc_dvc_varp->err_code) + if (asc_dvc_varp->err_code) { ret = -ENODEV; + kfree(asc_dvc_varp->overrun_buf); + } } } else { if (advansys_wide_init_chip(shost)) @@ -13894,6 +13902,7 @@ dma_unmap_single(board->dev, board->dvc_var.asc_dvc_var.overrun_dma, ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE); + kfree(board->dvc_var.asc_dvc_var.overrun_buf); } else { iounmap(board->ioremap_addr); advansys_wide_free_mem(board); --- linux-2.6.24.orig/drivers/scsi/scsi_transport_fc.c +++ linux-2.6.24/drivers/scsi/scsi_transport_fc.c @@ -478,9 +478,29 @@ MODULE_PARM_DESC(dev_loss_tmo, "Maximum number of seconds that the FC transport should" " insulate the loss of a remote port. Once this value is" - " exceeded, the scsi target is removed. Value should be" + " exceeded, the scsi target may be removed. Reference the" + " remove_on_dev_loss module parameter. Value should be" " between 1 and SCSI_DEVICE_BLOCK_MAX_TIMEOUT."); +/* + * remove_on_dev_loss: controls whether the transport will + * remove a scsi target after the device loss timer expires. + * Removal on disconnect is modeled after the USB subsystem + * and expects subsystems layered on SCSI to be aware of + * potential device loss and handle it appropriately. However, + * many subsystems do not support device removal, leaving situations + * where structure references may remain, causing new device + * name assignments, etc., if the target returns. + */ +static unsigned int fc_remove_on_dev_loss = 0; +module_param_named(remove_on_dev_loss, fc_remove_on_dev_loss, + int, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(remove_on_dev_loss, + "Boolean. When the device loss timer fires, this variable" + " controls whether the scsi infrastructure for the target" + " device is removed. Values: zero means do not remove," + " non-zero means remove. Default is zero."); + /** * Netlink Infrastructure **/ @@ -2297,7 +2317,8 @@ if (i->f->terminate_rport_io) i->f->terminate_rport_io(rport); - scsi_remove_target(&rport->dev); + if (fc_remove_on_dev_loss) + scsi_remove_target(&rport->dev); } @@ -2934,9 +2955,13 @@ return; } - dev_printk(KERN_ERR, &rport->dev, - "blocked FC remote port time out: removing target and " - "saving binding\n"); + if (fc_remove_on_dev_loss) + dev_printk(KERN_ERR, &rport->dev, + "blocked FC remote port time out: removing target and " + "saving binding\n"); + else + dev_printk(KERN_ERR, &rport->dev, + "blocked FC remote port time out: saving binding\n"); list_move_tail(&rport->peers, &fc_host->rport_bindings); --- linux-2.6.24.orig/drivers/scsi/gdth_proc.c +++ linux-2.6.24/drivers/scsi/gdth_proc.c @@ -694,15 +694,13 @@ { ulong flags; - spin_lock_irqsave(&ha->smp_lock, flags); - if (buf == ha->pscratch) { + spin_lock_irqsave(&ha->smp_lock, flags); ha->scratch_busy = FALSE; + spin_unlock_irqrestore(&ha->smp_lock, flags); } else { pci_free_consistent(ha->pdev, size, buf, paddr); } - - spin_unlock_irqrestore(&ha->smp_lock, flags); } #ifdef GDTH_IOCTL_PROC --- linux-2.6.24.orig/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c +++ linux-2.6.24/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c @@ -155,7 +155,7 @@ pci_save_state(pdev); pci_disable_device(pdev); - if (mesg.event == PM_EVENT_SUSPEND) + if (mesg.event & PM_EVENT_SLEEP) pci_set_power_state(pdev, PCI_D3hot); return rc; --- linux-2.6.24.orig/drivers/scsi/aic7xxx/aic79xx_osm_pci.c +++ linux-2.6.24/drivers/scsi/aic7xxx/aic79xx_osm_pci.c @@ -110,7 +110,7 @@ pci_save_state(pdev); pci_disable_device(pdev); - if (mesg.event == PM_EVENT_SUSPEND) + if (mesg.event & PM_EVENT_SLEEP) pci_set_power_state(pdev, PCI_D3hot); return rc; --- linux-2.6.24.orig/drivers/scsi/aic94xx/aic94xx_scb.c +++ linux-2.6.24/drivers/scsi/aic94xx/aic94xx_scb.c @@ -458,13 +458,19 @@ tc_abort = le16_to_cpu(tc_abort); list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) { - struct sas_task *task = ascb->uldd_task; + struct sas_task *task = a->uldd_task; + + if (a->tc_index != tc_abort) + continue; - if (task && a->tc_index == tc_abort) { + if (task) { failed_dev = task->dev; sas_task_abort(task); - break; + } else { + ASD_DPRINTK("R_T_A for non TASK scb 0x%x\n", + a->scb->header.opcode); } + break; } if (!failed_dev) { @@ -478,7 +484,7 @@ * that the EH will wake up and do something. */ list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) { - struct sas_task *task = ascb->uldd_task; + struct sas_task *task = a->uldd_task; if (task && task->dev == failed_dev && --- linux-2.6.24.orig/drivers/scsi/arcmsr/arcmsr_hba.c +++ linux-2.6.24/drivers/scsi/arcmsr/arcmsr_hba.c @@ -1380,17 +1380,16 @@ switch(controlcode) { case ARCMSR_MESSAGE_READ_RQBUFFER: { - unsigned long *ver_addr; - dma_addr_t buf_handle; + unsigned char *ver_addr; uint8_t *pQbuffer, *ptmpQbuffer; int32_t allxfer_len = 0; - ver_addr = pci_alloc_consistent(acb->pdev, 1032, &buf_handle); + ver_addr = kmalloc(1032, GFP_ATOMIC); if (!ver_addr) { retvalue = ARCMSR_MESSAGE_FAIL; goto message_out; } - ptmpQbuffer = (uint8_t *) ver_addr; + ptmpQbuffer = ver_addr; while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex) && (allxfer_len < 1031)) { pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; @@ -1419,25 +1418,24 @@ } arcmsr_iop_message_read(acb); } - memcpy(pcmdmessagefld->messagedatabuffer, (uint8_t *)ver_addr, allxfer_len); + memcpy(pcmdmessagefld->messagedatabuffer, ver_addr, allxfer_len); pcmdmessagefld->cmdmessage.Length = allxfer_len; pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; - pci_free_consistent(acb->pdev, 1032, ver_addr, buf_handle); + kfree(ver_addr); } break; case ARCMSR_MESSAGE_WRITE_WQBUFFER: { - unsigned long *ver_addr; - dma_addr_t buf_handle; + unsigned char *ver_addr; int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; uint8_t *pQbuffer, *ptmpuserbuffer; - ver_addr = pci_alloc_consistent(acb->pdev, 1032, &buf_handle); + ver_addr = kmalloc(1032, GFP_ATOMIC); if (!ver_addr) { retvalue = ARCMSR_MESSAGE_FAIL; goto message_out; } - ptmpuserbuffer = (uint8_t *)ver_addr; + ptmpuserbuffer = ver_addr; user_len = pcmdmessagefld->cmdmessage.Length; memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer, user_len); wqbuf_lastindex = acb->wqbuf_lastindex; @@ -1483,7 +1481,7 @@ retvalue = ARCMSR_MESSAGE_FAIL; } } - pci_free_consistent(acb->pdev, 1032, ver_addr, buf_handle); + kfree(ver_addr); } break; --- linux-2.6.24.orig/drivers/uio/uio.c +++ linux-2.6.24/drivers/uio/uio.c @@ -447,6 +447,8 @@ vma->vm_flags |= VM_IO | VM_RESERVED; + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + return remap_pfn_range(vma, vma->vm_start, idev->info->mem[mi].addr >> PAGE_SHIFT, --- linux-2.6.24.orig/drivers/message/fusion/mptbase.c +++ linux-2.6.24/drivers/message/fusion/mptbase.c @@ -2844,6 +2844,16 @@ pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus); pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo); pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices); + /* + * VMware emulation is broken, its PortFact's MaxDevices reports value + * programmed by IOC Init, so if you program IOC Init to 256 (which is 0, + * as that field is only 8 bit), it reports back 0 in port facts, instead + * of 256... And unfortunately using 256 triggers another bug in the + * code (parallel SCSI can have only 16 devices). + */ + if (pfacts->MaxDevices == 0) { + pfacts->MaxDevices = 16; + } pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID); pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags); pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers); --- linux-2.6.24.orig/drivers/message/fusion/mptsas.c +++ linux-2.6.24/drivers/message/fusion/mptsas.c @@ -1699,6 +1699,11 @@ if (error) goto out_free_consistent; + if (!buffer->NumPhys) { + error = -ENODEV; + goto out_free_consistent; + } + /* save config data */ port_info->num_phys = buffer->NumPhys; port_info->phy_info = kcalloc(port_info->num_phys, --- linux-2.6.24.orig/drivers/firmware/Kconfig +++ linux-2.6.24/drivers/firmware/Kconfig @@ -17,6 +17,15 @@ obscure configurations. Most disk controller BIOS vendors do not yet implement this feature. +config EDD_OFF + bool "Sets default behavior for EDD detection to off" + depends on EDD + default n + help + Say Y if you want EDD disabled by default, even though it is compiled into the + kernel. Say N if you want EDD enabled by default. EDD can be dynamically set + using the kernel parameter 'edd={on|off}'. + config EFI_VARS tristate "EFI Variable Support via sysfs" depends on EFI --- linux-2.6.24.orig/drivers/firmware/dmi_scan.c +++ linux-2.6.24/drivers/firmware/dmi_scan.c @@ -219,7 +219,7 @@ dev->name = "IPMI controller"; dev->device_data = data; - list_add(&dev->list, &dmi_devices); + list_add_tail(&dev->list, &dmi_devices); } /* --- linux-2.6.24.orig/drivers/firmware/dcdbas.c +++ linux-2.6.24/drivers/firmware/dcdbas.c @@ -658,4 +658,5 @@ MODULE_VERSION(DRIVER_VERSION); MODULE_AUTHOR("Dell Inc."); MODULE_LICENSE("GPL"); - +/* Any System or BIOS claiming to be by Dell */ +MODULE_ALIAS("dmi:*:[bs]vnD[Ee][Ll][Ll]*:*"); --- linux-2.6.24.orig/drivers/dma/ioat_dma.c +++ linux-2.6.24/drivers/dma/ioat_dma.c @@ -726,6 +726,7 @@ if (new) { new->len = len; + new->async_tx.ack = 0; return &new->async_tx; } else return NULL; @@ -749,6 +750,7 @@ if (new) { new->len = len; + new->async_tx.ack = 0; return &new->async_tx; } else return NULL; --- linux-2.6.24.orig/drivers/usb/class/cdc-acm.c +++ linux-2.6.24/drivers/usb/class/cdc-acm.c @@ -1183,6 +1183,9 @@ { USB_DEVICE(0x22b8, 0x7000), /* Motorola Q Phone */ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ }, + { USB_DEVICE(0x0e8d,0x0003), /* MediaTek Inc MT6227 */ + .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ + }, /* control interfaces with various AT-command sets */ { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, --- linux-2.6.24.orig/drivers/usb/class/usblp.c +++ linux-2.6.24/drivers/usb/class/usblp.c @@ -428,6 +428,7 @@ usblp->rcomplete = 0; if (handle_bidir(usblp) < 0) { + usb_autopm_put_interface(intf); usblp->used = 0; file->private_data = NULL; retval = -EIO; --- linux-2.6.24.orig/drivers/usb/core/message.c +++ linux-2.6.24/drivers/usb/core/message.c @@ -1189,7 +1189,10 @@ return -EINVAL; } - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + if (dev->quirks & USB_QUIRK_NO_SET_INTF) + ret = -EPIPE; + else + ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE, alternate, interface, NULL, 0, 5000); --- linux-2.6.24.orig/drivers/usb/core/hub.c +++ linux-2.6.24/drivers/usb/core/hub.c @@ -327,6 +327,9 @@ return status; } +static int hub_port_status(struct usb_hub *hub, int port1, + u16 *status, u16 *change); + static void kick_khubd(struct usb_hub *hub) { unsigned long flags; @@ -602,6 +605,81 @@ kick_khubd(hub); } +#define HUB_RESET 1 +#define HUB_RESUME 2 +#define HUB_RESET_RESUME 3 + +#ifdef CONFIG_PM + +static void hub_restart(struct usb_hub *hub, int type) +{ + struct usb_device *hdev = hub->hdev; + int port1; + + /* Check each of the children to see if they require + * USB-PERSIST handling or disconnection. Also check + * each unoccupied port to make sure it is still disabled. + */ + for (port1 = 1; port1 <= hdev->maxchild; ++port1) { + struct usb_device *udev = hdev->children[port1-1]; + int status = 0; + u16 portstatus, portchange; + + if (!udev || udev->state == USB_STATE_NOTATTACHED) { + if (type != HUB_RESET) { + status = hub_port_status(hub, port1, + &portstatus, &portchange); + if (status == 0 && (portstatus & + USB_PORT_STAT_ENABLE)) + clear_port_feature(hdev, port1, + USB_PORT_FEAT_ENABLE); + } + continue; + } + + /* Was the power session lost while we were suspended? */ + switch (type) { + case HUB_RESET_RESUME: + portstatus = 0; + portchange = USB_PORT_STAT_C_CONNECTION; + break; + + case HUB_RESET: + case HUB_RESUME: + status = hub_port_status(hub, port1, + &portstatus, &portchange); + break; + } + + /* For "USB_PERSIST"-enabled children we must + * mark the child device for reset-resume and + * turn off the various status changes to prevent + * khubd from disconnecting it later. + */ + if (USB_PERSIST && udev->persist_enabled && status == 0 && + !(portstatus & USB_PORT_STAT_ENABLE)) { + if (portchange & USB_PORT_STAT_C_ENABLE) + clear_port_feature(hub->hdev, port1, + USB_PORT_FEAT_C_ENABLE); + if (portchange & USB_PORT_STAT_C_CONNECTION) + clear_port_feature(hub->hdev, port1, + USB_PORT_FEAT_C_CONNECTION); + udev->reset_resume = 1; + } + + /* Otherwise for a reset_resume we must disconnect the child, + * but as we may not lock the child device here + * we have to do a "logical" disconnect. + */ + else if (type == HUB_RESET_RESUME) + hub_port_logical_disconnect(hub, port1); + } + + hub_activate(hub); +} + +#endif /* CONFIG_PM */ + /* caller has locked the hub device */ static int hub_pre_reset(struct usb_interface *intf) { @@ -1989,49 +2067,20 @@ static int hub_resume(struct usb_interface *intf) { - struct usb_hub *hub = usb_get_intfdata (intf); - - dev_dbg(&intf->dev, "%s\n", __FUNCTION__); + struct usb_hub *hub = usb_get_intfdata(intf); - /* tell khubd to look for changes on this hub */ - hub_activate(hub); + dev_dbg(&intf->dev, "%s\n", __func__); + hub_restart(hub, HUB_RESUME); return 0; } static int hub_reset_resume(struct usb_interface *intf) { struct usb_hub *hub = usb_get_intfdata(intf); - struct usb_device *hdev = hub->hdev; - int port1; + dev_dbg(&intf->dev, "%s\n", __func__); hub_power_on(hub); - - for (port1 = 1; port1 <= hdev->maxchild; ++port1) { - struct usb_device *child = hdev->children[port1-1]; - - if (child) { - - /* For "USB_PERSIST"-enabled children we must - * mark the child device for reset-resume and - * turn off the connect-change status to prevent - * khubd from disconnecting it later. - */ - if (USB_PERSIST && child->persist_enabled) { - child->reset_resume = 1; - clear_port_feature(hdev, port1, - USB_PORT_FEAT_C_CONNECTION); - - /* Otherwise we must disconnect the child, - * but as we may not lock the child device here - * we have to do a "logical" disconnect. - */ - } else { - hub_port_logical_disconnect(hub, port1); - } - } - } - - hub_activate(hub); + hub_restart(hub, HUB_RESET_RESUME); return 0; } --- linux-2.6.24.orig/drivers/usb/core/quirks.c +++ linux-2.6.24/drivers/usb/core/quirks.c @@ -39,6 +39,9 @@ /* M-Systems Flash Disk Pioneers */ { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, + /* X-Rite/Gretag-Macbeth Eye-One Pro display colorimeter */ + { USB_DEVICE(0x0971, 0x2000), .driver_info = USB_QUIRK_NO_SET_INTF }, + /* Philips PSC805 audio device */ { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME }, --- linux-2.6.24.orig/drivers/usb/storage/transport.c +++ linux-2.6.24/drivers/usb/storage/transport.c @@ -1010,7 +1010,8 @@ US_DEBUGP("Bulk Status S 0x%x T 0x%x R %u Stat 0x%x\n", le32_to_cpu(bcs->Signature), bcs->Tag, residue, bcs->Status); - if (bcs->Tag != us->tag || bcs->Status > US_BULK_STAT_PHASE) { + if (!(bcs->Tag == us->tag || (us->flags & US_FL_BULK_IGNORE_TAG)) || + bcs->Status > US_BULK_STAT_PHASE) { US_DEBUGP("Bulk logical error\n"); return USB_STOR_TRANSPORT_ERROR; } --- linux-2.6.24.orig/drivers/usb/storage/unusual_devs.h +++ linux-2.6.24/drivers/usb/storage/unusual_devs.h @@ -1557,6 +1557,17 @@ US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY), +/* + * Patch by Constantin Baranov + * Report by Andreas Koenecke. + * Motorola ROKR Z6. + */ +UNUSUAL_DEV( 0x22b8, 0x6426, 0x0101, 0x0101, + "Motorola", + "MSnc.", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY | US_FL_FIX_CAPACITY | US_FL_BULK_IGNORE_TAG), + /* Reported by Radovan Garabik */ UNUSUAL_DEV( 0x2735, 0x100b, 0x0000, 0x9999, "MPIO", @@ -1588,6 +1599,11 @@ US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_CAPACITY_HEURISTICS), +UNUSUAL_DEV( 0Xed10, 0x7636, 0x0001, 0x0001, + "TGE", + "Digital MP3 Audio Player", + US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ), + /* Control/Bulk transport for all SubClass values */ USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR), USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR), --- linux-2.6.24.orig/drivers/usb/storage/protocol.c +++ linux-2.6.24/drivers/usb/storage/protocol.c @@ -194,7 +194,7 @@ * and the starting offset within the page, and update * the *offset and *index values for the next loop. */ cnt = 0; - while (cnt < buflen) { + while (cnt < buflen && sg) { struct page *page = sg_page(sg) + ((sg->offset + *offset) >> PAGE_SHIFT); unsigned int poff = @@ -249,7 +249,8 @@ unsigned int offset = 0; struct scatterlist *sg = NULL; - usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset, + buflen = min(buflen, srb->request_bufflen); + buflen = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset, TO_XFER_BUF); if (buflen < srb->request_bufflen) srb->resid = srb->request_bufflen - buflen; --- linux-2.6.24.orig/drivers/usb/host/ehci-dbg.c +++ linux-2.6.24/drivers/usb/host/ehci-dbg.c @@ -763,9 +763,7 @@ } if (ehci->reclaim) { - temp = scnprintf (next, size, "reclaim qh %p%s\n", - ehci->reclaim, - ehci->reclaim_ready ? " ready" : ""); + temp = scnprintf(next, size, "reclaim qh %p\n", ehci->reclaim); size -= temp; next += temp; } --- linux-2.6.24.orig/drivers/usb/host/ohci-hcd.c +++ linux-2.6.24/drivers/usb/host/ohci-hcd.c @@ -85,6 +85,21 @@ static int ohci_restart (struct ohci_hcd *ohci); #endif +#ifdef CONFIG_PCI +static void quirk_amd_pll(int state); +static void amd_iso_dev_put(void); +#else +static inline void quirk_amd_pll(int state) +{ + return; +} +static inline void amd_iso_dev_put(void) +{ + return; +} +#endif + + #include "ohci-hub.c" #include "ohci-dbg.c" #include "ohci-mem.c" @@ -885,6 +900,8 @@ if (quirk_zfmicro(ohci)) del_timer(&ohci->unlink_watchdog); + if (quirk_amdiso(ohci)) + amd_iso_dev_put(); remove_debug_files (ohci); ohci_mem_cleanup (ohci); --- linux-2.6.24.orig/drivers/usb/host/ohci-q.c +++ linux-2.6.24/drivers/usb/host/ohci-q.c @@ -49,6 +49,9 @@ switch (usb_pipetype (urb->pipe)) { case PIPE_ISOCHRONOUS: ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs--; + if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0 + && quirk_amdiso(ohci)) + quirk_amd_pll(1); break; case PIPE_INTERRUPT: ohci_to_hcd(ohci)->self.bandwidth_int_reqs--; @@ -680,6 +683,9 @@ data + urb->iso_frame_desc [cnt].offset, urb->iso_frame_desc [cnt].length, urb, cnt); } + if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0 + && quirk_amdiso(ohci)) + quirk_amd_pll(0); periodic = ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs++ == 0 && ohci_to_hcd(ohci)->self.bandwidth_int_reqs == 0; break; --- linux-2.6.24.orig/drivers/usb/host/sl811-hcd.c +++ linux-2.6.24/drivers/usb/host/sl811-hcd.c @@ -1766,6 +1766,7 @@ retval = sl811h_bus_suspend(hcd); break; case PM_EVENT_SUSPEND: + case PM_EVENT_HIBERNATE: case PM_EVENT_PRETHAW: /* explicitly discard hw state */ port_power(sl811, 0); break; --- linux-2.6.24.orig/drivers/usb/host/u132-hcd.c +++ linux-2.6.24/drivers/usb/host/u132-hcd.c @@ -3213,15 +3213,20 @@ dev_err(&u132->platform_dev->dev, "device is being removed\n"); return -ESHUTDOWN; } else { - int retval = 0; - if (state.event == PM_EVENT_FREEZE) { + int retval = 0, ports; + + switch (state.event) { + case PM_EVENT_FREEZE: retval = u132_bus_suspend(hcd); - } else if (state.event == PM_EVENT_SUSPEND) { - int ports = MAX_U132_PORTS; + break; + case PM_EVENT_SUSPEND: + case PM_EVENT_HIBERNATE: + ports = MAX_U132_PORTS; while (ports-- > 0) { port_power(u132, ports, 0); } - } + break; + } if (retval == 0) pdev->dev.power.power_state = state; return retval; --- linux-2.6.24.orig/drivers/usb/host/ehci-pci.c +++ linux-2.6.24/drivers/usb/host/ehci-pci.c @@ -305,7 +305,7 @@ /* emptying the schedule aborts any urbs */ spin_lock_irq(&ehci->lock); if (ehci->reclaim) - ehci->reclaim_ready = 1; + end_unlink_async(ehci); ehci_work(ehci); spin_unlock_irq(&ehci->lock); --- linux-2.6.24.orig/drivers/usb/host/ehci-q.c +++ linux-2.6.24/drivers/usb/host/ehci-q.c @@ -315,10 +315,10 @@ if (likely (last->urb != urb)) { ehci_urb_done(ehci, last->urb, last_status); count++; + last_status = -EINPROGRESS; } ehci_qtd_free (ehci, last); last = NULL; - last_status = -EINPROGRESS; } /* ignore urbs submitted during completions we reported */ @@ -973,7 +973,7 @@ struct ehci_qh *qh = ehci->reclaim; struct ehci_qh *next; - timer_action_done (ehci, TIMER_IAA_WATCHDOG); + iaa_watchdog_done(ehci); // qh->hw_next = cpu_to_hc32(qh->qh_dma); qh->qh_state = QH_STATE_IDLE; @@ -983,7 +983,6 @@ /* other unlink(s) may be pending (in QH_STATE_UNLINK_WAIT) */ next = qh->reclaim; ehci->reclaim = next; - ehci->reclaim_ready = 0; qh->reclaim = NULL; qh_completions (ehci, qh); @@ -1059,11 +1058,10 @@ return; } - ehci->reclaim_ready = 0; cmd |= CMD_IAAD; ehci_writel(ehci, cmd, &ehci->regs->command); (void)ehci_readl(ehci, &ehci->regs->command); - timer_action (ehci, TIMER_IAA_WATCHDOG); + iaa_watchdog_start(ehci); } /*-------------------------------------------------------------------------*/ --- linux-2.6.24.orig/drivers/usb/host/ehci-hcd.c +++ linux-2.6.24/drivers/usb/host/ehci-hcd.c @@ -109,7 +109,7 @@ #define EHCI_TUNE_MULT_TT 1 #define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */ -#define EHCI_IAA_JIFFIES (HZ/100) /* arbitrary; ~10 msec */ +#define EHCI_IAA_MSECS 10 /* arbitrary */ #define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */ #define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */ #define EHCI_SHRINK_JIFFIES (HZ/200) /* async qh unlink delay */ @@ -266,6 +266,7 @@ /*-------------------------------------------------------------------------*/ +static void end_unlink_async(struct ehci_hcd *ehci); static void ehci_work(struct ehci_hcd *ehci); #include "ehci-hub.c" @@ -275,25 +276,62 @@ /*-------------------------------------------------------------------------*/ -static void ehci_watchdog (unsigned long param) +static void ehci_iaa_watchdog(unsigned long param) { struct ehci_hcd *ehci = (struct ehci_hcd *) param; unsigned long flags; spin_lock_irqsave (&ehci->lock, flags); - /* lost IAA irqs wedge things badly; seen with a vt8235 */ - if (ehci->reclaim) { - u32 status = ehci_readl(ehci, &ehci->regs->status); - if (status & STS_IAA) { - ehci_vdbg (ehci, "lost IAA\n"); + /* Lost IAA irqs wedge things badly; seen first with a vt8235. + * So we need this watchdog, but must protect it against both + * (a) SMP races against real IAA firing and retriggering, and + * (b) clean HC shutdown, when IAA watchdog was pending. + */ + if (ehci->reclaim + && !timer_pending(&ehci->iaa_watchdog) + && HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { + u32 cmd, status; + + /* If we get here, IAA is *REALLY* late. It's barely + * conceivable that the system is so busy that CMD_IAAD + * is still legitimately set, so let's be sure it's + * clear before we read STS_IAA. (The HC should clear + * CMD_IAAD when it sets STS_IAA.) + */ + cmd = ehci_readl(ehci, &ehci->regs->command); + if (cmd & CMD_IAAD) + ehci_writel(ehci, cmd & ~CMD_IAAD, + &ehci->regs->command); + + /* If IAA is set here it either legitimately triggered + * before we cleared IAAD above (but _way_ late, so we'll + * still count it as lost) ... or a silicon erratum: + * - VIA seems to set IAA without triggering the IRQ; + * - IAAD potentially cleared without setting IAA. + */ + status = ehci_readl(ehci, &ehci->regs->status); + if ((status & STS_IAA) || !(cmd & CMD_IAAD)) { COUNT (ehci->stats.lost_iaa); ehci_writel(ehci, STS_IAA, &ehci->regs->status); - ehci->reclaim_ready = 1; } + + ehci_vdbg(ehci, "IAA watchdog: status %x cmd %x\n", + status, cmd); + end_unlink_async(ehci); } - /* stop async processing after it's idled a bit */ + spin_unlock_irqrestore(&ehci->lock, flags); +} + +static void ehci_watchdog(unsigned long param) +{ + struct ehci_hcd *ehci = (struct ehci_hcd *) param; + unsigned long flags; + + spin_lock_irqsave(&ehci->lock, flags); + + /* stop async processing after it's idled a bit */ if (test_bit (TIMER_ASYNC_OFF, &ehci->actions)) start_unlink_async (ehci, ehci->async); @@ -363,8 +401,6 @@ static void ehci_work (struct ehci_hcd *ehci) { timer_action_done (ehci, TIMER_IO_WATCHDOG); - if (ehci->reclaim_ready) - end_unlink_async (ehci); /* another CPU may drop ehci->lock during a schedule scan while * it reports urb completions. this flag guards against bogus @@ -399,6 +435,7 @@ /* no more interrupts ... */ del_timer_sync (&ehci->watchdog); + del_timer_sync(&ehci->iaa_watchdog); spin_lock_irq(&ehci->lock); if (HC_IS_RUNNING (hcd->state)) @@ -447,6 +484,10 @@ ehci->watchdog.function = ehci_watchdog; ehci->watchdog.data = (unsigned long) ehci; + init_timer(&ehci->iaa_watchdog); + ehci->iaa_watchdog.function = ehci_iaa_watchdog; + ehci->iaa_watchdog.data = (unsigned long) ehci; + /* * hw default: 1K periodic list heads, one per frame. * periodic_size can shrink by USBCMD update if hcc_params allows. @@ -463,7 +504,6 @@ ehci->i_thresh = 2 + HCC_ISOC_THRES(hcc_params); ehci->reclaim = NULL; - ehci->reclaim_ready = 0; ehci->next_uframe = -1; /* @@ -611,7 +651,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); - u32 status, pcd_status = 0; + u32 status, pcd_status = 0, cmd; int bh; spin_lock (&ehci->lock); @@ -632,7 +672,7 @@ /* clear (just) interrupts */ ehci_writel(ehci, status, &ehci->regs->status); - ehci_readl(ehci, &ehci->regs->command); /* unblock posted write */ + cmd = ehci_readl(ehci, &ehci->regs->command); bh = 0; #ifdef EHCI_VERBOSE_DEBUG @@ -653,9 +693,17 @@ /* complete the unlinking of some qh [4.15.2.3] */ if (status & STS_IAA) { - COUNT (ehci->stats.reclaim); - ehci->reclaim_ready = 1; - bh = 1; + /* guard against (alleged) silicon errata */ + if (cmd & CMD_IAAD) { + ehci_writel(ehci, cmd & ~CMD_IAAD, + &ehci->regs->command); + ehci_dbg(ehci, "IAA with IAAD still set?\n"); + } + if (ehci->reclaim) { + COUNT(ehci->stats.reclaim); + end_unlink_async(ehci); + } else + ehci_dbg(ehci, "IAA with nothing to reclaim?\n"); } /* remote wakeup [4.3.1] */ @@ -761,10 +809,16 @@ static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) { - /* if we need to use IAA and it's busy, defer */ - if (qh->qh_state == QH_STATE_LINKED - && ehci->reclaim - && HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) { + /* failfast */ + if (!HC_IS_RUNNING(ehci_to_hcd(ehci)->state) && ehci->reclaim) + end_unlink_async(ehci); + + /* if it's not linked then there's nothing to do */ + if (qh->qh_state != QH_STATE_LINKED) + ; + + /* defer till later if busy */ + else if (ehci->reclaim) { struct ehci_qh *last; for (last = ehci->reclaim; @@ -774,12 +828,8 @@ qh->qh_state = QH_STATE_UNLINK_WAIT; last->reclaim = qh; - /* bypass IAA if the hc can't care */ - } else if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state) && ehci->reclaim) - end_unlink_async (ehci); - - /* something else might have unlinked the qh by now */ - if (qh->qh_state == QH_STATE_LINKED) + /* start IAA cycle */ + } else start_unlink_async (ehci, qh); } @@ -806,7 +856,19 @@ qh = (struct ehci_qh *) urb->hcpriv; if (!qh) break; - unlink_async (ehci, qh); + switch (qh->qh_state) { + case QH_STATE_LINKED: + case QH_STATE_COMPLETING: + unlink_async(ehci, qh); + break; + case QH_STATE_UNLINK: + case QH_STATE_UNLINK_WAIT: + /* already started */ + break; + case QH_STATE_IDLE: + WARN_ON(1); + break; + } break; case PIPE_INTERRUPT: @@ -898,6 +960,7 @@ unlink_async (ehci, qh); /* FALL THROUGH */ case QH_STATE_UNLINK: /* wait for hw to finish? */ + case QH_STATE_UNLINK_WAIT: idle_timeout: spin_unlock_irqrestore (&ehci->lock, flags); schedule_timeout_uninterruptible(1); --- linux-2.6.24.orig/drivers/usb/host/ohci.h +++ linux-2.6.24/drivers/usb/host/ohci.h @@ -399,6 +399,8 @@ #define OHCI_QUIRK_ZFMICRO 0x20 /* Compaq ZFMicro chipset*/ #define OHCI_QUIRK_NEC 0x40 /* lost interrupts */ #define OHCI_QUIRK_FRAME_NO 0x80 /* no big endian frame_no shift */ +#define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */ +#define OHCI_QUIRK_AMD_ISO 0x200 /* ISO transfers*/ // there are also chip quirks/bugs in init logic struct work_struct nec_work; /* Worker for NEC quirk */ @@ -419,6 +421,10 @@ { return ohci->flags & OHCI_QUIRK_ZFMICRO; } +static inline int quirk_amdiso(struct ohci_hcd *ohci) +{ + return ohci->flags & OHCI_QUIRK_AMD_ISO; +} #else static inline int quirk_nec(struct ohci_hcd *ohci) { @@ -428,6 +434,10 @@ { return 0; } +static inline int quirk_amdiso(struct ohci_hcd *ohci) +{ + return 0; +} #endif /* convert between an hcd pointer and the corresponding ohci_hcd */ --- linux-2.6.24.orig/drivers/usb/host/ehci.h +++ linux-2.6.24/drivers/usb/host/ehci.h @@ -74,7 +74,6 @@ /* async schedule support */ struct ehci_qh *async; struct ehci_qh *reclaim; - unsigned reclaim_ready : 1; unsigned scanning : 1; /* periodic schedule support */ @@ -105,6 +104,7 @@ struct dma_pool *itd_pool; /* itd per iso urb */ struct dma_pool *sitd_pool; /* sitd per split iso urb */ + struct timer_list iaa_watchdog; struct timer_list watchdog; unsigned long actions; unsigned stamp; @@ -140,9 +140,21 @@ } +static inline void +iaa_watchdog_start(struct ehci_hcd *ehci) +{ + WARN_ON(timer_pending(&ehci->iaa_watchdog)); + mod_timer(&ehci->iaa_watchdog, + jiffies + msecs_to_jiffies(EHCI_IAA_MSECS)); +} + +static inline void iaa_watchdog_done(struct ehci_hcd *ehci) +{ + del_timer(&ehci->iaa_watchdog); +} + enum ehci_timer_action { TIMER_IO_WATCHDOG, - TIMER_IAA_WATCHDOG, TIMER_ASYNC_SHRINK, TIMER_ASYNC_OFF, }; @@ -160,9 +172,6 @@ unsigned long t; switch (action) { - case TIMER_IAA_WATCHDOG: - t = EHCI_IAA_JIFFIES; - break; case TIMER_IO_WATCHDOG: t = EHCI_IO_JIFFIES; break; @@ -179,8 +188,7 @@ // async queue SHRINK often precedes IAA. while it's ready // to go OFF neither can matter, and afterwards the IO // watchdog stops unless there's still periodic traffic. - if (action != TIMER_IAA_WATCHDOG - && t > ehci->watchdog.expires + if (time_before_eq(t, ehci->watchdog.expires) && timer_pending (&ehci->watchdog)) return; mod_timer (&ehci->watchdog, t); --- linux-2.6.24.orig/drivers/usb/host/ohci-pci.c +++ linux-2.6.24/drivers/usb/host/ohci-pci.c @@ -18,6 +18,28 @@ #error "This file is PCI bus glue. CONFIG_PCI must be defined." #endif +#include +#include + + +/* constants used to work around PM-related transfer + * glitches in some AMD 700 series southbridges + */ +#define AB_REG_BAR 0xf0 +#define AB_INDX(addr) ((addr) + 0x00) +#define AB_DATA(addr) ((addr) + 0x04) +#define AX_INDXC 0X30 +#define AX_DATAC 0x34 + +#define NB_PCIE_INDX_ADDR 0xe0 +#define NB_PCIE_INDX_DATA 0xe4 +#define PCIE_P_CNTL 0x10040 +#define BIF_NB 0x10002 + +static struct pci_dev *amd_smbus_dev; +static struct pci_dev *amd_hb_dev; +static int amd_ohci_iso_count; + /*-------------------------------------------------------------------------*/ static int broken_suspend(struct usb_hcd *hcd) @@ -143,6 +165,103 @@ return 0; } +static int ohci_quirk_amd700(struct usb_hcd *hcd) +{ + struct ohci_hcd *ohci = hcd_to_ohci(hcd); + u8 rev = 0; + + if (!amd_smbus_dev) + amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, + PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL); + if (!amd_smbus_dev) + return 0; + + pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev); + if ((rev > 0x3b) || (rev < 0x30)) { + pci_dev_put(amd_smbus_dev); + amd_smbus_dev = NULL; + return 0; + } + + amd_ohci_iso_count++; + + if (!amd_hb_dev) + amd_hb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x9600, NULL); + + ohci->flags |= OHCI_QUIRK_AMD_ISO; + ohci_dbg(ohci, "enabled AMD ISO transfers quirk\n"); + + return 0; +} + +/* + * The hardware normally enables the A-link power management feature, which + * lets the system lower the power consumption in idle states. + * + * Assume the system is configured to have USB 1.1 ISO transfers going + * to or from a USB device. Without this quirk, that stream may stutter + * or have breaks occasionally. For transfers going to speakers, this + * makes a very audible mess... + * + * That audio playback corruption is due to the audio stream getting + * interrupted occasionally when the link goes in lower power state + * This USB quirk prevents the link going into that lower power state + * during audio playback or other ISO operations. + */ +static void quirk_amd_pll(int on) +{ + u32 addr; + u32 val; + u32 bit = (on > 0) ? 1 : 0; + + pci_read_config_dword(amd_smbus_dev, AB_REG_BAR, &addr); + + /* BIT names/meanings are NDA-protected, sorry ... */ + + outl(AX_INDXC, AB_INDX(addr)); + outl(0x40, AB_DATA(addr)); + outl(AX_DATAC, AB_INDX(addr)); + val = inl(AB_DATA(addr)); + val &= ~((1 << 3) | (1 << 4) | (1 << 9)); + val |= (bit << 3) | ((!bit) << 4) | ((!bit) << 9); + outl(val, AB_DATA(addr)); + + if (amd_hb_dev) { + addr = PCIE_P_CNTL; + pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_ADDR, addr); + + pci_read_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, &val); + val &= ~(1 | (1 << 3) | (1 << 4) | (1 << 9) | (1 << 12)); + val |= bit | (bit << 3) | (bit << 12); + val |= ((!bit) << 4) | ((!bit) << 9); + pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, val); + + addr = BIF_NB; + pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_ADDR, addr); + + pci_read_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, &val); + val &= ~(1 << 8); + val |= bit << 8; + pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, val); + } +} + +static void amd_iso_dev_put(void) +{ + amd_ohci_iso_count--; + if (amd_ohci_iso_count == 0) { + if (amd_smbus_dev) { + pci_dev_put(amd_smbus_dev); + amd_smbus_dev = NULL; + } + if (amd_hb_dev) { + pci_dev_put(amd_hb_dev); + amd_hb_dev = NULL; + } + } + +} + /* List of quirks for OHCI */ static const struct pci_device_id ohci_pci_quirks[] = { { @@ -181,6 +300,19 @@ PCI_DEVICE(PCI_VENDOR_ID_ITE, 0x8152), .driver_data = (unsigned long) broken_suspend, }, + { + PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4397), + .driver_data = (unsigned long)ohci_quirk_amd700, + }, + { + PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4398), + .driver_data = (unsigned long)ohci_quirk_amd700, + }, + { + PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399), + .driver_data = (unsigned long)ohci_quirk_amd700, + }, + /* FIXME for some of the early AMD 760 southbridges, OHCI * won't work at all. blacklist them. */ --- linux-2.6.24.orig/drivers/usb/host/ehci-hub.c +++ linux-2.6.24/drivers/usb/host/ehci-hub.c @@ -123,6 +123,8 @@ if (time_before (jiffies, ehci->next_statechange)) msleep(5); + del_timer_sync(&ehci->watchdog); + del_timer_sync(&ehci->iaa_watchdog); port = HCS_N_PORTS (ehci->hcs_params); spin_lock_irq (&ehci->lock); @@ -134,7 +136,7 @@ } ehci->command = ehci_readl(ehci, &ehci->regs->command); if (ehci->reclaim) - ehci->reclaim_ready = 1; + end_unlink_async(ehci); ehci_work(ehci); /* Unlike other USB host controller types, EHCI doesn't have @@ -171,7 +173,6 @@ } /* turn off now-idle HC */ - del_timer_sync (&ehci->watchdog); ehci_halt (ehci); hcd->state = HC_STATE_SUSPENDED; --- linux-2.6.24.orig/drivers/usb/serial/option.c +++ linux-2.6.24/drivers/usb/serial/option.c @@ -180,6 +180,7 @@ { USB_DEVICE(DELL_VENDOR_ID, 0x8117) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */ { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */ { USB_DEVICE(DELL_VENDOR_ID, 0x8128) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8133) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ { USB_DEVICE(DELL_VENDOR_ID, 0x8136) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */ { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, --- linux-2.6.24.orig/drivers/usb/serial/pl2303.h +++ linux-2.6.24/drivers/usb/serial/pl2303.h @@ -112,3 +112,7 @@ /* Y.C. Cable U.S.A., Inc - USB to RS-232 */ #define YCCABLE_VENDOR_ID 0x05ad #define YCCABLE_PRODUCT_ID 0x0fba + +/* Sanwa KB-USB2 multimeter cable (ID: 11ad:0001) */ +#define SANWA_VENDOR_ID 0x11ad +#define SANWA_PRODUCT_ID 0x0001 --- linux-2.6.24.orig/drivers/usb/serial/keyspan.h +++ linux-2.6.24/drivers/usb/serial/keyspan.h @@ -637,6 +637,7 @@ .description = "Keyspan - (without firmware)", .id_table = keyspan_pre_ids, .num_interrupt_in = NUM_DONT_CARE, + .num_interrupt_out = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, .num_bulk_out = NUM_DONT_CARE, .num_ports = 1, @@ -651,6 +652,7 @@ .description = "Keyspan 1 port adapter", .id_table = keyspan_1port_ids, .num_interrupt_in = NUM_DONT_CARE, + .num_interrupt_out = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, .num_bulk_out = NUM_DONT_CARE, .num_ports = 1, @@ -678,6 +680,7 @@ .description = "Keyspan 2 port adapter", .id_table = keyspan_2port_ids, .num_interrupt_in = NUM_DONT_CARE, + .num_interrupt_out = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, .num_bulk_out = NUM_DONT_CARE, .num_ports = 2, @@ -705,6 +708,7 @@ .description = "Keyspan 4 port adapter", .id_table = keyspan_4port_ids, .num_interrupt_in = NUM_DONT_CARE, + .num_interrupt_out = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, .num_bulk_out = NUM_DONT_CARE, .num_ports = 4, --- linux-2.6.24.orig/drivers/usb/serial/usb-serial.c +++ linux-2.6.24/drivers/usb/serial/usb-serial.c @@ -844,6 +844,7 @@ serial->num_interrupt_in = num_interrupt_in; serial->num_interrupt_out = num_interrupt_out; +#if 0 /* check that the device meets the driver's requirements */ if ((type->num_interrupt_in != NUM_DONT_CARE && type->num_interrupt_in != num_interrupt_in) @@ -857,6 +858,7 @@ kfree(serial); return -EIO; } +#endif /* found all that we need */ dev_info(&interface->dev, "%s converter detected\n", --- linux-2.6.24.orig/drivers/usb/serial/visor.c +++ linux-2.6.24/drivers/usb/serial/visor.c @@ -191,7 +191,7 @@ .id_table = id_table, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = 2, - .num_bulk_out = 2, + .num_bulk_out = NUM_DONT_CARE, .num_ports = 2, .open = visor_open, .close = visor_close, --- linux-2.6.24.orig/drivers/usb/serial/ftdi_sio.c +++ linux-2.6.24/drivers/usb/serial/ftdi_sio.c @@ -310,6 +310,7 @@ }; static int ftdi_olimex_probe (struct usb_serial *serial); +static int ftdi_mtxorb_hack_setup (struct usb_serial *serial); static void ftdi_USB_UIRT_setup (struct ftdi_private *priv); static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv); @@ -317,6 +318,10 @@ .probe = ftdi_olimex_probe, }; +static struct ftdi_sio_quirk ftdi_mtxorb_hack_quirk = { + .probe = ftdi_mtxorb_hack_setup, +}; + static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { .port_probe = ftdi_USB_UIRT_setup, }; @@ -379,6 +384,8 @@ { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, + { USB_DEVICE(MTXORB_VK_VID, MTXORB_VK_PID), + .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) }, { USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) }, @@ -492,6 +499,7 @@ { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1010PC_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) }, { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) }, @@ -1301,6 +1309,23 @@ return 0; } +/* + * The Matrix Orbital VK204-25-USB has an invalid IN endpoint. + * We have to correct it if we want to read from it. + */ +static int ftdi_mtxorb_hack_setup(struct usb_serial *serial) +{ + struct usb_host_endpoint *ep = serial->dev->ep_in[1]; + struct usb_endpoint_descriptor *ep_desc = &ep->desc; + + if (ep->enabled && ep_desc->wMaxPacketSize == 0) { + ep_desc->wMaxPacketSize = 0x40; + info("Fixing invalid wMaxPacketSize on read pipe"); + } + + return 0; +} + /* ftdi_shutdown is called from usbserial:usb_serial_disconnect * it is called when the usb device is disconnected * --- linux-2.6.24.orig/drivers/usb/serial/ftdi_sio.h +++ linux-2.6.24/drivers/usb/serial/ftdi_sio.h @@ -98,6 +98,13 @@ #define FTDI_MTXORB_5_PID 0xFA05 /* Matrix Orbital Product Id */ #define FTDI_MTXORB_6_PID 0xFA06 /* Matrix Orbital Product Id */ +/* + * The following are the values for the Matrix Orbital VK204-25-USB + * display, which use the FT232RL. + */ +#define MTXORB_VK_VID 0x1b3d +#define MTXORB_VK_PID 0x0158 + /* Interbiometrics USB I/O Board */ /* Developed for Interbiometrics by Rudolf Gugler */ #define INTERBIOMETRICS_VID 0x1209 --- linux-2.6.24.orig/drivers/usb/serial/ti_usb_3410_5052.c +++ linux-2.6.24/drivers/usb/serial/ti_usb_3410_5052.c @@ -264,8 +264,8 @@ .description = "TI USB 3410 1 port adapter", .usb_driver = &ti_usb_driver, .id_table = ti_id_table_3410, - .num_interrupt_in = 1, - .num_bulk_in = 1, + .num_interrupt_in = NUM_DONT_CARE, + .num_bulk_in = NUM_DONT_CARE, .num_bulk_out = 1, .num_ports = 1, .attach = ti_startup, --- linux-2.6.24.orig/drivers/usb/serial/ch341.c +++ linux-2.6.24/drivers/usb/serial/ch341.c @@ -28,6 +28,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x4348, 0x5523) }, + { USB_DEVICE(0x1a86, 0x7523) }, { }, }; MODULE_DEVICE_TABLE(usb, id_table); --- linux-2.6.24.orig/drivers/usb/serial/airprime.c +++ linux-2.6.24/drivers/usb/serial/airprime.c @@ -18,6 +18,14 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */ + { USB_DEVICE(0x413c, 0x8115) }, /* Dell Wireless HSDPA 5500 */ + { USB_DEVICE(0x0930, 0x1303) }, /* Toshiba (Novatel Wireless) HSDPA for M400 */ + { USB_DEVICE(0x106c, 0x3701) }, /* Audiovox PC5740 */ + { USB_DEVICE(0x106c, 0x3702) }, /* Sprint Pantech PX-500 DGE */ + { USB_DEVICE(0x1410, 0x4100) }, /* Novatel Wireless U727 */ + { USB_DEVICE(0x12d1, 0x1003) }, /* Huawei E220 */ + { USB_DEVICE(0x05c6, 0x6000) }, /* Momo design */ + { USB_DEVICE(0xf3d0, 0x0112) }, /* AirPrime 5220 */ { }, }; MODULE_DEVICE_TABLE(usb, id_table); --- linux-2.6.24.orig/drivers/usb/serial/pl2303.c +++ linux-2.6.24/drivers/usb/serial/pl2303.c @@ -89,6 +89,7 @@ { USB_DEVICE(COREGA_VENDOR_ID, COREGA_PRODUCT_ID) }, { USB_DEVICE(HL340_VENDOR_ID, HL340_PRODUCT_ID) }, { USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) }, + { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, { } /* Terminating entry */ }; --- linux-2.6.24.orig/drivers/usb/gadget/ether.c +++ linux-2.6.24/drivers/usb/gadget/ether.c @@ -1561,6 +1561,7 @@ memcpy(req->buf, buf, n); req->complete = rndis_response_complete; rndis_free_response(dev->rndis_config, buf); + value = n; } /* else stalls ... spec says to avoid that */ } --- linux-2.6.24.orig/drivers/base/platform.c +++ linux-2.6.24/drivers/base/platform.c @@ -647,7 +647,7 @@ high_totalram += high_totalram - 1; mask = (((u64)high_totalram) << 32) + 0xffffffff; } - return mask & *dev->dma_mask; + return mask; } EXPORT_SYMBOL_GPL(dma_get_required_mask); #endif --- linux-2.6.24.orig/drivers/acorn/char/defkeymap-l7200.c +++ linux-2.6.24/drivers/acorn/char/defkeymap-l7200.c @@ -347,40 +347,40 @@ }; struct kbdiacruc accent_table[MAX_DIACR] = { - {'`', 'A', '\300'}, {'`', 'a', '\340'}, - {'\'', 'A', '\301'}, {'\'', 'a', '\341'}, - {'^', 'A', '\302'}, {'^', 'a', '\342'}, - {'~', 'A', '\303'}, {'~', 'a', '\343'}, - {'"', 'A', '\304'}, {'"', 'a', '\344'}, - {'O', 'A', '\305'}, {'o', 'a', '\345'}, - {'0', 'A', '\305'}, {'0', 'a', '\345'}, - {'A', 'A', '\305'}, {'a', 'a', '\345'}, - {'A', 'E', '\306'}, {'a', 'e', '\346'}, - {',', 'C', '\307'}, {',', 'c', '\347'}, - {'`', 'E', '\310'}, {'`', 'e', '\350'}, - {'\'', 'E', '\311'}, {'\'', 'e', '\351'}, - {'^', 'E', '\312'}, {'^', 'e', '\352'}, - {'"', 'E', '\313'}, {'"', 'e', '\353'}, - {'`', 'I', '\314'}, {'`', 'i', '\354'}, - {'\'', 'I', '\315'}, {'\'', 'i', '\355'}, - {'^', 'I', '\316'}, {'^', 'i', '\356'}, - {'"', 'I', '\317'}, {'"', 'i', '\357'}, - {'-', 'D', '\320'}, {'-', 'd', '\360'}, - {'~', 'N', '\321'}, {'~', 'n', '\361'}, - {'`', 'O', '\322'}, {'`', 'o', '\362'}, - {'\'', 'O', '\323'}, {'\'', 'o', '\363'}, - {'^', 'O', '\324'}, {'^', 'o', '\364'}, - {'~', 'O', '\325'}, {'~', 'o', '\365'}, - {'"', 'O', '\326'}, {'"', 'o', '\366'}, - {'/', 'O', '\330'}, {'/', 'o', '\370'}, - {'`', 'U', '\331'}, {'`', 'u', '\371'}, - {'\'', 'U', '\332'}, {'\'', 'u', '\372'}, - {'^', 'U', '\333'}, {'^', 'u', '\373'}, - {'"', 'U', '\334'}, {'"', 'u', '\374'}, - {'\'', 'Y', '\335'}, {'\'', 'y', '\375'}, - {'T', 'H', '\336'}, {'t', 'h', '\376'}, - {'s', 's', '\337'}, {'"', 'y', '\377'}, - {'s', 'z', '\337'}, {'i', 'j', '\377'}, + {'`', 'A', 0300}, {'`', 'a', 0340}, + {'\'', 'A', 0301}, {'\'', 'a', 0341}, + {'^', 'A', 0302}, {'^', 'a', 0342}, + {'~', 'A', 0303}, {'~', 'a', 0343}, + {'"', 'A', 0304}, {'"', 'a', 0344}, + {'O', 'A', 0305}, {'o', 'a', 0345}, + {'0', 'A', 0305}, {'0', 'a', 0345}, + {'A', 'A', 0305}, {'a', 'a', 0345}, + {'A', 'E', 0306}, {'a', 'e', 0346}, + {',', 'C', 0307}, {',', 'c', 0347}, + {'`', 'E', 0310}, {'`', 'e', 0350}, + {'\'', 'E', 0311}, {'\'', 'e', 0351}, + {'^', 'E', 0312}, {'^', 'e', 0352}, + {'"', 'E', 0313}, {'"', 'e', 0353}, + {'`', 'I', 0314}, {'`', 'i', 0354}, + {'\'', 'I', 0315}, {'\'', 'i', 0355}, + {'^', 'I', 0316}, {'^', 'i', 0356}, + {'"', 'I', 0317}, {'"', 'i', 0357}, + {'-', 'D', 0320}, {'-', 'd', 0360}, + {'~', 'N', 0321}, {'~', 'n', 0361}, + {'`', 'O', 0322}, {'`', 'o', 0362}, + {'\'', 'O', 0323}, {'\'', 'o', 0363}, + {'^', 'O', 0324}, {'^', 'o', 0364}, + {'~', 'O', 0325}, {'~', 'o', 0365}, + {'"', 'O', 0326}, {'"', 'o', 0366}, + {'/', 'O', 0330}, {'/', 'o', 0370}, + {'`', 'U', 0331}, {'`', 'u', 0371}, + {'\'', 'U', 0332}, {'\'', 'u', 0372}, + {'^', 'U', 0333}, {'^', 'u', 0373}, + {'"', 'U', 0334}, {'"', 'u', 0374}, + {'\'', 'Y', 0335}, {'\'', 'y', 0375}, + {'T', 'H', 0336}, {'t', 'h', 0376}, + {'s', 's', 0337}, {'"', 'y', 0377}, + {'s', 'z', 0337}, {'i', 'j', 0377}, }; unsigned int accent_table_size = 68; --- linux-2.6.24.orig/drivers/media/dvb/frontends/tda10086.c +++ linux-2.6.24/drivers/media/dvb/frontends/tda10086.c @@ -106,9 +106,12 @@ static int tda10086_init(struct dvb_frontend* fe) { struct tda10086_state* state = fe->demodulator_priv; + u8 t22k_off = 0x80; dprintk ("%s\n", __FUNCTION__); + if (state->config->diseqc_tone) + t22k_off = 0; // reset tda10086_write_byte(state, 0x00, 0x00); msleep(10); @@ -158,7 +161,7 @@ tda10086_write_byte(state, 0x3d, 0x80); // setup SEC - tda10086_write_byte(state, 0x36, 0x80); // all SEC off, no 22k tone + tda10086_write_byte(state, 0x36, t22k_off); // all SEC off, 22k tone tda10086_write_byte(state, 0x34, (((1<<19) * (22000/1000)) / (SACLK/1000))); // } tone frequency tda10086_write_byte(state, 0x35, (((1<<19) * (22000/1000)) / (SACLK/1000)) >> 8); // } @@ -180,16 +183,20 @@ static int tda10086_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) { struct tda10086_state* state = fe->demodulator_priv; + u8 t22k_off = 0x80; dprintk ("%s\n", __FUNCTION__); + if (state->config->diseqc_tone) + t22k_off = 0; + switch (tone) { case SEC_TONE_OFF: - tda10086_write_byte(state, 0x36, 0x80); + tda10086_write_byte(state, 0x36, t22k_off); break; case SEC_TONE_ON: - tda10086_write_byte(state, 0x36, 0x81); + tda10086_write_byte(state, 0x36, 0x01 + t22k_off); break; } @@ -202,9 +209,13 @@ struct tda10086_state* state = fe->demodulator_priv; int i; u8 oldval; + u8 t22k_off = 0x80; dprintk ("%s\n", __FUNCTION__); + if (state->config->diseqc_tone) + t22k_off = 0; + if (cmd->msg_len > 6) return -EINVAL; oldval = tda10086_read_byte(state, 0x36); @@ -212,7 +223,8 @@ for(i=0; i< cmd->msg_len; i++) { tda10086_write_byte(state, 0x48+i, cmd->msg[i]); } - tda10086_write_byte(state, 0x36, 0x88 | ((cmd->msg_len - 1) << 4)); + tda10086_write_byte(state, 0x36, (0x08 + t22k_off) + | ((cmd->msg_len - 1) << 4)); tda10086_diseqc_wait(state); @@ -225,16 +237,20 @@ { struct tda10086_state* state = fe->demodulator_priv; u8 oldval = tda10086_read_byte(state, 0x36); + u8 t22k_off = 0x80; dprintk ("%s\n", __FUNCTION__); + if (state->config->diseqc_tone) + t22k_off = 0; + switch(minicmd) { case SEC_MINI_A: - tda10086_write_byte(state, 0x36, 0x84); + tda10086_write_byte(state, 0x36, 0x04 + t22k_off); break; case SEC_MINI_B: - tda10086_write_byte(state, 0x36, 0x86); + tda10086_write_byte(state, 0x36, 0x06 + t22k_off); break; } --- linux-2.6.24.orig/drivers/media/dvb/frontends/tda10086.h +++ linux-2.6.24/drivers/media/dvb/frontends/tda10086.h @@ -33,6 +33,9 @@ /* does the "inversion" need inverted? */ u8 invert; + + /* do we need the diseqc signal with carrier? */ + u8 diseqc_tone; }; #if defined(CONFIG_DVB_TDA10086) || (defined(CONFIG_DVB_TDA10086_MODULE) && defined(MODULE)) --- linux-2.6.24.orig/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ linux-2.6.24/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -16,6 +16,7 @@ #define USB_VID_ALINK 0x05e3 #define USB_VID_ANCHOR 0x0547 #define USB_VID_ANUBIS_ELECTRONIC 0x10fd +#define USB_VID_ASUS 0x0b05 #define USB_VID_AVERMEDIA 0x07ca #define USB_VID_COMPRO 0x185b #define USB_VID_COMPRO_UNK 0x145f @@ -44,6 +45,7 @@ #define USB_VID_ULTIMA_ELECTRONIC 0x05d8 #define USB_VID_UNIWILL 0x1584 #define USB_VID_WIDEVIEW 0x14aa +#define USB_VID_GIGABYTE 0x1044 /* Product IDs */ #define USB_PID_ADSTECH_USB2_COLD 0xa333 @@ -99,6 +101,7 @@ #define USB_PID_ULTIMA_TVBOX_USB2_WARM 0x810a #define USB_PID_ARTEC_T14_COLD 0x810b #define USB_PID_ARTEC_T14_WARM 0x810c +#define USB_PID_ARTEC_T14BR 0x810f #define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613 #define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002 #define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e @@ -120,6 +123,7 @@ #define USB_PID_HAUPPAUGE_NOVA_T_500_2 0x9950 #define USB_PID_HAUPPAUGE_NOVA_T_STICK 0x7050 #define USB_PID_HAUPPAUGE_NOVA_T_STICK_2 0x7060 +#define USB_PID_HAUPPAUGE_NOVA_T_STICK_3 0x7070 #define USB_PID_HAUPPAUGE_NOVA_TD_STICK 0x9580 #define USB_PID_AVERMEDIA_EXPRESS 0xb568 #define USB_PID_AVERMEDIA_VOLAR 0xa807 @@ -170,6 +174,9 @@ #define USB_PID_OPERA1_WARM 0x3829 #define USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD 0x0514 #define USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM 0x0513 - +/* dom pour gigabyte u7000 */ +#define USB_PID_GIGABYTE_U7000 0x7001 +#define USB_PID_ASUS_U3000 0x171f +#define USB_PID_ASUS_U3100 0x173f #endif --- linux-2.6.24.orig/drivers/media/dvb/dvb-usb/umt-010.c +++ linux-2.6.24/drivers/media/dvb/dvb-usb/umt-010.c @@ -104,7 +104,7 @@ /* parameter for the MPEG2-data transfer */ .stream = { .type = USB_BULK, - .count = 20, + .count = MAX_NO_URBS_FOR_DATA_STREAM, .endpoint = 0x06, .u = { .bulk = { --- linux-2.6.24.orig/drivers/media/dvb/dvb-usb/ttusb2.c +++ linux-2.6.24/drivers/media/dvb/dvb-usb/ttusb2.c @@ -144,6 +144,7 @@ static struct tda10086_config tda10086_config = { .demod_address = 0x0e, .invert = 0, + .diseqc_tone = 1, }; static int ttusb2_frontend_attach(struct dvb_usb_adapter *adap) --- linux-2.6.24.orig/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ linux-2.6.24/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -230,6 +230,27 @@ } }; +static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap) +{ + if (adap->id == 0) { + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); + msleep(10); + dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + msleep(10); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); + msleep(10); + dib7000p_i2c_enumeration(&adap->dev->i2c_adap,1,18,stk7700d_dib7000p_mt2266_config); + } + + adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1), + &stk7700d_dib7000p_mt2266_config[adap->id]); + + return adap->fe == NULL ? -ENODEV : 0; +} + static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap) { if (adap->id == 0) { @@ -821,6 +842,11 @@ { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T) }, { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500_PC) }, /* 20 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_EXPRESS) }, + { USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U7000) }, + { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) }, + { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000) }, + { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3100) }, +/* 25 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_3) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -891,6 +917,10 @@ { "AVerMedia AVerTV DVB-T Express", { &dib0700_usb_id_table[20] }, { NULL }, + }, + { "Gigabyte U7000", + { &dib0700_usb_id_table[21], NULL }, + { NULL }, } }, @@ -974,6 +1004,25 @@ .num_adapters = 1, .adapter = { { + .frontend_attach = stk7700P2_frontend_attach, + .tuner_attach = stk7700d_tuner_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x02), + }, + }, + + .num_device_descs = 1, + .devices = { + { "ASUS My Cinema U3000 Mini DVBT Tuner", + { &dib0700_usb_id_table[23], NULL }, + { NULL }, + }, + } + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, + + .num_adapters = 1, + .adapter = { + { .frontend_attach = stk7070p_frontend_attach, .tuner_attach = dib7070p_tuner_attach, @@ -983,7 +1032,7 @@ }, }, - .num_device_descs = 2, + .num_device_descs = 5, .devices = { { "DiBcom STK7070P reference design", { &dib0700_usb_id_table[15], NULL }, @@ -993,7 +1042,25 @@ { &dib0700_usb_id_table[16], NULL }, { NULL }, }, - } + { "Artec T14BR DVB-T", + { &dib0700_usb_id_table[22], NULL }, + { NULL }, + }, + { "ASUS My Cinema U3100 Mini DVBT Tuner", + { &dib0700_usb_id_table[24], NULL }, + { NULL }, + }, + { "Hauppauge Nova-T Stick", + { &dib0700_usb_id_table[25], NULL }, + { NULL }, + }, + }, + + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_key_map = dib0700_rc_keys, + .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), + .rc_query = dib0700_rc_query + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, .num_adapters = 2, --- linux-2.6.24.orig/drivers/media/dvb/ttpci/budget.c +++ linux-2.6.24/drivers/media/dvb/ttpci/budget.c @@ -351,6 +351,7 @@ static struct tda10086_config tda10086_config = { .demod_address = 0x0e, .invert = 0, + .diseqc_tone = 1, }; static u8 read_pwm(struct budget* budget) --- linux-2.6.24.orig/drivers/media/video/tvaudio.c +++ linux-2.6.24/drivers/media/video/tvaudio.c @@ -156,7 +156,7 @@ { unsigned char buffer[2]; - if (-1 == subaddr) { + if (subaddr < 0) { v4l_dbg(1, debug, &chip->c, "%s: chip_write: 0x%x\n", chip->c.name, val); chip->shadow.bytes[1] = val; @@ -167,6 +167,13 @@ return -1; } } else { + if (subaddr + 1 >= ARRAY_SIZE(chip->shadow.bytes)) { + v4l_info(&chip->c, + "Tried to access a non-existent register: %d\n", + subaddr); + return -EINVAL; + } + v4l_dbg(1, debug, &chip->c, "%s: chip_write: reg%d=0x%x\n", chip->c.name, subaddr, val); chip->shadow.bytes[subaddr+1] = val; @@ -181,12 +188,20 @@ return 0; } -static int chip_write_masked(struct CHIPSTATE *chip, int subaddr, int val, int mask) +static int chip_write_masked(struct CHIPSTATE *chip, + int subaddr, int val, int mask) { if (mask != 0) { - if (-1 == subaddr) { + if (subaddr < 0) { val = (chip->shadow.bytes[1] & ~mask) | (val & mask); } else { + if (subaddr + 1 >= ARRAY_SIZE(chip->shadow.bytes)) { + v4l_info(&chip->c, + "Tried to access a non-existent register: %d\n", + subaddr); + return -EINVAL; + } + val = (chip->shadow.bytes[subaddr+1] & ~mask) | (val & mask); } } @@ -232,6 +247,15 @@ if (0 == cmd->count) return 0; + if (cmd->count + cmd->bytes[0] - 1 >= ARRAY_SIZE(chip->shadow.bytes)) { + v4l_info(&chip->c, + "Tried to access a non-existent register range: %d to %d\n", + cmd->bytes[0] + 1, cmd->bytes[0] + cmd->count - 1); + return -EINVAL; + } + + /* FIXME: it seems that the shadow bytes are wrong bellow !*/ + /* update our shadow register set; print bytes if (debug > 0) */ v4l_dbg(1, debug, &chip->c, "%s: chip_cmd(%s): reg=%d, data:", chip->c.name, name,cmd->bytes[0]); @@ -1765,7 +1789,7 @@ case VIDIOCSFREQ: case VIDIOC_S_FREQUENCY: chip->mode = 0; /* automatic */ - if (desc->checkmode) { + if (desc->checkmode && desc->setmode) { desc->setmode(chip,VIDEO_SOUND_MONO); if (chip->prevmode != VIDEO_SOUND_MONO) chip->prevmode = -1; /* reset previous mode */ --- linux-2.6.24.orig/drivers/media/video/vivi.c +++ linux-2.6.24/drivers/media/video/vivi.c @@ -170,7 +170,7 @@ int users; /* various device info */ - struct video_device vfd; + struct video_device *vfd; struct vivi_dmaqueue vidq; @@ -986,7 +986,7 @@ printk(KERN_DEBUG "vivi: open called (minor=%d)\n",minor); list_for_each_entry(dev, &vivi_devlist, vivi_devlist) - if (dev->vfd.minor == minor) + if (dev->vfd->minor == minor) goto found; return -ENODEV; found: @@ -1067,7 +1067,7 @@ return videobuf_poll_stream(file, q, wait); } -static int vivi_release(struct inode *inode, struct file *file) +static int vivi_close(struct inode *inode, struct file *file) { struct vivi_fh *fh = file->private_data; struct vivi_dev *dev = fh->dev; @@ -1088,6 +1088,18 @@ return 0; } +static int vivi_release(struct vivi_dev *dev) +{ + if (-1 != dev->vfd->minor) + video_unregister_device(dev->vfd); + else + video_device_release(dev->vfd); + + dev->vfd = NULL; + + return 0; +} + static int vivi_mmap(struct file *file, struct vm_area_struct * vma) { @@ -1109,7 +1121,7 @@ static const struct file_operations vivi_fops = { .owner = THIS_MODULE, .open = vivi_open, - .release = vivi_release, + .release = vivi_close, .read = vivi_read, .poll = vivi_poll, .ioctl = video_ioctl2, /* V4L2 ioctl handler */ @@ -1117,12 +1129,12 @@ .llseek = no_llseek, }; -static struct video_device vivi = { +static struct video_device vivi_template = { .name = "vivi", .type = VID_TYPE_CAPTURE, .fops = &vivi_fops, .minor = -1, -// .release = video_device_release, + .release = video_device_release, .vidioc_querycap = vidioc_querycap, .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap, @@ -1156,6 +1168,7 @@ { int ret; struct vivi_dev *dev; + struct video_device *vfd; dev = kzalloc(sizeof(*dev),GFP_KERNEL); if (NULL == dev) @@ -1174,7 +1187,18 @@ dev->vidq.timeout.data = (unsigned long)dev; init_timer(&dev->vidq.timeout); - ret = video_register_device(&vivi, VFL_TYPE_GRABBER, video_nr); + vfd = video_device_alloc(); + if (NULL == vfd) + return -ENOMEM; + + *vfd = vivi_template; + + ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); + snprintf(vfd->name, sizeof(vfd->name), "%s (%i)", + vivi_template.name, vfd->minor); + + dev->vfd = vfd; + printk(KERN_INFO "Video Technology Magazine Virtual Video Capture Board (Load status: %d)\n", ret); return ret; } @@ -1188,9 +1212,9 @@ list = vivi_devlist.next; list_del(list); h = list_entry(list, struct vivi_dev, vivi_devlist); + vivi_release(h); kfree (h); } - video_unregister_device(&vivi); } module_init(vivi_init); --- linux-2.6.24.orig/drivers/media/video/saa7134/saa7134-dvb.c +++ linux-2.6.24/drivers/media/video/saa7134/saa7134-dvb.c @@ -826,6 +826,7 @@ static struct tda10086_config flydvbs = { .demod_address = 0x0e, .invert = 0, + .diseqc_tone = 0, }; /* ================================================================== --- linux-2.6.24.orig/drivers/media/video/ivtv/ivtv-ioctl.c +++ linux-2.6.24/drivers/media/video/ivtv/ivtv-ioctl.c @@ -727,7 +727,8 @@ memset(vcap, 0, sizeof(*vcap)); strcpy(vcap->driver, IVTV_DRIVER_NAME); /* driver name */ - strcpy(vcap->card, itv->card_name); /* card type */ + strncpy(vcap->card, itv->card_name, + sizeof(vcap->card)-1); /* card type */ strcpy(vcap->bus_info, pci_name(itv->dev)); /* bus info... */ vcap->version = IVTV_DRIVER_VERSION; /* version */ vcap->capabilities = itv->v4l2_cap; /* capabilities */ --- linux-2.6.24.orig/drivers/media/video/ivtv/ivtv-driver.c +++ linux-2.6.24/drivers/media/video/ivtv/ivtv-driver.c @@ -687,6 +687,9 @@ itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; itv->vbi.sliced_in = &itv->vbi.in.fmt.sliced; + /* Init the sg table for osd/yuv output */ + sg_init_table(itv->udma.SGlist, IVTV_DMA_SG_OSD_ENT); + /* OSD */ itv->osd_global_alpha_state = 1; itv->osd_global_alpha = 255; --- linux-2.6.24.orig/drivers/media/video/em28xx/em28xx-cards.c +++ linux-2.6.24/drivers/media/video/em28xx/em28xx-cards.c @@ -274,6 +274,7 @@ { USB_DEVICE(0x2304, 0x0208), .driver_info = EM2820_BOARD_PINNACLE_USB_2 }, { USB_DEVICE(0x2040, 0x4200), .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 }, { USB_DEVICE(0x2304, 0x0207), .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, + { USB_DEVICE(0x2040, 0x6502), .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 }, { }, }; --- linux-2.6.24.orig/drivers/media/video/cx88/cx88-cards.c +++ linux-2.6.24/drivers/media/video/cx88/cx88-cards.c @@ -1349,6 +1349,10 @@ }}, /* fixme: Add radio support */ .mpeg = CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD, + .radio = { + .type = CX88_RADIO, + .gpio0 = 0xe780, + }, }, [CX88_BOARD_ADSTECH_PTV_390] = { .name = "ADS Tech Instant Video PCI", --- linux-2.6.24.orig/drivers/pnp/pnpacpi/rsparser.c +++ linux-2.6.24/drivers/pnp/pnpacpi/rsparser.c @@ -85,7 +85,7 @@ i < PNP_MAX_IRQ) i++; if (i >= PNP_MAX_IRQ && !warned) { - printk(KERN_ERR "pnpacpi: exceeded the max number of IRQ " + printk(KERN_WARNING "pnpacpi: exceeded the max number of IRQ " "resources: %d \n", PNP_MAX_IRQ); warned = 1; return; @@ -187,7 +187,7 @@ res->dma_resource[i].start = dma; res->dma_resource[i].end = dma; } else if (!warned) { - printk(KERN_ERR "pnpacpi: exceeded the max number of DMA " + printk(KERN_WARNING "pnpacpi: exceeded the max number of DMA " "resources: %d \n", PNP_MAX_DMA); warned = 1; } @@ -213,7 +213,7 @@ res->port_resource[i].start = io; res->port_resource[i].end = io + len - 1; } else if (!warned) { - printk(KERN_ERR "pnpacpi: exceeded the max number of IO " + printk(KERN_WARNING "pnpacpi: exceeded the max number of IO " "resources: %d \n", PNP_MAX_PORT); warned = 1; } @@ -241,7 +241,7 @@ res->mem_resource[i].start = mem; res->mem_resource[i].end = mem + len - 1; } else if (!warned) { - printk(KERN_ERR "pnpacpi: exceeded the max number of mem " + printk(KERN_WARNING "pnpacpi: exceeded the max number of mem " "resources: %d\n", PNP_MAX_MEM); warned = 1; } @@ -752,6 +752,12 @@ if (pnpacpi_supported_resource(res)) { (*resource)->type = res->type; (*resource)->length = sizeof(struct acpi_resource); + if (res->type == ACPI_RESOURCE_TYPE_IRQ) + (*resource)->data.irq.descriptor_length = + res->data.irq.descriptor_length; + if (res->type == ACPI_RESOURCE_TYPE_START_DEPENDENT) + (*resource)->data.start_dpf.descriptor_length = + res->data.start_dpf.descriptor_length; (*resource)++; } --- linux-2.6.24.orig/drivers/char/keyboard.c +++ linux-2.6.24/drivers/char/keyboard.c @@ -1067,6 +1067,8 @@ int code; switch (keycode) { + case KEY_RESERVED: + break; case KEY_PAUSE: put_queue(vc, 0xe1); put_queue(vc, 0x1d | up_flag); @@ -1126,6 +1128,8 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char up_flag) { + if (keycode == KEY_RESERVED) + return 0; if (keycode > 127) return -1; --- linux-2.6.24.orig/drivers/char/Kconfig +++ linux-2.6.24/drivers/char/Kconfig @@ -80,6 +80,14 @@ information. For framebuffer console users, please refer to . +config DEV_KMEM + bool "/dev/kmem virtual device support" + help + Say Y here if you want to support the /dev/kmem device. The + /dev/kmem device is rarely used, but can be used for certain + kind of kernel debugging operations. + When in doubt, say "N". + config SERIAL_NONSTANDARD bool "Non-standard serial port support" depends on HAS_IOMEM --- linux-2.6.24.orig/drivers/char/defkeymap.c_shipped +++ linux-2.6.24/drivers/char/defkeymap.c_shipped @@ -223,40 +223,40 @@ }; struct kbdiacruc accent_table[MAX_DIACR] = { - {'`', 'A', '\300'}, {'`', 'a', '\340'}, - {'\'', 'A', '\301'}, {'\'', 'a', '\341'}, - {'^', 'A', '\302'}, {'^', 'a', '\342'}, - {'~', 'A', '\303'}, {'~', 'a', '\343'}, - {'"', 'A', '\304'}, {'"', 'a', '\344'}, - {'O', 'A', '\305'}, {'o', 'a', '\345'}, - {'0', 'A', '\305'}, {'0', 'a', '\345'}, - {'A', 'A', '\305'}, {'a', 'a', '\345'}, - {'A', 'E', '\306'}, {'a', 'e', '\346'}, - {',', 'C', '\307'}, {',', 'c', '\347'}, - {'`', 'E', '\310'}, {'`', 'e', '\350'}, - {'\'', 'E', '\311'}, {'\'', 'e', '\351'}, - {'^', 'E', '\312'}, {'^', 'e', '\352'}, - {'"', 'E', '\313'}, {'"', 'e', '\353'}, - {'`', 'I', '\314'}, {'`', 'i', '\354'}, - {'\'', 'I', '\315'}, {'\'', 'i', '\355'}, - {'^', 'I', '\316'}, {'^', 'i', '\356'}, - {'"', 'I', '\317'}, {'"', 'i', '\357'}, - {'-', 'D', '\320'}, {'-', 'd', '\360'}, - {'~', 'N', '\321'}, {'~', 'n', '\361'}, - {'`', 'O', '\322'}, {'`', 'o', '\362'}, - {'\'', 'O', '\323'}, {'\'', 'o', '\363'}, - {'^', 'O', '\324'}, {'^', 'o', '\364'}, - {'~', 'O', '\325'}, {'~', 'o', '\365'}, - {'"', 'O', '\326'}, {'"', 'o', '\366'}, - {'/', 'O', '\330'}, {'/', 'o', '\370'}, - {'`', 'U', '\331'}, {'`', 'u', '\371'}, - {'\'', 'U', '\332'}, {'\'', 'u', '\372'}, - {'^', 'U', '\333'}, {'^', 'u', '\373'}, - {'"', 'U', '\334'}, {'"', 'u', '\374'}, - {'\'', 'Y', '\335'}, {'\'', 'y', '\375'}, - {'T', 'H', '\336'}, {'t', 'h', '\376'}, - {'s', 's', '\337'}, {'"', 'y', '\377'}, - {'s', 'z', '\337'}, {'i', 'j', '\377'}, + {'`', 'A', 0300}, {'`', 'a', 0340}, + {'\'', 'A', 0301}, {'\'', 'a', 0341}, + {'^', 'A', 0302}, {'^', 'a', 0342}, + {'~', 'A', 0303}, {'~', 'a', 0343}, + {'"', 'A', 0304}, {'"', 'a', 0344}, + {'O', 'A', 0305}, {'o', 'a', 0345}, + {'0', 'A', 0305}, {'0', 'a', 0345}, + {'A', 'A', 0305}, {'a', 'a', 0345}, + {'A', 'E', 0306}, {'a', 'e', 0346}, + {',', 'C', 0307}, {',', 'c', 0347}, + {'`', 'E', 0310}, {'`', 'e', 0350}, + {'\'', 'E', 0311}, {'\'', 'e', 0351}, + {'^', 'E', 0312}, {'^', 'e', 0352}, + {'"', 'E', 0313}, {'"', 'e', 0353}, + {'`', 'I', 0314}, {'`', 'i', 0354}, + {'\'', 'I', 0315}, {'\'', 'i', 0355}, + {'^', 'I', 0316}, {'^', 'i', 0356}, + {'"', 'I', 0317}, {'"', 'i', 0357}, + {'-', 'D', 0320}, {'-', 'd', 0360}, + {'~', 'N', 0321}, {'~', 'n', 0361}, + {'`', 'O', 0322}, {'`', 'o', 0362}, + {'\'', 'O', 0323}, {'\'', 'o', 0363}, + {'^', 'O', 0324}, {'^', 'o', 0364}, + {'~', 'O', 0325}, {'~', 'o', 0365}, + {'"', 'O', 0326}, {'"', 'o', 0366}, + {'/', 'O', 0330}, {'/', 'o', 0370}, + {'`', 'U', 0331}, {'`', 'u', 0371}, + {'\'', 'U', 0332}, {'\'', 'u', 0372}, + {'^', 'U', 0333}, {'^', 'u', 0373}, + {'"', 'U', 0334}, {'"', 'u', 0374}, + {'\'', 'Y', 0335}, {'\'', 'y', 0375}, + {'T', 'H', 0336}, {'t', 'h', 0376}, + {'s', 's', 0337}, {'"', 'y', 0377}, + {'s', 'z', 0337}, {'i', 'j', 0377}, }; unsigned int accent_table_size = 68; --- linux-2.6.24.orig/drivers/char/vt.c +++ linux-2.6.24/drivers/char/vt.c @@ -264,6 +264,10 @@ #define DO_UPDATE(vc) CON_IS_VISIBLE(vc) #endif +#ifdef CONFIG_PROM_CONSOLE +static int force_prom_console; +#endif + static inline unsigned short *screenpos(struct vc_data *vc, int offset, int viewed) { unsigned short *p; @@ -702,6 +706,7 @@ if (is_switch) { set_leds(); compute_shiftstate(); + notify_update(vc); } } @@ -2882,6 +2887,17 @@ .unthrottle = con_unthrottle, }; +#ifdef CONFIG_PROM_CONSOLE +static int __init check_prom_console(char *str) +{ + force_prom_console = 1; + printk ("PROM console forced!\n"); + return 1; +} + +__setup("forcepromconsole", check_prom_console); +#endif + int __init vty_init(void) { vcs_init(); @@ -2904,7 +2920,8 @@ kbd_init(); console_map_init(); #ifdef CONFIG_PROM_CONSOLE - prom_con_init(); + if (force_prom_console) + prom_con_init(); #endif #ifdef CONFIG_MDA_CONSOLE mda_console_init(); --- linux-2.6.24.orig/drivers/char/mem.c +++ linux-2.6.24/drivers/char/mem.c @@ -108,6 +108,30 @@ } #endif +#ifdef CONFIG_NONPROMISC_DEVMEM +static inline int range_is_allowed(unsigned long from, unsigned long to) +{ + unsigned long cursor; + + cursor = from >> PAGE_SHIFT; + while ((cursor << PAGE_SHIFT) < to) { + if (!devmem_is_allowed(cursor)) { + printk(KERN_INFO "Program %s tried to read /dev/mem " + "between %lx->%lx.\n", + current->comm, from, to); + return 0; + } + cursor++; + } + return 1; +} +#else +static inline int range_is_allowed(unsigned long from, unsigned long to) +{ + return 1; +} +#endif + /* * This funcion reads the *physical* memory. The f_pos points directly to the * memory location. @@ -157,6 +181,8 @@ */ ptr = xlate_dev_mem_ptr(p); + if (!range_is_allowed(p, p+count)) + return -EPERM; if (copy_to_user(buf, ptr, sz)) return -EFAULT; buf += sz; @@ -214,6 +240,8 @@ */ ptr = xlate_dev_mem_ptr(p); + if (!range_is_allowed(p, p+sz)) + return -EPERM; copied = copy_from_user(ptr, buf, sz); if (copied) { written += sz - copied; @@ -295,6 +323,7 @@ return 0; } +#ifdef CONFIG_DEVKMEM static int mmap_kmem(struct file * file, struct vm_area_struct * vma) { unsigned long pfn; @@ -315,6 +344,7 @@ vma->vm_pgoff = pfn; return mmap_mem(file, vma); } +#endif #ifdef CONFIG_CRASH_DUMP /* @@ -353,6 +383,7 @@ extern long vread(char *buf, char *addr, unsigned long count); extern long vwrite(char *buf, char *addr, unsigned long count); +#ifdef CONFIG_DEVKMEM /* * This function reads the *virtual* memory as seen by the kernel. */ @@ -557,6 +588,7 @@ *ppos = p; return virtr + wrote; } +#endif #ifdef CONFIG_DEVPORT static ssize_t read_port(struct file * file, char __user * buf, @@ -734,6 +766,7 @@ .get_unmapped_area = get_unmapped_area_mem, }; +#ifdef CONFIG_DEVKMEM static const struct file_operations kmem_fops = { .llseek = memory_lseek, .read = read_kmem, @@ -742,6 +775,7 @@ .open = open_kmem, .get_unmapped_area = get_unmapped_area_mem, }; +#endif static const struct file_operations null_fops = { .llseek = null_lseek, @@ -820,11 +854,13 @@ filp->f_mapping->backing_dev_info = &directly_mappable_cdev_bdi; break; +#ifdef CONFIG_DEVKMEM case 2: filp->f_op = &kmem_fops; filp->f_mapping->backing_dev_info = &directly_mappable_cdev_bdi; break; +#endif case 3: filp->f_op = &null_fops; break; @@ -873,7 +909,9 @@ const struct file_operations *fops; } devlist[] = { /* list of minor devices */ {1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops}, +#ifdef CONFIG_DEVKMEM {2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops}, +#endif {3, "null", S_IRUGO | S_IWUGO, &null_fops}, #ifdef CONFIG_DEVPORT {4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops}, --- linux-2.6.24.orig/drivers/char/virtio_console.c +++ linux-2.6.24/drivers/char/virtio_console.c @@ -158,13 +158,13 @@ /* Find the input queue. */ /* FIXME: This is why we want to wean off hvc: we do nothing * when input comes in. */ - in_vq = vdev->config->find_vq(vdev, NULL); + in_vq = vdev->config->find_vq(vdev, 0, NULL); if (IS_ERR(in_vq)) { err = PTR_ERR(in_vq); goto free; } - out_vq = vdev->config->find_vq(vdev, NULL); + out_vq = vdev->config->find_vq(vdev, 1, NULL); if (IS_ERR(out_vq)) { err = PTR_ERR(out_vq); goto free_in_vq; --- linux-2.6.24.orig/drivers/char/vt_ioctl.c +++ linux-2.6.24/drivers/char/vt_ioctl.c @@ -35,6 +35,8 @@ #include #include +#define max_font_size 65536 + char vt_dont_switch; extern struct tty_driver *console_driver; @@ -1166,6 +1168,7 @@ static void complete_change_console(struct vc_data *vc) { unsigned char old_vc_mode; + struct vc_data *oldvc = vc_cons[fg_console].d; last_console = fg_console; @@ -1174,9 +1177,31 @@ * KD_TEXT mode or vice versa, which means we need to blank or * unblank the screen later. */ - old_vc_mode = vc_cons[fg_console].d->vc_mode; + old_vc_mode = oldvc->vc_mode; + +#if defined(CONFIG_VGA_CONSOLE) + if (old_vc_mode == KD_TEXT && oldvc->vc_sw == &vga_con && + oldvc->vc_sw->con_font_get) { + if (!oldvc->vc_font.data) + oldvc->vc_font.data = kmalloc(max_font_size, + GFP_KERNEL); + lock_kernel(); + oldvc->vc_sw->con_font_get(oldvc, &oldvc->vc_font); + unlock_kernel(); + } +#endif switch_screen(vc); +#if defined(CONFIG_VGA_CONSOLE) + if (vc->vc_mode == KD_TEXT && vc->vc_sw == &vga_con && + vc->vc_sw->con_font_set) { + if (vc->vc_font.data) { + lock_kernel(); + vc->vc_sw->con_font_set(vc, &vc->vc_font, 0); + unlock_kernel(); + } + } +#endif /* * This can't appear below a successful kill_pid(). If it did, * then the *blank_screen operation could occur while X, having --- linux-2.6.24.orig/drivers/char/drm/via_chrome9_drm.c +++ linux-2.6.24/drivers/char/drm/via_chrome9_drm.c @@ -0,0 +1,993 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, subject to the + * following conditions: + * + * The above copyright notice and this permission notice + * (including the next paragraph) shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL VIA, S3 GRAPHICS, AND/OR + * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include "drmP.h" +#include "via_chrome9_drm.h" +#include "via_chrome9_drv.h" +#include "via_chrome9_mm.h" +#include "via_chrome9_dma.h" +#include "via_chrome9_3d_reg.h" + +#define VIA_CHROME9DRM_VIDEO_STARTADDRESS_ALIGNMENT 10 + + +void __via_chrome9ke_udelay(unsigned long usecs) +{ + unsigned long start; + unsigned long stop; + unsigned long period; + unsigned long wait_period; + struct timespec tval; + +#ifdef NDELAY_LIMIT +#define UDELAY_LIMIT (NDELAY_LIMIT/1000) /* supposed to be 10 msec */ +#else +#define UDELAY_LIMIT (10000) /* 10 msec */ +#endif + + if (usecs > UDELAY_LIMIT) { + start = jiffies; + tval.tv_sec = usecs / 1000000; + tval.tv_nsec = (usecs - tval.tv_sec * 1000000) * 1000; + wait_period = timespec_to_jiffies(&tval); + do { + stop = jiffies; + + if (stop < start) + period = ((unsigned long)-1 - start) + stop + 1; + else + period = stop - start; + + } while (period < wait_period); + } else + udelay(usecs); /* delay value might get checked once again */ +} + +int via_chrome9_ioctl_process_exit(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + return 0; +} + +int via_chrome9_ioctl_restore_primary(struct drm_device *dev, + void *data, struct drm_file *file_priv) +{ + return 0; +} + +void Initialize3DEngine(struct drm_via_chrome9_private *dev_priv) +{ + int i; + unsigned int StageOfTexture; + + if (dev_priv->chip_sub_index == CHIP_H5 || + dev_priv->chip_sub_index == CHIP_H5S1) { + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + 0x00010000); + + for (i = 0; i <= 0x8A; i++) { + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (unsigned int) i << 24); + } + + /* Initial Texture Stage Setting*/ + for (StageOfTexture = 0; StageOfTexture < 0xf; + StageOfTexture++) { + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + (0x00020000 | 0x00000000 | + (StageOfTexture & 0xf)<<24)); + /* *((unsigned int volatile*)(pMapIOPort+HC_REG_TRANS_SET)) = + (0x00020000 | HC_ParaSubType_Tex0 | (StageOfTexture & + 0xf)<<24);*/ + for (i = 0 ; i <= 0x30 ; i++) { + /* *((unsigned int volatile*)(pMapIOPort+ + HC_REG_Hpara0)) = ((unsigned int) i << 24);*/ + SetMMIORegister(dev_priv->mmio->handle, + 0x440, (unsigned int) i << 24); + } + } + + /* Initial Texture Sampler Setting*/ + for (StageOfTexture = 0; StageOfTexture < 0xf; + StageOfTexture++) { + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + (0x00020000 | 0x00020000 | + (StageOfTexture & 0xf)<<24)); + /* *((unsigned int volatile*)(pMapIOPort+ + HC_REG_TRANS_SET)) = (0x00020000 | 0x00020000 | + ( StageOfTexture & 0xf)<<24);*/ + for (i = 0 ; i <= 0x30 ; i++) { + /* *((unsigned int volatile*)(pMapIOPort+ + HC_REG_Hpara0)) = ((unsigned int) i << 24);*/ + SetMMIORegister(dev_priv->mmio->handle, + 0x440, (unsigned int) i << 24); + } + } + + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + (0x00020000 | 0xfe000000)); + /* *((unsigned int volatile*)(pMapIOPort+HC_REG_TRANS_SET)) = + (0x00020000 | HC_ParaSubType_TexGen);*/ + for (i = 0 ; i <= 0x13 ; i++) { + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (unsigned int) i << 24); + /* *((unsigned int volatile*)(pMapIOPort+ + HC_REG_Hpara0)) = ((unsigned int) i << 24);*/ + } + + /* Initial Gamma Table Setting*/ + /* Initial Gamma Table Setting*/ + /* 5 + 4 = 9 (12) dwords*/ + /* sRGB texture is not directly support by H3 hardware. + We have to set the deGamma table for texture sampling.*/ + + /* degamma table*/ + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + (0x00030000 | 0x15000000)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (0x40000000 | (30 << 20) | (15 << 10) | (5))); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + ((119 << 20) | (81 << 10) | (52))); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + ((283 << 20) | (219 << 10) | (165))); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + ((535 << 20) | (441 << 10) | (357))); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + ((119 << 20) | (884 << 20) | (757 << 10) | + (640))); + + /* gamma table*/ + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + (0x00030000 | 0x17000000)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (0x40000000 | (13 << 20) | (13 << 10) | (13))); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (0x40000000 | (26 << 20) | (26 << 10) | (26))); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (0x40000000 | (39 << 20) | (39 << 10) | (39))); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + ((51 << 20) | (51 << 10) | (51))); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + ((71 << 20) | (71 << 10) | (71))); + SetMMIORegister(dev_priv->mmio->handle, + 0x440, (87 << 20) | (87 << 10) | (87)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (113 << 20) | (113 << 10) | (113)); + SetMMIORegister(dev_priv->mmio->handle, + 0x440, (135 << 20) | (135 << 10) | (135)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (170 << 20) | (170 << 10) | (170)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (199 << 20) | (199 << 10) | (199)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (246 << 20) | (246 << 10) | (246)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (284 << 20) | (284 << 10) | (284)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (317 << 20) | (317 << 10) | (317)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (347 << 20) | (347 << 10) | (347)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (373 << 20) | (373 << 10) | (373)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (398 << 20) | (398 << 10) | (398)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (442 << 20) | (442 << 10) | (442)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (481 << 20) | (481 << 10) | (481)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (517 << 20) | (517 << 10) | (517)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (550 << 20) | (550 << 10) | (550)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (609 << 20) | (609 << 10) | (609)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (662 << 20) | (662 << 10) | (662)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (709 << 20) | (709 << 10) | (709)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (753 << 20) | (753 << 10) | (753)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (794 << 20) | (794 << 10) | (794)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (832 << 20) | (832 << 10) | (832)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (868 << 20) | (868 << 10) | (868)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (902 << 20) | (902 << 10) | (902)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (934 << 20) | (934 << 10) | (934)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (966 << 20) | (966 << 10) | (966)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (996 << 20) | (996 << 10) | (996)); + + + /* + For Interrupt Restore only All types of write through + regsiters should be write header data to hardware at + least before it can restore. H/W will automatically + record the header to write through state buffer for + resture usage. + By Jaren: + HParaType = 8'h03, HParaSubType = 8'h00 + 8'h11 + 8'h12 + 8'h14 + 8'h15 + 8'h17 + HParaSubType 8'h12, 8'h15 is initialized. + [HWLimit] + 1. All these write through registers can't be partial + update. + 2. All these write through must be AGP command + 16 entries : 4 128-bit data */ + + /* Initialize INV_ParaSubType_TexPal */ + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + (0x00030000 | 0x00000000)); + for (i = 0; i < 16; i++) { + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x00000000); + } + + /* Initialize INV_ParaSubType_4X4Cof */ + /* 32 entries : 8 128-bit data */ + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + (0x00030000 | 0x11000000)); + for (i = 0; i < 32; i++) { + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x00000000); + } + + /* Initialize INV_ParaSubType_StipPal */ + /* 5 entries : 2 128-bit data */ + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + (0x00030000 | 0x14000000)); + for (i = 0; i < (5+3); i++) { + SetMMIORegister(dev_priv->mmio->handle, + 0x440, 0x00000000); + } + + /* primitive setting & vertex format*/ + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + (0x00040000 | 0x14000000)); + for (i = 0; i < 52; i++) { + SetMMIORegister(dev_priv->mmio->handle, + 0x440, ((unsigned int) i << 24)); + } + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + 0x00fe0000); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x4000840f); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x47000400); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x44000000); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x46000000); + + /* setting Misconfig*/ + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + 0x00fe0000); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x00001004); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x0800004b); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x0a000049); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x0b0000fb); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x0c000001); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x0d0000cb); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x0e000009); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x10000000); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x110000ff); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x12000000); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x130000db); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x14000000); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x15000000); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x16000000); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x17000000); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x18000000); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x19000000); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x20000000); + } else if (dev_priv->chip_sub_index == CHIP_H6S2) { + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + 0x00010000); + for (i = 0; i <= 0x9A; i++) { + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (unsigned int) i << 24); + } + + /* Initial Texture Stage Setting*/ + for (StageOfTexture = 0; StageOfTexture <= 0xf; + StageOfTexture++) { + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + (0x00020000 | 0x00000000 | + (StageOfTexture & 0xf)<<24)); + /* *((unsigned int volatile*)(pMapIOPort+ + HC_REG_TRANS_SET)) = + (0x00020000 | HC_ParaSubType_Tex0 | + (StageOfTexture & 0xf)<<24);*/ + for (i = 0 ; i <= 0x30 ; i++) { + /* *((unsigned int volatile*)(pMapIOPort+ + HC_REG_Hpara0)) =((unsigned int) i << 24);*/ + SetMMIORegister(dev_priv->mmio->handle, + 0x440, (unsigned int) i << 24); + } + } + + /* Initial Texture Sampler Setting*/ + for (StageOfTexture = 0; StageOfTexture <= 0xf; + StageOfTexture++) { + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + (0x00020000 | 0x20000000 | + (StageOfTexture & 0xf)<<24)); + /* *((unsigned int volatile*)(pMapIOPort+ + HC_REG_TRANS_SET)) =(0x00020000 | 0x00020000 | + ( StageOfTexture & 0xf)<<24);*/ + for (i = 0 ; i <= 0x36 ; i++) { + /* *((unsigned int volatile*)(pMapIOPort+ + HC_REG_Hpara0)) =((unsigned int) i << 24);*/ + SetMMIORegister(dev_priv->mmio->handle, + 0x440, (unsigned int) i << 24); + } + } + + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + (0x00020000 | 0xfe000000)); + for (i = 0 ; i <= 0x13 ; i++) { + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (unsigned int) i << 24); + /* *((unsigned int volatile*)(pMapIOPort+ + HC_REG_Hpara0)) =((unsigned int) i << 24);*/ + } + + /* Initial Gamma Table Setting*/ + /* Initial Gamma Table Setting*/ + /* 5 + 4 = 9 (12) dwords*/ + /* sRGB texture is not directly support by + H3 hardware.*/ + /* We have to set the deGamma table for texture + sampling.*/ + + /* degamma table*/ + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + (0x00030000 | 0x15000000)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (0x40000000 | (30 << 20) | (15 << 10) | (5))); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + ((119 << 20) | (81 << 10) | (52))); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + ((283 << 20) | (219 << 10) | (165))); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + ((535 << 20) | (441 << 10) | (357))); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + ((119 << 20) | (884 << 20) | (757 << 10) + | (640))); + + /* gamma table*/ + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + (0x00030000 | 0x17000000)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (0x40000000 | (13 << 20) | (13 << 10) | (13))); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (0x40000000 | (26 << 20) | (26 << 10) | (26))); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (0x40000000 | (39 << 20) | (39 << 10) | (39))); + SetMMIORegister(dev_priv->mmio->handle, + 0x440, ((51 << 20) | (51 << 10) | (51))); + SetMMIORegister(dev_priv->mmio->handle, + 0x440, ((71 << 20) | (71 << 10) | (71))); + SetMMIORegister(dev_priv->mmio->handle, + 0x440, (87 << 20) | (87 << 10) | (87)); + SetMMIORegister(dev_priv->mmio->handle, + 0x440, (113 << 20) | (113 << 10) | (113)); + SetMMIORegister(dev_priv->mmio->handle, + 0x440, (135 << 20) | (135 << 10) | (135)); + SetMMIORegister(dev_priv->mmio->handle, + 0x440, (170 << 20) | (170 << 10) | (170)); + SetMMIORegister(dev_priv->mmio->handle, + 0x440, (199 << 20) | (199 << 10) | (199)); + SetMMIORegister(dev_priv->mmio->handle, + 0x440, (246 << 20) | (246 << 10) | (246)); + SetMMIORegister(dev_priv->mmio->handle, + 0x440, (284 << 20) | (284 << 10) | (284)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (317 << 20) | (317 << 10) | (317)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (347 << 20) | (347 << 10) | (347)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (373 << 20) | (373 << 10) | (373)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (398 << 20) | (398 << 10) | (398)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (442 << 20) | (442 << 10) | (442)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (481 << 20) | (481 << 10) | (481)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (517 << 20) | (517 << 10) | (517)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (550 << 20) | (550 << 10) | (550)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (609 << 20) | (609 << 10) | (609)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (662 << 20) | (662 << 10) | (662)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (709 << 20) | (709 << 10) | (709)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (753 << 20) | (753 << 10) | (753)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (794 << 20) | (794 << 10) | (794)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (832 << 20) | (832 << 10) | (832)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (868 << 20) | (868 << 10) | (868)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (902 << 20) | (902 << 10) | (902)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (934 << 20) | (934 << 10) | (934)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (966 << 20) | (966 << 10) | (966)); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + (996 << 20) | (996 << 10) | (996)); + + + /* For Interrupt Restore only + All types of write through regsiters should be write + header data to hardware at least before it can restore. + H/W will automatically record the header to write + through state buffer for restureusage. + By Jaren: + HParaType = 8'h03, HParaSubType = 8'h00 + 8'h11 + 8'h12 + 8'h14 + 8'h15 + 8'h17 + HParaSubType 8'h12, 8'h15 is initialized. + [HWLimit] + 1. All these write through registers can't be partial + update. + 2. All these write through must be AGP command + 16 entries : 4 128-bit data */ + + /* Initialize INV_ParaSubType_TexPal */ + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + (0x00030000 | 0x00000000)); + for (i = 0; i < 16; i++) { + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x00000000); + } + + /* Initialize INV_ParaSubType_4X4Cof */ + /* 32 entries : 8 128-bit data */ + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + (0x00030000 | 0x11000000)); + for (i = 0; i < 32; i++) { + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x00000000); + } + + /* Initialize INV_ParaSubType_StipPal */ + /* 5 entries : 2 128-bit data */ + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + (0x00030000 | 0x14000000)); + for (i = 0; i < (5+3); i++) { + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x00000000); + } + + /* primitive setting & vertex format*/ + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + (0x00040000)); + for (i = 0; i <= 0x62; i++) { + SetMMIORegister(dev_priv->mmio->handle, 0x440, + ((unsigned int) i << 24)); + } + + /*ParaType 0xFE - Configure and Misc Setting*/ + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + (0x00fe0000)); + for (i = 0; i <= 0x47; i++) { + SetMMIORegister(dev_priv->mmio->handle, 0x440, + ((unsigned int) i << 24)); + } + /*ParaType 0x11 - Frame Buffer Auto-Swapping and + Command Regulator Misc*/ + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + (0x00110000)); + for (i = 0; i <= 0x20; i++) { + SetMMIORegister(dev_priv->mmio->handle, 0x440, + ((unsigned int) i << 24)); + } + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + 0x00fe0000); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x4000840f); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x47000404); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x44000000); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x46000005); + + /* setting Misconfig*/ + SetMMIORegister(dev_priv->mmio->handle, 0x43C, + 0x00fe0000); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x00001004); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x08000249); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x0a0002c9); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x0b0002fb); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x0c000000); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x0d0002cb); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x0e000009); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x10000049); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x110002ff); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x12000008); + SetMMIORegister(dev_priv->mmio->handle, 0x440, + 0x130002db); + } +} + +int via_chrome9_drm_resume(struct pci_dev *pci) +{ + struct drm_device *dev = (struct drm_device *)pci_get_drvdata(pci); + struct drm_via_chrome9_private *dev_priv = + (struct drm_via_chrome9_private *)dev->dev_private; + struct drm_via_chrome9_DMA_manager *lpcmDMAManager = + dev_priv->dma_manager; + + Initialize3DEngine(dev_priv); + + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_TRANS, 0x00110000); + if (dev_priv->chip_sub_index == CHIP_H6S2) { + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, + 0x06000000); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, + 0x07100000); + } else{ + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, + 0x02000000); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, + 0x03100000); + } + + + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_TRANS, + INV_ParaType_PreCR); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, + INV_SubA_HSetRBGID | INV_HSetRBGID_CR); + + if (dev_priv->chip_sub_index == CHIP_H6S2) { + unsigned int *pGARTTable; + unsigned int i, entries, GARTOffset; + unsigned char sr6a, sr6b, sr6c, sr6f, sr7b; + unsigned int *addrlinear; + unsigned int size, alignedoffset; + + entries = dev_priv->pagetable_map.pagetable_size / + sizeof(unsigned int); + pGARTTable = dev_priv->pagetable_map.pagetable_handle; + + GARTOffset = dev_priv->pagetable_map.pagetable_offset; + + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6c); + sr6c = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5); + sr6c &= (~0x80); + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6c); + + sr6a = (unsigned char)((GARTOffset & 0xff000) >> 12); + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6a); + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6a); + + sr6b = (unsigned char)((GARTOffset & 0xff00000) >> 20); + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6b); + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6b); + + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6c); + sr6c = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5); + sr6c |= ((unsigned char)((GARTOffset >> 28) & 0x01)); + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6c); + + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x7b); + sr7b = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5); + sr7b &= (~0x0f); + sr7b |= ProtectSizeValue(dev_priv-> + pagetable_map.pagetable_size); + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr7b); + + for (i = 0; i < entries; i++) + writel(0x80000000, pGARTTable+i); + + /*flush*/ + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6f); + do { + sr6f = GetMMIORegisterU8(dev_priv->mmio->handle, + 0x83c5); + } while (sr6f & 0x80); + + sr6f |= 0x80; + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6f); + + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6c); + sr6c = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5); + sr6c |= 0x80; + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6c); + + size = lpcmDMAManager->DMASize * sizeof(unsigned int) + + dev_priv->agp_size; + alignedoffset = 0; + entries = (size + PAGE_SIZE - 1) / PAGE_SIZE; + addrlinear = (unsigned int *)dev_priv->pcie_vmalloc_nocache; + + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6c); + sr6c = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5); + sr6c &= (~0x80); + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6c); + + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6f); + do { + sr6f = GetMMIORegisterU8(dev_priv->mmio->handle, + 0x83c5); + } while (sr6f & 0x80); + + for (i = 0; i < entries; i++) + writel(page_to_pfn(vmalloc_to_page((void *)addrlinear + + PAGE_SIZE * i)) & 0x3fffffff, pGARTTable+ + i+alignedoffset); + + sr6f |= 0x80; + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6f); + + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6c); + sr6c = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5); + sr6c |= 0x80; + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6c); + + } + + if (dev_priv->drm_agp_type == DRM_AGP_DOUBLE_BUFFER) + SetAGPDoubleCmd_inv(dev); + else if (dev_priv->drm_agp_type == DRM_AGP_RING_BUFFER) + SetAGPRingCmdRegs_inv(dev); + return 0; +} + +int via_chrome9_drm_suspend(struct pci_dev *dev, + pm_message_t state) +{ + return 0; +} + +int via_chrome9_driver_load(struct drm_device *dev, + unsigned long chipset) +{ + struct drm_via_chrome9_private *dev_priv; + int ret = 0; + static int associate; + + if (!associate) { + pci_set_drvdata(dev->pdev, dev); + dev->pdev->driver = &dev->driver->pci_driver; + associate = 1; + } + + dev->counters += 4; + dev->types[6] = _DRM_STAT_IRQ; + dev->types[7] = _DRM_STAT_PRIMARY; + dev->types[8] = _DRM_STAT_SECONDARY; + dev->types[9] = _DRM_STAT_DMA; + + dev_priv = drm_calloc(1, sizeof(struct drm_via_chrome9_private), + DRM_MEM_DRIVER); + if (dev_priv == NULL) + return -ENOMEM; + + /* Clear */ + memset(dev_priv, 0, sizeof(struct drm_via_chrome9_private)); + + dev_priv->dev = dev; + dev->dev_private = (void *)dev_priv; + + dev_priv->chip_index = chipset; + + ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); + if (ret) + drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); + return ret; +} + +int via_chrome9_driver_unload(struct drm_device *dev) +{ + struct drm_via_chrome9_private *dev_priv = dev->dev_private; + + drm_sman_takedown(&dev_priv->sman); + + drm_free(dev_priv, sizeof(struct drm_via_chrome9_private), + DRM_MEM_DRIVER); + + return 0; +} + +static int via_chrome9_initialize(struct drm_device *dev, + struct drm_via_chrome9_init *init) +{ + struct drm_via_chrome9_private *dev_priv = + (struct drm_via_chrome9_private *)dev->dev_private; + + dev_priv->chip_agp = init->chip_agp; + dev_priv->chip_index = init->chip_index; + dev_priv->chip_sub_index = init->chip_sub_index; + + dev_priv->usec_timeout = init->usec_timeout; + dev_priv->front_offset = init->front_offset; + dev_priv->back_offset = init->back_offset >> + VIA_CHROME9DRM_VIDEO_STARTADDRESS_ALIGNMENT << + VIA_CHROME9DRM_VIDEO_STARTADDRESS_ALIGNMENT; + dev_priv->available_fb_size = init->available_fb_size - + (init->available_fb_size % + (1 << VIA_CHROME9DRM_VIDEO_STARTADDRESS_ALIGNMENT)); + dev_priv->depth_offset = init->depth_offset; + + /* Find all the map added first, doing this is necessary to + intialize hw */ + if (via_chrome9_map_init(dev, init)) { + DRM_ERROR("function via_chrome9_map_init ERROR !\n"); + goto error; + } + + /* Necessary information has been gathered for initialize hw */ + if (via_chrome9_hw_init(dev, init)) { + DRM_ERROR("function via_chrome9_hw_init ERROR !\n"); + goto error; + } + + /* After hw intialization, we have kown whether to use agp + or to use pcie for texture */ + if (via_chrome9_heap_management_init(dev, init)) { + DRM_ERROR("function \ + via_chrome9_heap_management_init ERROR !\n"); + goto error; + } + + return 0; + +error: + /* all the error recover has been processed in relevant function, + so here just return error */ + return -EINVAL; +} + +static void via_chrome9_cleanup(struct drm_device *dev, + struct drm_via_chrome9_init *init) +{ + struct drm_via_chrome9_DMA_manager *lpcmDMAManager = NULL; + struct drm_via_chrome9_private *dev_priv = + (struct drm_via_chrome9_private *)dev->dev_private; + DRM_DEBUG("function via_chrome9_cleanup run!\n"); + + if (!dev_priv) + return ; + + lpcmDMAManager = + (struct drm_via_chrome9_DMA_manager *)dev_priv->dma_manager; + if (dev_priv->pcie_vmalloc_nocache) { + vfree((void *)dev_priv->pcie_vmalloc_nocache); + dev_priv->pcie_vmalloc_nocache = 0; + if (lpcmDMAManager) + lpcmDMAManager->addr_linear = NULL; + } + + if (dev_priv->pagetable_map.pagetable_handle) { + iounmap(dev_priv->pagetable_map.pagetable_handle); + dev_priv->pagetable_map.pagetable_handle = NULL; + } + + if (lpcmDMAManager && lpcmDMAManager->addr_linear) { + iounmap(lpcmDMAManager->addr_linear); + lpcmDMAManager->addr_linear = NULL; + } + + kfree(lpcmDMAManager); + dev_priv->dma_manager = NULL; + + if (dev_priv->event_tag_info) { + vfree(dev_priv->event_tag_info); + dev_priv->event_tag_info = NULL; + } + + if (dev_priv->bci_buffer) { + vfree(dev_priv->bci_buffer); + dev_priv->bci_buffer = NULL; + } + + via_chrome9_memory_destroy_heap(dev, dev_priv); +} + +/* +Do almost everything intialize here,include: +1.intialize all addmaps in private data structure +2.intialize memory heap management for video agp/pcie +3.intialize hw for dma(pcie/agp) function + +Note:all this function will dispatch into relevant function +*/ +int via_chrome9_ioctl_init(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_via_chrome9_init *init = (struct drm_via_chrome9_init *)data; + + switch (init->func) { + case VIA_CHROME9_INIT: + if (via_chrome9_initialize(dev, init)) { + DRM_ERROR("function via_chrome9_initialize error\n"); + return -1; + } + break; + + case VIA_CHROME9_CLEANUP: + via_chrome9_cleanup(dev, init); + break; + + default: + return -1; + } + + return 0; +} + +int via_chrome9_ioctl_allocate_event_tag(struct drm_device *dev, + void *data, struct drm_file *file_priv) +{ + struct drm_via_chrome9_event_tag *event_tag = data; + struct drm_via_chrome9_private *dev_priv = + (struct drm_via_chrome9_private *)dev->dev_private; + struct drm_clb_event_tag_info *event_tag_info = + dev_priv->event_tag_info; + unsigned int *event_addr = 0, i = 0; + + for (i = 0; i < NUMBER_OF_EVENT_TAGS; i++) { + if (!event_tag_info->usage[i]) + break; + } + + if (i < NUMBER_OF_EVENT_TAGS) { + event_tag_info->usage[i] = 1; + event_tag->event_offset = i; + event_tag->last_sent_event_value.event_low = 0; + event_tag->current_event_value.event_low = 0; + event_addr = event_tag_info->linear_address + + event_tag->event_offset * 4; + *event_addr = 0; + return 0; + } else { + return -7; + } + + return 0; +} + +int via_chrome9_ioctl_free_event_tag(struct drm_device *dev, + void *data, struct drm_file *file_priv) +{ + struct drm_via_chrome9_private *dev_priv = + (struct drm_via_chrome9_private *)dev->dev_private; + struct drm_clb_event_tag_info *event_tag_info = + dev_priv->event_tag_info; + struct drm_via_chrome9_event_tag *event_tag = data; + + event_tag_info->usage[event_tag->event_offset] = 0; + return 0; +} + +void via_chrome9_lastclose(struct drm_device *dev) +{ + via_chrome9_cleanup(dev, 0); + return ; +} + +static int via_chrome9_do_wait_vblank(struct drm_via_chrome9_private + *dev_priv) +{ + int i; + + for (i = 0; i < dev_priv->usec_timeout; i++) { + VIA_CHROME9_WRITE8(0x83d4, 0x34); + if ((VIA_CHROME9_READ8(0x83d5)) & 0x8) + return 0; + __via_chrome9ke_udelay(1); + } + + return (-1); +} + +void via_chrome9_preclose(struct drm_device *dev, struct drm_file *file_priv) +{ + struct drm_via_chrome9_private *dev_priv = + (struct drm_via_chrome9_private *) dev->dev_private; + struct drm_via_chrome9_sarea *sarea_priv = NULL; + + if (!dev_priv) + return ; + + sarea_priv = dev_priv->sarea_priv; + if (!sarea_priv) + return ; + + if ((sarea_priv->page_flip == 1) && + (sarea_priv->current_page != VIA_CHROME9_FRONT)) { + volatile unsigned long *bci_base; + if (via_chrome9_do_wait_vblank(dev_priv)) + return; + + bci_base = (volatile unsigned long *)(dev_priv->bci); + + BCI_SET_STREAM_REGISTER(bci_base, 0x81c4, 0xc0000000); + BCI_SET_STREAM_REGISTER(bci_base, 0x81c0, + dev_priv->front_offset); + BCI_SEND(bci_base, 0x64000000);/* wait vsync */ + + sarea_priv->current_page = VIA_CHROME9_FRONT; + } +} + +int via_chrome9_is_agp(struct drm_device *dev) +{ + /* filter out pcie group which has no AGP device */ + if (dev->pci_device == 0x1122) { + dev->driver->driver_features &= + ~(DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_REQUIRE_AGP); + return 0; + } + return 1; +} + --- linux-2.6.24.orig/drivers/char/drm/via_chrome9_3d_reg.h +++ linux-2.6.24/drivers/char/drm/via_chrome9_3d_reg.h @@ -0,0 +1,401 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, subject to the + * following conditions: + * + * The above copyright notice and this permission notice + * (including the next paragraph) shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL VIA, S3 GRAPHICS, AND/OR + * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef VIA_CHROME9_3D_REG_H +#define VIA_CHROME9_3D_REG_H + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +#define GetMMIORegister(base, offset) \ + (*(volatile unsigned int *)(void *)(((unsigned char *)(base)) + \ + (offset))) +#define SetMMIORegister(base, offset, val) \ + (*(volatile unsigned int *)(void *)(((unsigned char *)(base)) + \ + (offset)) = (val)) + +#define GetMMIORegisterU8(base, offset) \ + (*(volatile unsigned char *)(void *)(((unsigned char *)(base)) + \ + (offset))) +#define SetMMIORegisterU8(base, offset, val) \ + (*(volatile unsigned char *)(void *)(((unsigned char *)(base)) + \ + (offset)) = (val)) + +#define BCI_SEND(bci, value) (*(bci)++ = (unsigned long)(value)) +#define BCI_SET_STREAM_REGISTER(bci_base, bci_index, reg_value) \ +do { \ + unsigned long cmd; \ + \ + cmd = (0x90000000 \ + | (1<<16) /* stream processor register */ \ + | (bci_index & 0x3FFC)); /* MMIO register address */ \ + BCI_SEND(bci_base, cmd); \ + BCI_SEND(bci_base, reg_value); \ + } while (0) + +/* Command Header Type */ + +#define INV_AGPHeader0 0xFE000000 +#define INV_AGPHeader1 0xFE010000 +#define INV_AGPHeader2 0xFE020000 +#define INV_AGPHeader3 0xFE030000 +#define INV_AGPHeader4 0xFE040000 +#define INV_AGPHeader5 0xFE050000 +#define INV_AGPHeader6 0xFE060000 +#define INV_AGPHeader7 0xFE070000 +#define INV_AGPHeader82 0xFE820000 +#define INV_AGPHeader_MASK 0xFFFF0000 + +/*send pause address of AGP ring command buffer via_chrome9 this IO port*/ +#define INV_REG_PCIPAUSE 0x294 +#define INV_REG_PCIPAUSE_ENABLE 0x4 + +#define INV_CMDBUF_THRESHOLD (8) +#define INV_QW_PAUSE_ALIGN 0x40 + +/* Transmission IO Space*/ +#define INV_REG_CR_TRANS 0x041C +#define INV_REG_CR_BEGIN 0x0420 +#define INV_REG_CR_END 0x0438 + +#define INV_REG_3D_TRANS 0x043C +#define INV_REG_3D_BEGIN 0x0440 +#define INV_REG_3D_END 0x06FC +#define INV_REG_23D_WAIT 0x326C +/*3D / 2D ID Control (Only For Group A)*/ +#define INV_REG_2D3D_ID_CTRL 0x060 + + +/* Engine Status */ + +#define INV_RB_ENG_STATUS 0x0400 +#define INV_ENG_BUSY_HQV0 0x00040000 +#define INV_ENG_BUSY_HQV1 0x00020000 +#define INV_ENG_BUSY_CR 0x00000010 +#define INV_ENG_BUSY_MPEG 0x00000008 +#define INV_ENG_BUSY_VQ 0x00000004 +#define INV_ENG_BUSY_2D 0x00000002 +#define INV_ENG_BUSY_3D 0x00001FE1 +#define INV_ENG_BUSY_ALL \ + (INV_ENG_BUSY_2D | INV_ENG_BUSY_3D | INV_ENG_BUSY_CR) + +/* Command Queue Status*/ +#define INV_RB_VQ_STATUS 0x0448 +#define INV_VQ_FULL 0x40000000 + +/* AGP command buffer pointer current position*/ +#define INV_RB_AGPCMD_CURRADDR 0x043C + +/* AGP command buffer status*/ +#define INV_RB_AGPCMD_STATUS 0x0444 +#define INV_AGPCMD_InPause 0x80000000 + +/*AGP command buffer pause address*/ +#define INV_RB_AGPCMD_PAUSEADDR 0x045C + +/*AGP command buffer jump address*/ +#define INV_RB_AGPCMD_JUMPADDR 0x0460 + +/*AGP command buffer start address*/ +#define INV_RB_AGPCMD_STARTADDR 0x0464 + + +/* Constants */ +#define NUMBER_OF_EVENT_TAGS 1024 +#define NUMBER_OF_APERTURES_CLB 16 + +/* Register definition */ +#define HW_SHADOW_ADDR 0x8520 +#define HW_GARTTABLE_ADDR 0x8540 + +#define INV_HSWFlag_DBGMASK 0x00000FFF +#define INV_HSWFlag_ENCODEMASK 0x007FFFF0 +#define INV_HSWFlag_ADDRSHFT 8 +#define INV_HSWFlag_DECODEMASK \ + (INV_HSWFlag_ENCODEMASK << INV_HSWFlag_ADDRSHFT) +#define INV_HSWFlag_ADDR_ENCODE(x) 0xCC000000 +#define INV_HSWFlag_ADDR_DECODE(x) \ + (((unsigned int)x & INV_HSWFlag_DECODEMASK) >> INV_HSWFlag_ADDRSHFT) + + +#define INV_SubA_HAGPBstL 0x60000000 +#define INV_SubA_HAGPBstH 0x61000000 +#define INV_SubA_HAGPBendL 0x62000000 +#define INV_SubA_HAGPBendH 0x63000000 +#define INV_SubA_HAGPBpL 0x64000000 +#define INV_SubA_HAGPBpID 0x65000000 +#define INV_HAGPBpID_PAUSE 0x00000000 +#define INV_HAGPBpID_JUMP 0x00000100 +#define INV_HAGPBpID_STOP 0x00000200 + +#define INV_HAGPBpH_MASK 0x000000FF +#define INV_HAGPBpH_SHFT 0 + +#define INV_SubA_HAGPBjumpL 0x66000000 +#define INV_SubA_HAGPBjumpH 0x67000000 +#define INV_HAGPBjumpH_MASK 0x000000FF +#define INV_HAGPBjumpH_SHFT 0 + +#define INV_SubA_HFthRCM 0x68000000 +#define INV_HFthRCM_MASK 0x003F0000 +#define INV_HFthRCM_SHFT 16 +#define INV_HFthRCM_8 0x00080000 +#define INV_HFthRCM_10 0x000A0000 +#define INV_HFthRCM_18 0x00120000 +#define INV_HFthRCM_24 0x00180000 +#define INV_HFthRCM_32 0x00200000 + +#define INV_HAGPBClear 0x00000008 + +#define INV_HRSTTrig_RestoreAGP 0x00000004 +#define INV_HRSTTrig_RestoreAll 0x00000002 +#define INV_HAGPBTrig 0x00000001 + +#define INV_ParaSubType_MASK 0xff000000 +#define INV_ParaType_MASK 0x00ff0000 +#define INV_ParaOS_MASK 0x0000ff00 +#define INV_ParaAdr_MASK 0x000000ff +#define INV_ParaSubType_SHIFT 24 +#define INV_ParaType_SHIFT 16 +#define INV_ParaOS_SHIFT 8 +#define INV_ParaAdr_SHIFT 0 + +#define INV_ParaType_Vdata 0x00000000 +#define INV_ParaType_Attr 0x00010000 +#define INV_ParaType_Tex 0x00020000 +#define INV_ParaType_Pal 0x00030000 +#define INV_ParaType_FVF 0x00040000 +#define INV_ParaType_PreCR 0x00100000 +#define INV_ParaType_CR 0x00110000 +#define INV_ParaType_Cfg 0x00fe0000 +#define INV_ParaType_Dummy 0x00300000 + +#define INV_HWBasL_MASK 0x00FFFFFF +#define INV_HWBasH_MASK 0xFF000000 +#define INV_HWBasH_SHFT 24 +#define INV_HWBasL(x) ((unsigned int)(x) & INV_HWBasL_MASK) +#define INV_HWBasH(x) ((unsigned int)(x) >> INV_HWBasH_SHFT) +#define INV_HWBas256(x) ((unsigned int)(x) >> 8) +#define INV_HWPit32(x) ((unsigned int)(x) >> 5) + +/* Read Back Register Setting */ +#define INV_SubA_HSetRBGID 0x02000000 +#define INV_HSetRBGID_CR 0x00000000 +#define INV_HSetRBGID_FE 0x00000001 +#define INV_HSetRBGID_PE 0x00000002 +#define INV_HSetRBGID_RC 0x00000003 +#define INV_HSetRBGID_PS 0x00000004 +#define INV_HSetRBGID_XE 0x00000005 +#define INV_HSetRBGID_BE 0x00000006 + + +struct drm_clb_event_tag_info { + unsigned int *linear_address; + unsigned int *event_tag_linear_address; + int usage[NUMBER_OF_EVENT_TAGS]; + unsigned int pid[NUMBER_OF_EVENT_TAGS]; +}; + +static inline int IS_AGPHEADER_INV(unsigned int data) +{ + switch (data & INV_AGPHeader_MASK) { + case INV_AGPHeader0: + case INV_AGPHeader1: + case INV_AGPHeader2: + case INV_AGPHeader3: + case INV_AGPHeader4: + case INV_AGPHeader5: + case INV_AGPHeader6: + case INV_AGPHeader7: + return TRUE; + default: + return FALSE; + } +} + +/* Header0: 2D */ +#define ADDCmdHeader0_INVI(pCmd, dwCount) \ +{ \ + /* 4 unsigned int align, insert NULL Command for padding */ \ + while (((unsigned long *)(pCmd)) & 0xF) { \ + *(pCmd)++ = 0xCC000000; \ + } \ + *(pCmd)++ = INV_AGPHeader0; \ + *(pCmd)++ = (dwCount); \ + *(pCmd)++ = 0; \ + *(pCmd)++ = (unsigned int)INV_HSWFlag_ADDR_ENCODE(pCmd); \ +} + +/* Header1: 2D */ +#define ADDCmdHeader1_INVI(pCmd, dwAddr, dwCount) \ +{ \ + /* 4 unsigned int align, insert NULL Command for padding */ \ + while (((unsigned long *)(pCmd)) & 0xF) { \ + *(pCmd)++ = 0xCC000000; \ + } \ + *(pCmd)++ = INV_AGPHeader1 | (dwAddr); \ + *(pCmd)++ = (dwCount); \ + *(pCmd)++ = 0; \ + *(pCmd)++ = (unsigned int)INV_HSWFlag_ADDR_ENCODE(pCmd); \ +} + +/* Header2: CR/3D */ +#define ADDCmdHeader2_INVI(pCmd, dwAddr, dwType) \ +{ \ + /* 4 unsigned int align, insert NULL Command for padding */ \ + while (((unsigned int)(pCmd)) & 0xF) { \ + *(pCmd)++ = 0xCC000000; \ + } \ + *(pCmd)++ = INV_AGPHeader2 | ((dwAddr)+4); \ + *(pCmd)++ = (dwAddr); \ + *(pCmd)++ = (dwType); \ + *(pCmd)++ = (unsigned int)INV_HSWFlag_ADDR_ENCODE(pCmd); \ +} + +/* Header2: CR/3D with SW Flag */ +#define ADDCmdHeader2_SWFlag_INVI(pCmd, dwAddr, dwType, dwSWFlag) \ +{ \ + /* 4 unsigned int align, insert NULL Command for padding */ \ + while (((unsigned long *)(pCmd)) & 0xF) { \ + *(pCmd)++ = 0xCC000000; \ + } \ + *(pCmd)++ = INV_AGPHeader2 | ((dwAddr)+4); \ + *(pCmd)++ = (dwAddr); \ + *(pCmd)++ = (dwType); \ + *(pCmd)++ = (dwSWFlag); \ +} + + +/* Header3: 3D */ +#define ADDCmdHeader3_INVI(pCmd, dwType, dwStart, dwCount) \ +{ \ + /* 4 unsigned int align, insert NULL Command for padding */ \ + while (((unsigned long *)(pCmd)) & 0xF) { \ + *(pCmd)++ = 0xCC000000; \ + } \ + *(pCmd)++ = INV_AGPHeader3 | INV_REG_3D_TRANS; \ + *(pCmd)++ = (dwCount); \ + *(pCmd)++ = (dwType) | ((dwStart) & 0xFFFF); \ + *(pCmd)++ = (unsigned int)INV_HSWFlag_ADDR_ENCODE(pCmd); \ +} + +/* Header3: 3D with SW Flag */ +#define ADDCmdHeader3_SWFlag_INVI(pCmd, dwType, dwStart, dwSWFlag, dwCount) \ +{ \ + /* 4 unsigned int align, insert NULL Command for padding */ \ + while (((unsigned long *)(pCmd)) & 0xF) { \ + *(pCmd)++ = 0xCC000000; \ + } \ + *(pCmd)++ = INV_AGPHeader3 | INV_REG_3D_TRANS; \ + *(pCmd)++ = (dwCount); \ + *(pCmd)++ = (dwType) | ((dwStart) & 0xFFFF); \ + *(pCmd)++ = (dwSWFlag); \ +} + +/* Header4: DVD */ +#define ADDCmdHeader4_INVI(pCmd, dwAddr, dwCount, id) \ +{ \ + /* 4 unsigned int align, insert NULL Command for padding */ \ + while (((unsigned long *)(pCmd)) & 0xF) { \ + *(pCmd)++ = 0xCC000000; \ + } \ + *(pCmd)++ = INV_AGPHeader4 | (dwAddr); \ + *(pCmd)++ = (dwCount); \ + *(pCmd)++ = (id); \ + *(pCmd)++ = 0; \ +} + +/* Header5: DVD */ +#define ADDCmdHeader5_INVI(pCmd, dwQWcount, id) \ +{ \ + /* 4 unsigned int align, insert NULL Command for padding */ \ + while (((unsigned long *)(pCmd)) & 0xF) { \ + *(pCmd)++ = 0xCC000000; \ + } \ + *(pCmd)++ = INV_AGPHeader5; \ + *(pCmd)++ = (dwQWcount); \ + *(pCmd)++ = (id); \ + *(pCmd)++ = 0; \ +} + +/* Header6: DEBUG */ +#define ADDCmdHeader6_INVI(pCmd) \ +{ \ + /* 4 unsigned int align, insert NULL Command for padding */ \ + while (((unsigned long *)(pCmd)) & 0xF) { \ + *(pCmd)++ = 0xCC000000; \ + } \ + *(pCmd)++ = INV_AGPHeader6; \ + *(pCmd)++ = 0; \ + *(pCmd)++ = 0; \ + *(pCmd)++ = 0; \ +} + +/* Header7: DMA */ +#define ADDCmdHeader7_INVI(pCmd, dwQWcount, id) \ +{ \ + /* 4 unsigned int align, insert NULL Command for padding */ \ + while (((unsigned long *)(pCmd)) & 0xF) { \ + *(pCmd)++ = 0xCC000000; \ + } \ + *(pCmd)++ = INV_AGPHeader7; \ + *(pCmd)++ = (dwQWcount); \ + *(pCmd)++ = (id); \ + *(pCmd)++ = 0; \ +} + +/* Header82: Branch buffer */ +#define ADDCmdHeader82_INVI(pCmd, dwAddr, dwType); \ +{ \ + /* 4 unsigned int align, insert NULL Command for padding */ \ + while (((unsigned long *)(pCmd)) & 0xF) { \ + *(pCmd)++ = 0xCC000000; \ + } \ + *(pCmd)++ = INV_AGPHeader82 | ((dwAddr)+4); \ + *(pCmd)++ = (dwAddr); \ + *(pCmd)++ = (dwType); \ + *(pCmd)++ = 0xCC000000; \ +} + + +#define ADD2DCmd_INVI(pCmd, dwAddr, dwCmd) \ +{ \ + *(pCmd)++ = (dwAddr); \ + *(pCmd)++ = (dwCmd); \ +} + +#define ADDCmdData_INVI(pCmd, dwCmd) *(pCmd)++ = (dwCmd) + +#define ADDCmdDataStream_INVI(pCmdBuf, pCmd, dwCount) \ +{ \ + memcpy((pCmdBuf), (pCmd), ((dwCount)<<2)); \ + (pCmdBuf) += (dwCount); \ +} + +#endif --- linux-2.6.24.orig/drivers/char/drm/drm_stub.c +++ linux-2.6.24/drivers/char/drm/drm_stub.c @@ -168,11 +168,10 @@ goto err_g1; } - head->dev_class = drm_sysfs_device_add(drm_class, head); - if (IS_ERR(head->dev_class)) { + ret = drm_sysfs_device_add(dev, head); + if (ret) { printk(KERN_ERR "DRM: Error sysfs_device_add.\n"); - ret = PTR_ERR(head->dev_class); goto err_g2; } *heads = head; @@ -284,7 +283,7 @@ DRM_DEBUG("release secondary minor %d\n", minor); drm_proc_cleanup(minor, drm_proc_root, head->dev_root); - drm_sysfs_device_remove(head->dev_class); + drm_sysfs_device_remove(head->dev); *head = (struct drm_head) {.dev = NULL}; --- linux-2.6.24.orig/drivers/char/drm/via_chrome9_drm.h +++ linux-2.6.24/drivers/char/drm/via_chrome9_drm.h @@ -0,0 +1,423 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, subject to the + * following conditions: + * + * The above copyright notice and this permission notice + * (including the next paragraph) shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL VIA, S3 GRAPHICS, AND/OR + * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef _VIA_CHROME9_DRM_H_ +#define _VIA_CHROME9_DRM_H_ + +/* WARNING: These defines must be the same as what the Xserver uses. + * if you change them, you must change the defines in the Xserver. + */ + +#ifndef _VIA_CHROME9_DEFINES_ +#define _VIA_CHROME9_DEFINES_ + +#ifndef __KERNEL__ +#include "via_drmclient.h" +#endif + +#define VIA_CHROME9_NR_SAREA_CLIPRECTS 8 +#define VIA_CHROME9_NR_XVMC_PORTS 10 +#define VIA_CHROME9_NR_XVMC_LOCKS 5 +#define VIA_CHROME9_MAX_CACHELINE_SIZE 64 +#define XVMCLOCKPTR(saPriv,lockNo) \ + ((volatile struct drm_hw_lock *) \ + (((((unsigned long) (saPriv)->XvMCLockArea) + \ + (VIA_CHROME9_MAX_CACHELINE_SIZE - 1)) & \ + ~(VIA_CHROME9_MAX_CACHELINE_SIZE - 1)) + \ + VIA_CHROME9_MAX_CACHELINE_SIZE*(lockNo))) + +/* Each region is a minimum of 64k, and there are at most 64 of them. + */ +#define VIA_CHROME9_NR_TEX_REGIONS 64 +#define VIA_CHROME9_LOG_MIN_TEX_REGION_SIZE 16 +#endif + +#define VIA_CHROME9_UPLOAD_TEX0IMAGE 0x1 /* handled clientside */ +#define VIA_CHROME9_UPLOAD_TEX1IMAGE 0x2 /* handled clientside */ +#define VIA_CHROME9_UPLOAD_CTX 0x4 +#define VIA_CHROME9_UPLOAD_BUFFERS 0x8 +#define VIA_CHROME9_UPLOAD_TEX0 0x10 +#define VIA_CHROME9_UPLOAD_TEX1 0x20 +#define VIA_CHROME9_UPLOAD_CLIPRECTS 0x40 +#define VIA_CHROME9_UPLOAD_ALL 0xff + +/* VIA_CHROME9 specific ioctls */ +#define DRM_VIA_CHROME9_ALLOCMEM 0x00 +#define DRM_VIA_CHROME9_FREEMEM 0x01 +#define DRM_VIA_CHROME9_FREE 0x02 +#define DRM_VIA_CHROME9_ALLOCATE_EVENT_TAG 0x03 +#define DRM_VIA_CHROME9_FREE_EVENT_TAG 0x04 +#define DRM_VIA_CHROME9_ALLOCATE_APERTURE 0x05 +#define DRM_VIA_CHROME9_FREE_APERTURE 0x06 +#define DRM_VIA_CHROME9_ALLOCATE_VIDEO_MEM 0x07 +#define DRM_VIA_CHROME9_FREE_VIDEO_MEM 0x08 +#define DRM_VIA_CHROME9_WAIT_CHIP_IDLE 0x09 +#define DRM_VIA_CHROME9_PROCESS_EXIT 0x0A +#define DRM_VIA_CHROME9_RESTORE_PRIMARY 0x0B +#define DRM_VIA_CHROME9_FLUSH_CACHE 0x0C +#define DRM_VIA_CHROME9_INIT 0x0D +#define DRM_VIA_CHROME9_FLUSH 0x0E +#define DRM_VIA_CHROME9_CHECKVIDMEMSIZE 0x0F +#define DRM_VIA_CHROME9_PCIEMEMCTRL 0x10 +#define DRM_VIA_CHROME9_AUTH_MAGIC 0x11 + +#define DRM_IOCTL_VIA_CHROME9_INIT \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_INIT, \ + struct drm_via_chrome9_init) +#define DRM_IOCTL_VIA_CHROME9_FLUSH \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_FLUSH, \ + struct drm_via_chrome9_flush) +#define DRM_IOCTL_VIA_CHROME9_FREE \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_FREE, int) +#define DRM_IOCTL_VIA_CHROME9_ALLOCATE_EVENT_TAG \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_ALLOCATE_EVENT_TAG, \ + struct drm_event_via_chrome9_tag) +#define DRM_IOCTL_VIA_CHROME9_FREE_EVENT_TAG \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_FREE_EVENT_TAG, \ + struct drm_event_via_chrome9_tag) +#define DRM_IOCTL_VIA_CHROME9_ALLOCATE_APERTURE \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_ALLOCATE_APERTURE, \ + struct drm_via_chrome9_aperture) +#define DRM_IOCTL_VIA_CHROME9_FREE_APERTURE \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_FREE_APERTURE, \ + struct drm_via_chrome9_aperture) +#define DRM_IOCTL_VIA_CHROME9_ALLOCATE_VIDEO_MEM \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_ALLOCATE_VIDEO_MEM, \ + struct drm_via_chrome9_memory_alloc) +#define DRM_IOCTL_VIA_CHROME9_FREE_VIDEO_MEM \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_FREE_VIDEO_MEM, \ + struct drm_via_chrome9_memory_alloc) +#define DRM_IOCTL_VIA_CHROME9_WAIT_CHIP_IDLE \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_WAIT_CHIP_IDLE, int) +#define DRM_IOCTL_VIA_CHROME9_PROCESS_EXIT \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_PROCESS_EXIT, int) +#define DRM_IOCTL_VIA_CHROME9_RESTORE_PRIMARY \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_RESTORE_PRIMARY, int) +#define DRM_IOCTL_VIA_CHROME9_FLUSH_CACHE \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_FLUSH_CACHE, int) +#define DRM_IOCTL_VIA_CHROME9_ALLOCMEM \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_ALLOCMEM, int) +#define DRM_IOCTL_VIA_CHROME9_FREEMEM \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_FREEMEM, int) +#define DRM_IOCTL_VIA_CHROME9_CHECK_VIDMEM_SIZE \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_CHECKVIDMEMSIZE, \ + struct drm_via_chrome9_memory_alloc) +#define DRM_IOCTL_VIA_CHROME9_PCIEMEMCTRL \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_PCIEMEMCTRL,\ + drm_via_chrome9_pciemem_ctrl_t) +#define DRM_IOCTL_VIA_CHROME9_AUTH_MAGIC \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CHROME9_AUTH_MAGIC, drm_auth_t) + +enum S3GCHIPIDS { + CHIP_UNKNOWN = -1, + CHIP_CMODEL, /*Model for any chip. */ + CHIP_CLB, /*Columbia */ + CHIP_DST, /*Destination */ + CHIP_CSR, /*Castlerock */ + CHIP_INV, /*Innovation (H3) */ + CHIP_H5, /*Innovation (H5) */ + CHIP_H5S1, /*Innovation (H5S1) */ + CHIP_H6S2, /*Innovation (H6S2) */ + CHIP_CMS, /*Columbia MS */ + CHIP_METRO, /*Metropolis */ + CHIP_MANHATTAN, /*manhattan */ + CHIP_MATRIX, /*matrix */ + CHIP_EVO, /*change for GCC 4.1 -add- 07.02.12*/ + CHIP_H6S1, /*Innovation (H6S1)*/ + CHIP_DST2, /*Destination-2 */ + CHIP_LAST /*Maximum number of chips supported. */ +}; + +enum VIA_CHROME9CHIPBUS { + CHIP_PCI, + CHIP_AGP, + CHIP_PCIE +}; + +struct drm_via_chrome9_init { + enum { + VIA_CHROME9_INIT = 0x01, + VIA_CHROME9_CLEANUP = 0x02 + } func; + int chip_agp; + int chip_index; + int chip_sub_index; + int usec_timeout; + unsigned int sarea_priv_offset; + unsigned int fb_cpp; + unsigned int front_offset; + unsigned int back_offset; + unsigned int depth_offset; + unsigned int mmio_handle; + unsigned int dma_handle; + unsigned int fb_handle; + unsigned int front_handle; + unsigned int back_handle; + unsigned int depth_handle; + + unsigned int fb_tex_offset; + unsigned int fb_tex_size; + + unsigned int agp_tex_size; + unsigned int agp_tex_handle; + unsigned int shadow_size; + unsigned int shadow_handle; + unsigned int garttable_size; + unsigned int garttable_offset; + unsigned long available_fb_size; + unsigned long fb_base_address; + unsigned int DMA_size; + unsigned long DMA_phys_address; + enum { + AGP_RING_BUFFER, + AGP_DOUBLE_BUFFER, + AGP_DISABLED + } agp_type; + unsigned int hostBlt_handle; +}; + +enum dma_cmd_type { + flush_bci = 0, + flush_bci_and_wait, + dma_kickoff, + flush_dma_buffer, + flush_dma_and_wait +}; + +struct drm_via_chrome9_flush { + enum dma_cmd_type dma_cmd_type; + /* command buffer index */ + int cmd_idx; + /* command buffer offset */ + int cmd_offset; + /* command dword size,command always from beginning */ + int cmd_size; + /* if use dma kick off,it is dma kick off command */ + unsigned long dma_kickoff[2]; + /* user mode DMA buffer pointer */ + unsigned int *usermode_dma_buf; +}; + +struct event_value { + int event_low; + int event_high; +}; + +struct drm_via_chrome9_event_tag { + unsigned int event_size; /* event tag size */ + int event_offset; /* event tag id */ + struct event_value last_sent_event_value; + struct event_value current_event_value; + int query_mask0; + int query_mask1; + int query_Id1; +}; + +/* Indices into buf.Setup where various bits of state are mirrored per + * context and per buffer. These can be fired at the card as a unit, + * or in a piecewise fashion as required. + */ + +#define VIA_CHROME9_TEX_SETUP_SIZE 8 + +/* Flags for clear ioctl + */ +#define VIA_CHROME9_FRONT 0x1 +#define VIA_CHROME9_BACK 0x2 +#define VIA_CHROME9_DEPTH 0x4 +#define VIA_CHROME9_STENCIL 0x8 +#define VIA_CHROME9_MEM_VIDEO 0 /* matches drm constant */ +#define VIA_CHROME9_MEM_AGP 1 /* matches drm constant */ +#define VIA_CHROME9_MEM_SYSTEM 2 +#define VIA_CHROME9_MEM_MIXED 3 +#define VIA_CHROME9_MEM_UNKNOWN 4 + +struct drm_via_chrome9_agp { + uint32_t offset; + uint32_t size; +}; + +struct drm_via_chrome9_fb { + uint32_t offset; + uint32_t size; +}; + +struct drm_via_chrome9_mem { + uint32_t context; + uint32_t type; + uint32_t size; + unsigned long index; + unsigned long offset; +}; + +struct drm_via_chrome9_aperture { + /*IN: The frame buffer offset of the surface. */ + int surface_offset; + /*IN: Surface pitch in byte, */ + int pitch; + /*IN: Surface width in pixel */ + int width; + /*IN: Surface height in pixel */ + int height; + /*IN: Surface color format, Columbia has more color formats */ + int color_format; + /*IN: Rotation degrees, only for Columbia */ + int rotation_degree; + /*IN Is the PCIE Video, for MATRIX support NONLOCAL Aperture */ + int isPCIEVIDEO; + /*IN: Is the surface tilled, only for Columbia */ + int is_tiled; + /*IN: Only allocate apertur, not hardware setup. */ + int allocate_only; + /* OUT: linear address for aperture */ + unsigned int *aperture_linear_address; + /*OUT: The pitch of the aperture,for CPU write not for GE */ + int aperture_pitch; + /*OUT: The index of the aperture */ + int aperture_handle; + int apertureID; + /* always =0xAAAAAAAA */ + /* Aligned surface's width(in pixel) */ + int width_aligned; + /* Aligned surface's height(in pixel) */ + int height_aligned; +}; + +/* + Some fileds of this data structure has no meaning now since + we have managed heap based on mechanism provided by DRM + Remain what it was to keep consistent with 3D driver interface. +*/ +struct drm_via_chrome9_memory_alloc { + enum { + memory_heap_video = 0, + memory_heap_agp, + memory_heap_pcie_video, + memory_heap_pcie, + max_memory_heaps + } heap_type; + struct { + void *lpL1Node; + unsigned int alcL1Tag; + unsigned int usageCount; + unsigned int dwVersion; + unsigned int dwResHandle; + unsigned int dwProcessID; + } heap_info; + unsigned int flags; + unsigned int size; + unsigned int physaddress; + unsigned int offset; + unsigned int align; + void *linearaddress; +}; + +struct drm_via_chrome9_dma_init { + enum { + VIA_CHROME9_INIT_DMA = 0x01, + VIA_CHROME9_CLEANUP_DMA = 0x02, + VIA_CHROME9_DMA_INITIALIZED = 0x03 + } func; + + unsigned long offset; + unsigned long size; + unsigned long reg_pause_addr; +}; + +struct drm_via_chrome9_cmdbuffer { + char __user *buf; + unsigned long size; +}; + +/* Warning: If you change the SAREA structure you must change the Xserver + * structure as well */ + +struct drm_via_chrome9_tex_region { + unsigned char next, prev; /* indices to form a circular LRU */ + unsigned char inUse; /* owned by a client, or free? */ + int age; /* tracked by clients to update local LRU's */ +}; + +struct drm_via_chrome9_sarea { + int page_flip; + int current_page; + unsigned int req_drawable;/* the X drawable id */ + unsigned int req_draw_buffer;/* VIA_CHROME9_FRONT or VIA_CHROME9_BACK */ + /* Last context that uploaded state */ + int ctx_owner; +}; + +struct drm_via_chrome9_cmdbuf_size { + enum { + VIA_CHROME9_CMDBUF_SPACE = 0x01, + VIA_CHROME9_CMDBUF_LAG = 0x02 + } func; + int wait; + uint32_t size; +}; + +struct drm_via_chrome9_DMA_manager { + unsigned int *addr_linear; + unsigned int DMASize; + unsigned int bDMAAgp; + unsigned int LastIssuedEventTag; + unsigned int *pBeg; + unsigned int *pInUseByHW; + unsigned int **ppInUseByHW; + unsigned int *pInUseBySW; + unsigned int *pFree; + unsigned int *pEnd; + + unsigned long pPhysical; + unsigned int MaxKickoffSize; +}; + +extern int via_chrome9_ioctl_wait_chip_idle(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int via_chrome9_ioctl_init(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int via_chrome9_ioctl_allocate_event_tag(struct drm_device + *dev, void *data, struct drm_file *file_priv); +extern int via_chrome9_ioctl_free_event_tag(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int via_chrome9_driver_load(struct drm_device *dev, + unsigned long chipset); +extern int via_chrome9_driver_unload(struct drm_device *dev); +extern int via_chrome9_ioctl_process_exit(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int via_chrome9_ioctl_restore_primary(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int via_chrome9_drm_resume(struct pci_dev *dev); +extern int via_chrome9_drm_suspend(struct pci_dev *dev, + pm_message_t state); +extern void __via_chrome9ke_udelay(unsigned long usecs); +extern void via_chrome9_lastclose(struct drm_device *dev); +extern void via_chrome9_preclose(struct drm_device *dev, + struct drm_file *file_priv); +extern int via_chrome9_is_agp(struct drm_device *dev); + + +#endif /* _VIA_CHROME9_DRM_H_ */ --- linux-2.6.24.orig/drivers/char/drm/drm_fops.c +++ linux-2.6.24/drivers/char/drm/drm_fops.c @@ -326,6 +326,7 @@ struct drm_file *file_priv = filp->private_data; struct drm_device *dev = file_priv->head->dev; int retcode = 0; + unsigned long irqflags; lock_kernel(); @@ -357,9 +358,11 @@ */ do{ - spin_lock(&dev->lock.spinlock); + spin_lock_irqsave(&dev->lock.spinlock, + irqflags); locked = dev->lock.idle_has_lock; - spin_unlock(&dev->lock.spinlock); + spin_unlock_irqrestore(&dev->lock.spinlock, + irqflags); if (locked) break; schedule(); --- linux-2.6.24.orig/drivers/char/drm/drm_bufs.c +++ linux-2.6.24/drivers/char/drm/drm_bufs.c @@ -429,6 +429,7 @@ return ret; } +EXPORT_SYMBOL(drm_rmmap); /* The rmmap ioctl appears to be unnecessary. All mappings are torn down on * the last close of the device, and this is necessary for cleanup when things --- linux-2.6.24.orig/drivers/char/drm/i915_dma.c +++ linux-2.6.24/drivers/char/drm/i915_dma.c @@ -31,17 +31,6 @@ #include "i915_drm.h" #include "i915_drv.h" -#define IS_I965G(dev) (dev->pci_device == 0x2972 || \ - dev->pci_device == 0x2982 || \ - dev->pci_device == 0x2992 || \ - dev->pci_device == 0x29A2 || \ - dev->pci_device == 0x2A02 || \ - dev->pci_device == 0x2A12) - -#define IS_G33(dev) (dev->pci_device == 0x29b2 || \ - dev->pci_device == 0x29c2 || \ - dev->pci_device == 0x29d2) - /* Really want an OS-independent resettable timer. Would like to have * this loop run for (eg) 3 sec, but have the timer reset every time * the head pointer changes, so that EBUSY only happens if the ring @@ -90,6 +79,7 @@ static int i915_dma_cleanup(struct drm_device * dev) { + drm_i915_private_t *dev_priv = dev->dev_private; /* Make sure interrupts are disabled here because the uninstall ioctl * may not have been called from userspace and after dev_private * is freed, it's too late. @@ -97,52 +87,42 @@ if (dev->irq) drm_irq_uninstall(dev); - if (dev->dev_private) { - drm_i915_private_t *dev_priv = - (drm_i915_private_t *) dev->dev_private; - - if (dev_priv->ring.virtual_start) { - drm_core_ioremapfree(&dev_priv->ring.map, dev); - } - - if (dev_priv->status_page_dmah) { - drm_pci_free(dev, dev_priv->status_page_dmah); - /* Need to rewrite hardware status page */ - I915_WRITE(0x02080, 0x1ffff000); - } - - if (dev_priv->status_gfx_addr) { - dev_priv->status_gfx_addr = 0; - drm_core_ioremapfree(&dev_priv->hws_map, dev); - I915_WRITE(0x2080, 0x1ffff000); - } + if (dev_priv->ring.virtual_start) { + drm_core_ioremapfree(&dev_priv->ring.map, dev); + dev_priv->ring.virtual_start = 0; + dev_priv->ring.map.handle = 0; + dev_priv->ring.map.size = 0; + } - drm_free(dev->dev_private, sizeof(drm_i915_private_t), - DRM_MEM_DRIVER); + if (dev_priv->status_page_dmah) { + drm_pci_free(dev, dev_priv->status_page_dmah); + dev_priv->status_page_dmah = NULL; + /* Need to rewrite hardware status page */ + I915_WRITE(0x02080, 0x1ffff000); + } - dev->dev_private = NULL; + if (dev_priv->status_gfx_addr) { + dev_priv->status_gfx_addr = 0; + drm_core_ioremapfree(&dev_priv->hws_map, dev); + I915_WRITE(0x2080, 0x1ffff000); } return 0; } -static int i915_initialize(struct drm_device * dev, - drm_i915_private_t * dev_priv, - drm_i915_init_t * init) +static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) { - memset(dev_priv, 0, sizeof(drm_i915_private_t)); + drm_i915_private_t *dev_priv = dev->dev_private; dev_priv->sarea = drm_getsarea(dev); if (!dev_priv->sarea) { DRM_ERROR("can not find sarea!\n"); - dev->dev_private = (void *)dev_priv; i915_dma_cleanup(dev); return -EINVAL; } dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset); if (!dev_priv->mmio_map) { - dev->dev_private = (void *)dev_priv; i915_dma_cleanup(dev); DRM_ERROR("can not find mmio map!\n"); return -EINVAL; @@ -165,7 +145,6 @@ drm_core_ioremap(&dev_priv->ring.map, dev); if (dev_priv->ring.map.handle == NULL) { - dev->dev_private = (void *)dev_priv; i915_dma_cleanup(dev); DRM_ERROR("can not ioremap virtual address for" " ring buffer\n"); @@ -192,12 +171,11 @@ dev_priv->allow_batchbuffer = 1; /* Program Hardware Status Page */ - if (!IS_G33(dev)) { + if (!I915_NEED_GFX_HWS(dev)) { dev_priv->status_page_dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff); if (!dev_priv->status_page_dmah) { - dev->dev_private = (void *)dev_priv; i915_dma_cleanup(dev); DRM_ERROR("Can not allocate hardware status page\n"); return -ENOMEM; @@ -209,7 +187,6 @@ I915_WRITE(0x02080, dev_priv->dma_status_page); } DRM_DEBUG("Enabled hardware status page\n"); - dev->dev_private = (void *)dev_priv; return 0; } @@ -254,17 +231,12 @@ static int i915_dma_init(struct drm_device *dev, void *data, struct drm_file *file_priv) { - drm_i915_private_t *dev_priv; drm_i915_init_t *init = data; int retcode = 0; switch (init->func) { case I915_INIT_DMA: - dev_priv = drm_alloc(sizeof(drm_i915_private_t), - DRM_MEM_DRIVER); - if (dev_priv == NULL) - return -ENOMEM; - retcode = i915_initialize(dev, dev_priv, init); + retcode = i915_initialize(dev, init); break; case I915_CLEANUP_DMA: retcode = i915_dma_cleanup(dev); @@ -748,6 +720,9 @@ drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_hws_addr_t *hws = data; + if (!I915_NEED_GFX_HWS(dev)) + return -EINVAL; + if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return -EINVAL; @@ -765,7 +740,6 @@ drm_core_ioremap(&dev_priv->hws_map, dev); if (dev_priv->hws_map.handle == NULL) { - dev->dev_private = (void *)dev_priv; i915_dma_cleanup(dev); dev_priv->status_gfx_addr = 0; DRM_ERROR("can not ioremap virtual address for" @@ -784,6 +758,15 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) { + struct drm_i915_private *dev_priv = dev->dev_private; + unsigned long base, size; + int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1; + + if (!IS_I9XX(dev)) { + dev->driver->suspend = NULL; + dev->driver->resume = NULL; + } + /* i915 has 4 more counters */ dev->counters += 4; dev->types[6] = _DRM_STAT_IRQ; @@ -791,24 +774,50 @@ dev->types[8] = _DRM_STAT_SECONDARY; dev->types[9] = _DRM_STAT_DMA; + dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER); + if (dev_priv == NULL) + return -ENOMEM; + + memset(dev_priv, 0, sizeof(drm_i915_private_t)); + + dev->dev_private = (void *)dev_priv; + + /* Add register map (needed for suspend/resume) */ + base = drm_get_resource_start(dev, mmio_bar); + size = drm_get_resource_len(dev, mmio_bar); + + ret = drm_addmap(dev, base, size, _DRM_REGISTERS, _DRM_KERNEL, + &dev_priv->mmio_map); + return ret; +} + +int i915_driver_unload(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (dev_priv->mmio_map) + drm_rmmap(dev, dev_priv->mmio_map); + + drm_free(dev->dev_private, sizeof(drm_i915_private_t), + DRM_MEM_DRIVER); + return 0; } void i915_driver_lastclose(struct drm_device * dev) { - if (dev->dev_private) { - drm_i915_private_t *dev_priv = dev->dev_private; + drm_i915_private_t *dev_priv = dev->dev_private; + + if (dev_priv->agp_heap) i915_mem_takedown(&(dev_priv->agp_heap)); - } + i915_dma_cleanup(dev); } void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) { - if (dev->dev_private) { - drm_i915_private_t *dev_priv = dev->dev_private; - i915_mem_release(dev, file_priv, dev_priv->agp_heap); - } + drm_i915_private_t *dev_priv = dev->dev_private; + i915_mem_release(dev, file_priv, dev_priv->agp_heap); } struct drm_ioctl_desc i915_ioctls[] = { @@ -828,7 +837,7 @@ DRM_IOCTL_DEF(DRM_I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ), DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ), DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH), + DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), }; int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); --- linux-2.6.24.orig/drivers/char/drm/via_chrome9_drv.c +++ linux-2.6.24/drivers/char/drm/via_chrome9_drv.c @@ -0,0 +1,153 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, subject to the + * following conditions: + * + * The above copyright notice and this permission notice + * (including the next paragraph) shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL VIA, S3 GRAPHICS, AND/OR + * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "drmP.h" +#include "via_chrome9_drm.h" +#include "via_chrome9_drv.h" +#include "via_chrome9_dma.h" +#include "via_chrome9_mm.h" + +#include "drm_pciids.h" + +static int dri_library_name(struct drm_device *dev, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "via_chrome9"); +} + +int via_chrome9_drm_authmagic(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + return 0; +} + +struct drm_ioctl_desc via_chrome9_ioctls[] = { + DRM_IOCTL_DEF(DRM_VIA_CHROME9_INIT, via_chrome9_ioctl_init, + DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),/* via_chrome9_map.c*/ + DRM_IOCTL_DEF(DRM_VIA_CHROME9_FLUSH, via_chrome9_ioctl_flush, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_CHROME9_FREE, via_chrome9_ioctl_free, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_CHROME9_ALLOCATE_EVENT_TAG, + via_chrome9_ioctl_allocate_event_tag, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_CHROME9_FREE_EVENT_TAG, + via_chrome9_ioctl_free_event_tag, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_CHROME9_ALLOCATE_APERTURE, + via_chrome9_ioctl_allocate_aperture, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_CHROME9_FREE_APERTURE, + via_chrome9_ioctl_free_aperture, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_CHROME9_ALLOCATE_VIDEO_MEM, + via_chrome9_ioctl_allocate_mem_wrapper, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_CHROME9_FREE_VIDEO_MEM, + via_chrome9_ioctl_free_mem_wrapper, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_CHROME9_WAIT_CHIP_IDLE, + via_chrome9_ioctl_wait_chip_idle, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_CHROME9_PROCESS_EXIT, + via_chrome9_ioctl_process_exit, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_CHROME9_RESTORE_PRIMARY, + via_chrome9_ioctl_restore_primary, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_CHROME9_FLUSH_CACHE, + via_chrome9_ioctl_flush_cache, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_CHROME9_ALLOCMEM, + via_chrome9_ioctl_allocate_mem_base, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_CHROME9_FREEMEM, + via_chrome9_ioctl_freemem_base, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_CHROME9_CHECKVIDMEMSIZE, + via_chrome9_ioctl_check_vidmem_size, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_CHROME9_PCIEMEMCTRL, + via_chrome9_ioctl_pciemem_ctrl, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_CHROME9_AUTH_MAGIC, via_chrome9_drm_authmagic, 0) +}; + +int via_chrome9_max_ioctl = DRM_ARRAY_SIZE(via_chrome9_ioctls); + +static struct pci_device_id pciidlist[] = { + via_chrome9DRV_PCI_IDS +}; + +int via_chrome9_driver_open(struct drm_device *dev, + struct drm_file *priv) +{ + priv->authenticated = 1; + return 0; +} + +static struct drm_driver driver = { + .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | + DRIVER_HAVE_DMA | DRIVER_FB_DMA | DRIVER_USE_MTRR, + .open = via_chrome9_driver_open, + .load = via_chrome9_driver_load, + .unload = via_chrome9_driver_unload, + .device_is_agp = via_chrome9_is_agp, + .dri_library_name = dri_library_name, + .reclaim_buffers = drm_core_reclaim_buffers, + .reclaim_buffers_locked = NULL, + .reclaim_buffers_idlelocked = via_chrome9_reclaim_buffers_locked, + .lastclose = via_chrome9_lastclose, + .preclose = via_chrome9_preclose, + .get_map_ofs = drm_core_get_map_ofs, + .get_reg_ofs = drm_core_get_reg_ofs, + .ioctls = via_chrome9_ioctls, + .fops = { + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, + .fasync = drm_fasync, + }, + .pci_driver = { + .name = DRIVER_NAME, + .id_table = pciidlist, + .resume = via_chrome9_drm_resume, + .suspend = via_chrome9_drm_suspend, + }, + + .name = DRIVER_NAME, + .desc = DRIVER_DESC, + .date = DRIVER_DATE, + .major = DRIVER_MAJOR, + .minor = DRIVER_MINOR, + .patchlevel = DRIVER_PATCHLEVEL, +}; + +static int __init via_chrome9_init(void) +{ + driver.num_ioctls = via_chrome9_max_ioctl; + driver.dev_priv_size = sizeof(struct drm_via_chrome9_private); + return drm_init(&driver); +} + +static void __exit via_chrome9_exit(void) +{ + drm_exit(&driver); +} + +module_init(via_chrome9_init); +module_exit(via_chrome9_exit); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL and additional rights"); --- linux-2.6.24.orig/drivers/char/drm/drmP.h +++ linux-2.6.24/drivers/char/drm/drmP.h @@ -567,6 +567,8 @@ void (*postclose) (struct drm_device *, struct drm_file *); void (*lastclose) (struct drm_device *); int (*unload) (struct drm_device *); + int (*suspend) (struct drm_device *, pm_message_t state); + int (*resume) (struct drm_device *); int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv); void (*dma_ready) (struct drm_device *); int (*dma_quiescent) (struct drm_device *); @@ -642,6 +644,7 @@ * may contain multiple heads. */ struct drm_device { + struct device dev; /**< Linux device */ char *unique; /**< Unique identifier: e.g., busid */ int unique_len; /**< Length of unique field */ char *devname; /**< For /proc/interrupts */ @@ -1061,11 +1064,11 @@ extern void drm_pci_free(struct drm_device *dev, drm_dma_handle_t * dmah); /* sysfs support (drm_sysfs.c) */ +struct drm_sysfs_class; extern struct class *drm_sysfs_create(struct module *owner, char *name); -extern void drm_sysfs_destroy(struct class *cs); -extern struct class_device *drm_sysfs_device_add(struct class *cs, - struct drm_head *head); -extern void drm_sysfs_device_remove(struct class_device *class_dev); +extern void drm_sysfs_destroy(void); +extern int drm_sysfs_device_add(struct drm_device *dev, struct drm_head *head); +extern void drm_sysfs_device_remove(struct drm_device *dev); /* * Basic memory manager support (drm_mm.c) --- linux-2.6.24.orig/drivers/char/drm/drm_drv.c +++ linux-2.6.24/drivers/char/drm/drm_drv.c @@ -386,19 +386,19 @@ DRM_INFO("Initialized %s %d.%d.%d %s\n", CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE); return 0; - err_p3: - drm_sysfs_destroy(drm_class); - err_p2: +err_p3: + drm_sysfs_destroy(); +err_p2: unregister_chrdev(DRM_MAJOR, "drm"); drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB); - err_p1: +err_p1: return ret; } static void __exit drm_core_exit(void) { remove_proc_entry("dri", NULL); - drm_sysfs_destroy(drm_class); + drm_sysfs_destroy(); unregister_chrdev(DRM_MAJOR, "drm"); --- linux-2.6.24.orig/drivers/char/drm/Kconfig +++ linux-2.6.24/drivers/char/drm/Kconfig @@ -38,7 +38,7 @@ Choose this option if you have an ATI Radeon graphics card. There are both PCI and AGP versions. You don't need to choose this to run the Radeon in plain VGA mode. - + If M is selected, the module will be called radeon. config DRM_I810 @@ -71,9 +71,9 @@ 852GM, 855GM 865G or 915G integrated graphics. If M is selected, the module will be called i915. AGP support is required for this driver to work. This driver is used by the Intel driver in X.org 6.8 and - XFree86 4.4 and above. If unsure, build this and i830 as modules and + XFree86 4.4 and above. If unsure, build this and i830 as modules and the X server will load the correct one. - + endchoice config DRM_MGA @@ -88,7 +88,7 @@ tristate "SiS video cards" depends on DRM && AGP help - Choose this option if you have a SiS 630 or compatible video + Choose this option if you have a SiS 630 or compatible video chipset. If M is selected the module will be called sis. AGP support is required for this driver to work. @@ -98,6 +98,13 @@ help Choose this option if you have a Via unichrome or compatible video chipset. If M is selected the module will be called via. + +config DRM_VIA_CHROME9 + tristate "Via unichrome9 video cards" + depends on DRM + help + Choose this option if you have a Via unichrome9 or compatible video + chipset. If M is selected the module will be called via_chrome9. config DRM_SAVAGE tristate "Savage video cards" @@ -105,4 +112,3 @@ help Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister chipset. If M is selected the module will be called savage. - --- linux-2.6.24.orig/drivers/char/drm/via_chrome9_drv.h +++ linux-2.6.24/drivers/char/drm/via_chrome9_drv.h @@ -0,0 +1,145 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, subject to the + * following conditions: + * + * The above copyright notice and this permission notice + * (including the next paragraph) shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL VIA, S3 GRAPHICS, AND/OR + * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef _VIA_CHROME9_DRV_H_ +#define _VIA_CHROME9_DRV_H_ + +#include "drm_sman.h" +#define DRIVER_AUTHOR "Various" + +#define DRIVER_NAME "via_chrome9_chrome9" +#define DRIVER_DESC "VIA_CHROME9 Unichrome / Pro" +#define DRIVER_DATE "20080415" + +#define DRIVER_MAJOR 2 +#define DRIVER_MINOR 11 +#define DRIVER_PATCHLEVEL 1 + +#define via_chrome9_PCI_BUF_SIZE 60000 +#define via_chrome9_FIRE_BUF_SIZE 1024 +#define via_chrome9_NUM_IRQS 4 + +#define MAX_MEMORY_HEAPS 4 +#define NUMBER_OF_APERTURES 32 + +/*typedef struct drm_via_chrome9_shadow_map drm_via_chrome9_shadow_map_t;*/ +struct drm_via_chrome9_shadow_map { + struct drm_map *shadow; + unsigned int shadow_size; + unsigned int *shadow_handle; +}; + +/*typedef struct drm_via_chrome9_pagetable_map + *drm_via_chrome9_pagetable_map_t; + */ +struct drm_via_chrome9_pagetable_map { + unsigned int pagetable_offset; + unsigned int pagetable_size; + unsigned int *pagetable_handle; + unsigned int mmt_register; +}; + +/*typedef struct drm_via_chrome9_private drm_via_chrome9_private_t;*/ +struct drm_via_chrome9_private { + int chip_agp; + int chip_index; + int chip_sub_index; + + unsigned long front_offset; + unsigned long back_offset; + unsigned long depth_offset; + unsigned long fb_base_address; + unsigned long available_fb_size; + int usec_timeout; + int max_apertures; + struct drm_sman sman; + unsigned int alignment; + /* bit[31]:0:indicate no alignment needed,1:indicate + alignment needed and size is bit[0:30]*/ + + struct drm_map *sarea; + struct drm_via_chrome9_sarea *sarea_priv; + + struct drm_map *mmio; + struct drm_map *hostBlt; + struct drm_map *fb; + struct drm_map *front; + struct drm_map *back; + struct drm_map *depth; + struct drm_map *agp_tex; + unsigned int agp_size; + unsigned int agp_offset; + + struct semaphore *drm_s3g_sem; + + struct drm_via_chrome9_shadow_map shadow_map; + struct drm_via_chrome9_pagetable_map pagetable_map; + + char *bci; + + int aperture_usage[NUMBER_OF_APERTURES]; + void *event_tag_info; + + /* DMA buffer manager */ + void *dma_manager; + /* Indicate agp/pcie heap initialization flag */ + int agp_initialized; + /* Indicate video heap initialization flag */ + int vram_initialized; + + unsigned long pcie_vmalloc_addr; + + /* pointer to device information */ + void *dev; + /* if agp init fail, go ahead and force dri use PCI*/ + enum { + DRM_AGP_RING_BUFFER, + DRM_AGP_DOUBLE_BUFFER, + DRM_AGP_DISABLED + } drm_agp_type; + /*end*/ + + unsigned long *bci_buffer; + unsigned long pcie_vmalloc_nocache; +}; + + +enum via_chrome9_family { + VIA_CHROME9_OTHER = 0, /* Baseline */ + VIA_CHROME9_PRO_GROUP_A,/* Another video engine and DMA commands */ + VIA_CHROME9_DX9_0, + VIA_CHROME9_PCIE_GROUP +}; + +/* VIA_CHROME9 MMIO register access */ +#define VIA_CHROME9_BASE ((dev_priv->mmio)) + +#define VIA_CHROME9_READ(reg) DRM_READ32(VIA_CHROME9_BASE, reg) +#define VIA_CHROME9_WRITE(reg, val) DRM_WRITE32(VIA_CHROME9_BASE, reg, val) +#define VIA_CHROME9_READ8(reg) DRM_READ8(VIA_CHROME9_BASE, reg) +#define VIA_CHROME9_WRITE8(reg, val) DRM_WRITE8(VIA_CHROME9_BASE, reg, val) + +#endif --- linux-2.6.24.orig/drivers/char/drm/drm_pciids.h +++ linux-2.6.24/drivers/char/drm/drm_pciids.h @@ -240,10 +240,17 @@ {0x1106, 0x3108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1106, 0x3344, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1106, 0x3343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_DX9_0}, \ {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \ {0, 0, 0} + +#define via_chrome9DRV_PCI_IDS \ + {0x1106, 0x3225, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_CHROME9_DX9_0}, \ + {0x1106, 0x3371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x1106, 0x1122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_CHROME9_PCIE_GROUP},\ + {0, 0, 0} + #define i810_PCI_IDS \ {0x8086, 0x7121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ @@ -311,5 +318,6 @@ {0x8086, 0x29d2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x2a02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x2a12, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x2a42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0, 0, 0} --- linux-2.6.24.orig/drivers/char/drm/drm_lock.c +++ linux-2.6.24/drivers/char/drm/drm_lock.c @@ -53,6 +53,7 @@ DECLARE_WAITQUEUE(entry, current); struct drm_lock *lock = data; int ret = 0; + unsigned long irqflags; ++file_priv->lock_count; @@ -71,9 +72,9 @@ return -EINVAL; add_wait_queue(&dev->lock.lock_queue, &entry); - spin_lock(&dev->lock.spinlock); + spin_lock_irqsave(&dev->lock.spinlock, irqflags); dev->lock.user_waiters++; - spin_unlock(&dev->lock.spinlock); + spin_unlock_irqrestore(&dev->lock.spinlock, irqflags); for (;;) { __set_current_state(TASK_INTERRUPTIBLE); if (!dev->lock.hw_lock) { @@ -95,9 +96,9 @@ break; } } - spin_lock(&dev->lock.spinlock); + spin_lock_irqsave(&dev->lock.spinlock, irqflags); dev->lock.user_waiters--; - spin_unlock(&dev->lock.spinlock); + spin_unlock_irqrestore(&dev->lock.spinlock, irqflags); __set_current_state(TASK_RUNNING); remove_wait_queue(&dev->lock.lock_queue, &entry); @@ -198,8 +199,9 @@ { unsigned int old, new, prev; volatile unsigned int *lock = &lock_data->hw_lock->lock; + unsigned long irqflags; - spin_lock(&lock_data->spinlock); + spin_lock_irqsave(&lock_data->spinlock, irqflags); do { old = *lock; if (old & _DRM_LOCK_HELD) @@ -211,7 +213,7 @@ } prev = cmpxchg(lock, old, new); } while (prev != old); - spin_unlock(&lock_data->spinlock); + spin_unlock_irqrestore(&lock_data->spinlock, irqflags); if (_DRM_LOCKING_CONTEXT(old) == context) { if (old & _DRM_LOCK_HELD) { @@ -272,15 +274,16 @@ { unsigned int old, new, prev; volatile unsigned int *lock = &lock_data->hw_lock->lock; + unsigned long irqflags; - spin_lock(&lock_data->spinlock); + spin_lock_irqsave(&lock_data->spinlock, irqflags); if (lock_data->kernel_waiters != 0) { drm_lock_transfer(lock_data, 0); lock_data->idle_has_lock = 1; - spin_unlock(&lock_data->spinlock); + spin_unlock_irqrestore(&lock_data->spinlock, irqflags); return 1; } - spin_unlock(&lock_data->spinlock); + spin_unlock_irqrestore(&lock_data->spinlock, irqflags); do { old = *lock; @@ -344,19 +347,20 @@ void drm_idlelock_take(struct drm_lock_data *lock_data) { int ret = 0; + unsigned long irqflags; - spin_lock(&lock_data->spinlock); + spin_lock_irqsave(&lock_data->spinlock, irqflags); lock_data->kernel_waiters++; if (!lock_data->idle_has_lock) { - spin_unlock(&lock_data->spinlock); + spin_unlock_irqrestore(&lock_data->spinlock, irqflags); ret = drm_lock_take(lock_data, DRM_KERNEL_CONTEXT); - spin_lock(&lock_data->spinlock); + spin_lock_irqsave(&lock_data->spinlock, irqflags); if (ret == 1) lock_data->idle_has_lock = 1; } - spin_unlock(&lock_data->spinlock); + spin_unlock_irqrestore(&lock_data->spinlock, irqflags); } EXPORT_SYMBOL(drm_idlelock_take); @@ -364,8 +368,9 @@ { unsigned int old, prev; volatile unsigned int *lock = &lock_data->hw_lock->lock; + unsigned long irqflags; - spin_lock(&lock_data->spinlock); + spin_lock_irqsave(&lock_data->spinlock, irqflags); if (--lock_data->kernel_waiters == 0) { if (lock_data->idle_has_lock) { do { @@ -376,7 +381,7 @@ lock_data->idle_has_lock = 0; } } - spin_unlock(&lock_data->spinlock); + spin_unlock_irqrestore(&lock_data->spinlock, irqflags); } EXPORT_SYMBOL(drm_idlelock_release); --- linux-2.6.24.orig/drivers/char/drm/Makefile +++ linux-2.6.24/drivers/char/drm/Makefile @@ -18,6 +18,7 @@ sis-objs := sis_drv.o sis_mm.o savage-objs := savage_drv.o savage_bci.o savage_state.o via-objs := via_irq.o via_drv.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o via_dmablit.o +via_chrome9-objs := via_chrome9_drv.o via_chrome9_drm.o via_chrome9_mm.o via_chrome9_dma.o ifeq ($(CONFIG_COMPAT),y) drm-objs += drm_ioc32.o @@ -38,5 +39,4 @@ obj-$(CONFIG_DRM_SIS) += sis.o obj-$(CONFIG_DRM_SAVAGE)+= savage.o obj-$(CONFIG_DRM_VIA) +=via.o - - +obj-$(CONFIG_DRM_VIA_CHROME9) += via_chrome9.o --- linux-2.6.24.orig/drivers/char/drm/via_chrome9_dma.h +++ linux-2.6.24/drivers/char/drm/via_chrome9_dma.h @@ -0,0 +1,68 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, subject to the + * following conditions: + * + * The above copyright notice and this permission notice + * (including the next paragraph) shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL VIA, S3 GRAPHICS, AND/OR + * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef _VIA_CHROME9_DMA_H_ +#define _VIA_CHROME9_DMA_H_ + +#define MAX_BCI_BUFFER_SIZE 16*1024*1024 + +enum cmd_request_type { + CM_REQUEST_BCI, + CM_REQUEST_DMA, + CM_REQUEST_RB, + CM_REQUEST_RB_FORCED_DMA, + CM_REQUEST_NOTAVAILABLE +}; + +struct cmd_get_space { + unsigned int dwRequestSize; + enum cmd_request_type hint; + volatile unsigned int *pCmdData; +}; + +struct cmd_release_space { + unsigned int dwReleaseSize; +}; + +extern int via_chrome9_hw_init(struct drm_device *dev, + struct drm_via_chrome9_init *init); +extern int via_chrome9_ioctl_flush(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int via_chrome9_ioctl_free(struct drm_device *dev, void *data, + struct drm_file *file_prev); +extern int via_chrome9_ioctl_wait_chip_idle(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int via_chrome9_ioctl_flush_cache(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int via_chrome9_ioctl_flush(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int via_chrome9_ioctl_free(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern unsigned int ProtectSizeValue(unsigned int size); +extern void SetAGPDoubleCmd_inv(struct drm_device *dev); +extern void SetAGPRingCmdRegs_inv(struct drm_device *dev); + +#endif --- linux-2.6.24.orig/drivers/char/drm/via_chrome9_mm.c +++ linux-2.6.24/drivers/char/drm/via_chrome9_mm.c @@ -0,0 +1,388 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, subject to the + * following conditions: + * + * The above copyright notice and this permission notice + * (including the next paragraph) shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL VIA, S3 GRAPHICS, AND/OR + * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "drmP.h" +#include "via_chrome9_drm.h" +#include "via_chrome9_drv.h" +#include "drm_sman.h" +#include "via_chrome9_mm.h" + +#define VIA_CHROME9_MM_GRANULARITY 4 +#define VIA_CHROME9_MM_GRANULARITY_MASK ((1 << VIA_CHROME9_MM_GRANULARITY) - 1) + + +int via_chrome9_map_init(struct drm_device *dev, + struct drm_via_chrome9_init *init) +{ + struct drm_via_chrome9_private *dev_priv = + (struct drm_via_chrome9_private *)dev->dev_private; + + dev_priv->sarea = drm_getsarea(dev); + if (!dev_priv->sarea) { + DRM_ERROR("could not find sarea!\n"); + goto error; + } + dev_priv->sarea_priv = + (struct drm_via_chrome9_sarea *)((unsigned char *)dev_priv-> + sarea->handle + init->sarea_priv_offset); + + dev_priv->fb = drm_core_findmap(dev, init->fb_handle); + if (!dev_priv->fb) { + DRM_ERROR("could not find framebuffer!\n"); + goto error; + } + /* Frame buffer physical base address */ + dev_priv->fb_base_address = init->fb_base_address; + + if (init->shadow_size) { + /* find apg shadow region mappings */ + dev_priv->shadow_map.shadow = drm_core_findmap(dev, init-> + shadow_handle); + if (!dev_priv->shadow_map.shadow) { + DRM_ERROR("could not shadow map!\n"); + goto error; + } + dev_priv->shadow_map.shadow_size = init->shadow_size; + dev_priv->shadow_map.shadow_handle = (unsigned int *)dev_priv-> + shadow_map.shadow->handle; + init->shadow_handle = dev_priv->shadow_map.shadow->offset; + } + if (init->agp_tex_size && init->chip_agp != CHIP_PCIE) { + /* find apg texture buffer mappings */ + dev_priv->agp_tex = drm_core_findmap(dev, init->agp_tex_handle); + dev_priv->agp_size = init->agp_tex_size; + dev_priv->agp_offset = init->agp_tex_handle; + if (!dev_priv->agp_tex) { + DRM_ERROR("could not find agp texture map !\n"); + goto error; + } + } + /* find mmio/dma mappings */ + dev_priv->mmio = drm_core_findmap(dev, init->mmio_handle); + if (!dev_priv->mmio) { + DRM_ERROR("failed to find mmio region!\n"); + goto error; + } + + dev_priv->hostBlt = drm_core_findmap(dev, init->hostBlt_handle); + if (!dev_priv->hostBlt) { + DRM_ERROR("failed to find host bitblt region!\n"); + goto error; + } + + dev_priv->drm_agp_type = init->agp_type; + if (init->agp_type != AGP_DISABLED && init->chip_agp != CHIP_PCIE) { + dev->agp_buffer_map = drm_core_findmap(dev, init->dma_handle); + if (!dev->agp_buffer_map) { + DRM_ERROR("failed to find dma buffer region!\n"); + goto error; + } + } + + dev_priv->bci = (char *)dev_priv->mmio->handle + 0x10000; + + return 0; + +error: + /* do cleanup here, refine_later */ + return (-EINVAL); +} + +int via_chrome9_heap_management_init(struct drm_device *dev, + struct drm_via_chrome9_init *init) +{ + struct drm_via_chrome9_private *dev_priv = + (struct drm_via_chrome9_private *) dev->dev_private; + int ret = 0; + + /* video memory management. range: 0 ---- video_whole_size */ + mutex_lock(&dev->struct_mutex); + ret = drm_sman_set_range(&dev_priv->sman, VIA_CHROME9_MEM_VIDEO, + 0, dev_priv->available_fb_size >> VIA_CHROME9_MM_GRANULARITY); + if (ret) { + DRM_ERROR("VRAM memory manager initialization ******ERROR\ + !******\n"); + mutex_unlock(&dev->struct_mutex); + goto error; + } + dev_priv->vram_initialized = 1; + /* agp/pcie heap management. + note:because agp is contradict with pcie, so only one is enough + for managing both of them.*/ + init->agp_type = dev_priv->drm_agp_type; + if (init->agp_type != AGP_DISABLED && dev_priv->agp_size) { + ret = drm_sman_set_range(&dev_priv->sman, VIA_CHROME9_MEM_AGP, + 0, dev_priv->agp_size >> VIA_CHROME9_MM_GRANULARITY); + if (ret) { + DRM_ERROR("AGP/PCIE memory manager initialization ******ERROR\ + !******\n"); + mutex_unlock(&dev->struct_mutex); + goto error; + } + dev_priv->agp_initialized = 1; + } + mutex_unlock(&dev->struct_mutex); + return 0; + +error: + /* Do error recover here, refine_later */ + return -EINVAL; +} + + +void via_chrome9_memory_destroy_heap(struct drm_device *dev, + struct drm_via_chrome9_private *dev_priv) +{ + mutex_lock(&dev->struct_mutex); + drm_sman_cleanup(&dev_priv->sman); + dev_priv->vram_initialized = 0; + dev_priv->agp_initialized = 0; + mutex_unlock(&dev->struct_mutex); +} + +void via_chrome9_reclaim_buffers_locked(struct drm_device *dev, + struct drm_file *file_priv) +{ + return; +} + +int via_chrome9_ioctl_allocate_aperture(struct drm_device *dev, + void *data, struct drm_file *file_priv) +{ + return 0; +} + +int via_chrome9_ioctl_free_aperture(struct drm_device *dev, + void *data, struct drm_file *file_priv) +{ + return 0; +} + + +/* Allocate memory from DRM module for video playing */ +int via_chrome9_ioctl_allocate_mem_base(struct drm_device *dev, +void *data, struct drm_file *file_priv) +{ + struct drm_via_chrome9_mem *mem = data; + struct drm_memblock_item *item; + struct drm_via_chrome9_private *dev_priv = + (struct drm_via_chrome9_private *) dev->dev_private; + unsigned long tmpSize = 0, offset = 0, alignment = 0; + /* modify heap_type to agp for pcie, since we treat pcie/agp heap + no difference in heap management */ + if (mem->type == memory_heap_pcie) { + if (dev_priv->chip_agp != CHIP_PCIE) { + DRM_ERROR( + "User want to alloc memory from pcie heap but via_chrome9.ko\ + has no this heap exist.******ERROR******\n"); + return -EINVAL; + } + mem->type = memory_heap_agp; + } + + if (mem->type > VIA_CHROME9_MEM_AGP) { + DRM_ERROR("Unknown memory type allocation\n"); + return -EINVAL; + } + mutex_lock(&dev->struct_mutex); + if (0 == ((mem->type == VIA_CHROME9_MEM_VIDEO) ? + dev_priv->vram_initialized : dev_priv->agp_initialized)) { + DRM_ERROR("Attempt to allocate from uninitialized\ + memory manager.\n"); + mutex_unlock(&dev->struct_mutex); + return -EINVAL; + } + tmpSize = (mem->size + VIA_CHROME9_MM_GRANULARITY_MASK) >> + VIA_CHROME9_MM_GRANULARITY; + mem->size = tmpSize << VIA_CHROME9_MM_GRANULARITY; + alignment = (dev_priv->alignment & 0x80000000) ? dev_priv-> + alignment & 0x7FFFFFFF:0; + alignment /= (1 << VIA_CHROME9_MM_GRANULARITY); + item = drm_sman_alloc(&dev_priv->sman, mem->type, tmpSize, alignment, + (unsigned long)file_priv); + mutex_unlock(&dev->struct_mutex); + /* alloc failed */ + if (!item) { + DRM_ERROR("Allocate memory failed ******ERROR******.\n"); + return -ENOMEM; + } + /* Till here every thing is ok, we check the memory type allocated + and return appropriate value to user mode Here the value return to + user is very difficult to operate. BE CAREFULLY!!! */ + /* offset is used by user mode ap to calculate the virtual address + which is used to access the memory allocated */ + mem->index = item->user_hash.key; + offset = item->mm->offset(item->mm, item->mm_info) << + VIA_CHROME9_MM_GRANULARITY; + switch (mem->type) { + case VIA_CHROME9_MEM_VIDEO: + mem->offset = offset + dev_priv->back_offset; + break; + case VIA_CHROME9_MEM_AGP: + /* return different value to user according to the chip type */ + if (dev_priv->chip_agp == CHIP_PCIE) { + mem->offset = offset + + ((struct drm_via_chrome9_DMA_manager *)dev_priv-> + dma_manager)->DMASize * sizeof(unsigned long); + } else { + mem->offset = offset; + } + break; + default: + /* Strange thing happen! Faint. Code bug! */ + DRM_ERROR("Enter here is impossible ******\ + ERROR******.\n"); + return -EINVAL; + } + /*DONE. Need we call function copy_to_user ?NO. We can't even + touch user's space.But we are lucky, since kernel drm:drm_ioctl + will to the job for us. */ + return 0; +} + +/* Allocate video/AGP/PCIE memory from heap management */ +int via_chrome9_ioctl_allocate_mem_wrapper(struct drm_device + *dev, void *data, struct drm_file *file_priv) +{ + struct drm_via_chrome9_memory_alloc *memory_alloc = + (struct drm_via_chrome9_memory_alloc *)data; + struct drm_via_chrome9_private *dev_priv = + (struct drm_via_chrome9_private *) dev->dev_private; + struct drm_via_chrome9_mem mem; + + mem.size = memory_alloc->size; + mem.type = memory_alloc->heap_type; + dev_priv->alignment = memory_alloc->align | 0x80000000; + if (via_chrome9_ioctl_allocate_mem_base(dev, &mem, file_priv)) { + DRM_ERROR("Allocate memory error!.\n"); + return -ENOMEM; + } + dev_priv->alignment = 0; + /* Till here every thing is ok, we check the memory type allocated and + return appropriate value to user mode Here the value return to user is + very difficult to operate. BE CAREFULLY!!!*/ + /* offset is used by user mode ap to calculate the virtual address + which is used to access the memory allocated */ + memory_alloc->offset = mem.offset; + memory_alloc->heap_info.lpL1Node = (void *)mem.index; + memory_alloc->size = mem.size; + switch (memory_alloc->heap_type) { + case VIA_CHROME9_MEM_VIDEO: + memory_alloc->physaddress = memory_alloc->offset + + dev_priv->fb_base_address; + memory_alloc->linearaddress = (void *)memory_alloc->physaddress; + break; + case VIA_CHROME9_MEM_AGP: + /* return different value to user according to the chip type */ + if (dev_priv->chip_agp == CHIP_PCIE) { + memory_alloc->physaddress = memory_alloc->offset; + memory_alloc->linearaddress = (void *)memory_alloc-> + physaddress; + } else { + memory_alloc->physaddress = dev->agp->base + + memory_alloc->offset + + ((struct drm_via_chrome9_DMA_manager *) + dev_priv->dma_manager)->DMASize * sizeof(unsigned long); + memory_alloc->linearaddress = + (void *)memory_alloc->physaddress; + } + break; + default: + /* Strange thing happen! Faint. Code bug! */ + DRM_ERROR("Enter here is impossible ******ERROR******.\n"); + return -EINVAL; + } + return 0; +} + +int via_chrome9_ioctl_free_mem_wrapper(struct drm_device *dev, + void *data, struct drm_file *file_priv) +{ + struct drm_via_chrome9_memory_alloc *memory_alloc = data; + struct drm_via_chrome9_mem mem; + + mem.index = (unsigned long)memory_alloc->heap_info.lpL1Node; + if (via_chrome9_ioctl_freemem_base(dev, &mem, file_priv)) { + DRM_ERROR("function free_mem_wrapper error.\n"); + return -EINVAL; + } + + return 0; +} + +int via_chrome9_ioctl_freemem_base(struct drm_device *dev, + void *data, struct drm_file *file_priv) +{ + struct drm_via_chrome9_private *dev_priv = dev->dev_private; + struct drm_via_chrome9_mem *mem = data; + int ret; + + mutex_lock(&dev->struct_mutex); + ret = drm_sman_free_key(&dev_priv->sman, mem->index); + mutex_unlock(&dev->struct_mutex); + DRM_DEBUG("free = 0x%lx\n", mem->index); + + return ret; +} + +int via_chrome9_ioctl_check_vidmem_size(struct drm_device *dev, + void *data, struct drm_file *file_priv) +{ + return 0; +} + +int via_chrome9_ioctl_pciemem_ctrl(struct drm_device *dev, + void *data, struct drm_file *file_priv) +{ + int result = 0; + struct drm_via_chrome9_private *dev_priv = dev->dev_private; + struct drm_via_chrome9_pciemem_ctrl *pcie_memory_ctrl = data; + switch (pcie_memory_ctrl->ctrl_type) { + case pciemem_copy_from_user: + result = copy_from_user((void *)( + dev_priv->pcie_vmalloc_nocache+ + pcie_memory_ctrl->pcieoffset), + pcie_memory_ctrl->usermode_data, + pcie_memory_ctrl->size); + break; + case pciemem_copy_to_user: + result = copy_to_user(pcie_memory_ctrl->usermode_data, + (void *)(dev_priv->pcie_vmalloc_nocache+ + pcie_memory_ctrl->pcieoffset), + pcie_memory_ctrl->size); + break; + case pciemem_memset: + memset((void *)(dev_priv->pcie_vmalloc_nocache + + pcie_memory_ctrl->pcieoffset), + pcie_memory_ctrl->memsetdata, + pcie_memory_ctrl->size); + break; + default: + break; + } + return 0; +} --- linux-2.6.24.orig/drivers/char/drm/via_chrome9_dma.c +++ linux-2.6.24/drivers/char/drm/via_chrome9_dma.c @@ -0,0 +1,1147 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, subject to the + * following conditions: + * + * The above copyright notice and this permission notice + * (including the next paragraph) shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL VIA, S3 GRAPHICS, AND/OR + * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "drmP.h" +#include "drm.h" +#include "via_chrome9_drm.h" +#include "via_chrome9_drv.h" +#include "via_chrome9_3d_reg.h" +#include "via_chrome9_dma.h" + +#define NULLCOMMANDNUMBER 256 +unsigned int NULL_COMMAND_INV[4] = + { 0xCC000000, 0xCD000000, 0xCE000000, 0xCF000000 }; + +void +via_chrome9ke_assert(int a) +{ +} + +unsigned int +ProtectSizeValue(unsigned int size) +{ + unsigned int i; + for (i = 0; i < 8; i++) + if ((size > (1 << (i + 12))) + && (size <= (1 << (i + 13)))) + return (i + 1); + return 0; +} + +static unsigned int +InitPCIEGART(struct drm_via_chrome9_private *dev_priv) +{ + unsigned int *pGARTTable; + unsigned int i, entries, GARTOffset; + unsigned char sr6a, sr6b, sr6c, sr6f, sr7b; + + if (!dev_priv->pagetable_map.pagetable_size) + return 0; + + entries = dev_priv->pagetable_map.pagetable_size / sizeof(unsigned int); + + pGARTTable = + ioremap_nocache(dev_priv->fb_base_address + + dev_priv->pagetable_map.pagetable_offset, + dev_priv->pagetable_map.pagetable_size); + if (pGARTTable) + dev_priv->pagetable_map.pagetable_handle = pGARTTable; + else + return 0; + + /*set gart table base */ + GARTOffset = dev_priv->pagetable_map.pagetable_offset; + + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6c); + sr6c = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5); + sr6c &= (~0x80); + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6c); + + sr6a = (unsigned char) ((GARTOffset & 0xff000) >> 12); + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6a); + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6a); + + sr6b = (unsigned char) ((GARTOffset & 0xff00000) >> 20); + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6b); + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6b); + + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6c); + sr6c = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5); + sr6c |= ((unsigned char) ((GARTOffset >> 28) & 0x01)); + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6c); + + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x7b); + sr7b = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5); + sr7b &= (~0x0f); + sr7b |= ProtectSizeValue(dev_priv->pagetable_map.pagetable_size); + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr7b); + + for (i = 0; i < entries; i++) + writel(0x80000000, pGARTTable + i); + /*flush */ + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6f); + do { + sr6f = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5); + } + while (sr6f & 0x80) + ; + + sr6f |= 0x80; + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6f); + + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6c); + sr6c = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5); + sr6c |= 0x80; + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6c); + + return 1; +} + + +static unsigned int * +AllocAndBindPCIEMemory(struct drm_via_chrome9_private *dev_priv, + unsigned int size, unsigned int offset) +{ + unsigned int *addrlinear; + unsigned int *pGARTTable; + unsigned int entries, alignedoffset, i; + unsigned char sr6c, sr6f; + + if (!size) + return NULL; + + entries = (size + PAGE_SIZE - 1) / PAGE_SIZE; + alignedoffset = (offset + PAGE_SIZE - 1) / PAGE_SIZE; + + if ((entries + alignedoffset) > + (dev_priv->pagetable_map.pagetable_size / sizeof(unsigned int))) + return NULL; + + addrlinear = + __vmalloc(entries * PAGE_SIZE, GFP_KERNEL | __GFP_HIGHMEM, + PAGE_KERNEL_NOCACHE); + + if (!addrlinear) + return NULL; + + pGARTTable = dev_priv->pagetable_map.pagetable_handle; + + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6c); + sr6c = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5); + sr6c &= (~0x80); + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6c); + + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6f); + do { + sr6f = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5); + } + while (sr6f & 0x80) + ; + + for (i = 0; i < entries; i++) + writel(page_to_pfn + (vmalloc_to_page((void *) addrlinear + PAGE_SIZE * i)) & + 0x3fffffff, pGARTTable + i + alignedoffset); + + sr6f |= 0x80; + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6f); + + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c4, 0x6c); + sr6c = GetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5); + sr6c |= 0x80; + SetMMIORegisterU8(dev_priv->mmio->handle, 0x83c5, sr6c); + + return addrlinear; + +} + +void +SetAGPDoubleCmd_inv(struct drm_device *dev) +{ + /* we now don't use double buffer */ + return; +} + +void +SetAGPRingCmdRegs_inv(struct drm_device *dev) +{ + struct drm_via_chrome9_private *dev_priv = + (struct drm_via_chrome9_private *) dev->dev_private; + struct drm_via_chrome9_DMA_manager *lpcmDMAManager = + (struct drm_via_chrome9_DMA_manager *) dev_priv->dma_manager; + unsigned int AGPBufLinearBase = 0, AGPBufPhysicalBase = 0; + unsigned long *pFree; + unsigned int dwStart, dwEnd, dwPause, AGPCurrAddr, AGPCurStat, CurrAGP; + unsigned int dwReg60, dwReg61, dwReg62, dwReg63, + dwReg64, dwReg65, dwJump; + + lpcmDMAManager->pFree = lpcmDMAManager->pBeg; + + AGPBufLinearBase = (unsigned int) lpcmDMAManager->addr_linear; + AGPBufPhysicalBase = + (dev_priv->chip_agp == + CHIP_PCIE) ? 0 : (unsigned int) dev->agp->base + + lpcmDMAManager->pPhysical; + /*add shadow offset */ + + CurrAGP = + GetMMIORegister(dev_priv->mmio->handle, INV_RB_AGPCMD_CURRADDR); + AGPCurStat = + GetMMIORegister(dev_priv->mmio->handle, INV_RB_AGPCMD_STATUS); + + if (AGPCurStat & INV_AGPCMD_InPause) { + AGPCurrAddr = + GetMMIORegister(dev_priv->mmio->handle, + INV_RB_AGPCMD_CURRADDR); + pFree = (unsigned long *) (AGPBufLinearBase + AGPCurrAddr - + AGPBufPhysicalBase); + ADDCmdHeader2_INVI(pFree, INV_REG_CR_TRANS, INV_ParaType_Dummy); + if (dev_priv->chip_sub_index == CHIP_H6S2) + do { + ADDCmdData_INVI(pFree, 0xCCCCCCC0); + ADDCmdData_INVI(pFree, 0xDDD00000); + } + while ((u32)((unsigned int) pFree) & 0x7f) + ; + /*for 8*128bit aligned */ + else + do { + ADDCmdData_INVI(pFree, 0xCCCCCCC0); + ADDCmdData_INVI(pFree, 0xDDD00000); + } + while ((u32) ((unsigned int) pFree) & 0x1f) + ; + /*for 256bit aligned */ + dwPause = + (u32) (((unsigned int) pFree) - AGPBufLinearBase + + AGPBufPhysicalBase - 16); + + dwReg64 = INV_SubA_HAGPBpL | INV_HWBasL(dwPause); + dwReg65 = + INV_SubA_HAGPBpID | INV_HWBasH(dwPause) | + INV_HAGPBpID_STOP; + + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_TRANS, + INV_ParaType_PreCR); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, + dwReg64); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, + dwReg65); + + while ((GetMMIORegister + (dev_priv->mmio->handle, + INV_RB_ENG_STATUS) & INV_ENG_BUSY_ALL)); + } + dwStart = + (u32) ((unsigned int) lpcmDMAManager->pBeg - AGPBufLinearBase + + AGPBufPhysicalBase); + dwEnd = (u32) ((unsigned int) lpcmDMAManager->pEnd - AGPBufLinearBase + + AGPBufPhysicalBase); + + lpcmDMAManager->pFree = lpcmDMAManager->pBeg; + if (dev_priv->chip_sub_index == CHIP_H6S2) { + ADDCmdHeader2_INVI(lpcmDMAManager->pFree, INV_REG_CR_TRANS, + INV_ParaType_Dummy); + do { + ADDCmdData_INVI(lpcmDMAManager->pFree, 0xCCCCCCC0); + ADDCmdData_INVI(lpcmDMAManager->pFree, 0xDDD00000); + } + while ((u32)((unsigned long *) lpcmDMAManager->pFree) & 0x7f) + ; + } + dwJump = 0xFFFFFFF0; + dwPause = + (u32)(((unsigned int) lpcmDMAManager->pFree) - + 16 - AGPBufLinearBase + AGPBufPhysicalBase); + + DRM_DEBUG("dwStart = %08x, dwEnd = %08x, dwPause = %08x\n", dwStart, + dwEnd, dwPause); + + dwReg60 = INV_SubA_HAGPBstL | INV_HWBasL(dwStart); + dwReg61 = INV_SubA_HAGPBstH | INV_HWBasH(dwStart); + dwReg62 = INV_SubA_HAGPBendL | INV_HWBasL(dwEnd); + dwReg63 = INV_SubA_HAGPBendH | INV_HWBasH(dwEnd); + dwReg64 = INV_SubA_HAGPBpL | INV_HWBasL(dwPause); + dwReg65 = INV_SubA_HAGPBpID | INV_HWBasH(dwPause) | INV_HAGPBpID_PAUSE; + + if (dev_priv->chip_sub_index == CHIP_H6S2) + dwReg60 |= 0x01; + + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_TRANS, + INV_ParaType_PreCR); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg60); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg61); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg62); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg63); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg64); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg65); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, + INV_SubA_HAGPBjumpL | INV_HWBasL(dwJump)); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, + INV_SubA_HAGPBjumpH | INV_HWBasH(dwJump)); + + /* Trigger AGP cycle */ + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, + INV_SubA_HFthRCM | INV_HFthRCM_10 | INV_HAGPBTrig); + + /*for debug */ + CurrAGP = + GetMMIORegister(dev_priv->mmio->handle, INV_RB_AGPCMD_CURRADDR); + + lpcmDMAManager->pInUseBySW = lpcmDMAManager->pFree; +} + +/* Do hw intialization and determine whether to use dma or mmio to +talk with hw */ +int +via_chrome9_hw_init(struct drm_device *dev, + struct drm_via_chrome9_init *init) +{ + struct drm_via_chrome9_private *dev_priv = + (struct drm_via_chrome9_private *) dev->dev_private; + unsigned retval = 0; + unsigned int *pGARTTable, *addrlinear = NULL; + int pages; + struct drm_clb_event_tag_info *event_tag_info; + struct drm_via_chrome9_DMA_manager *lpcmDMAManager = NULL; + + if (init->chip_agp == CHIP_PCIE) { + dev_priv->pagetable_map.pagetable_offset = + init->garttable_offset; + dev_priv->pagetable_map.pagetable_size = init->garttable_size; + dev_priv->agp_size = init->agp_tex_size; + /*Henry :prepare for PCIE texture buffer */ + } else { + dev_priv->pagetable_map.pagetable_offset = 0; + dev_priv->pagetable_map.pagetable_size = 0; + } + + dev_priv->dma_manager = + kmalloc(sizeof(struct drm_via_chrome9_DMA_manager), GFP_KERNEL); + if (!dev_priv->dma_manager) { + DRM_ERROR("could not allocate system for dma_manager!\n"); + return -ENOMEM; + } + + lpcmDMAManager = + (struct drm_via_chrome9_DMA_manager *) dev_priv->dma_manager; + ((struct drm_via_chrome9_DMA_manager *) + dev_priv->dma_manager)->DMASize = init->DMA_size; + ((struct drm_via_chrome9_DMA_manager *) + dev_priv->dma_manager)->pPhysical = init->DMA_phys_address; + + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_TRANS, 0x00110000); + if (dev_priv->chip_sub_index == CHIP_H6S2) { + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, + 0x06000000); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, + 0x07100000); + } else { + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, + 0x02000000); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, + 0x03100000); + } + + /* Specify fence command read back ID */ + /* Default the read back ID is CR */ + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_TRANS, + INV_ParaType_PreCR); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, + INV_SubA_HSetRBGID | INV_HSetRBGID_CR); + + DRM_DEBUG("begin to init\n"); + + if (dev_priv->chip_sub_index == CHIP_H6S2) { + dev_priv->pcie_vmalloc_nocache = 0; + if (dev_priv->pagetable_map.pagetable_size) + retval = InitPCIEGART(dev_priv); + + if (retval && dev_priv->drm_agp_type != DRM_AGP_DISABLED) { + addrlinear = + AllocAndBindPCIEMemory(dev_priv, + lpcmDMAManager->DMASize + + dev_priv->agp_size, 0); + if (addrlinear) { + dev_priv->pcie_vmalloc_nocache = (unsigned long) + addrlinear; + } else { + dev_priv->bci_buffer = + vmalloc(MAX_BCI_BUFFER_SIZE); + dev_priv->drm_agp_type = DRM_AGP_DISABLED; + } + } else { + dev_priv->bci_buffer = vmalloc(MAX_BCI_BUFFER_SIZE); + dev_priv->drm_agp_type = DRM_AGP_DISABLED; + } + } else { + if (dev_priv->drm_agp_type != DRM_AGP_DISABLED) { + pGARTTable = NULL; + addrlinear = (unsigned int *) + ioremap(dev->agp->base + + lpcmDMAManager->pPhysical, + lpcmDMAManager->DMASize); + dev_priv->bci_buffer = NULL; + } else { + dev_priv->bci_buffer = vmalloc(MAX_BCI_BUFFER_SIZE); + /*Homer, BCI path always use this block of memory8 */ + } + } + + /*till here we have known whether support dma or not */ + pages = dev->sg->pages; + event_tag_info = vmalloc(sizeof(struct drm_clb_event_tag_info)); + memset(event_tag_info, 0, sizeof(struct drm_clb_event_tag_info)); + if (!event_tag_info) + return DRM_ERROR(" event_tag_info allocate error!"); + + /* aligned to 16k alignment */ + event_tag_info->linear_address = + (int + *) (((unsigned int) dev_priv->shadow_map.shadow_handle + + 0x3fff) & 0xffffc000); + event_tag_info->event_tag_linear_address = + event_tag_info->linear_address + 3; + dev_priv->event_tag_info = (void *) event_tag_info; + dev_priv->max_apertures = NUMBER_OF_APERTURES_CLB; + + /* Initialize DMA data structure */ + lpcmDMAManager->DMASize /= sizeof(unsigned int); + lpcmDMAManager->pBeg = addrlinear; + lpcmDMAManager->pFree = lpcmDMAManager->pBeg; + lpcmDMAManager->pInUseBySW = lpcmDMAManager->pBeg; + lpcmDMAManager->pInUseByHW = lpcmDMAManager->pBeg; + lpcmDMAManager->LastIssuedEventTag = (unsigned int) (unsigned long *) + lpcmDMAManager->pBeg; + lpcmDMAManager->ppInUseByHW = + (unsigned int **) ((char *) (dev_priv->mmio->handle) + + INV_RB_AGPCMD_CURRADDR); + lpcmDMAManager->bDMAAgp = dev_priv->chip_agp; + lpcmDMAManager->addr_linear = (unsigned int *) addrlinear; + + if (dev_priv->drm_agp_type == DRM_AGP_DOUBLE_BUFFER) { + lpcmDMAManager->MaxKickoffSize = lpcmDMAManager->DMASize >> 1; + lpcmDMAManager->pEnd = + lpcmDMAManager->addr_linear + + (lpcmDMAManager->DMASize >> 1) - 1; + SetAGPDoubleCmd_inv(dev); + if (dev_priv->chip_sub_index == CHIP_H6S2) { + DRM_INFO("DMA buffer initialized finished. "); + DRM_INFO("Use PCIE Double Buffer type!\n"); + DRM_INFO("Total PCIE DMA buffer size = %8d bytes. \n", + lpcmDMAManager->DMASize << 2); + } else { + DRM_INFO("DMA buffer initialized finished. "); + DRM_INFO("Use AGP Double Buffer type!\n"); + DRM_INFO("Total AGP DMA buffer size = %8d bytes. \n", + lpcmDMAManager->DMASize << 2); + } + } else if (dev_priv->drm_agp_type == DRM_AGP_RING_BUFFER) { + lpcmDMAManager->MaxKickoffSize = lpcmDMAManager->DMASize; + lpcmDMAManager->pEnd = + lpcmDMAManager->addr_linear + lpcmDMAManager->DMASize; + SetAGPRingCmdRegs_inv(dev); + if (dev_priv->chip_sub_index == CHIP_H6S2) { + DRM_INFO("DMA buffer initialized finished. \n"); + DRM_INFO("Use PCIE Ring Buffer type!"); + DRM_INFO("Total PCIE DMA buffer size = %8d bytes. \n", + lpcmDMAManager->DMASize << 2); + } else { + DRM_INFO("DMA buffer initialized finished. "); + DRM_INFO("Use AGP Ring Buffer type!\n"); + DRM_INFO("Total AGP DMA buffer size = %8d bytes. \n", + lpcmDMAManager->DMASize << 2); + } + } else if (dev_priv->drm_agp_type == DRM_AGP_DISABLED) { + lpcmDMAManager->MaxKickoffSize = 0x0; + if (dev_priv->chip_sub_index == CHIP_H6S2) + DRM_INFO("PCIE init failed! Use PCI\n"); + else + DRM_INFO("AGP init failed! Use PCI\n"); + } + return 0; +} + +static void +kickoff_bci_inv(struct drm_via_chrome9_private *dev_priv, + struct drm_via_chrome9_flush *dma_info) +{ + u32 HdType, dwQWCount, i, dwCount, Addr1, Addr2, SWPointer, + SWPointerEnd; + unsigned long *pCmdData; + int result; + + /*pCmdData = __s3gke_vmalloc(dma_info->cmd_size<<2); */ + pCmdData = dev_priv->bci_buffer; + + if (!pCmdData) + return; + + result = copy_from_user((int *) pCmdData, dma_info->usermode_dma_buf, + dma_info->cmd_size << 2); + + SWPointer = 0; + SWPointerEnd = (u32) dma_info->cmd_size; + while (SWPointer < SWPointerEnd) { + HdType = pCmdData[SWPointer] & INV_AGPHeader_MASK; + switch (HdType) { + case INV_AGPHeader0: + case INV_AGPHeader5: + dwQWCount = pCmdData[SWPointer + 1]; + SWPointer += 4; + + for (i = 0; i < dwQWCount; i++) { + SetMMIORegister(dev_priv->mmio->handle, + pCmdData[SWPointer], + pCmdData[SWPointer + 1]); + SWPointer += 2; + } + break; + + case INV_AGPHeader1: + dwCount = pCmdData[SWPointer + 1]; + Addr1 = 0x0; + SWPointer += 4; /* skip 128-bit. */ + + for (; dwCount > 0; dwCount--, SWPointer++, + Addr1 += 4) { + SetMMIORegister(dev_priv->hostBlt->handle, + Addr1, pCmdData[SWPointer]); + } + break; + + case INV_AGPHeader4: + dwCount = pCmdData[SWPointer + 1]; + Addr1 = pCmdData[SWPointer] & 0x0000FFFF; + SWPointer += 4; /* skip 128-bit. */ + + for (; dwCount > 0; dwCount--, SWPointer++) + SetMMIORegister(dev_priv->mmio->handle, Addr1, + pCmdData[SWPointer]); + break; + + case INV_AGPHeader2: + Addr1 = pCmdData[SWPointer + 1] & 0xFFFF; + Addr2 = pCmdData[SWPointer] & 0xFFFF; + + /* Write first data (either ParaType or whatever) to + Addr1 */ + SetMMIORegister(dev_priv->mmio->handle, Addr1, + pCmdData[SWPointer + 2]); + SWPointer += 4; + + /* The following data are all written to Addr2, + until another header is met */ + while (!IS_AGPHEADER_INV(pCmdData[SWPointer]) + && (SWPointer < SWPointerEnd)) { + SetMMIORegister(dev_priv->mmio->handle, Addr2, + pCmdData[SWPointer]); + SWPointer++; + } + break; + + case INV_AGPHeader3: + Addr1 = pCmdData[SWPointer] & 0xFFFF; + Addr2 = Addr1 + 4; + dwCount = pCmdData[SWPointer + 1]; + + /* Write first data (either ParaType or whatever) to + Addr1 */ + SetMMIORegister(dev_priv->mmio->handle, Addr1, + pCmdData[SWPointer + 2]); + SWPointer += 4; + + for (i = 0; i < dwCount; i++) { + SetMMIORegister(dev_priv->mmio->handle, Addr2, + pCmdData[SWPointer]); + SWPointer++; + } + break; + + case INV_AGPHeader6: + break; + + case INV_AGPHeader7: + break; + + default: + SWPointer += 4; /* Advance to next header */ + } + + SWPointer = (SWPointer + 3) & ~3; + } +} + +void +kickoff_dma_db_inv(struct drm_device *dev) +{ + struct drm_via_chrome9_private *dev_priv = + (struct drm_via_chrome9_private *) dev->dev_private; + struct drm_via_chrome9_DMA_manager *lpcmDMAManager = + dev_priv->dma_manager; + + u32 BufferSize = (u32) (lpcmDMAManager->pFree - lpcmDMAManager->pBeg); + + unsigned int AGPBufLinearBase = + (unsigned int) lpcmDMAManager->addr_linear; + unsigned int AGPBufPhysicalBase = + (unsigned int) dev->agp->base + lpcmDMAManager->pPhysical; + /*add shadow offset */ + + unsigned int dwStart, dwEnd, dwPause; + unsigned int dwReg60, dwReg61, dwReg62, dwReg63, dwReg64, dwReg65; + unsigned int CR_Status; + + if (BufferSize == 0) + return; + + /* 256-bit alignment of AGP pause address */ + if ((u32) ((unsigned long *) lpcmDMAManager->pFree) & 0x1f) { + ADDCmdHeader2_INVI(lpcmDMAManager->pFree, INV_REG_CR_TRANS, + INV_ParaType_Dummy); + do { + ADDCmdData_INVI(lpcmDMAManager->pFree, 0xCCCCCCC0); + ADDCmdData_INVI(lpcmDMAManager->pFree, 0xDDD00000); + } + while (((unsigned int) lpcmDMAManager->pFree) & 0x1f) + ; + } + + dwStart = + (u32) (unsigned long *)lpcmDMAManager->pBeg - + AGPBufLinearBase + AGPBufPhysicalBase; + dwEnd = (u32) (unsigned long *)lpcmDMAManager->pEnd - + AGPBufLinearBase + AGPBufPhysicalBase; + dwPause = + (u32)(unsigned long *)lpcmDMAManager->pFree - + AGPBufLinearBase + AGPBufPhysicalBase - 4; + + dwReg60 = INV_SubA_HAGPBstL | INV_HWBasL(dwStart); + dwReg61 = INV_SubA_HAGPBstH | INV_HWBasH(dwStart); + dwReg62 = INV_SubA_HAGPBendL | INV_HWBasL(dwEnd); + dwReg63 = INV_SubA_HAGPBendH | INV_HWBasH(dwEnd); + dwReg64 = INV_SubA_HAGPBpL | INV_HWBasL(dwPause); + dwReg65 = INV_SubA_HAGPBpID | INV_HWBasH(dwPause) | INV_HAGPBpID_STOP; + + /* wait CR idle */ + CR_Status = GetMMIORegister(dev_priv->mmio->handle, INV_RB_ENG_STATUS); + while (CR_Status & INV_ENG_BUSY_CR) + CR_Status = + GetMMIORegister(dev_priv->mmio->handle, + INV_RB_ENG_STATUS); + + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_TRANS, + INV_ParaType_PreCR); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg60); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg61); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg62); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg63); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg64); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg65); + + /* Trigger AGP cycle */ + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, + INV_SubA_HFthRCM | INV_HFthRCM_10 | INV_HAGPBTrig); + + if (lpcmDMAManager->pBeg == lpcmDMAManager->addr_linear) { + /* The second AGP command buffer */ + lpcmDMAManager->pBeg = + lpcmDMAManager->addr_linear + + (lpcmDMAManager->DMASize >> 2); + lpcmDMAManager->pEnd = + lpcmDMAManager->addr_linear + lpcmDMAManager->DMASize; + lpcmDMAManager->pFree = lpcmDMAManager->pBeg; + } else { + /* The first AGP command buffer */ + lpcmDMAManager->pBeg = lpcmDMAManager->addr_linear; + lpcmDMAManager->pEnd = + lpcmDMAManager->addr_linear + + (lpcmDMAManager->DMASize / 2) - 1; + lpcmDMAManager->pFree = lpcmDMAManager->pBeg; + } + CR_Status = GetMMIORegister(dev_priv->mmio->handle, INV_RB_ENG_STATUS); +} + + +void +kickoff_dma_ring_inv(struct drm_device *dev) +{ + unsigned int dwPause, dwReg64, dwReg65; + + struct drm_via_chrome9_private *dev_priv = + (struct drm_via_chrome9_private *) dev->dev_private; + struct drm_via_chrome9_DMA_manager *lpcmDMAManager = + dev_priv->dma_manager; + + unsigned int AGPBufLinearBase = + (unsigned int) lpcmDMAManager->addr_linear; + unsigned int AGPBufPhysicalBase = + (dev_priv->chip_agp == + CHIP_PCIE) ? 0 : (unsigned int) dev->agp->base + + lpcmDMAManager->pPhysical; + /*add shadow offset */ + + /* 256-bit alignment of AGP pause address */ + if (dev_priv->chip_sub_index == CHIP_H6S2) { + if ((u32) + ((unsigned long *) lpcmDMAManager->pFree) & 0x7f) { + ADDCmdHeader2_INVI(lpcmDMAManager->pFree, + INV_REG_CR_TRANS, + INV_ParaType_Dummy); + do { + ADDCmdData_INVI(lpcmDMAManager->pFree, + 0xCCCCCCC0); + ADDCmdData_INVI(lpcmDMAManager->pFree, + 0xDDD00000); + } + while ((u32)((unsigned long *) lpcmDMAManager->pFree) & + 0x7f) + ; + } + } else { + if ((u32) + ((unsigned long *) lpcmDMAManager->pFree) & 0x1f) { + ADDCmdHeader2_INVI(lpcmDMAManager->pFree, + INV_REG_CR_TRANS, + INV_ParaType_Dummy); + do { + ADDCmdData_INVI(lpcmDMAManager->pFree, + 0xCCCCCCC0); + ADDCmdData_INVI(lpcmDMAManager->pFree, + 0xDDD00000); + } + while ((u32)((unsigned long *) lpcmDMAManager->pFree) & + 0x1f) + ; + } + } + + + dwPause = (u32) ((unsigned long *) lpcmDMAManager->pFree) + - AGPBufLinearBase + AGPBufPhysicalBase - 16; + + dwReg64 = INV_SubA_HAGPBpL | INV_HWBasL(dwPause); + dwReg65 = INV_SubA_HAGPBpID | INV_HWBasH(dwPause) | INV_HAGPBpID_PAUSE; + + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_TRANS, + INV_ParaType_PreCR); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg64); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg65); + + lpcmDMAManager->pInUseBySW = lpcmDMAManager->pFree; +} + +static int +waitchipidle_inv(struct drm_via_chrome9_private *dev_priv) +{ + unsigned int count = 50000; + unsigned int eng_status; + unsigned int engine_busy; + + do { + eng_status = + GetMMIORegister(dev_priv->mmio->handle, + INV_RB_ENG_STATUS); + engine_busy = eng_status & INV_ENG_BUSY_ALL; + count--; + } + while (engine_busy && count) + ; + if (count && engine_busy == 0) + return 0; + return -1; +} + +void +get_space_db_inv(struct drm_device *dev, + struct cmd_get_space *lpcmGetSpaceData) +{ + struct drm_via_chrome9_private *dev_priv = + (struct drm_via_chrome9_private *) dev->dev_private; + struct drm_via_chrome9_DMA_manager *lpcmDMAManager = + dev_priv->dma_manager; + + unsigned int dwRequestSize = lpcmGetSpaceData->dwRequestSize; + if (dwRequestSize > lpcmDMAManager->MaxKickoffSize) { + DRM_INFO("too big DMA buffer request!!!\n"); + via_chrome9ke_assert(0); + *lpcmGetSpaceData->pCmdData = (unsigned int) NULL; + return; + } + + if ((lpcmDMAManager->pFree + dwRequestSize) > + (lpcmDMAManager->pEnd - INV_CMDBUF_THRESHOLD * 2)) + kickoff_dma_db_inv(dev); + + *lpcmGetSpaceData->pCmdData = (unsigned int) lpcmDMAManager->pFree; +} + +void +RewindRingAGP_inv(struct drm_device *dev) +{ + struct drm_via_chrome9_private *dev_priv = + (struct drm_via_chrome9_private *) dev->dev_private; + struct drm_via_chrome9_DMA_manager *lpcmDMAManager = + dev_priv->dma_manager; + + unsigned int AGPBufLinearBase = + (unsigned int) lpcmDMAManager->addr_linear; + unsigned int AGPBufPhysicalBase = + (dev_priv->chip_agp == + CHIP_PCIE) ? 0 : (unsigned int) dev->agp->base + + lpcmDMAManager->pPhysical; + /*add shadow offset */ + + unsigned int dwPause, dwJump; + unsigned int dwReg66, dwReg67; + unsigned int dwReg64, dwReg65; + + ADDCmdHeader2_INVI(lpcmDMAManager->pFree, INV_REG_CR_TRANS, + INV_ParaType_Dummy); + ADDCmdData_INVI(lpcmDMAManager->pFree, 0xCCCCCCC7); + if (dev_priv->chip_sub_index == CHIP_H6S2) + while ((unsigned int) lpcmDMAManager->pFree & 0x7F) + ADDCmdData_INVI(lpcmDMAManager->pFree, 0xCCCCCCC7); + else + while ((unsigned int) lpcmDMAManager->pFree & 0x1F) + ADDCmdData_INVI(lpcmDMAManager->pFree, 0xCCCCCCC7); + dwJump = ((u32) ((unsigned long *) lpcmDMAManager->pFree)) + - AGPBufLinearBase + AGPBufPhysicalBase - 16; + + lpcmDMAManager->pFree = lpcmDMAManager->pBeg; + + dwPause = ((u32) ((unsigned long *) lpcmDMAManager->pFree)) + - AGPBufLinearBase + AGPBufPhysicalBase - 16; + + dwReg64 = INV_SubA_HAGPBpL | INV_HWBasL(dwPause); + dwReg65 = INV_SubA_HAGPBpID | INV_HWBasH(dwPause) | INV_HAGPBpID_PAUSE; + + dwReg66 = INV_SubA_HAGPBjumpL | INV_HWBasL(dwJump); + dwReg67 = INV_SubA_HAGPBjumpH | INV_HWBasH(dwJump); + + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_TRANS, + INV_ParaType_PreCR); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg66); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg67); + + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg64); + SetMMIORegister(dev_priv->mmio->handle, INV_REG_CR_BEGIN, dwReg65); + lpcmDMAManager->pInUseBySW = lpcmDMAManager->pFree; +} + + +void +get_space_ring_inv(struct drm_device *dev, + struct cmd_get_space *lpcmGetSpaceData) +{ + struct drm_via_chrome9_private *dev_priv = + (struct drm_via_chrome9_private *) dev->dev_private; + struct drm_via_chrome9_DMA_manager *lpcmDMAManager = + dev_priv->dma_manager; + unsigned int dwUnFlushed; + unsigned int dwRequestSize = lpcmGetSpaceData->dwRequestSize; + + unsigned int AGPBufLinearBase = + (unsigned int) lpcmDMAManager->addr_linear; + unsigned int AGPBufPhysicalBase = + (dev_priv->chip_agp == + CHIP_PCIE) ? 0 : (unsigned int) dev->agp->base + + lpcmDMAManager->pPhysical; + /*add shadow offset */ + u32 BufStart, BufEnd, CurSW, CurHW, NextSW, BoundaryCheck; + + dwUnFlushed = + (unsigned int) (lpcmDMAManager->pFree - lpcmDMAManager->pBeg); + /*default bEnableModuleSwitch is on for metro,is off for rest */ + /*cmHW_Module_Switch is context-wide variable which is enough for 2d/3d + switch in a context. */ + /*But we must keep the dma buffer being wrapped head and tail by 3d cmds + when it is kicked off to kernel mode. */ + /*Get DMA Space (If requested, or no BCI space and BCI not forced. */ + + if (dwRequestSize > lpcmDMAManager->MaxKickoffSize) { + DRM_INFO("too big DMA buffer request!!!\n"); + via_chrome9ke_assert(0); + *lpcmGetSpaceData->pCmdData = 0; + return; + } + + if (dwUnFlushed + dwRequestSize > lpcmDMAManager->MaxKickoffSize) + kickoff_dma_ring_inv(dev); + + BufStart = + (u32)((unsigned int) lpcmDMAManager->pBeg) - AGPBufLinearBase + + AGPBufPhysicalBase; + BufEnd = (u32)((unsigned int) lpcmDMAManager->pEnd) - AGPBufLinearBase + + AGPBufPhysicalBase; + dwRequestSize = lpcmGetSpaceData->dwRequestSize << 2; + NextSW = (u32) ((unsigned int) lpcmDMAManager->pFree) + dwRequestSize + + INV_CMDBUF_THRESHOLD * 8 - AGPBufLinearBase + + AGPBufPhysicalBase; + + CurSW = (u32)((unsigned int) lpcmDMAManager->pFree) - AGPBufLinearBase + + AGPBufPhysicalBase; + CurHW = GetMMIORegister(dev_priv->mmio->handle, INV_RB_AGPCMD_CURRADDR); + + if (NextSW >= BufEnd) { + kickoff_dma_ring_inv(dev); + CurSW = (u32) ((unsigned int) lpcmDMAManager->pFree) - + AGPBufLinearBase + AGPBufPhysicalBase; + /* make sure the last rewind is completed */ + CurHW = GetMMIORegister(dev_priv->mmio->handle, + INV_RB_AGPCMD_CURRADDR); + while (CurHW > CurSW) + CurHW = GetMMIORegister(dev_priv->mmio->handle, + INV_RB_AGPCMD_CURRADDR); + /* Sometime the value read from HW is unreliable, + so need double confirm. */ + CurHW = GetMMIORegister(dev_priv->mmio->handle, + INV_RB_AGPCMD_CURRADDR); + while (CurHW > CurSW) + CurHW = GetMMIORegister(dev_priv->mmio->handle, + INV_RB_AGPCMD_CURRADDR); + BoundaryCheck = + BufStart + dwRequestSize + INV_QW_PAUSE_ALIGN * 16; + if (BoundaryCheck >= BufEnd) + /* If an empty command buffer can't hold + the request data. */ + via_chrome9ke_assert(0); + else { + /* We need to guarntee the new commands have no chance + to override the unexected commands or wait until there + is no unexecuted commands in agp buffer */ + if (CurSW <= BoundaryCheck) { + CurHW = GetMMIORegister(dev_priv->mmio->handle, + INV_RB_AGPCMD_CURRADDR); + while (CurHW < CurSW) + CurHW = GetMMIORegister( + dev_priv->mmio->handle, + INV_RB_AGPCMD_CURRADDR); + /*Sometime the value read from HW is unreliable, + so need double confirm. */ + CurHW = GetMMIORegister(dev_priv->mmio->handle, + INV_RB_AGPCMD_CURRADDR); + while (CurHW < CurSW) { + CurHW = GetMMIORegister( + dev_priv->mmio->handle, + INV_RB_AGPCMD_CURRADDR); + } + RewindRingAGP_inv(dev); + CurSW = (u32) ((unsigned long *) + lpcmDMAManager->pFree) - + AGPBufLinearBase + AGPBufPhysicalBase; + CurHW = GetMMIORegister(dev_priv->mmio->handle, + INV_RB_AGPCMD_CURRADDR); + /* Waiting until hw pointer jump to start + and hw pointer will */ + /* equal to sw pointer */ + while (CurHW != CurSW) { + CurHW = GetMMIORegister( + dev_priv->mmio->handle, + INV_RB_AGPCMD_CURRADDR); + } + } else { + CurHW = GetMMIORegister(dev_priv->mmio->handle, + INV_RB_AGPCMD_CURRADDR); + + while (CurHW <= BoundaryCheck) { + CurHW = GetMMIORegister( + dev_priv->mmio->handle, + INV_RB_AGPCMD_CURRADDR); + } + CurHW = GetMMIORegister(dev_priv->mmio->handle, + INV_RB_AGPCMD_CURRADDR); + /* Sometime the value read from HW is + unreliable, so need double confirm. */ + while (CurHW <= BoundaryCheck) { + CurHW = GetMMIORegister( + dev_priv->mmio->handle, + INV_RB_AGPCMD_CURRADDR); + } + RewindRingAGP_inv(dev); + } + } + } else { + /* no need to rewind Ensure unexecuted agp commands will + not be override by new + agp commands */ + CurSW = (u32) ((unsigned int) lpcmDMAManager->pFree) - + AGPBufLinearBase + AGPBufPhysicalBase; + CurHW = GetMMIORegister(dev_priv->mmio->handle, + INV_RB_AGPCMD_CURRADDR); + + while ((CurHW > CurSW) && (CurHW <= NextSW)) + CurHW = GetMMIORegister(dev_priv->mmio->handle, + INV_RB_AGPCMD_CURRADDR); + + /* Sometime the value read from HW is unreliable, + so need double confirm. */ + CurHW = GetMMIORegister(dev_priv->mmio->handle, + INV_RB_AGPCMD_CURRADDR); + while ((CurHW > CurSW) && (CurHW <= NextSW)) + CurHW = GetMMIORegister(dev_priv->mmio->handle, + INV_RB_AGPCMD_CURRADDR); + } + /*return the space handle */ + *lpcmGetSpaceData->pCmdData = (unsigned int) lpcmDMAManager->pFree; +} + +void +release_space_inv(struct drm_device *dev, + struct cmd_release_space *lpcmReleaseSpaceData) +{ + struct drm_via_chrome9_private *dev_priv = + (struct drm_via_chrome9_private *) dev->dev_private; + struct drm_via_chrome9_DMA_manager *lpcmDMAManager = + dev_priv->dma_manager; + unsigned int dwReleaseSize = lpcmReleaseSpaceData->dwReleaseSize; + int i = 0; + + lpcmDMAManager->pFree += dwReleaseSize; + + /* aligned address */ + while (((unsigned int) lpcmDMAManager->pFree) & 0xF) { + /* not in 4 unsigned ints (16 Bytes) align address, + insert NULL Commands */ + *lpcmDMAManager->pFree++ = NULL_COMMAND_INV[i & 0x3]; + i++; + } + + if ((dev_priv->chip_sub_index == CHIP_H5) + && (dev_priv->drm_agp_type == DRM_AGP_RING_BUFFER)) { + ADDCmdHeader2_INVI(lpcmDMAManager->pFree, INV_REG_CR_TRANS, + INV_ParaType_Dummy); + for (i = 0; i < NULLCOMMANDNUMBER; i++) + ADDCmdData_INVI(lpcmDMAManager->pFree, 0xCC000000); + } +} + +int +via_chrome9_ioctl_flush(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_via_chrome9_flush *dma_info = data; + struct drm_via_chrome9_private *dev_priv = + (struct drm_via_chrome9_private *) dev->dev_private; + int ret = 0; + int result = 0; + struct cmd_get_space getspace; + struct cmd_release_space releasespace; + volatile unsigned long *pCmdData = NULL; + + switch (dma_info->dma_cmd_type) { + /* Copy DMA buffer to BCI command buffer */ + case flush_bci: + case flush_bci_and_wait: + if (dma_info->cmd_size <= 0) + return 0; + if (dma_info->cmd_size > MAX_BCI_BUFFER_SIZE) { + DRM_INFO("too big BCI space request!!!\n"); + return 0; + } + + kickoff_bci_inv(dev_priv, dma_info); + waitchipidle_inv(dev_priv); + break; + /* Use DRM DMA buffer manager to kick off DMA directly */ + case dma_kickoff: + break; + + /* Copy user mode DMA buffer to kernel DMA buffer, + then kick off DMA */ + case flush_dma_buffer: + case flush_dma_and_wait: + if (dma_info->cmd_size <= 0) + return 0; + + getspace.dwRequestSize = dma_info->cmd_size; + if ((dev_priv->chip_sub_index == CHIP_H5) + && (dev_priv->drm_agp_type == DRM_AGP_RING_BUFFER)) + getspace.dwRequestSize += (NULLCOMMANDNUMBER + 4); + /*henry:Patch for VT3293 agp ring buffer stability */ + getspace.pCmdData = (unsigned int *) &pCmdData; + + if (dev_priv->drm_agp_type == DRM_AGP_DOUBLE_BUFFER) + get_space_db_inv(dev, &getspace); + else if (dev_priv->drm_agp_type == DRM_AGP_RING_BUFFER) + get_space_ring_inv(dev, &getspace); + + if (pCmdData) { + /*copy data from userspace to kernel-dma-agp buffer */ + result = copy_from_user((int *) + pCmdData, + dma_info->usermode_dma_buf, + dma_info->cmd_size << 2); + releasespace.dwReleaseSize = dma_info->cmd_size; + release_space_inv(dev, &releasespace); + + if (dev_priv->drm_agp_type == DRM_AGP_DOUBLE_BUFFER) + kickoff_dma_db_inv(dev); + else if (dev_priv->drm_agp_type == DRM_AGP_RING_BUFFER) + kickoff_dma_ring_inv(dev); + + if (dma_info->dma_cmd_type == flush_dma_and_wait) + waitchipidle_inv(dev_priv); + } else { + DRM_INFO("No enough DMA space"); + ret = -ENOMEM; + } + break; + + default: + DRM_INFO("Invalid DMA buffer type"); + ret = -EINVAL; + break; + } + return ret; +} + +int +via_chrome9_ioctl_free(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + return 0; +} + +int +via_chrome9_ioctl_wait_chip_idle(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_via_chrome9_private *dev_priv = + (struct drm_via_chrome9_private *) dev->dev_private; + + waitchipidle_inv(dev_priv); + /* maybe_bug here, do we always return 0 */ + return 0; +} + +int +via_chrome9_ioctl_flush_cache(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + return 0; +} --- linux-2.6.24.orig/drivers/char/drm/i915_drv.h +++ linux-2.6.24/drivers/char/drm/i915_drv.h @@ -114,6 +114,93 @@ spinlock_t swaps_lock; drm_i915_vbl_swap_t vbl_swaps; unsigned int swaps_pending; + + /* Register state */ + u8 saveLBB; + u32 saveDSPACNTR; + u32 saveDSPBCNTR; + u32 savePIPEACONF; + u32 savePIPEBCONF; + u32 savePIPEASRC; + u32 savePIPEBSRC; + u32 saveFPA0; + u32 saveFPA1; + u32 saveDPLL_A; + u32 saveDPLL_A_MD; + u32 saveHTOTAL_A; + u32 saveHBLANK_A; + u32 saveHSYNC_A; + u32 saveVTOTAL_A; + u32 saveVBLANK_A; + u32 saveVSYNC_A; + u32 saveBCLRPAT_A; + u32 savePIPEASTAT; + u32 saveDSPASTRIDE; + u32 saveDSPASIZE; + u32 saveDSPAPOS; + u32 saveDSPABASE; + u32 saveDSPASURF; + u32 saveDSPATILEOFF; + u32 savePFIT_PGM_RATIOS; + u32 saveBLC_PWM_CTL; + u32 saveBLC_PWM_CTL2; + u32 saveFPB0; + u32 saveFPB1; + u32 saveDPLL_B; + u32 saveDPLL_B_MD; + u32 saveHTOTAL_B; + u32 saveHBLANK_B; + u32 saveHSYNC_B; + u32 saveVTOTAL_B; + u32 saveVBLANK_B; + u32 saveVSYNC_B; + u32 saveBCLRPAT_B; + u32 savePIPEBSTAT; + u32 saveDSPBSTRIDE; + u32 saveDSPBSIZE; + u32 saveDSPBPOS; + u32 saveDSPBBASE; + u32 saveDSPBSURF; + u32 saveDSPBTILEOFF; + u32 saveVCLK_DIVISOR_VGA0; + u32 saveVCLK_DIVISOR_VGA1; + u32 saveVCLK_POST_DIV; + u32 saveVGACNTRL; + u32 saveADPA; + u32 saveLVDS; + u32 saveLVDSPP_ON; + u32 saveLVDSPP_OFF; + u32 saveDVOA; + u32 saveDVOB; + u32 saveDVOC; + u32 savePP_ON; + u32 savePP_OFF; + u32 savePP_CONTROL; + u32 savePP_CYCLE; + u32 savePFIT_CONTROL; + u32 save_palette_a[256]; + u32 save_palette_b[256]; + u32 saveFBC_CFB_BASE; + u32 saveFBC_LL_BASE; + u32 saveFBC_CONTROL; + u32 saveFBC_CONTROL2; + u32 saveIER; + u32 saveIIR; + u32 saveIMR; + u32 saveCACHE_MODE_0; + u32 saveDSPCLK_GATE_D; + u32 saveMI_ARB_STATE; + u32 saveSWF0[16]; + u32 saveSWF1[16]; + u32 saveSWF2[3]; + u8 saveMSR; + u8 saveSR[8]; + u8 saveGR[25]; + u8 saveAR_INDEX; + u8 saveAR[20]; + u8 saveDACMASK; + u8 saveDACDATA[256*3]; /* 256 3-byte colors */ + u8 saveCR[36]; } drm_i915_private_t; extern struct drm_ioctl_desc i915_ioctls[]; @@ -122,6 +209,7 @@ /* i915_dma.c */ extern void i915_kernel_lost_context(struct drm_device * dev); extern int i915_driver_load(struct drm_device *, unsigned long flags); +extern int i915_driver_unload(struct drm_device *); extern void i915_driver_lastclose(struct drm_device * dev); extern void i915_driver_preclose(struct drm_device *dev, struct drm_file *file_priv); @@ -200,7 +288,51 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); -#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) +/* Extended config space */ +#define LBB 0xf4 + +/* VGA stuff */ + +#define VGA_ST01_MDA 0x3ba +#define VGA_ST01_CGA 0x3da + +#define VGA_MSR_WRITE 0x3c2 +#define VGA_MSR_READ 0x3cc +#define VGA_MSR_MEM_EN (1<<1) +#define VGA_MSR_CGA_MODE (1<<0) + +#define VGA_SR_INDEX 0x3c4 +#define VGA_SR_DATA 0x3c5 + +#define VGA_AR_INDEX 0x3c0 +#define VGA_AR_VID_EN (1<<5) +#define VGA_AR_DATA_WRITE 0x3c0 +#define VGA_AR_DATA_READ 0x3c1 + +#define VGA_GR_INDEX 0x3ce +#define VGA_GR_DATA 0x3cf +/* GR05 */ +#define VGA_GR_MEM_READ_MODE_SHIFT 3 +#define VGA_GR_MEM_READ_MODE_PLANE 1 +/* GR06 */ +#define VGA_GR_MEM_MODE_MASK 0xc +#define VGA_GR_MEM_MODE_SHIFT 2 +#define VGA_GR_MEM_A0000_AFFFF 0 +#define VGA_GR_MEM_A0000_BFFFF 1 +#define VGA_GR_MEM_B0000_B7FFF 2 +#define VGA_GR_MEM_B0000_BFFFF 3 + +#define VGA_DACMASK 0x3c6 +#define VGA_DACRX 0x3c7 +#define VGA_DACWX 0x3c8 +#define VGA_DACDATA 0x3c9 + +#define VGA_CR_INDEX_MDA 0x3b4 +#define VGA_CR_DATA_MDA 0x3b5 +#define VGA_CR_INDEX_CGA 0x3d4 +#define VGA_CR_DATA_CGA 0x3d5 + +#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) #define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) #define CMD_REPORT_HEAD (7<<23) #define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1) @@ -215,6 +347,44 @@ #define BB1_UNPROTECTED (0<<0) #define BB2_END_ADDR_MASK (~0x7) +/* Framebuffer compression */ +#define FBC_CFB_BASE 0x03200 /* 4k page aligned */ +#define FBC_LL_BASE 0x03204 /* 4k page aligned */ +#define FBC_CONTROL 0x03208 +#define FBC_CTL_EN (1<<31) +#define FBC_CTL_PERIODIC (1<<30) +#define FBC_CTL_INTERVAL_SHIFT (16) +#define FBC_CTL_UNCOMPRESSIBLE (1<<14) +#define FBC_CTL_STRIDE_SHIFT (5) +#define FBC_CTL_FENCENO (1<<0) +#define FBC_COMMAND 0x0320c +#define FBC_CMD_COMPRESS (1<<0) +#define FBC_STATUS 0x03210 +#define FBC_STAT_COMPRESSING (1<<31) +#define FBC_STAT_COMPRESSED (1<<30) +#define FBC_STAT_MODIFIED (1<<29) +#define FBC_STAT_CURRENT_LINE (1<<0) +#define FBC_CONTROL2 0x03214 +#define FBC_CTL_FENCE_DBL (0<<4) +#define FBC_CTL_IDLE_IMM (0<<2) +#define FBC_CTL_IDLE_FULL (1<<2) +#define FBC_CTL_IDLE_LINE (2<<2) +#define FBC_CTL_IDLE_DEBUG (3<<2) +#define FBC_CTL_CPU_FENCE (1<<1) +#define FBC_CTL_PLANEA (0<<0) +#define FBC_CTL_PLANEB (1<<0) +#define FBC_FENCE_OFF 0x0321b + +#define FBC_LL_SIZE (1536) +#define FBC_LL_PAD (32) + +/* Interrupt bits: + */ +#define USER_INT_FLAG (1<<1) +#define VSYNC_PIPEB_FLAG (1<<5) +#define VSYNC_PIPEA_FLAG (1<<7) +#define HWB_OOM_FLAG (1<<13) /* binner out of memory */ + #define I915REG_HWSTAM 0x02098 #define I915REG_INT_IDENTITY_R 0x020a4 #define I915REG_INT_MASK_R 0x020a8 @@ -252,6 +422,11 @@ #define LP_RING 0x2030 #define HP_RING 0x2040 #define RING_TAIL 0x00 +/* The binner has its own ring buffer: + */ +#define HWB_RING 0x2400 + +#define RING_TAIL 0x00 #define TAIL_ADDR 0x001FFFF8 #define RING_HEAD 0x04 #define HEAD_WRAP_COUNT 0xFFE00000 @@ -269,11 +444,110 @@ #define RING_VALID 0x00000001 #define RING_INVALID 0x00000000 +/* Instruction parser error reg: + */ +#define IPEIR 0x2088 + +/* Scratch pad debug 0 reg: + */ +#define SCPD0 0x209c + +/* Error status reg: + */ +#define ESR 0x20b8 + +/* Secondary DMA fetch address debug reg: + */ +#define DMA_FADD_S 0x20d4 + +/* Memory Interface Arbitration State + */ +#define MI_ARB_STATE 0x20e4 + +/* Cache mode 0 reg. + * - Manipulating render cache behaviour is central + * to the concept of zone rendering, tuning this reg can help avoid + * unnecessary render cache reads and even writes (for z/stencil) + * at beginning and end of scene. + * + * - To change a bit, write to this reg with a mask bit set and the + * bit of interest either set or cleared. EG: (BIT<<16) | BIT to set. + */ +#define Cache_Mode_0 0x2120 +#define CACHE_MODE_0 0x2120 +#define CM0_MASK_SHIFT 16 +#define CM0_IZ_OPT_DISABLE (1<<6) +#define CM0_ZR_OPT_DISABLE (1<<5) +#define CM0_DEPTH_EVICT_DISABLE (1<<4) +#define CM0_COLOR_EVICT_DISABLE (1<<3) +#define CM0_DEPTH_WRITE_DISABLE (1<<1) +#define CM0_RC_OP_FLUSH_DISABLE (1<<0) + + +/* Graphics flush control. A CPU write flushes the GWB of all writes. + * The data is discarded. + */ +#define GFX_FLSH_CNTL 0x2170 + +/* Binner control. Defines the location of the bin pointer list: + */ +#define BINCTL 0x2420 +#define BC_MASK (1 << 9) + +/* Binned scene info. + */ +#define BINSCENE 0x2428 +#define BS_OP_LOAD (1 << 8) +#define BS_MASK (1 << 22) + +/* Bin command parser debug reg: + */ +#define BCPD 0x2480 + +/* Bin memory control debug reg: + */ +#define BMCD 0x2484 + +/* Bin data cache debug reg: + */ +#define BDCD 0x2488 + +/* Binner pointer cache debug reg: + */ +#define BPCD 0x248c + +/* Binner scratch pad debug reg: + */ +#define BINSKPD 0x24f0 + +/* HWB scratch pad debug reg: + */ +#define HWBSKPD 0x24f4 + +/* Binner memory pool reg: + */ +#define BMP_BUFFER 0x2430 +#define BMP_PAGE_SIZE_4K (0 << 10) +#define BMP_BUFFER_SIZE_SHIFT 1 +#define BMP_ENABLE (1 << 0) + +/* Get/put memory from the binner memory pool: + */ +#define BMP_GET 0x2438 +#define BMP_PUT 0x2440 +#define BMP_OFFSET_SHIFT 5 + +/* 3D state packets: + */ +#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24)) + #define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19)) #define SC_UPDATE_SCISSOR (0x1<<1) #define SC_ENABLE_MASK (0x1<<0) #define SC_ENABLE (0x1<<0) +#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16)) + #define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1)) #define SCI_YMIN_MASK (0xffff<<16) #define SCI_XMIN_MASK (0xffff<<0) @@ -290,6 +564,7 @@ #define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2) +#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4) #define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) #define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) #define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) @@ -301,6 +576,7 @@ #define MI_BATCH_NON_SECURE_I965 (1<<8) #define MI_WAIT_FOR_EVENT ((0x3<<23)) +#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) #define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) #define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1) @@ -308,9 +584,542 @@ #define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2) #define ASYNC_FLIP (1<<22) +#define DISPLAY_PLANE_A (0<<20) +#define DISPLAY_PLANE_B (1<<20) + +/* Display regs */ +#define DSPACNTR 0x70180 +#define DSPBCNTR 0x71180 +#define DISPPLANE_SEL_PIPE_MASK (1<<24) + +/* Define the region of interest for the binner: + */ +#define CMD_OP_BIN_CONTROL ((0x3<<29)|(0x1d<<24)|(0x84<<16)|4) #define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1) -#define READ_BREADCRUMB(dev_priv) (((u32 *)(dev_priv->hw_status_page))[5]) +#define CMD_MI_FLUSH (0x04 << 23) +#define MI_NO_WRITE_FLUSH (1 << 2) +#define MI_READ_FLUSH (1 << 0) +#define MI_EXE_FLUSH (1 << 1) +#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */ +#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */ + +#define BREADCRUMB_BITS 31 +#define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1) + +#define READ_BREADCRUMB(dev_priv) (((volatile u32*)(dev_priv->hw_status_page))[5]) +#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg]) + +#define BLC_PWM_CTL 0x61254 +#define BACKLIGHT_MODULATION_FREQ_SHIFT (17) + +#define BLC_PWM_CTL2 0x61250 +/** + * This is the most significant 15 bits of the number of backlight cycles in a + * complete cycle of the modulated backlight control. + * + * The actual value is this field multiplied by two. + */ +#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) +#define BLM_LEGACY_MODE (1 << 16) +/** + * This is the number of cycles out of the backlight modulation cycle for which + * the backlight is on. + * + * This field must be no greater than the number of cycles in the complete + * backlight modulation cycle. + */ +#define BACKLIGHT_DUTY_CYCLE_SHIFT (0) +#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) + +#define I915_GCFGC 0xf0 +#define I915_LOW_FREQUENCY_ENABLE (1 << 7) +#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4) +#define I915_DISPLAY_CLOCK_333_MHZ (4 << 4) +#define I915_DISPLAY_CLOCK_MASK (7 << 4) + +#define I855_HPLLCC 0xc0 +#define I855_CLOCK_CONTROL_MASK (3 << 0) +#define I855_CLOCK_133_200 (0 << 0) +#define I855_CLOCK_100_200 (1 << 0) +#define I855_CLOCK_100_133 (2 << 0) +#define I855_CLOCK_166_250 (3 << 0) + +/* p317, 319 + */ +#define VCLK2_VCO_M 0x6008 /* treat as 16 bit? (includes msbs) */ +#define VCLK2_VCO_N 0x600a +#define VCLK2_VCO_DIV_SEL 0x6012 + +#define VCLK_DIVISOR_VGA0 0x6000 +#define VCLK_DIVISOR_VGA1 0x6004 +#define VCLK_POST_DIV 0x6010 +/** Selects a post divisor of 4 instead of 2. */ +# define VGA1_PD_P2_DIV_4 (1 << 15) +/** Overrides the p2 post divisor field */ +# define VGA1_PD_P1_DIV_2 (1 << 13) +# define VGA1_PD_P1_SHIFT 8 +/** P1 value is 2 greater than this field */ +# define VGA1_PD_P1_MASK (0x1f << 8) +/** Selects a post divisor of 4 instead of 2. */ +# define VGA0_PD_P2_DIV_4 (1 << 7) +/** Overrides the p2 post divisor field */ +# define VGA0_PD_P1_DIV_2 (1 << 5) +# define VGA0_PD_P1_SHIFT 0 +/** P1 value is 2 greater than this field */ +# define VGA0_PD_P1_MASK (0x1f << 0) + +#define DSPCLK_GATE_D 0x6200 + +/* I830 CRTC registers */ +#define HTOTAL_A 0x60000 +#define HBLANK_A 0x60004 +#define HSYNC_A 0x60008 +#define VTOTAL_A 0x6000c +#define VBLANK_A 0x60010 +#define VSYNC_A 0x60014 +#define PIPEASRC 0x6001c +#define BCLRPAT_A 0x60020 +#define VSYNCSHIFT_A 0x60028 + +#define HTOTAL_B 0x61000 +#define HBLANK_B 0x61004 +#define HSYNC_B 0x61008 +#define VTOTAL_B 0x6100c +#define VBLANK_B 0x61010 +#define VSYNC_B 0x61014 +#define PIPEBSRC 0x6101c +#define BCLRPAT_B 0x61020 +#define VSYNCSHIFT_B 0x61028 + +#define PP_STATUS 0x61200 +# define PP_ON (1 << 31) +/** + * Indicates that all dependencies of the panel are on: + * + * - PLL enabled + * - pipe enabled + * - LVDS/DVOB/DVOC on + */ +# define PP_READY (1 << 30) +# define PP_SEQUENCE_NONE (0 << 28) +# define PP_SEQUENCE_ON (1 << 28) +# define PP_SEQUENCE_OFF (2 << 28) +# define PP_SEQUENCE_MASK 0x30000000 +#define PP_CONTROL 0x61204 +# define POWER_TARGET_ON (1 << 0) + +#define LVDSPP_ON 0x61208 +#define LVDSPP_OFF 0x6120c +#define PP_CYCLE 0x61210 + +#define PFIT_CONTROL 0x61230 +# define PFIT_ENABLE (1 << 31) +# define PFIT_PIPE_MASK (3 << 29) +# define PFIT_PIPE_SHIFT 29 +# define VERT_INTERP_DISABLE (0 << 10) +# define VERT_INTERP_BILINEAR (1 << 10) +# define VERT_INTERP_MASK (3 << 10) +# define VERT_AUTO_SCALE (1 << 9) +# define HORIZ_INTERP_DISABLE (0 << 6) +# define HORIZ_INTERP_BILINEAR (1 << 6) +# define HORIZ_INTERP_MASK (3 << 6) +# define HORIZ_AUTO_SCALE (1 << 5) +# define PANEL_8TO6_DITHER_ENABLE (1 << 3) + +#define PFIT_PGM_RATIOS 0x61234 +# define PFIT_VERT_SCALE_MASK 0xfff00000 +# define PFIT_HORIZ_SCALE_MASK 0x0000fff0 + +#define PFIT_AUTO_RATIOS 0x61238 + + +#define DPLL_A 0x06014 +#define DPLL_B 0x06018 +# define DPLL_VCO_ENABLE (1 << 31) +# define DPLL_DVO_HIGH_SPEED (1 << 30) +# define DPLL_SYNCLOCK_ENABLE (1 << 29) +# define DPLL_VGA_MODE_DIS (1 << 28) +# define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */ +# define DPLLB_MODE_LVDS (2 << 26) /* i915 */ +# define DPLL_MODE_MASK (3 << 26) +# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */ +# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */ +# define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */ +# define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ +# define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ +# define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ +/** + * The i830 generation, in DAC/serial mode, defines p1 as two plus this + * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set. + */ +# define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000 +/** + * The i830 generation, in LVDS mode, defines P1 as the bit number set within + * this field (only one bit may be set). + */ +# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000 +# define DPLL_FPA01_P1_POST_DIV_SHIFT 16 +# define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required in DVO non-gang */ +# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */ +# define PLL_REF_INPUT_DREFCLK (0 << 13) +# define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */ +# define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */ +# define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13) +# define PLL_REF_INPUT_MASK (3 << 13) +# define PLL_LOAD_PULSE_PHASE_SHIFT 9 +/* + * Parallel to Serial Load Pulse phase selection. + * Selects the phase for the 10X DPLL clock for the PCIe + * digital display port. The range is 4 to 13; 10 or more + * is just a flip delay. The default is 6 + */ +# define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT) +# define DISPLAY_RATE_SELECT_FPA1 (1 << 8) + +/** + * SDVO multiplier for 945G/GM. Not used on 965. + * + * \sa DPLL_MD_UDI_MULTIPLIER_MASK + */ +# define SDVO_MULTIPLIER_MASK 0x000000ff +# define SDVO_MULTIPLIER_SHIFT_HIRES 4 +# define SDVO_MULTIPLIER_SHIFT_VGA 0 + +/** @defgroup DPLL_MD + * @{ + */ +/** Pipe A SDVO/UDI clock multiplier/divider register for G965. */ +#define DPLL_A_MD 0x0601c +/** Pipe B SDVO/UDI clock multiplier/divider register for G965. */ +#define DPLL_B_MD 0x06020 +/** + * UDI pixel divider, controlling how many pixels are stuffed into a packet. + * + * Value is pixels minus 1. Must be set to 1 pixel for SDVO. + */ +# define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000 +# define DPLL_MD_UDI_DIVIDER_SHIFT 24 +/** UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */ +# define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000 +# define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16 +/** + * SDVO/UDI pixel multiplier. + * + * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus + * clock rate is 10 times the DPLL clock. At low resolution/refresh rate + * modes, the bus rate would be below the limits, so SDVO allows for stuffing + * dummy bytes in the datastream at an increased clock rate, with both sides of + * the link knowing how many bytes are fill. + * + * So, for a mode with a dotclock of 65Mhz, we would want to double the clock + * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be + * set to 130Mhz, and the SDVO multiplier set to 2x in this register and + * through an SDVO command. + * + * This register field has values of multiplication factor minus 1, with + * a maximum multiplier of 5 for SDVO. + */ +# define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00 +# define DPLL_MD_UDI_MULTIPLIER_SHIFT 8 +/** SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK. + * This best be set to the default value (3) or the CRT won't work. No, + * I don't entirely understand what this does... + */ +# define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f +# define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0 +/** @} */ + +#define DPLL_TEST 0x606c +# define DPLLB_TEST_SDVO_DIV_1 (0 << 22) +# define DPLLB_TEST_SDVO_DIV_2 (1 << 22) +# define DPLLB_TEST_SDVO_DIV_4 (2 << 22) +# define DPLLB_TEST_SDVO_DIV_MASK (3 << 22) +# define DPLLB_TEST_N_BYPASS (1 << 19) +# define DPLLB_TEST_M_BYPASS (1 << 18) +# define DPLLB_INPUT_BUFFER_ENABLE (1 << 16) +# define DPLLA_TEST_N_BYPASS (1 << 3) +# define DPLLA_TEST_M_BYPASS (1 << 2) +# define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) + +#define ADPA 0x61100 +#define ADPA_DAC_ENABLE (1<<31) +#define ADPA_DAC_DISABLE 0 +#define ADPA_PIPE_SELECT_MASK (1<<30) +#define ADPA_PIPE_A_SELECT 0 +#define ADPA_PIPE_B_SELECT (1<<30) +#define ADPA_USE_VGA_HVPOLARITY (1<<15) +#define ADPA_SETS_HVPOLARITY 0 +#define ADPA_VSYNC_CNTL_DISABLE (1<<11) +#define ADPA_VSYNC_CNTL_ENABLE 0 +#define ADPA_HSYNC_CNTL_DISABLE (1<<10) +#define ADPA_HSYNC_CNTL_ENABLE 0 +#define ADPA_VSYNC_ACTIVE_HIGH (1<<4) +#define ADPA_VSYNC_ACTIVE_LOW 0 +#define ADPA_HSYNC_ACTIVE_HIGH (1<<3) +#define ADPA_HSYNC_ACTIVE_LOW 0 + +#define FPA0 0x06040 +#define FPA1 0x06044 +#define FPB0 0x06048 +#define FPB1 0x0604c +# define FP_N_DIV_MASK 0x003f0000 +# define FP_N_DIV_SHIFT 16 +# define FP_M1_DIV_MASK 0x00003f00 +# define FP_M1_DIV_SHIFT 8 +# define FP_M2_DIV_MASK 0x0000003f +# define FP_M2_DIV_SHIFT 0 + + +#define PORT_HOTPLUG_EN 0x61110 +# define SDVOB_HOTPLUG_INT_EN (1 << 26) +# define SDVOC_HOTPLUG_INT_EN (1 << 25) +# define TV_HOTPLUG_INT_EN (1 << 18) +# define CRT_HOTPLUG_INT_EN (1 << 9) +# define CRT_HOTPLUG_FORCE_DETECT (1 << 3) + +#define PORT_HOTPLUG_STAT 0x61114 +# define CRT_HOTPLUG_INT_STATUS (1 << 11) +# define TV_HOTPLUG_INT_STATUS (1 << 10) +# define CRT_HOTPLUG_MONITOR_MASK (3 << 8) +# define CRT_HOTPLUG_MONITOR_COLOR (3 << 8) +# define CRT_HOTPLUG_MONITOR_MONO (2 << 8) +# define CRT_HOTPLUG_MONITOR_NONE (0 << 8) +# define SDVOC_HOTPLUG_INT_STATUS (1 << 7) +# define SDVOB_HOTPLUG_INT_STATUS (1 << 6) + +#define SDVOB 0x61140 +#define SDVOC 0x61160 +#define SDVO_ENABLE (1 << 31) +#define SDVO_PIPE_B_SELECT (1 << 30) +#define SDVO_STALL_SELECT (1 << 29) +#define SDVO_INTERRUPT_ENABLE (1 << 26) +/** + * 915G/GM SDVO pixel multiplier. + * + * Programmed value is multiplier - 1, up to 5x. + * + * \sa DPLL_MD_UDI_MULTIPLIER_MASK + */ +#define SDVO_PORT_MULTIPLY_MASK (7 << 23) +#define SDVO_PORT_MULTIPLY_SHIFT 23 +#define SDVO_PHASE_SELECT_MASK (15 << 19) +#define SDVO_PHASE_SELECT_DEFAULT (6 << 19) +#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18) +#define SDVOC_GANG_MODE (1 << 16) +#define SDVO_BORDER_ENABLE (1 << 7) +#define SDVOB_PCIE_CONCURRENCY (1 << 3) +#define SDVO_DETECTED (1 << 2) +/* Bits to be preserved when writing */ +#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14)) +#define SDVOC_PRESERVE_MASK (1 << 17) + +/** @defgroup LVDS + * @{ + */ +/** + * This register controls the LVDS output enable, pipe selection, and data + * format selection. + * + * All of the clock/data pairs are force powered down by power sequencing. + */ +#define LVDS 0x61180 +/** + * Enables the LVDS port. This bit must be set before DPLLs are enabled, as + * the DPLL semantics change when the LVDS is assigned to that pipe. + */ +# define LVDS_PORT_EN (1 << 31) +/** Selects pipe B for LVDS data. Must be set on pre-965. */ +# define LVDS_PIPEB_SELECT (1 << 30) + +/** + * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per + * pixel. + */ +# define LVDS_A0A2_CLKA_POWER_MASK (3 << 8) +# define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8) +# define LVDS_A0A2_CLKA_POWER_UP (3 << 8) +/** + * Controls the A3 data pair, which contains the additional LSBs for 24 bit + * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be + * on. + */ +# define LVDS_A3_POWER_MASK (3 << 6) +# define LVDS_A3_POWER_DOWN (0 << 6) +# define LVDS_A3_POWER_UP (3 << 6) +/** + * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP + * is set. + */ +# define LVDS_CLKB_POWER_MASK (3 << 4) +# define LVDS_CLKB_POWER_DOWN (0 << 4) +# define LVDS_CLKB_POWER_UP (3 << 4) + +/** + * Controls the B0-B3 data pairs. This must be set to match the DPLL p2 + * setting for whether we are in dual-channel mode. The B3 pair will + * additionally only be powered up when LVDS_A3_POWER_UP is set. + */ +# define LVDS_B0B3_POWER_MASK (3 << 2) +# define LVDS_B0B3_POWER_DOWN (0 << 2) +# define LVDS_B0B3_POWER_UP (3 << 2) + +#define PIPEACONF 0x70008 +#define PIPEACONF_ENABLE (1<<31) +#define PIPEACONF_DISABLE 0 +#define PIPEACONF_DOUBLE_WIDE (1<<30) +#define I965_PIPECONF_ACTIVE (1<<30) +#define PIPEACONF_SINGLE_WIDE 0 +#define PIPEACONF_PIPE_UNLOCKED 0 +#define PIPEACONF_PIPE_LOCKED (1<<25) +#define PIPEACONF_PALETTE 0 +#define PIPEACONF_GAMMA (1<<24) +#define PIPECONF_FORCE_BORDER (1<<25) +#define PIPECONF_PROGRESSIVE (0 << 21) +#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) +#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) + +#define PIPEBCONF 0x71008 +#define PIPEBCONF_ENABLE (1<<31) +#define PIPEBCONF_DISABLE 0 +#define PIPEBCONF_DOUBLE_WIDE (1<<30) +#define PIPEBCONF_DISABLE 0 +#define PIPEBCONF_GAMMA (1<<24) +#define PIPEBCONF_PALETTE 0 + +#define PIPEBGCMAXRED 0x71010 +#define PIPEBGCMAXGREEN 0x71014 +#define PIPEBGCMAXBLUE 0x71018 +#define PIPEBSTAT 0x71024 +#define PIPEBFRAMEHIGH 0x71040 +#define PIPEBFRAMEPIXEL 0x71044 + +#define DSPACNTR 0x70180 +#define DSPBCNTR 0x71180 +#define DISPLAY_PLANE_ENABLE (1<<31) +#define DISPLAY_PLANE_DISABLE 0 +#define DISPPLANE_GAMMA_ENABLE (1<<30) +#define DISPPLANE_GAMMA_DISABLE 0 +#define DISPPLANE_PIXFORMAT_MASK (0xf<<26) +#define DISPPLANE_8BPP (0x2<<26) +#define DISPPLANE_15_16BPP (0x4<<26) +#define DISPPLANE_16BPP (0x5<<26) +#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26) +#define DISPPLANE_32BPP (0x7<<26) +#define DISPPLANE_STEREO_ENABLE (1<<25) +#define DISPPLANE_STEREO_DISABLE 0 +#define DISPPLANE_SEL_PIPE_MASK (1<<24) +#define DISPPLANE_SEL_PIPE_A 0 +#define DISPPLANE_SEL_PIPE_B (1<<24) +#define DISPPLANE_SRC_KEY_ENABLE (1<<22) +#define DISPPLANE_SRC_KEY_DISABLE 0 +#define DISPPLANE_LINE_DOUBLE (1<<20) +#define DISPPLANE_NO_LINE_DOUBLE 0 +#define DISPPLANE_STEREO_POLARITY_FIRST 0 +#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) +/* plane B only */ +#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15) +#define DISPPLANE_ALPHA_TRANS_DISABLE 0 +#define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0 +#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1) + +#define DSPABASE 0x70184 +#define DSPASTRIDE 0x70188 + +#define DSPBBASE 0x71184 +#define DSPBADDR DSPBBASE +#define DSPBSTRIDE 0x71188 + +#define DSPAKEYVAL 0x70194 +#define DSPAKEYMASK 0x70198 + +#define DSPAPOS 0x7018C /* reserved */ +#define DSPASIZE 0x70190 +#define DSPBPOS 0x7118C +#define DSPBSIZE 0x71190 + +#define DSPASURF 0x7019C +#define DSPATILEOFF 0x701A4 + +#define DSPBSURF 0x7119C +#define DSPBTILEOFF 0x711A4 + +#define VGACNTRL 0x71400 +# define VGA_DISP_DISABLE (1 << 31) +# define VGA_2X_MODE (1 << 30) +# define VGA_PIPE_B_SELECT (1 << 29) + +/* + * Some BIOS scratch area registers. The 845 (and 830?) store the amount + * of video memory available to the BIOS in SWF1. + */ + +#define SWF0 0x71410 + +/* + * 855 scratch registers. + */ +#define SWF10 0x70410 + +#define SWF30 0x72414 + +/* + * Overlay registers. These are overlay registers accessed via MMIO. + * Those loaded via the overlay register page are defined in i830_video.c. + */ +#define OVADD 0x30000 + +#define DOVSTA 0x30008 +#define OC_BUF (0x3<<20) + +#define OGAMC5 0x30010 +#define OGAMC4 0x30014 +#define OGAMC3 0x30018 +#define OGAMC2 0x3001c +#define OGAMC1 0x30020 +#define OGAMC0 0x30024 +/* + * Palette registers + */ +#define PALETTE_A 0x0a000 +#define PALETTE_B 0x0a800 + +#define IS_I830(dev) ((dev)->pci_device == 0x3577) +#define IS_845G(dev) ((dev)->pci_device == 0x2562) +#define IS_I85X(dev) ((dev)->pci_device == 0x3582) +#define IS_I855(dev) ((dev)->pci_device == 0x3582) +#define IS_I865G(dev) ((dev)->pci_device == 0x2572) + +#define IS_I915G(dev) ((dev)->pci_device == 0x2582 || (dev)->pci_device == 0x258a) +#define IS_I915GM(dev) ((dev)->pci_device == 0x2592) +#define IS_I945G(dev) ((dev)->pci_device == 0x2772) +#define IS_I945GM(dev) ((dev)->pci_device == 0x27A2 ||\ + (dev)->pci_device == 0x27AE) +#define IS_I965G(dev) ((dev)->pci_device == 0x2972 || \ + (dev)->pci_device == 0x2982 || \ + (dev)->pci_device == 0x2992 || \ + (dev)->pci_device == 0x29A2 || \ + (dev)->pci_device == 0x2A02 || \ + (dev)->pci_device == 0x2A12 || \ + (dev)->pci_device == 0x2A42) + +#define IS_I965GM(dev) ((dev)->pci_device == 0x2A02) + +#define IS_IGD_GM(dev) ((dev)->pci_device == 0x2A42) + +#define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \ + (dev)->pci_device == 0x29B2 || \ + (dev)->pci_device == 0x29D2) + +#define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \ + IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev)) + +#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ + IS_I945GM(dev) || IS_I965GM(dev) || IS_IGD_GM(dev)) + +#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_IGD_GM(dev)) + +#define PRIMARY_RINGBUFFER_SIZE (128*1024) #endif --- linux-2.6.24.orig/drivers/char/drm/drm_sysfs.c +++ linux-2.6.24/drivers/char/drm/drm_sysfs.c @@ -19,6 +19,43 @@ #include "drm_core.h" #include "drmP.h" +#define to_drm_device(d) container_of(d, struct drm_device, dev) + +/** + * drm_sysfs_suspend - DRM class suspend hook + * @dev: Linux device to suspend + * @state: power state to enter + * + * Just figures out what the actual struct drm_device associated with + * @dev is and calls its suspend hook, if present. + */ +static int drm_sysfs_suspend(struct device *dev, pm_message_t state) +{ + struct drm_device *drm_dev = to_drm_device(dev); + + if (drm_dev->driver->suspend) + return drm_dev->driver->suspend(drm_dev, state); + + return 0; +} + +/** + * drm_sysfs_resume - DRM class resume hook + * @dev: Linux device to resume + * + * Just figures out what the actual struct drm_device associated with + * @dev is and calls its resume hook, if present. + */ +static int drm_sysfs_resume(struct device *dev) +{ + struct drm_device *drm_dev = to_drm_device(dev); + + if (drm_dev->driver->resume) + return drm_dev->driver->resume(drm_dev); + + return 0; +} + /* Display the version of drm_core. This doesn't work right in current design */ static ssize_t version_show(struct class *dev, char *buf) { @@ -33,7 +70,7 @@ * @owner: pointer to the module that is to "own" this struct drm_sysfs_class * @name: pointer to a string for the name of this class. * - * This is used to create a struct drm_sysfs_class pointer that can then be used + * This is used to create DRM class pointer that can then be used * in calls to drm_sysfs_device_add(). * * Note, the pointer created here is to be destroyed when finished by making a @@ -50,6 +87,9 @@ goto err_out; } + class->suspend = drm_sysfs_suspend; + class->resume = drm_sysfs_resume; + err = class_create_file(class, &class_attr_version); if (err) goto err_out_class; @@ -63,94 +103,105 @@ } /** - * drm_sysfs_destroy - destroys a struct drm_sysfs_class structure - * @cs: pointer to the struct drm_sysfs_class that is to be destroyed + * drm_sysfs_destroy - destroys DRM class * - * Note, the pointer to be destroyed must have been created with a call to - * drm_sysfs_create(). + * Destroy the DRM device class. */ -void drm_sysfs_destroy(struct class *class) +void drm_sysfs_destroy(void) { - if ((class == NULL) || (IS_ERR(class))) + if ((drm_class == NULL) || (IS_ERR(drm_class))) return; - - class_remove_file(class, &class_attr_version); - class_destroy(class); + class_remove_file(drm_class, &class_attr_version); + class_destroy(drm_class); } -static ssize_t show_dri(struct class_device *class_device, char *buf) +static ssize_t show_dri(struct device *device, struct device_attribute *attr, + char *buf) { - struct drm_device * dev = ((struct drm_head *)class_get_devdata(class_device))->dev; + struct drm_device *dev = to_drm_device(device); if (dev->driver->dri_library_name) return dev->driver->dri_library_name(dev, buf); return snprintf(buf, PAGE_SIZE, "%s\n", dev->driver->pci_driver.name); } -static struct class_device_attribute class_device_attrs[] = { +static struct device_attribute device_attrs[] = { __ATTR(dri_library_name, S_IRUGO, show_dri, NULL), }; /** + * drm_sysfs_device_release - do nothing + * @dev: Linux device + * + * Normally, this would free the DRM device associated with @dev, along + * with cleaning up any other stuff. But we do that in the DRM core, so + * this function can just return and hope that the core does its job. + */ +static void drm_sysfs_device_release(struct device *dev) +{ + return; +} + +/** * drm_sysfs_device_add - adds a class device to sysfs for a character driver - * @cs: pointer to the struct class that this device should be registered to. - * @dev: the dev_t for the device to be added. - * @device: a pointer to a struct device that is assiociated with this class device. - * @fmt: string for the class device's name - * - * A struct class_device will be created in sysfs, registered to the specified - * class. A "dev" file will be created, showing the dev_t for the device. The - * pointer to the struct class_device will be returned from the call. Any further - * sysfs files that might be required can be created using this pointer. - * Note: the struct class passed to this function must have previously been - * created with a call to drm_sysfs_create(). - */ -struct class_device *drm_sysfs_device_add(struct class *cs, struct drm_head *head) -{ - struct class_device *class_dev; - int i, j, err; - - class_dev = class_device_create(cs, NULL, - MKDEV(DRM_MAJOR, head->minor), - &(head->dev->pdev)->dev, - "card%d", head->minor); - if (IS_ERR(class_dev)) { - err = PTR_ERR(class_dev); + * @dev: DRM device to be added + * @head: DRM head in question + * + * Add a DRM device to the DRM's device model class. We use @dev's PCI device + * as the parent for the Linux device, and make sure it has a file containing + * the driver we're using (for userspace compatibility). + */ +int drm_sysfs_device_add(struct drm_device *dev, struct drm_head *head) +{ + int err; + int i, j; + + dev->dev.parent = &dev->pdev->dev; + dev->dev.class = drm_class; + dev->dev.release = drm_sysfs_device_release; + /* + * This will actually add the major:minor file so that udev + * will create the device node. We don't want to do that just + * yet... + */ + /* dev->dev.devt = head->device; */ + snprintf(dev->dev.bus_id, BUS_ID_SIZE, "card%d", head->minor); + + err = device_register(&dev->dev); + if (err) { + DRM_ERROR("device add failed: %d\n", err); goto err_out; } - class_set_devdata(class_dev, head); - - for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) { - err = class_device_create_file(class_dev, - &class_device_attrs[i]); + for (i = 0; i < ARRAY_SIZE(device_attrs); i++) { + err = device_create_file(&dev->dev, &device_attrs[i]); if (err) goto err_out_files; } - return class_dev; + return 0; err_out_files: if (i > 0) for (j = 0; j < i; j++) - class_device_remove_file(class_dev, - &class_device_attrs[i]); - class_device_unregister(class_dev); + device_remove_file(&dev->dev, &device_attrs[i]); + device_unregister(&dev->dev); err_out: - return ERR_PTR(err); + + return err; } /** - * drm_sysfs_device_remove - removes a class device that was created with drm_sysfs_device_add() - * @dev: the dev_t of the device that was previously registered. + * drm_sysfs_device_remove - remove DRM device + * @dev: DRM device to remove * * This call unregisters and cleans up a class device that was created with a * call to drm_sysfs_device_add() */ -void drm_sysfs_device_remove(struct class_device *class_dev) +void drm_sysfs_device_remove(struct drm_device *dev) { int i; - for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) - class_device_remove_file(class_dev, &class_device_attrs[i]); - class_device_unregister(class_dev); + for (i = 0; i < ARRAY_SIZE(device_attrs); i++) + device_remove_file(&dev->dev, &device_attrs[i]); + device_unregister(&dev->dev); } --- linux-2.6.24.orig/drivers/char/drm/i915_drv.c +++ linux-2.6.24/drivers/char/drm/i915_drv.c @@ -38,6 +38,494 @@ i915_PCI_IDS }; +enum pipe { + PIPE_A = 0, + PIPE_B, +}; + +static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (pipe == PIPE_A) + return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE); + else + return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE); +} + +static void i915_save_palette(struct drm_device *dev, enum pipe pipe) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B); + u32 *array; + int i; + + if (!i915_pipe_enabled(dev, pipe)) + return; + + if (pipe == PIPE_A) + array = dev_priv->save_palette_a; + else + array = dev_priv->save_palette_b; + + for(i = 0; i < 256; i++) + array[i] = I915_READ(reg + (i << 2)); +} + +static void i915_restore_palette(struct drm_device *dev, enum pipe pipe) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B); + u32 *array; + int i; + + if (!i915_pipe_enabled(dev, pipe)) + return; + + if (pipe == PIPE_A) + array = dev_priv->save_palette_a; + else + array = dev_priv->save_palette_b; + + for(i = 0; i < 256; i++) + I915_WRITE(reg + (i << 2), array[i]); +} + +static u8 i915_read_indexed(u16 index_port, u16 data_port, u8 reg) +{ + outb(reg, index_port); + return inb(data_port); +} + +static u8 i915_read_ar(u16 st01, u8 reg, u16 palette_enable) +{ + inb(st01); + outb(palette_enable | reg, VGA_AR_INDEX); + return inb(VGA_AR_DATA_READ); +} + +static void i915_write_ar(u8 st01, u8 reg, u8 val, u16 palette_enable) +{ + inb(st01); + outb(palette_enable | reg, VGA_AR_INDEX); + outb(val, VGA_AR_DATA_WRITE); +} + +static void i915_write_indexed(u16 index_port, u16 data_port, u8 reg, u8 val) +{ + outb(reg, index_port); + outb(val, data_port); +} + +static void i915_save_vga(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int i; + u16 cr_index, cr_data, st01; + + /* VGA color palette registers */ + dev_priv->saveDACMASK = inb(VGA_DACMASK); + /* DACCRX automatically increments during read */ + outb(0, VGA_DACRX); + /* Read 3 bytes of color data from each index */ + for (i = 0; i < 256 * 3; i++) + dev_priv->saveDACDATA[i] = inb(VGA_DACDATA); + + /* MSR bits */ + dev_priv->saveMSR = inb(VGA_MSR_READ); + if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) { + cr_index = VGA_CR_INDEX_CGA; + cr_data = VGA_CR_DATA_CGA; + st01 = VGA_ST01_CGA; + } else { + cr_index = VGA_CR_INDEX_MDA; + cr_data = VGA_CR_DATA_MDA; + st01 = VGA_ST01_MDA; + } + + /* CRT controller regs */ + i915_write_indexed(cr_index, cr_data, 0x11, + i915_read_indexed(cr_index, cr_data, 0x11) & + (~0x80)); + for (i = 0; i < 0x24; i++) + dev_priv->saveCR[i] = + i915_read_indexed(cr_index, cr_data, i); + /* Make sure we don't turn off CR group 0 writes */ + dev_priv->saveCR[0x11] &= ~0x80; + + /* Attribute controller registers */ + inb(st01); + dev_priv->saveAR_INDEX = inb(VGA_AR_INDEX); + for (i = 0; i < 20; i++) + dev_priv->saveAR[i] = i915_read_ar(st01, i, 0); + inb(st01); + outb(dev_priv->saveAR_INDEX, VGA_AR_INDEX); + inb(st01); + + /* Graphics controller registers */ + for (i = 0; i < 9; i++) + dev_priv->saveGR[i] = + i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, i); + + dev_priv->saveGR[0x10] = + i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x10); + dev_priv->saveGR[0x11] = + i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x11); + dev_priv->saveGR[0x18] = + i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x18); + + /* Sequencer registers */ + for (i = 0; i < 8; i++) + dev_priv->saveSR[i] = + i915_read_indexed(VGA_SR_INDEX, VGA_SR_DATA, i); +} + +static void i915_restore_vga(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int i; + u16 cr_index, cr_data, st01; + + /* MSR bits */ + outb(dev_priv->saveMSR, VGA_MSR_WRITE); + if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) { + cr_index = VGA_CR_INDEX_CGA; + cr_data = VGA_CR_DATA_CGA; + st01 = VGA_ST01_CGA; + } else { + cr_index = VGA_CR_INDEX_MDA; + cr_data = VGA_CR_DATA_MDA; + st01 = VGA_ST01_MDA; + } + + /* Sequencer registers, don't write SR07 */ + for (i = 0; i < 7; i++) + i915_write_indexed(VGA_SR_INDEX, VGA_SR_DATA, i, + dev_priv->saveSR[i]); + + /* CRT controller regs */ + /* Enable CR group 0 writes */ + i915_write_indexed(cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]); + for (i = 0; i < 0x24; i++) + i915_write_indexed(cr_index, cr_data, i, dev_priv->saveCR[i]); + + /* Graphics controller regs */ + for (i = 0; i < 9; i++) + i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, i, + dev_priv->saveGR[i]); + + i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x10, + dev_priv->saveGR[0x10]); + i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x11, + dev_priv->saveGR[0x11]); + i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x18, + dev_priv->saveGR[0x18]); + + /* Attribute controller registers */ + for (i = 0; i < 20; i++) + i915_write_ar(st01, i, dev_priv->saveAR[i], 0); + inb(st01); /* switch back to index mode */ + outb(dev_priv->saveAR_INDEX | 0x20, VGA_AR_INDEX); + inb(st01); + + /* VGA color palette registers */ + outb(dev_priv->saveDACMASK, VGA_DACMASK); + /* DACCRX automatically increments during read */ + outb(0, VGA_DACWX); + /* Read 3 bytes of color data from each index */ + for (i = 0; i < 256 * 3; i++) + outb(dev_priv->saveDACDATA[i], VGA_DACDATA); + +} + +static int i915_suspend(struct drm_device *dev, pm_message_t state) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int i; + + if (!dev || !dev_priv) { + printk(KERN_ERR "dev: %p, dev_priv: %p\n", dev, dev_priv); + printk(KERN_ERR "DRM not initialized, aborting suspend.\n"); + return -ENODEV; + } + + if (state.event == PM_EVENT_PRETHAW) + return 0; + + pci_save_state(dev->pdev); + pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); + + /* Pipe & plane A info */ + dev_priv->savePIPEACONF = I915_READ(PIPEACONF); + dev_priv->savePIPEASRC = I915_READ(PIPEASRC); + dev_priv->saveFPA0 = I915_READ(FPA0); + dev_priv->saveFPA1 = I915_READ(FPA1); + dev_priv->saveDPLL_A = I915_READ(DPLL_A); + if (IS_I965G(dev)) + dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD); + dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A); + dev_priv->saveHBLANK_A = I915_READ(HBLANK_A); + dev_priv->saveHSYNC_A = I915_READ(HSYNC_A); + dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A); + dev_priv->saveVBLANK_A = I915_READ(VBLANK_A); + dev_priv->saveVSYNC_A = I915_READ(VSYNC_A); + dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); + + dev_priv->saveDSPACNTR = I915_READ(DSPACNTR); + dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE); + dev_priv->saveDSPASIZE = I915_READ(DSPASIZE); + dev_priv->saveDSPAPOS = I915_READ(DSPAPOS); + dev_priv->saveDSPABASE = I915_READ(DSPABASE); + if (IS_I965G(dev)) { + dev_priv->saveDSPASURF = I915_READ(DSPASURF); + dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF); + } + i915_save_palette(dev, PIPE_A); + dev_priv->savePIPEASTAT = I915_READ(I915REG_PIPEASTAT); + + /* Pipe & plane B info */ + dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); + dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC); + dev_priv->saveFPB0 = I915_READ(FPB0); + dev_priv->saveFPB1 = I915_READ(FPB1); + dev_priv->saveDPLL_B = I915_READ(DPLL_B); + if (IS_I965G(dev)) + dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD); + dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B); + dev_priv->saveHBLANK_B = I915_READ(HBLANK_B); + dev_priv->saveHSYNC_B = I915_READ(HSYNC_B); + dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B); + dev_priv->saveVBLANK_B = I915_READ(VBLANK_B); + dev_priv->saveVSYNC_B = I915_READ(VSYNC_B); + dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); + + dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR); + dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE); + dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE); + dev_priv->saveDSPBPOS = I915_READ(DSPBPOS); + dev_priv->saveDSPBBASE = I915_READ(DSPBBASE); + if (IS_I965GM(dev) || IS_IGD_GM(dev)) { + dev_priv->saveDSPBSURF = I915_READ(DSPBSURF); + dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF); + } + i915_save_palette(dev, PIPE_B); + dev_priv->savePIPEBSTAT = I915_READ(I915REG_PIPEBSTAT); + + /* CRT state */ + dev_priv->saveADPA = I915_READ(ADPA); + + /* LVDS state */ + dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL); + dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS); + dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); + if (IS_I965G(dev)) + dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2); + if (IS_MOBILE(dev) && !IS_I830(dev)) + dev_priv->saveLVDS = I915_READ(LVDS); + if (!IS_I830(dev) && !IS_845G(dev)) + dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL); + dev_priv->saveLVDSPP_ON = I915_READ(LVDSPP_ON); + dev_priv->saveLVDSPP_OFF = I915_READ(LVDSPP_OFF); + dev_priv->savePP_CYCLE = I915_READ(PP_CYCLE); + + /* FIXME: save TV & SDVO state */ + + /* FBC state */ + dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE); + dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE); + dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2); + dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL); + + /* Interrupt state */ + dev_priv->saveIIR = I915_READ(I915REG_INT_IDENTITY_R); + dev_priv->saveIER = I915_READ(I915REG_INT_ENABLE_R); + dev_priv->saveIMR = I915_READ(I915REG_INT_MASK_R); + + /* VGA state */ + dev_priv->saveVCLK_DIVISOR_VGA0 = I915_READ(VCLK_DIVISOR_VGA0); + dev_priv->saveVCLK_DIVISOR_VGA1 = I915_READ(VCLK_DIVISOR_VGA1); + dev_priv->saveVCLK_POST_DIV = I915_READ(VCLK_POST_DIV); + dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); + + /* Clock gating state */ + dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D); + + /* Cache mode state */ + dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); + + /* Memory Arbitration state */ + dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE); + + /* Scratch space */ + for (i = 0; i < 16; i++) { + dev_priv->saveSWF0[i] = I915_READ(SWF0 + (i << 2)); + dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2)); + } + for (i = 0; i < 3; i++) + dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); + + i915_save_vga(dev); + + if (state.event == PM_EVENT_SUSPEND) { + /* Shut down the device */ + pci_disable_device(dev->pdev); + pci_set_power_state(dev->pdev, PCI_D3hot); + } + + return 0; +} + +static int i915_resume(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int i; + + pci_set_power_state(dev->pdev, PCI_D0); + pci_restore_state(dev->pdev); + if (pci_enable_device(dev->pdev)) + return -1; + + pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); + + /* Pipe & plane A info */ + /* Prime the clock */ + if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { + I915_WRITE(DPLL_A, dev_priv->saveDPLL_A & + ~DPLL_VCO_ENABLE); + udelay(150); + } + I915_WRITE(FPA0, dev_priv->saveFPA0); + I915_WRITE(FPA1, dev_priv->saveFPA1); + /* Actually enable it */ + I915_WRITE(DPLL_A, dev_priv->saveDPLL_A); + udelay(150); + if (IS_I965G(dev)) + I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); + udelay(150); + + /* Restore mode */ + I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); + I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A); + I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A); + I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); + I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); + I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); + I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); + + /* Restore plane info */ + I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE); + I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS); + I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC); + I915_WRITE(DSPABASE, dev_priv->saveDSPABASE); + I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE); + if (IS_I965G(dev)) { + I915_WRITE(DSPASURF, dev_priv->saveDSPASURF); + I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); + } + + I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); + + i915_restore_palette(dev, PIPE_A); + /* Enable the plane */ + I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR); + I915_WRITE(DSPABASE, I915_READ(DSPABASE)); + + /* Pipe & plane B info */ + if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { + I915_WRITE(DPLL_B, dev_priv->saveDPLL_B & + ~DPLL_VCO_ENABLE); + udelay(150); + } + I915_WRITE(FPB0, dev_priv->saveFPB0); + I915_WRITE(FPB1, dev_priv->saveFPB1); + /* Actually enable it */ + I915_WRITE(DPLL_B, dev_priv->saveDPLL_B); + udelay(150); + if (IS_I965G(dev)) + I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); + udelay(150); + + /* Restore mode */ + I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); + I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B); + I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B); + I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); + I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); + I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); + I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); + + /* Restore plane info */ + I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE); + I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS); + I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC); + I915_WRITE(DSPBBASE, dev_priv->saveDSPBBASE); + I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE); + if (IS_I965G(dev)) { + I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF); + I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); + } + + I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); + + i915_restore_palette(dev, PIPE_B); + /* Enable the plane */ + I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); + I915_WRITE(DSPBBASE, I915_READ(DSPBBASE)); + + /* CRT state */ + I915_WRITE(ADPA, dev_priv->saveADPA); + + /* LVDS state */ + if (IS_I965G(dev)) + I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); + if (IS_MOBILE(dev) && !IS_I830(dev)) + I915_WRITE(LVDS, dev_priv->saveLVDS); + if (!IS_I830(dev) && !IS_845G(dev)) + I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); + + I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS); + I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL); + I915_WRITE(LVDSPP_ON, dev_priv->saveLVDSPP_ON); + I915_WRITE(LVDSPP_OFF, dev_priv->saveLVDSPP_OFF); + I915_WRITE(PP_CYCLE, dev_priv->savePP_CYCLE); + I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); + + /* FIXME: restore TV & SDVO state */ + + /* FBC info */ + I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE); + I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE); + I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2); + I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL); + + /* VGA state */ + I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); + I915_WRITE(VCLK_DIVISOR_VGA0, dev_priv->saveVCLK_DIVISOR_VGA0); + I915_WRITE(VCLK_DIVISOR_VGA1, dev_priv->saveVCLK_DIVISOR_VGA1); + I915_WRITE(VCLK_POST_DIV, dev_priv->saveVCLK_POST_DIV); + udelay(150); + + /* Clock gating state */ + I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D); + + /* Cache mode state */ + I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); + + /* Memory arbitration state */ + I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000); + + for (i = 0; i < 16; i++) { + I915_WRITE(SWF0 + (i << 2), dev_priv->saveSWF0[i]); + I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]); + } + for (i = 0; i < 3; i++) + I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); + + i915_restore_vga(dev); + + return 0; +} + static struct drm_driver driver = { /* don't use mtrr's here, the Xserver or user space app should * deal with them for intel hardware. @@ -47,8 +535,11 @@ DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL | DRIVER_IRQ_VBL2, .load = i915_driver_load, + .unload = i915_driver_unload, .lastclose = i915_driver_lastclose, .preclose = i915_driver_preclose, + .suspend = i915_suspend, + .resume = i915_resume, .device_is_agp = i915_driver_device_is_agp, .vblank_wait = i915_driver_vblank_wait, .vblank_wait2 = i915_driver_vblank_wait2, --- linux-2.6.24.orig/drivers/char/drm/via_chrome9_mm.h +++ linux-2.6.24/drivers/char/drm/via_chrome9_mm.h @@ -0,0 +1,67 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, subject to the + * following conditions: + * + * The above copyright notice and this permission notice + * (including the next paragraph) shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL VIA, S3 GRAPHICS, AND/OR + * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef _VIA_CHROME9_MM_H_ +#define _VIA_CHROME9_MM_H_ +struct drm_via_chrome9_pciemem_ctrl { + enum { + pciemem_copy_from_user = 0, + pciemem_copy_to_user, + pciemem_memset, + } ctrl_type; + unsigned int pcieoffset; + unsigned int size;/*in Byte*/ + unsigned char memsetdata;/*for memset*/ + void *usermode_data;/*user mode data pointer*/ +}; + +extern int via_chrome9_map_init(struct drm_device *dev, + struct drm_via_chrome9_init *init); +extern int via_chrome9_heap_management_init(struct drm_device + *dev, struct drm_via_chrome9_init *init); +extern void via_chrome9_memory_destroy_heap(struct drm_device + *dev, struct drm_via_chrome9_private *dev_priv); +extern int via_chrome9_ioctl_check_vidmem_size(struct drm_device + *dev, void *data, struct drm_file *file_priv); +extern int via_chrome9_ioctl_pciemem_ctrl(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int via_chrome9_ioctl_allocate_aperture(struct drm_device + *dev, void *data, struct drm_file *file_priv); +extern int via_chrome9_ioctl_free_aperture(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int via_chrome9_ioctl_allocate_mem_base(struct drm_device + *dev, void *data, struct drm_file *file_priv); +extern int via_chrome9_ioctl_allocate_mem_wrapper( + struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int via_chrome9_ioctl_freemem_base(struct drm_device + *dev, void *data, struct drm_file *file_priv); +extern int via_chrome9_ioctl_free_mem_wrapper(struct drm_device + *dev, void *data, struct drm_file *file_priv); +extern void via_chrome9_reclaim_buffers_locked(struct drm_device + *dev, struct drm_file *file_priv); + +#endif + --- linux-2.6.24.orig/drivers/char/agp/via-agp.c +++ linux-2.6.24/drivers/char/agp/via-agp.c @@ -548,6 +548,7 @@ ID(PCI_DEVICE_ID_VIA_VT3324), ID(PCI_DEVICE_ID_VIA_VT3336), ID(PCI_DEVICE_ID_VIA_P4M890), + ID(PCI_DEVICE_ID_VIA_VT3364), { } }; --- linux-2.6.24.orig/drivers/char/agp/ati-agp.c +++ linux-2.6.24/drivers/char/agp/ati-agp.c @@ -468,6 +468,10 @@ .chipset_name = "IGP9100/M", }, { + .device_id = PCI_DEVICE_ID_ATI_RS350_133, + .chipset_name = "IGP9000/M", + }, + { .device_id = PCI_DEVICE_ID_ATI_RS350_200, .chipset_name = "IGP9100/M", }, --- linux-2.6.24.orig/drivers/acpi/osl.c +++ linux-2.6.24/drivers/acpi/osl.c @@ -312,6 +312,67 @@ return AE_OK; } +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD +struct acpi_table_header * acpi_find_dsdt_initrd(void) +{ + struct file *firmware_file; + mm_segment_t oldfs; + unsigned long len, len2; + struct acpi_table_header *dsdt_buffer, *ret = NULL; + struct kstat stat; + /* maybe this could be an argument on the cmd line, but let's keep it simple for now */ + char *ramfs_dsdt_name = "/DSDT.aml"; + + printk(KERN_INFO PREFIX "Looking for DSDT in initramfs... "); + + /* + * Never do this at home, only the user-space is allowed to open a file. + * The clean way would be to use the firmware loader. But this code must be run + * before there is any userspace available. So we need a static/init firmware + * infrastructure, which doesn't exist yet... + */ + if (vfs_stat(ramfs_dsdt_name, &stat) < 0) { + printk("error, file %s not found.\n", ramfs_dsdt_name); + return ret; + } + + len = stat.size; + /* check especially against empty files */ + if (len <= 4) { + printk("error file is too small, only %lu bytes.\n", len); + return ret; + } + + firmware_file = filp_open(ramfs_dsdt_name, O_RDONLY, 0); + if (IS_ERR(firmware_file)) { + printk("error, could not open file %s.\n", ramfs_dsdt_name); + return ret; + } + + dsdt_buffer = ACPI_ALLOCATE(len); + if (!dsdt_buffer) { + printk("error when allocating %lu bytes of memory.\n", len); + goto err; + } + + oldfs = get_fs(); + set_fs(KERNEL_DS); + len2 = vfs_read(firmware_file, (char __user *)dsdt_buffer, len, &firmware_file->f_pos); + set_fs(oldfs); + if (len2 < len) { + printk("error trying to read %lu bytes from %s.\n", len, ramfs_dsdt_name); + ACPI_FREE(dsdt_buffer); + goto err; + } + + printk("successfully read %lu bytes from %s.\n", len, ramfs_dsdt_name); + ret = dsdt_buffer; +err: + filp_close(firmware_file, NULL); + return ret; +} +#endif + acpi_status acpi_os_table_override(struct acpi_table_header * existing_table, struct acpi_table_header ** new_table) @@ -319,13 +380,18 @@ if (!existing_table || !new_table) return AE_BAD_PARAMETER; + *new_table = NULL; + #ifdef CONFIG_ACPI_CUSTOM_DSDT if (strncmp(existing_table->signature, "DSDT", 4) == 0) *new_table = (struct acpi_table_header *)AmlCode; - else - *new_table = NULL; -#else - *new_table = NULL; +#endif +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD + if (strncmp(existing_table->signature, "DSDT", 4) == 0) { + struct acpi_table_header* initrd_table = acpi_find_dsdt_initrd(); + if (initrd_table) + *new_table = initrd_table; + } #endif return AE_OK; } @@ -750,6 +816,7 @@ void acpi_os_wait_events_complete(void *context) { flush_workqueue(kacpid_wq); + flush_workqueue(kacpi_notify_wq); } EXPORT_SYMBOL(acpi_os_wait_events_complete); --- linux-2.6.24.orig/drivers/acpi/reboot.c +++ linux-2.6.24/drivers/acpi/reboot.c @@ -0,0 +1,81 @@ +#include +#include +#include +#include + +/* + * Some systems the have been proved to be able to reboot this way (even if + * some fail to claim this in the FADT). + */ +static struct dmi_system_id reboot_dmi_whitelist[] = { + { + .ident = "ASUS M6NE", + .matches = { + DMI_MATCH(DMI_BIOS_VERSION,"0208"), + DMI_MATCH(DMI_PRODUCT_NAME,"M6Ne"), + }, + }, + { + .ident = "Intel powered classmate PC", + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, + "Intel powered classmate PC"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Gen 1.5"), + }, + }, + {} +}; + +void acpi_reboot(void) +{ + struct acpi_generic_address *rr; + struct pci_bus *bus0; + u8 reset_value; + unsigned int devfn; + + if (acpi_disabled) + return; + + rr = &acpi_gbl_FADT.reset_register; + + /* + * For those systems that have not been whitelisted, check the ACPI + * flags and the register layout. + */ + if (!dmi_check_system(reboot_dmi_whitelist)) { + /* Is the reset register supported? */ + if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER)) + return; + /* Is the width and ofset as specified? */ + if (rr->bit_width != 8 || rr->bit_offset != 0) + return; + } + + reset_value = acpi_gbl_FADT.reset_value; + + /* The reset register can only exist in I/O, Memory or PCI config space + * on a device on bus 0. */ + switch (rr->space_id) { + case ACPI_ADR_SPACE_PCI_CONFIG: + /* The reset register can only live on bus 0. */ + bus0 = pci_find_bus(0, 0); + if (!bus0) + return; + /* Form PCI device/function pair. */ + devfn = PCI_DEVFN((rr->address >> 32) & 0xffff, + (rr->address >> 16) & 0xffff); + printk(KERN_DEBUG "Resetting with ACPI PCI RESET_REG."); + /* Write the value that resets us. */ + pci_bus_write_config_byte(bus0, devfn, + (rr->address & 0xffff), reset_value); + break; + + case ACPI_ADR_SPACE_SYSTEM_MEMORY: + case ACPI_ADR_SPACE_SYSTEM_IO: + printk(KERN_DEBUG "ACPI MEMORY or I/O RESET_REG.\n"); + acpi_hw_low_level_write(8, reset_value, rr); + break; + } + /* Wait ten seconds */ + acpi_os_stall(10000000); +} --- linux-2.6.24.orig/drivers/acpi/toshiba_acpi.c +++ linux-2.6.24/drivers/acpi/toshiba_acpi.c @@ -27,13 +27,28 @@ * engineering the Windows drivers * Yasushi Nagato - changes for linux kernel 2.4 -> 2.5 * Rob Miller - TV out and hotkeys help + * Daniel Silverstone - Punting of hotkeys via acpi using a thread * + * PLEASE NOTE + * + * This is an experimental version of toshiba_acpi which includes emulation + * of the original toshiba driver's /proc/toshiba and /dev/toshiba, + * allowing Toshiba userspace utilities to work. The relevant code was + * based on toshiba.c (copyright 1996-2001 Jonathan A. Buzzard) and + * incorporated into this driver with help from Gintautas Miliauskas, + * Charles Schwieters, and Christoph Burger-Scheidlin. + * + * Caveats: + * * hotkey status in /proc/toshiba is not implemented + * * to make accesses to /dev/toshiba load this driver instead of + * the original driver, you will have to modify your module + * auto-loading configuration * * TODO * */ -#define TOSHIBA_ACPI_VERSION "0.18" +#define TOSHIBA_ACPI_VERSION "0.19a-dev" #define PROC_INTERFACE_VERSION 1 #include @@ -41,12 +56,32 @@ #include #include #include +#include +#include +#include +#include +#include #include - +#include #include #include +/* Some compatibility for isa legacy interface */ +#ifndef isa_readb + +#define isa_readb(a) readb(__ISA_IO_base + (a)) +#define isa_readw(a) readw(__ISA_IO_base + (a)) +#define isa_readl(a) readl(__ISA_IO_base + (a)) +#define isa_writeb(b,a) writeb(b,__ISA_IO_base + (a)) +#define isa_writew(w,a) writew(w,__ISA_IO_base + (a)) +#define isa_writel(l,a) writel(l,__ISA_IO_base + (a)) +#define isa_memset_io(a,b,c) memset_io(__ISA_IO_base + (a),(b),(c)) +#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a),__ISA_IO_base + (b),(c)) +#define isa_memcpy_toio(a,b,c) memcpy_toio(__ISA_IO_base + (a),(b),(c)) + +#endif + MODULE_AUTHOR("John Belmonte"); MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver"); MODULE_LICENSE("GPL"); @@ -216,6 +251,11 @@ static int force_fan; static int last_key_event; static int key_event_valid; +static int hotkeys_over_acpi = 1; +static int hotkeys_check_per_sec = 2; + +module_param(hotkeys_over_acpi, uint, 0400); +module_param(hotkeys_check_per_sec, uint, 0400); typedef struct _ProcItem { const char *name; @@ -443,27 +483,34 @@ u32 hci_result; u32 value; - if (!key_event_valid) { - hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result); - if (hci_result == HCI_SUCCESS) { - key_event_valid = 1; - last_key_event = value; - } else if (hci_result == HCI_EMPTY) { - /* better luck next time */ - } else if (hci_result == HCI_NOT_SUPPORTED) { - /* This is a workaround for an unresolved issue on - * some machines where system events sporadically - * become disabled. */ - hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); - printk(MY_NOTICE "Re-enabled hotkeys\n"); - } else { - printk(MY_ERR "Error reading hotkey status\n"); - goto end; + if (!hotkeys_over_acpi) { + if (!key_event_valid) { + hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result); + if (hci_result == HCI_SUCCESS) { + key_event_valid = 1; + last_key_event = value; + } else if (hci_result == HCI_EMPTY) { + /* better luck next time */ + } else if (hci_result == HCI_NOT_SUPPORTED) { + /* This is a workaround for an + * unresolved issue on some machines + * where system events sporadically + * become disabled. */ + hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); + printk(MY_NOTICE "Re-enabled hotkeys\n"); + } else { + printk(MY_ERR "Error reading hotkey status\n"); + goto end; + } } + } else { + key_event_valid = 0; + last_key_event = 0; } p += sprintf(p, "hotkey_ready: %d\n", key_event_valid); p += sprintf(p, "hotkey: 0x%04x\n", last_key_event); + p += sprintf(p, "hotkeys_via_acpi: %d\n", hotkeys_over_acpi); end: return p; @@ -490,6 +537,179 @@ return p; } +/* /dev/toshiba and /proc/toshiba handlers {{{ + * + * ISSUE: lots of magic numbers and mysterious code + */ + +#define TOSH_MINOR_DEV 181 +#define OLD_PROC_TOSHIBA "toshiba" + +static int +tosh_acpi_bridge(SMMRegisters* regs) +{ + acpi_status status; + + /* assert(sizeof(SMMRegisters) == sizeof(u32)*HCI_WORDS); */ + status = hci_raw((u32*)regs, (u32*)regs); + if (status == AE_OK && (regs->eax & 0xff00) == HCI_SUCCESS) + return 0; + + return -EINVAL; +} + +static int +tosh_ioctl(struct inode* ip, struct file* fp, unsigned int cmd, + unsigned long arg) +{ + SMMRegisters regs; + unsigned short ax,bx; + int err; + + if ((!arg) || (cmd != TOSH_SMM)) + return -EINVAL; + + if (copy_from_user(®s, (SMMRegisters*)arg, sizeof(SMMRegisters))) + return -EFAULT; + + ax = regs.eax & 0xff00; + bx = regs.ebx & 0xffff; + + /* block HCI calls to read/write memory & PCI devices */ + if (((ax==HCI_SET) || (ax==HCI_GET)) && (bx>0x0069)) + return -EINVAL; + + err = tosh_acpi_bridge(®s); + + if (copy_to_user((SMMRegisters*)arg, ®s, sizeof(SMMRegisters))) + return -EFAULT; + + return err; +} + +static int +tosh_get_machine_id(void) +{ + int id; + unsigned short bx,cx; + unsigned long address; + + id = (0x100*(int)isa_readb(0xffffe))+((int)isa_readb(0xffffa)); + + /* do we have a SCTTable machine identication number on our hands */ + if (id==0xfc2f) { + bx = 0xe6f5; /* cheat */ + /* now twiddle with our pointer a bit */ + address = 0x000f0000+bx; + cx = isa_readw(address); + address = 0x000f0009+bx+cx; + cx = isa_readw(address); + address = 0x000f000a+cx; + cx = isa_readw(address); + /* now construct our machine identification number */ + id = ((cx & 0xff)<<8)+((cx & 0xff00)>>8); + } + + return id; +} + +static int tosh_id; +static int tosh_bios; +static int tosh_date; +static int tosh_sci; + +static struct file_operations tosh_fops = { + .owner = THIS_MODULE, + .ioctl = tosh_ioctl +}; + +static struct miscdevice tosh_device = { + TOSH_MINOR_DEV, + "toshiba", + &tosh_fops +}; + +static void +setup_tosh_info(void __iomem *bios) +{ + int major, minor; + int day, month, year; + + tosh_id = tosh_get_machine_id(); + + /* get the BIOS version */ + major = isa_readb(0xfe009)-'0'; + minor = ((isa_readb(0xfe00b)-'0')*10)+(isa_readb(0xfe00c)-'0'); + tosh_bios = (major*0x100)+minor; + + /* get the BIOS date */ + day = ((isa_readb(0xffff5)-'0')*10)+(isa_readb(0xffff6)-'0'); + month = ((isa_readb(0xffff8)-'0')*10)+(isa_readb(0xffff9)-'0'); + year = ((isa_readb(0xffffb)-'0')*10)+(isa_readb(0xffffc)-'0'); + tosh_date = (((year-90) & 0x1f)<<10) | ((month & 0xf)<<6) + | ((day & 0x1f)<<1); +} + +/* /proc/toshiba read handler */ +static int +tosh_get_info(char* buffer, char** start, off_t fpos, int length) +{ + char* temp = buffer; + /* TODO: tosh_fn_status() */ + int key = 0; + + /* Format: + * 0) Linux driver version (this will change if format changes) + * 1) Machine ID + * 2) SCI version + * 3) BIOS version (major, minor) + * 4) BIOS date (in SCI date format) + * 5) Fn Key status + */ + + temp += sprintf(temp, "1.1 0x%04x %d.%d %d.%d 0x%04x 0x%02x\n", + tosh_id, + (tosh_sci & 0xff00)>>8, + tosh_sci & 0xff, + (tosh_bios & 0xff00)>>8, + tosh_bios & 0xff, + tosh_date, + key); + + return temp-buffer; +} + +static int __init +old_driver_emulation_init(void) +{ + int status; + void __iomem *bios = ioremap(0xf0000, 0x10000); + if (!bios) + return -ENOMEM; + + if ((status = misc_register(&tosh_device))) { + printk(MY_ERR "failed to register misc device %d (\"%s\")\n", + tosh_device.minor, tosh_device.name); + return status; + } + + setup_tosh_info(bios); + create_proc_info_entry(OLD_PROC_TOSHIBA, 0, NULL, tosh_get_info); + + iounmap(bios); + + return 0; +} + +static void __exit +old_driver_emulation_exit(void) +{ + remove_proc_entry(OLD_PROC_TOSHIBA, NULL); + misc_deregister(&tosh_device); +} + +/* }}} end of /dev/toshiba and /proc/toshiba handlers */ + /* proc and module init */ @@ -538,16 +758,151 @@ .update_status = set_lcd_status, }; +static struct semaphore thread_sem; +static int thread_should_die; + +static struct acpi_device *threaded_device = 0; + +static void thread_deliver_button_event(u32 value) +{ + if (!threaded_device) return; + if( value == 0x0100 ) { + /* Ignore FN on its own */ + } else if( value & 0x80 ) { + acpi_bus_generate_proc_event( threaded_device, 1, value & ~0x80 ); + } else { + acpi_bus_generate_proc_event( threaded_device, 0, value ); + } +} + +static int toshiba_acpi_thread(void *data) +{ + int dropped = 0; + u32 hci_result, value; + + daemonize("ktoshkeyd"); + set_user_nice(current, 4); + thread_should_die = 0; + + up(&thread_sem); + + do { + /* In case we get stuck; we can rmmod the module here */ + if (thread_should_die) + break; + + hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result); + if (hci_result == HCI_SUCCESS) { + dropped++; + } else if (hci_result == HCI_EMPTY) { + /* better luck next time */ + } else if (hci_result == HCI_NOT_SUPPORTED) { + /* This is a workaround for an unresolved issue on + * some machines where system events sporadically + * become disabled. */ + hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); + printk(MY_NOTICE "Re-enabled hotkeys\n"); + } + } while (hci_result != HCI_EMPTY); + + printk(MY_INFO "Dropped %d keys from the queue on startup\n", dropped); + + for (;;) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ / hotkeys_check_per_sec); + + if (thread_should_die) + break; + + if (try_to_freeze()) + continue; + + do { + hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result); + if (hci_result == HCI_SUCCESS) { + thread_deliver_button_event(value); + } else if (hci_result == HCI_EMPTY) { + /* better luck next time */ + } else if (hci_result == HCI_NOT_SUPPORTED) { + /* This is a workaround for an + * unresolved issue on some machines + * where system events sporadically + * become disabled. */ + hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); + printk(MY_NOTICE "Re-enabled hotkeys\n"); + } + } while (hci_result == HCI_SUCCESS); + } + set_user_nice(current, -20); /* Become nasty so we are cleaned up + * before the module exits making us oops */ + up(&thread_sem); + return 0; +} + +static int acpi_toshkeys_add (struct acpi_device *device) +{ + threaded_device = device; + strcpy(acpi_device_name(device), "Toshiba laptop hotkeys"); + strcpy(acpi_device_class(device), "hkey"); + return 0; +} + +static int acpi_toshkeys_remove (struct acpi_device *device, int type) +{ + if (threaded_device == device) + threaded_device = 0; + return 0; +} + +static const struct acpi_device_id acpi_toshkeys_ids[] = { + { "TOS6200", 0 }, + { "TOS6207", 0 }, + { "TOS6208", 0 }, + {"", 0} +}; + +static struct acpi_driver acpi_threaded_toshkeys = { + .name = "Toshiba laptop hotkeys driver", + .class = "hkey", + .ids = acpi_toshkeys_ids, + .ops = { + .add = acpi_toshkeys_add, + .remove = acpi_toshkeys_remove, + }, +}; + +static int __init init_threaded_acpi(void) +{ + acpi_status result = AE_OK; + result = acpi_bus_register_driver(&acpi_threaded_toshkeys); + if( result < 0 ) + printk(MY_ERR "Registration of toshkeys acpi device failed\n"); + return result; +} + +static void kill_threaded_acpi(void) +{ + acpi_bus_unregister_driver(&acpi_threaded_toshkeys); +} + static void toshiba_acpi_exit(void) { if (toshiba_backlight_device) backlight_device_unregister(toshiba_backlight_device); + if (hotkeys_over_acpi) { + thread_should_die = 1; + down(&thread_sem); + kill_threaded_acpi(); + } + remove_device(); if (toshiba_proc_dir) remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); + old_driver_emulation_exit(); + return; } @@ -555,6 +910,7 @@ { acpi_status status = AE_OK; u32 hci_result; + int status2; if (acpi_disabled) return -ENODEV; @@ -571,6 +927,9 @@ TOSHIBA_ACPI_VERSION); printk(MY_INFO " HCI method: %s\n", method_hci); + if ((status2 = old_driver_emulation_init())) + return status2; + force_fan = 0; key_event_valid = 0; @@ -598,7 +957,27 @@ toshiba_acpi_exit(); return ret; } - toshiba_backlight_device->props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; + toshiba_backlight_device->props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; + + if (hotkeys_over_acpi && ACPI_SUCCESS(status)) { + printk(MY_INFO "Toshiba hotkeys are sent as ACPI events\n"); + if (hotkeys_check_per_sec < 1) + hotkeys_check_per_sec = 1; + if (hotkeys_check_per_sec > 10) + hotkeys_check_per_sec = 10; + printk(MY_INFO "ktoshkeyd will check %d time%s per second\n", + hotkeys_check_per_sec, hotkeys_check_per_sec==1?"":"s"); + if (init_threaded_acpi() >= 0) { + init_MUTEX_LOCKED(&thread_sem); + kernel_thread(toshiba_acpi_thread, NULL, CLONE_KERNEL); + down(&thread_sem); + } else { + remove_device(); + remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); + status = AE_ERROR; + printk(MY_INFO "ktoshkeyd initialisation failed. Refusing to load module\n"); + } + } return (ACPI_SUCCESS(status)) ? 0 : -ENODEV; } --- linux-2.6.24.orig/drivers/acpi/ec.c +++ linux-2.6.24/drivers/acpi/ec.c @@ -573,7 +573,7 @@ void *handler_context, void *region_context) { struct acpi_ec *ec = handler_context; - int result = 0, i = 0; + int result = 0, i; u8 temp = 0; if ((address > 0xFF) || !value || !handler_context) @@ -585,7 +585,18 @@ if (bits != 8 && acpi_strict) return AE_BAD_PARAMETER; - while (bits - i > 0) { + acpi_ec_burst_enable(ec); + + if (function == ACPI_READ) { + result = acpi_ec_read(ec, address, &temp); + *value = temp; + } else { + temp = 0xff & (*value); + result = acpi_ec_write(ec, address, temp); + } + + for (i = 8; unlikely(bits - i > 0); i += 8) { + ++address; if (function == ACPI_READ) { result = acpi_ec_read(ec, address, &temp); (*value) |= ((acpi_integer)temp) << i; @@ -593,10 +604,10 @@ temp = 0xff & ((*value) >> i); result = acpi_ec_write(ec, address, temp); } - i += 8; - ++address; } + acpi_ec_burst_disable(ec); + switch (result) { case -EINVAL: return AE_BAD_PARAMETER; --- linux-2.6.24.orig/drivers/acpi/video.c +++ linux-2.6.24/drivers/acpi/video.c @@ -72,6 +72,10 @@ MODULE_DESCRIPTION("ACPI Video Driver"); MODULE_LICENSE("GPL"); +static int no_automatic_changes = 1; + +module_param(no_automatic_changes, uint, 0600); + static int acpi_video_bus_add(struct acpi_device *device); static int acpi_video_bus_remove(struct acpi_device *device, int type); @@ -292,18 +296,26 @@ static int acpi_video_get_brightness(struct backlight_device *bd) { unsigned long cur_level; + int i; struct acpi_video_device *vd = (struct acpi_video_device *)bl_get_data(bd); acpi_video_device_lcd_get_level_current(vd, &cur_level); - return (int) cur_level; + for (i = 2; i < vd->brightness->count; i++) { + if (vd->brightness->levels[i] == cur_level) + /* The first two entries are special - see page 575 + of the ACPI spec 3.0 */ + return i-2; + } + return 0; } static int acpi_video_set_brightness(struct backlight_device *bd) { - int request_level = bd->props.brightness; + int request_level = bd->props.brightness+2; struct acpi_video_device *vd = (struct acpi_video_device *)bl_get_data(bd); - acpi_video_device_lcd_set_level(vd, request_level); + acpi_video_device_lcd_set_level(vd, + vd->brightness->levels[request_level]); return 0; } @@ -652,7 +664,6 @@ kfree(obj); if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){ - unsigned long tmp; static int count = 0; char *name; name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); @@ -660,11 +671,10 @@ return; sprintf(name, "acpi_video%d", count++); - acpi_video_device_lcd_get_level_current(device, &tmp); device->backlight = backlight_device_register(name, NULL, device, &acpi_backlight_ops); - device->backlight->props.max_brightness = max_level; - device->backlight->props.brightness = (int)tmp; + device->backlight->props.max_brightness = device->brightness->count-3; + device->backlight->props.brightness = acpi_video_get_brightness(device->backlight); backlight_update_status(device->backlight); kfree(name); @@ -1850,27 +1860,32 @@ switch (event) { case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */ - acpi_video_switch_brightness(video_device, event); + if (!no_automatic_changes) + acpi_video_switch_brightness(video_device, event); acpi_bus_generate_proc_event(device, event, 0); keycode = KEY_BRIGHTNESS_CYCLE; break; case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */ - acpi_video_switch_brightness(video_device, event); + if (!no_automatic_changes) + acpi_video_switch_brightness(video_device, event); acpi_bus_generate_proc_event(device, event, 0); keycode = KEY_BRIGHTNESSUP; break; case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */ - acpi_video_switch_brightness(video_device, event); + if (!no_automatic_changes) + acpi_video_switch_brightness(video_device, event); acpi_bus_generate_proc_event(device, event, 0); keycode = KEY_BRIGHTNESSDOWN; break; case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */ - acpi_video_switch_brightness(video_device, event); + if (!no_automatic_changes) + acpi_video_switch_brightness(video_device, event); acpi_bus_generate_proc_event(device, event, 0); keycode = KEY_BRIGHTNESS_ZERO; break; case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */ - acpi_video_switch_brightness(video_device, event); + if (!no_automatic_changes) + acpi_video_switch_brightness(video_device, event); acpi_bus_generate_proc_event(device, event, 0); keycode = KEY_DISPLAY_OFF; break; --- linux-2.6.24.orig/drivers/acpi/Kconfig +++ linux-2.6.24/drivers/acpi/Kconfig @@ -274,6 +274,23 @@ Enter the full path name to the file which includes the AmlCode declaration. +config ACPI_CUSTOM_DSDT_INITRD + bool "Read Custom DSDT from initramfs" + depends on BLK_DEV_INITRD + default y + help + The DSDT (Differentiated System Description Table) often needs to be + overridden because of broken BIOS implementations. If this feature is + activated you will be able to provide a customized DSDT by adding it + to your initramfs. For now you need to use a special mkinitrd tool. + For more details see or + . If there is no table found, it + will fallback to the custom DSDT in-kernel (if activated) or to the + DSDT from the BIOS. + + Even if you do not need a new one at the moment, you may want to use a + better implemented DSDT later. It is safe to say Y here. + config ACPI_BLACKLIST_YEAR int "Disable ACPI for systems before Jan 1st this year" if X86_32 default 0 --- linux-2.6.24.orig/drivers/acpi/processor_idle.c +++ linux-2.6.24/drivers/acpi/processor_idle.c @@ -125,52 +125,7 @@ static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = { { set_max_cstate, "IBM ThinkPad R40e", { DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET70WW")}, (void *)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW")}, (void *)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET43WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET45WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET47WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET50WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET52WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET55WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET56WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET59WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET61WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET62WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET64WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET65WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET68WW") }, (void*)1}, + DMI_MATCH(DMI_BIOS_VERSION,"1SET")}, (void *)1}, { set_max_cstate, "Medion 41700", { DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J")}, (void *)1}, @@ -1249,6 +1204,8 @@ { int result = 0; + if (boot_option_idle_override) + return 0; if (!pr) return -EINVAL; @@ -1593,6 +1550,7 @@ return -EINVAL; } + dev->cpu = pr->id; for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) { cx = &pr->power.states[i]; state = &dev->states[count]; @@ -1651,7 +1609,10 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr) { - int ret; + int ret = 0; + + if (boot_option_idle_override) + return 0; if (!pr) return -EINVAL; @@ -1666,8 +1627,11 @@ cpuidle_pause_and_lock(); cpuidle_disable_device(&pr->power.dev); acpi_processor_get_power_info(pr); - acpi_processor_setup_cpuidle(pr); - ret = cpuidle_enable_device(&pr->power.dev); + if (pr->flags.power) { + acpi_processor_setup_cpuidle(pr); + ret = cpuidle_enable_device(&pr->power.dev); + } + cpuidle_resume_and_unlock(); return ret; @@ -1683,6 +1647,8 @@ struct proc_dir_entry *entry = NULL; unsigned int i; + if (boot_option_idle_override) + return 0; if (!first_run) { dmi_check_system(processor_power_dmi_table); @@ -1717,10 +1683,9 @@ * Note that we use previously set idle handler will be used on * platforms that only support C1. */ - if ((pr->flags.power) && (!boot_option_idle_override)) { + if (pr->flags.power) { #ifdef CONFIG_CPU_IDLE acpi_processor_setup_cpuidle(pr); - pr->power.dev.cpu = pr->id; if (cpuidle_register_device(&pr->power.dev)) return -EIO; #endif @@ -1757,9 +1722,11 @@ int acpi_processor_power_exit(struct acpi_processor *pr, struct acpi_device *device) { + if (boot_option_idle_override) + return 0; + #ifdef CONFIG_CPU_IDLE - if ((pr->flags.power) && (!boot_option_idle_override)) - cpuidle_unregister_device(&pr->power.dev); + cpuidle_unregister_device(&pr->power.dev); #endif pr->flags.power_setup_done = 0; --- linux-2.6.24.orig/drivers/acpi/scan.c +++ linux-2.6.24/drivers/acpi/scan.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include /* for acpi_ex_eisa_id_to_string() */ @@ -86,17 +87,37 @@ } static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); -static int acpi_eject_operation(acpi_handle handle, int lockable) +static int acpi_bus_hot_remove_device(void *context) { + struct acpi_device *device; + acpi_handle handle = context; struct acpi_object_list arg_list; union acpi_object arg; acpi_status status = AE_OK; - /* - * TBD: evaluate _PS3? - */ + if (acpi_bus_get_device(handle, &device)) + return 0; - if (lockable) { + if (!device) + return 0; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Hot-removing device %s...\n", device->dev.bus_id)); + + + if (acpi_bus_trim(device, 1)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Removing device failed\n")); + return -1; + } + + /* power off device */ + status = acpi_evaluate_object(handle, "_PS3", NULL, NULL); + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) + ACPI_DEBUG_PRINT((ACPI_DB_WARN, + "Power-off device failed\n")); + + if (device->flags.lockable) { arg_list.count = 1; arg_list.pointer = &arg; arg.type = ACPI_TYPE_INTEGER; @@ -112,24 +133,19 @@ /* * TBD: _EJD support. */ - status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL); - if (ACPI_FAILURE(status)) { - return (-ENODEV); - } + if (ACPI_FAILURE(status)) + return -ENODEV; - return (0); + return 0; } static ssize_t acpi_eject_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { - int result; int ret = count; - int islockable; acpi_status status; - acpi_handle handle; acpi_object_type type = 0; struct acpi_device *acpi_device = to_acpi_device(d); @@ -148,17 +164,9 @@ goto err; } - islockable = acpi_device->flags.lockable; - handle = acpi_device->handle; - - result = acpi_bus_trim(acpi_device, 1); - - if (!result) - result = acpi_eject_operation(handle, islockable); - - if (result) { - ret = -EBUSY; - } + /* remove the device in another thread to fix the deadlock issue */ + ret = kernel_thread(acpi_bus_hot_remove_device, + acpi_device->handle, SIGCHLD); err: return ret; } --- linux-2.6.24.orig/drivers/acpi/processor_core.c +++ linux-2.6.24/drivers/acpi/processor_core.c @@ -622,7 +622,7 @@ int result = 0; acpi_status status = AE_OK; struct acpi_processor *pr; - + struct sys_device *sysdev; pr = acpi_driver_data(device); @@ -653,6 +653,10 @@ if (result) goto end; + sysdev = get_cpu_sysdev(pr->id); + if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) + return -EFAULT; + status = acpi_install_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY, acpi_processor_notify, pr); @@ -789,10 +793,12 @@ status = acpi_remove_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY, acpi_processor_notify); + sysfs_remove_link(&device->dev.kobj, "sysdev"); + acpi_processor_remove_fs(device); processors[pr->id] = NULL; - + processor_device_array[pr->id] = NULL; kfree(pr); return 0; @@ -978,9 +984,9 @@ static int acpi_processor_handle_eject(struct acpi_processor *pr) { - if (cpu_online(pr->id)) { - return (-EINVAL); - } + if (cpu_online(pr->id)) + cpu_down(pr->id); + arch_unregister_cpu(pr->id); acpi_unmap_lsapic(pr->id); return (0); --- linux-2.6.24.orig/drivers/acpi/bus.c +++ linux-2.6.24/drivers/acpi/bus.c @@ -350,10 +350,11 @@ } spin_lock_irqsave(&acpi_bus_event_lock, flags); - entry = - list_entry(acpi_bus_event_list.next, struct acpi_bus_event, node); - if (entry) + if (!list_empty(&acpi_bus_event_list)) { + entry = list_entry(acpi_bus_event_list.next, + struct acpi_bus_event, node); list_del(&entry->node); + } spin_unlock_irqrestore(&acpi_bus_event_lock, flags); if (!entry) --- linux-2.6.24.orig/drivers/acpi/Makefile +++ linux-2.6.24/drivers/acpi/Makefile @@ -21,7 +21,7 @@ # # ACPI Core Subsystem (Interpreter) # -obj-y += osl.o utils.o \ +obj-y += osl.o utils.o reboot.o\ dispatcher/ events/ executer/ hardware/ \ namespace/ parser/ resources/ tables/ \ utilities/ --- linux-2.6.24.orig/drivers/acpi/utilities/utobject.c +++ linux-2.6.24/drivers/acpi/utilities/utobject.c @@ -432,7 +432,7 @@ * element -- which is legal) */ if (!internal_object) { - *obj_length = 0; + *obj_length = sizeof(union acpi_object); return_ACPI_STATUS(AE_OK); } --- linux-2.6.24.orig/drivers/acpi/executer/exconfig.c +++ linux-2.6.24/drivers/acpi/executer/exconfig.c @@ -268,6 +268,8 @@ struct acpi_table_desc table_desc; acpi_native_uint table_index; acpi_status status; + u32 length; + void *maddr; ACPI_FUNCTION_TRACE(ex_load_op); @@ -299,9 +301,24 @@ } } + length = obj_desc->region.length; + table_desc.pointer = ACPI_ALLOCATE(length); + if (!table_desc.pointer) { + return_ACPI_STATUS(AE_NO_MEMORY); + } + + maddr = acpi_os_map_memory(obj_desc->region.address, length); + if (!maddr) { + ACPI_FREE(table_desc.pointer); + return_ACPI_STATUS(AE_NO_MEMORY); + } + ACPI_MEMCPY(table_desc.pointer, maddr, length); + acpi_os_unmap_memory(maddr, length); + + /* Keep the address for the pretty table info print */ table_desc.address = obj_desc->region.address; table_desc.length = obj_desc->region.length; - table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED; + table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED; break; case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */ --- linux-2.6.24.orig/drivers/acpi/resources/rscalc.c +++ linux-2.6.24/drivers/acpi/resources/rscalc.c @@ -211,6 +211,13 @@ * variable-length fields */ switch (resource->type) { + case ACPI_RESOURCE_TYPE_IRQ: + + if (resource->data.irq.descriptor_length == 2) { + total_size--; + } + break; + case ACPI_RESOURCE_TYPE_VENDOR: /* * Vendor Defined Resource: --- linux-2.6.24.orig/drivers/acpi/resources/rsmisc.c +++ linux-2.6.24/drivers/acpi/resources/rsmisc.c @@ -497,6 +497,17 @@ } break; + case ACPI_RSC_EXIT_EQ: + /* + * Control - Exit conversion if equal + */ + if (*ACPI_ADD_PTR(u8, resource, + COMPARE_TARGET(info)) == + COMPARE_VALUE(info)) { + goto exit; + } + break; + default: ACPI_ERROR((AE_INFO, "Invalid conversion opcode")); --- linux-2.6.24.orig/drivers/acpi/resources/rsirq.c +++ linux-2.6.24/drivers/acpi/resources/rsirq.c @@ -52,7 +52,7 @@ * acpi_rs_get_irq * ******************************************************************************/ -struct acpi_rsconvert_info acpi_rs_get_irq[7] = { +struct acpi_rsconvert_info acpi_rs_get_irq[8] = { {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IRQ, ACPI_RS_SIZE(struct acpi_resource_irq), ACPI_RSC_TABLE_SIZE(acpi_rs_get_irq)}, @@ -69,6 +69,12 @@ ACPI_EDGE_SENSITIVE, 1}, + /* Get the descriptor length (2 or 3 for IRQ descriptor) */ + + {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.irq.descriptor_length), + AML_OFFSET(irq.descriptor_type), + 0}, + /* All done if no flag byte present in descriptor */ {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 3}, @@ -94,7 +100,9 @@ * ******************************************************************************/ -struct acpi_rsconvert_info acpi_rs_set_irq[9] = { +struct acpi_rsconvert_info acpi_rs_set_irq[13] = { + /* Start with a default descriptor of length 3 */ + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IRQ, sizeof(struct aml_resource_irq), ACPI_RSC_TABLE_SIZE(acpi_rs_set_irq)}, @@ -105,7 +113,7 @@ AML_OFFSET(irq.irq_mask), ACPI_RS_OFFSET(data.irq.interrupt_count)}, - /* Set the flags byte by default */ + /* Set the flags byte */ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering), AML_OFFSET(irq.flags), @@ -118,6 +126,33 @@ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.sharable), AML_OFFSET(irq.flags), 4}, + + /* + * All done if the output descriptor length is required to be 3 + * (i.e., optimization to 2 bytes cannot be attempted) + */ + {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE, + ACPI_RS_OFFSET(data.irq.descriptor_length), + 3}, + + /* Set length to 2 bytes (no flags byte) */ + + {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq_noflags)}, + + /* + * All done if the output descriptor length is required to be 2. + * + * TBD: Perhaps we should check for error if input flags are not + * compatible with a 2-byte descriptor. + */ + {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE, + ACPI_RS_OFFSET(data.irq.descriptor_length), + 2}, + + /* Reset length to 3 bytes (descriptor with flags byte) */ + + {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq)}, + /* * Check if the flags byte is necessary. Not needed if the flags are: * ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_HIGH, ACPI_EXCLUSIVE @@ -134,7 +169,7 @@ ACPI_RS_OFFSET(data.irq.sharable), ACPI_EXCLUSIVE}, - /* irq_no_flags() descriptor can be used */ + /* We can optimize to a 2-byte irq_no_flags() descriptor */ {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq_noflags)} }; --- linux-2.6.24.orig/drivers/acpi/resources/rsio.c +++ linux-2.6.24/drivers/acpi/resources/rsio.c @@ -185,7 +185,7 @@ * ******************************************************************************/ -struct acpi_rsconvert_info acpi_rs_get_start_dpf[5] = { +struct acpi_rsconvert_info acpi_rs_get_start_dpf[6] = { {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_START_DEPENDENT, ACPI_RS_SIZE(struct acpi_resource_start_dependent), ACPI_RSC_TABLE_SIZE(acpi_rs_get_start_dpf)}, @@ -196,6 +196,12 @@ ACPI_ACCEPTABLE_CONFIGURATION, 2}, + /* Get the descriptor length (0 or 1 for Start Dpf descriptor) */ + + {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.start_dpf.descriptor_length), + AML_OFFSET(start_dpf.descriptor_type), + 0}, + /* All done if there is no flag byte present in the descriptor */ {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 1}, @@ -219,7 +225,9 @@ * ******************************************************************************/ -struct acpi_rsconvert_info acpi_rs_set_start_dpf[6] = { +struct acpi_rsconvert_info acpi_rs_set_start_dpf[10] = { + /* Start with a default descriptor of length 1 */ + {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_START_DEPENDENT, sizeof(struct aml_resource_start_dependent), ACPI_RSC_TABLE_SIZE(acpi_rs_set_start_dpf)}, @@ -236,6 +244,33 @@ AML_OFFSET(start_dpf.flags), 2}, /* + * All done if the output descriptor length is required to be 1 + * (i.e., optimization to 0 bytes cannot be attempted) + */ + {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE, + ACPI_RS_OFFSET(data.start_dpf.descriptor_length), + 1}, + + /* Set length to 0 bytes (no flags byte) */ + + {ACPI_RSC_LENGTH, 0, 0, + sizeof(struct aml_resource_start_dependent_noprio)}, + + /* + * All done if the output descriptor length is required to be 0. + * + * TBD: Perhaps we should check for error if input flags are not + * compatible with a 0-byte descriptor. + */ + {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE, + ACPI_RS_OFFSET(data.start_dpf.descriptor_length), + 0}, + + /* Reset length to 1 byte (descriptor with flags byte) */ + + {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq)}, + + /* * All done if flags byte is necessary -- if either priority value * is not ACPI_ACCEPTABLE_CONFIGURATION */ --- linux-2.6.24.orig/drivers/acpi/resources/rsdump.c +++ linux-2.6.24/drivers/acpi/resources/rsdump.c @@ -87,8 +87,10 @@ * ******************************************************************************/ -struct acpi_rsdump_info acpi_rs_dump_irq[6] = { +struct acpi_rsdump_info acpi_rs_dump_irq[7] = { {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_irq), "IRQ", NULL}, + {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(irq.descriptor_length), + "Descriptor Length", NULL}, {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.triggering), "Triggering", acpi_gbl_he_decode}, {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.polarity), "Polarity", @@ -115,9 +117,11 @@ NULL} }; -struct acpi_rsdump_info acpi_rs_dump_start_dpf[3] = { +struct acpi_rsdump_info acpi_rs_dump_start_dpf[4] = { {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_start_dpf), "Start-Dependent-Functions", NULL}, + {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(start_dpf.descriptor_length), + "Descriptor Length", NULL}, {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.compatibility_priority), "Compatibility Priority", acpi_gbl_config_decode}, {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.performance_robustness), --- linux-2.6.24.orig/drivers/md/dm.c +++ linux-2.6.24/drivers/md/dm.c @@ -1566,6 +1566,7 @@ { return md->disk; } +EXPORT_SYMBOL_GPL(dm_disk); int dm_suspended(struct mapped_device *md) { --- linux-2.6.24.orig/drivers/md/md.c +++ linux-2.6.24/drivers/md/md.c @@ -1847,17 +1847,6 @@ __ATTR(state, S_IRUGO|S_IWUSR, state_show, state_store); static ssize_t -super_show(mdk_rdev_t *rdev, char *page) -{ - if (rdev->sb_loaded && rdev->sb_size) { - memcpy(page, page_address(rdev->sb_page), rdev->sb_size); - return rdev->sb_size; - } else - return 0; -} -static struct rdev_sysfs_entry rdev_super = __ATTR_RO(super); - -static ssize_t errors_show(mdk_rdev_t *rdev, char *page) { return sprintf(page, "%d\n", atomic_read(&rdev->corrected_errors)); @@ -1959,7 +1948,6 @@ static struct attribute *rdev_default_attrs[] = { &rdev_state.attr, - &rdev_super.attr, &rdev_errors.attr, &rdev_slot.attr, &rdev_offset.attr, --- linux-2.6.24.orig/drivers/md/raid5.c +++ linux-2.6.24/drivers/md/raid5.c @@ -2348,25 +2348,15 @@ static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh, struct stripe_head_state *s, int disks) { + int canceled_check = 0; + set_bit(STRIPE_HANDLE, &sh->state); - /* Take one of the following actions: - * 1/ start a check parity operation if (uptodate == disks) - * 2/ finish a check parity operation and act on the result - * 3/ skip to the writeback section if we previously - * initiated a recovery operation - */ - if (s->failed == 0 && - !test_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending)) { - if (!test_and_set_bit(STRIPE_OP_CHECK, &sh->ops.pending)) { - BUG_ON(s->uptodate != disks); - clear_bit(R5_UPTODATE, &sh->dev[sh->pd_idx].flags); - sh->ops.count++; - s->uptodate--; - } else if ( - test_and_clear_bit(STRIPE_OP_CHECK, &sh->ops.complete)) { - clear_bit(STRIPE_OP_CHECK, &sh->ops.ack); - clear_bit(STRIPE_OP_CHECK, &sh->ops.pending); + /* complete a check operation */ + if (test_and_clear_bit(STRIPE_OP_CHECK, &sh->ops.complete)) { + clear_bit(STRIPE_OP_CHECK, &sh->ops.ack); + clear_bit(STRIPE_OP_CHECK, &sh->ops.pending); + if (s->failed == 0) { if (sh->ops.zero_sum_result == 0) /* parity is correct (on disc, * not in buffer any more) @@ -2391,7 +2381,8 @@ s->uptodate++; } } - } + } else + canceled_check = 1; /* STRIPE_INSYNC is not set */ } /* check if we can clear a parity disk reconstruct */ @@ -2404,12 +2395,28 @@ clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending); } - /* Wait for check parity and compute block operations to complete - * before write-back + /* start a new check operation if there are no failures, the stripe is + * not insync, and a repair is not in flight */ - if (!test_bit(STRIPE_INSYNC, &sh->state) && - !test_bit(STRIPE_OP_CHECK, &sh->ops.pending) && - !test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending)) { + if (s->failed == 0 && + !test_bit(STRIPE_INSYNC, &sh->state) && + !test_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending)) { + if (!test_and_set_bit(STRIPE_OP_CHECK, &sh->ops.pending)) { + BUG_ON(s->uptodate != disks); + clear_bit(R5_UPTODATE, &sh->dev[sh->pd_idx].flags); + sh->ops.count++; + s->uptodate--; + } + } + + /* Wait for check parity and compute block operations to complete + * before write-back. If a failure occurred while the check operation + * was in flight we need to cycle this stripe through handle_stripe + * since the parity block may not be uptodate + */ + if (!canceled_check && !test_bit(STRIPE_INSYNC, &sh->state) && + !test_bit(STRIPE_OP_CHECK, &sh->ops.pending) && + !test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending)) { struct r5dev *dev; /* either failed parity check, or recovery is happening */ if (s->failed == 0) @@ -3159,7 +3166,8 @@ atomic_inc(&conf->preread_active_stripes); list_add_tail(&sh->lru, &conf->handle_list); } - } + } else + blk_plug_device(conf->mddev->queue); } static void activate_bit_delay(raid5_conf_t *conf) @@ -3549,7 +3557,8 @@ goto retry; } finish_wait(&conf->wait_for_overlap, &w); - handle_stripe(sh, NULL); + set_bit(STRIPE_HANDLE, &sh->state); + clear_bit(STRIPE_DELAYED, &sh->state); release_stripe(sh); } else { /* cannot get stripe for read-ahead, just give-up */ @@ -3864,7 +3873,7 @@ * During the scan, completed stripes are saved for us by the interrupt * handler, so that they will not have to wait for our next wakeup. */ -static void raid5d (mddev_t *mddev) +static void raid5d(mddev_t *mddev) { struct stripe_head *sh; raid5_conf_t *conf = mddev_to_conf(mddev); @@ -3889,12 +3898,6 @@ activate_bit_delay(conf); } - if (list_empty(&conf->handle_list) && - atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD && - !blk_queue_plugged(mddev->queue) && - !list_empty(&conf->delayed_list)) - raid5_activate_delayed(conf); - while ((bio = remove_bio_from_retry(conf))) { int ok; spin_unlock_irq(&conf->device_lock); --- linux-2.6.24.orig/drivers/hid/hid-input.c +++ linux-2.6.24/drivers/hid/hid-input.c @@ -34,10 +34,10 @@ #include #include -static int hid_pb_fnmode = 1; -module_param_named(pb_fnmode, hid_pb_fnmode, int, 0644); +static int hid_apple_fnmode = 1; +module_param_named(pb_fnmode, hid_apple_fnmode, int, 0644); MODULE_PARM_DESC(pb_fnmode, - "Mode of fn key on PowerBooks (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst)"); + "Mode of fn key on Apple keyboards (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst)"); #define unk KEY_UNKNOWN @@ -98,20 +98,41 @@ u8 flags; }; -#define POWERBOOK_FLAG_FKEY 0x01 +#define APPLE_FLAG_FKEY 0x01 + +static struct hidinput_key_translation apple_fn_keys[] = { + { KEY_BACKSPACE, KEY_DELETE }, + { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, + { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, + { KEY_F3, KEY_CYCLEWINDOWS, APPLE_FLAG_FKEY }, /* Exposé */ + { KEY_F4, KEY_FN_F4, APPLE_FLAG_FKEY }, /* Dashboard */ + { KEY_F5, KEY_FN_F5 }, + { KEY_F6, KEY_FN_F6 }, + { KEY_F7, KEY_BACK, APPLE_FLAG_FKEY }, + { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY }, + { KEY_F9, KEY_FORWARD, APPLE_FLAG_FKEY }, + { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY }, + { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, + { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, + { KEY_UP, KEY_PAGEUP }, + { KEY_DOWN, KEY_PAGEDOWN }, + { KEY_LEFT, KEY_HOME }, + { KEY_RIGHT, KEY_END }, + { } +}; static struct hidinput_key_translation powerbook_fn_keys[] = { { KEY_BACKSPACE, KEY_DELETE }, - { KEY_F1, KEY_BRIGHTNESSDOWN, POWERBOOK_FLAG_FKEY }, - { KEY_F2, KEY_BRIGHTNESSUP, POWERBOOK_FLAG_FKEY }, - { KEY_F3, KEY_MUTE, POWERBOOK_FLAG_FKEY }, - { KEY_F4, KEY_VOLUMEDOWN, POWERBOOK_FLAG_FKEY }, - { KEY_F5, KEY_VOLUMEUP, POWERBOOK_FLAG_FKEY }, - { KEY_F6, KEY_NUMLOCK, POWERBOOK_FLAG_FKEY }, - { KEY_F7, KEY_SWITCHVIDEOMODE, POWERBOOK_FLAG_FKEY }, - { KEY_F8, KEY_KBDILLUMTOGGLE, POWERBOOK_FLAG_FKEY }, - { KEY_F9, KEY_KBDILLUMDOWN, POWERBOOK_FLAG_FKEY }, - { KEY_F10, KEY_KBDILLUMUP, POWERBOOK_FLAG_FKEY }, + { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, + { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, + { KEY_F3, KEY_MUTE, APPLE_FLAG_FKEY }, + { KEY_F4, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, + { KEY_F5, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, + { KEY_F6, KEY_NUMLOCK, APPLE_FLAG_FKEY }, + { KEY_F7, KEY_SWITCHVIDEOMODE, APPLE_FLAG_FKEY }, + { KEY_F8, KEY_KBDILLUMTOGGLE, APPLE_FLAG_FKEY }, + { KEY_F9, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY }, + { KEY_F10, KEY_KBDILLUMUP, APPLE_FLAG_FKEY }, { KEY_UP, KEY_PAGEUP }, { KEY_DOWN, KEY_PAGEDOWN }, { KEY_LEFT, KEY_HOME }, @@ -142,7 +163,7 @@ { } }; -static struct hidinput_key_translation powerbook_iso_keyboard[] = { +static struct hidinput_key_translation apple_iso_keyboard[] = { { KEY_GRAVE, KEY_102ND }, { KEY_102ND, KEY_GRAVE }, { } @@ -160,39 +181,42 @@ return NULL; } -static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, +static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, struct hid_usage *usage, __s32 value) { struct hidinput_key_translation *trans; if (usage->code == KEY_FN) { - if (value) hid->quirks |= HID_QUIRK_POWERBOOK_FN_ON; - else hid->quirks &= ~HID_QUIRK_POWERBOOK_FN_ON; + if (value) hid->quirks |= HID_QUIRK_APPLE_FN_ON; + else hid->quirks &= ~HID_QUIRK_APPLE_FN_ON; input_event(input, usage->type, usage->code, value); return 1; } - if (hid_pb_fnmode) { + if (hid_apple_fnmode) { int do_translate; - trans = find_translation(powerbook_fn_keys, usage->code); + trans = find_translation((hid->product < 0x220 || + hid->product >= 0x300) ? + powerbook_fn_keys : apple_fn_keys, + usage->code); if (trans) { - if (test_bit(usage->code, hid->pb_pressed_fn)) + if (test_bit(usage->code, hid->apple_pressed_fn)) do_translate = 1; - else if (trans->flags & POWERBOOK_FLAG_FKEY) + else if (trans->flags & APPLE_FLAG_FKEY) do_translate = - (hid_pb_fnmode == 2 && (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)) || - (hid_pb_fnmode == 1 && !(hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)); + (hid_apple_fnmode == 2 && (hid->quirks & HID_QUIRK_APPLE_FN_ON)) || + (hid_apple_fnmode == 1 && !(hid->quirks & HID_QUIRK_APPLE_FN_ON)); else - do_translate = (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON); + do_translate = (hid->quirks & HID_QUIRK_APPLE_FN_ON); if (do_translate) { if (value) - set_bit(usage->code, hid->pb_pressed_fn); + set_bit(usage->code, hid->apple_pressed_fn); else - clear_bit(usage->code, hid->pb_pressed_fn); + clear_bit(usage->code, hid->apple_pressed_fn); input_event(input, usage->type, trans->to, value); @@ -200,8 +224,9 @@ } } - if (test_bit(usage->code, hid->pb_pressed_numlock) || - test_bit(LED_NUML, input->led)) { + if (hid->quirks & HID_QUIRK_APPLE_NUMLOCK_EMULATION && ( + test_bit(usage->code, hid->pb_pressed_numlock) || + test_bit(LED_NUML, input->led))) { trans = find_translation(powerbook_numlock_keys, usage->code); if (trans) { @@ -217,8 +242,8 @@ } } - if (hid->quirks & HID_QUIRK_POWERBOOK_ISO_KEYBOARD) { - trans = find_translation(powerbook_iso_keyboard, usage->code); + if (hid->quirks & HID_QUIRK_APPLE_ISO_KEYBOARD) { + trans = find_translation(apple_iso_keyboard, usage->code); if (trans) { input_event(input, usage->type, trans->to, value); return 1; @@ -228,31 +253,35 @@ return 0; } -static void hidinput_pb_setup(struct input_dev *input) +static void hidinput_apple_setup(struct input_dev *input) { struct hidinput_key_translation *trans; set_bit(KEY_NUMLOCK, input->keybit); /* Enable all needed keys */ + for (trans = apple_fn_keys; trans->from; trans++) + set_bit(trans->to, input->keybit); + for (trans = powerbook_fn_keys; trans->from; trans++) set_bit(trans->to, input->keybit); for (trans = powerbook_numlock_keys; trans->from; trans++) set_bit(trans->to, input->keybit); - for (trans = powerbook_iso_keyboard; trans->from; trans++) + for (trans = apple_iso_keyboard; trans->from; trans++) set_bit(trans->to, input->keybit); } #else -static inline int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, - struct hid_usage *usage, __s32 value) +static inline int hidinput_apple_event(struct hid_device *hid, + struct input_dev *input, + struct hid_usage *usage, __s32 value) { return 0; } -static inline void hidinput_pb_setup(struct input_dev *input) +static inline void hidinput_apple_setup(struct input_dev *input) { } #endif @@ -785,14 +814,14 @@ } break; - case HID_UP_CUSTOM: /* Reported on Logitech and Powerbook USB keyboards */ + case HID_UP_CUSTOM: /* Reported on Logitech and Apple USB keyboards */ set_bit(EV_REP, input->evbit); switch(usage->hid & HID_USAGE) { case 0x003: - /* The fn key on Apple PowerBooks */ + /* The fn key on Apple USB keyboards */ map_key_clear(KEY_FN); - hidinput_pb_setup(input); + hidinput_apple_setup(input); break; default: goto ignore; @@ -867,9 +896,10 @@ map_key(BTN_1); } - if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5)) && - (usage->type == EV_REL) && (usage->code == REL_WHEEL)) - set_bit(REL_HWHEEL, bit); + if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5 | + HID_QUIRK_2WHEEL_MOUSE_HACK_B8)) && (usage->type == EV_REL) && + (usage->code == REL_WHEEL)) + set_bit(REL_HWHEEL, bit); if (((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) || ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) @@ -967,6 +997,19 @@ return; } + if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) && + (usage->type == EV_REL) && + (usage->code == REL_WHEEL)) { + hid->delayed_value = value; + return; + } + + if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) && + (usage->hid == 0x000100b8)) { + input_event(input, EV_REL, value ? REL_HWHEEL : REL_WHEEL, hid->delayed_value); + return; + } + if ((hid->quirks & HID_QUIRK_INVERT_HWHEEL) && (usage->code == REL_HWHEEL)) { input_event(input, usage->type, usage->code, -value); return; @@ -977,7 +1020,7 @@ return; } - if ((hid->quirks & HID_QUIRK_POWERBOOK_HAS_FN) && hidinput_pb_event(hid, input, usage, value)) + if ((hid->quirks & HID_QUIRK_APPLE_HAS_FN) && hidinput_apple_event(hid, input, usage, value)) return; if (usage->hat_min < usage->hat_max || usage->hat_dir) { --- linux-2.6.24.orig/drivers/hid/usbhid/Kconfig +++ linux-2.6.24/drivers/hid/usbhid/Kconfig @@ -25,12 +25,13 @@ depends on USB_HID && INPUT=n config USB_HIDINPUT_POWERBOOK - bool "Enable support for iBook/PowerBook/MacBook/MacBookPro special keys" + bool "Enable support for Apple laptop/aluminum USB special keys" default n depends on USB_HID help Say Y here if you want support for the special keys (Fn, Numlock) on - Apple iBooks, PowerBooks, MacBooks and MacBook Pros. + Apple iBooks, PowerBooks, MacBooks, MacBook Pros and aluminum USB + keyboards. If unsure, say N. --- linux-2.6.24.orig/drivers/hid/usbhid/hid-quirks.c +++ linux-2.6.24/drivers/hid/usbhid/hid-quirks.c @@ -19,6 +19,7 @@ #define USB_VENDOR_ID_A4TECH 0x09da #define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 +#define USB_DEVICE_ID_A4TECH_X5_005D 0x000a #define USB_VENDOR_ID_AASHIMA 0x06d6 #define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025 @@ -59,6 +60,21 @@ #define USB_DEVICE_ID_APPLE_GEYSER4_ANSI 0x021a #define USB_DEVICE_ID_APPLE_GEYSER4_ISO 0x021b #define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c +#define USB_DEVICE_ID_APPLE_ALU_ANSI 0x0220 +#define USB_DEVICE_ID_APPLE_ALU_ISO 0x0221 +#define USB_DEVICE_ID_APPLE_ALU_JIS 0x0222 +#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI 0x0229 +#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO 0x022a +#define USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS 0x022b +#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI 0x022c +#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO 0x022d +#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS 0x022e +#define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223 +#define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224 +#define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225 +#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230 +#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231 +#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232 #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b #define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242 @@ -66,6 +82,9 @@ #define USB_VENDOR_ID_ASUS 0x0b05 #define USB_DEVICE_ID_ASUS_LCM 0x1726 +#define USB_VENDOR_ID_ASUS 0x0b05 +#define USB_DEVICE_ID_ASUS_LCM 0x1726 + #define USB_VENDOR_ID_ATEN 0x0557 #define USB_DEVICE_ID_ATEN_UC100KM 0x2004 #define USB_DEVICE_ID_ATEN_CS124U 0x2202 @@ -116,6 +135,7 @@ #define USB_VENDOR_ID_GAMERON 0x0810 #define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001 +#define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002 #define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc @@ -368,6 +388,7 @@ } hid_blacklist[] = { { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, + { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D, HID_QUIRK_2WHEEL_MOUSE_HACK_B8 }, { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 }, { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER, HID_QUIRK_BAD_RELATIVE_KEYS }, @@ -377,6 +398,7 @@ { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR, HID_QUIRK_MULTI_INPUT }, + { USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, @@ -540,19 +562,34 @@ { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD}, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD}, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD}, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI, HID_QUIRK_APPLE_HAS_FN }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS, HID_QUIRK_APPLE_HAS_FN }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS }, { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD, HID_QUIRK_RESET_LEDS }, @@ -645,6 +682,8 @@ { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_RDESC_SWAPPED_MIN_MAX }, { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_RDESC_SWAPPED_MIN_MAX }, + { USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM, HID_QUIRK_IGNORE}, + { 0, 0 } }; @@ -751,6 +790,7 @@ return 0; } +EXPORT_SYMBOL(usbhid_modify_dquirk); /** * usbhid_remove_all_dquirks: remove all runtime HID quirks from memory --- linux-2.6.24.orig/drivers/cpuidle/cpuidle.c +++ linux-2.6.24/drivers/cpuidle/cpuidle.c @@ -26,6 +26,8 @@ static int enabled_devices; +static int __cpuidle_register_device(struct cpuidle_device *dev); + /** * cpuidle_idle_call - the main idle loop * @@ -126,6 +128,12 @@ if (!dev->state_count) return -EINVAL; + if (dev->registered == 0) { + ret = __cpuidle_register_device(dev); + if (ret) + return ret; + } + if ((ret = cpuidle_add_state_sysfs(dev))) return ret; @@ -181,10 +189,13 @@ EXPORT_SYMBOL_GPL(cpuidle_disable_device); /** - * cpuidle_register_device - registers a CPU's idle PM feature + * __cpuidle_register_device - internal register function called before register + * and enable routines * @dev: the cpu + * + * cpuidle_lock mutex must be held before this is called */ -int cpuidle_register_device(struct cpuidle_device *dev) +static int __cpuidle_register_device(struct cpuidle_device *dev) { int ret; struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu); @@ -196,23 +207,38 @@ init_completion(&dev->kobj_unregister); - mutex_lock(&cpuidle_lock); - per_cpu(cpuidle_devices, dev->cpu) = dev; list_add(&dev->device_list, &cpuidle_detected_devices); if ((ret = cpuidle_add_sysfs(sys_dev))) { - mutex_unlock(&cpuidle_lock); module_put(cpuidle_curr_driver->owner); return ret; } + dev->registered = 1; + return 0; +} + +/** + * cpuidle_register_device - registers a CPU's idle PM feature + * @dev: the cpu + */ +int cpuidle_register_device(struct cpuidle_device *dev) +{ + int ret; + + mutex_lock(&cpuidle_lock); + + if ((ret = __cpuidle_register_device(dev))) { + mutex_unlock(&cpuidle_lock); + return ret; + } + cpuidle_enable_device(dev); cpuidle_install_idle_handler(); mutex_unlock(&cpuidle_lock); return 0; - } EXPORT_SYMBOL_GPL(cpuidle_register_device); @@ -225,6 +251,9 @@ { struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu); + if (dev->registered == 0) + return; + cpuidle_pause_and_lock(); cpuidle_disable_device(dev); --- linux-2.6.24.orig/drivers/s390/char/defkeymap.c +++ linux-2.6.24/drivers/s390/char/defkeymap.c @@ -151,8 +151,8 @@ }; struct kbdiacruc accent_table[MAX_DIACR] = { - {'^', 'c', '\003'}, {'^', 'd', '\004'}, - {'^', 'z', '\032'}, {'^', '\012', '\000'}, + {'^', 'c', 0003}, {'^', 'd', 0004}, + {'^', 'z', 0032}, {'^', 0012, 0000}, }; unsigned int accent_table_size = 4; --- linux-2.6.24.orig/drivers/ide/ide-cd.h +++ linux-2.6.24/drivers/ide/ide-cd.h @@ -15,7 +15,7 @@ memory, though. */ #ifndef VERBOSE_IDE_CD_ERRORS -#define VERBOSE_IDE_CD_ERRORS 1 +#define VERBOSE_IDE_CD_ERRORS 0 #endif --- linux-2.6.24.orig/drivers/ide/ide-cd.c +++ linux-2.6.24/drivers/ide/ide-cd.c @@ -2988,7 +2988,8 @@ if (strcmp(drive->id->model, "MATSHITADVD-ROM SR-8187") == 0 || strcmp(drive->id->model, "MATSHITADVD-ROM SR-8186") == 0 || strcmp(drive->id->model, "MATSHITADVD-ROM SR-8176") == 0 || - strcmp(drive->id->model, "MATSHITADVD-ROM SR-8174") == 0) + strcmp(drive->id->model, "MATSHITADVD-ROM SR-8174") == 0 || + strcmp(drive->id->model, "Optiarc DVD RW AD-5200A") == 0) CDROM_CONFIG_FLAGS(drive)->audio_play = 1; #if ! STANDARD_ATAPI --- linux-2.6.24.orig/drivers/ide/ppc/pmac.c +++ linux-2.6.24/drivers/ide/ppc/pmac.c @@ -1269,7 +1269,7 @@ int rc = 0; if (mesg.event != mdev->ofdev.dev.power.power_state.event - && mesg.event == PM_EVENT_SUSPEND) { + && (mesg.event & PM_EVENT_SLEEP)) { rc = pmac_ide_do_suspend(hwif); if (rc == 0) mdev->ofdev.dev.power.power_state = mesg; @@ -1374,7 +1374,7 @@ int rc = 0; if (mesg.event != pdev->dev.power.power_state.event - && mesg.event == PM_EVENT_SUSPEND) { + && (mesg.event & PM_EVENT_SLEEP)) { rc = pmac_ide_do_suspend(hwif); if (rc == 0) pdev->dev.power.power_state = mesg; --- linux-2.6.24.orig/net/bluetooth/hci_sysfs.c +++ linux-2.6.24/net/bluetooth/hci_sysfs.c @@ -12,6 +12,8 @@ #undef BT_DBG #define BT_DBG(D...) #endif +static struct workqueue_struct *btaddconn; +static struct workqueue_struct *btdelconn; static inline char *typetostr(int type) { @@ -279,6 +281,8 @@ struct hci_conn *conn = container_of(work, struct hci_conn, work); int i; + flush_workqueue(btdelconn); + if (device_add(&conn->dev) < 0) { BT_ERR("Failed to register connection device"); return; @@ -313,7 +317,7 @@ INIT_WORK(&conn->work, add_conn); - schedule_work(&conn->work); + queue_work(btaddconn, &conn->work); } static int __match_tty(struct device *dev, void *data) @@ -349,7 +353,7 @@ INIT_WORK(&conn->work, del_conn); - schedule_work(&conn->work); + queue_work(btdelconn, &conn->work); } int hci_register_sysfs(struct hci_dev *hdev) @@ -398,28 +402,54 @@ { int err; + btaddconn = create_singlethread_workqueue("btaddconn"); + if (!btaddconn) { + err = -ENOMEM; + goto out; + } + + btdelconn = create_singlethread_workqueue("btdelconn"); + if (!btdelconn) { + err = -ENOMEM; + goto out_del; + } + bt_platform = platform_device_register_simple("bluetooth", -1, NULL, 0); - if (IS_ERR(bt_platform)) - return PTR_ERR(bt_platform); + if (IS_ERR(bt_platform)) { + err = PTR_ERR(bt_platform); + goto out_platform; + } err = bus_register(&bt_bus); - if (err < 0) { - platform_device_unregister(bt_platform); - return err; - } + if (err < 0) + goto out_bus; bt_class = class_create(THIS_MODULE, "bluetooth"); if (IS_ERR(bt_class)) { - bus_unregister(&bt_bus); - platform_device_unregister(bt_platform); - return PTR_ERR(bt_class); + err = PTR_ERR(bt_class); + goto out_class; } return 0; + +out_class: + bus_unregister(&bt_bus); +out_bus: + platform_device_unregister(bt_platform); +out_platform: + destroy_workqueue(btdelconn); +out_del: + destroy_workqueue(btaddconn); +out: + return err; } void bt_sysfs_cleanup(void) { + destroy_workqueue(btaddconn); + + destroy_workqueue(btdelconn); + class_destroy(bt_class); bus_unregister(&bt_bus); --- linux-2.6.24.orig/net/bluetooth/sco.c +++ linux-2.6.24/net/bluetooth/sco.c @@ -53,7 +53,13 @@ #define BT_DBG(D...) #endif -#define VERSION "0.5" +#define VERSION "0.6" + +#define MAX_SCO_TXBUFS 200 +#define MAX_SCO_RXBUFS 200 + +#define DEFAULT_SCO_TXBUFS 5 +#define DEFAULT_SCO_RXBUFS 5 static const struct proto_ops sco_sock_ops; @@ -69,6 +75,33 @@ static void sco_sock_close(struct sock *sk); static void sco_sock_kill(struct sock *sk); +/* + * Write buffer destructor automatically called from kfree_skb. + */ +void sco_sock_wfree(struct sk_buff *skb) +{ + struct sock *sk = skb->sk; + + atomic_dec(&sk->sk_wmem_alloc); + sk->sk_write_space(sk); + sock_put(sk); +} + +static void sco_sock_write_space(struct sock *sk) +{ + read_lock(&sk->sk_callback_lock); + + if (atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) { + if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) + wake_up_interruptible(sk->sk_sleep); + + if (sock_writeable(sk)) + sk_wake_async(sk, 2, POLL_OUT); + } + + read_unlock(&sk->sk_callback_lock); +} + /* ---- SCO timers ---- */ static void sco_sock_timeout(unsigned long arg) { @@ -200,7 +233,11 @@ err = -ENOMEM; - type = lmp_esco_capable(hdev) ? ESCO_LINK : SCO_LINK; + /* + * Since eSCO seems currently broken, always use SCO (LP#39414). + * type = lmp_esco_capable(hdev) ? ESCO_LINK : SCO_LINK; + */ + type = SCO_LINK; hcon = hci_connect(hdev, type, dst); if (!hcon) @@ -237,33 +274,55 @@ { struct sco_conn *conn = sco_pi(sk)->conn; struct sk_buff *skb; - int err, count; - - /* Check outgoing MTU */ - if (len > conn->mtu) - return -EINVAL; + int err; BT_DBG("sk %p len %d", sk, len); - count = min_t(unsigned int, conn->mtu, len); - if (!(skb = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err))) + if (!(skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err))) return err; - if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) { + /* fix sk_wmem_alloc value : by default it is increased by skb->truesize, but + we want it only increased by 1 */ + atomic_sub(skb->truesize - 1, &sk->sk_wmem_alloc); + /* fix destructor */ + skb->destructor = sco_sock_wfree; + + if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { err = -EFAULT; goto fail; } - if ((err = hci_send_sco(conn->hcon, skb)) < 0) - return err; + err = hci_send_sco(conn->hcon, skb); + + if (err < 0) + goto fail; - return count; + return len; fail: kfree_skb(skb); return err; } +static int sco_sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) +{ + BT_DBG("sock %p, sk_rcvbuf %d, qlen %d", sk, sk->sk_rcvbuf, skb_queue_len(&sk->sk_receive_queue)); + + if (skb_queue_len(&sk->sk_receive_queue) + 1 > (unsigned)sk->sk_rcvbuf) + return -ENOMEM; + + skb->dev = NULL; + skb->sk = sk; + skb->destructor = NULL; + + skb_queue_tail(&sk->sk_receive_queue, skb); + + if (!sock_flag(sk, SOCK_DEAD)) + sk->sk_data_ready(sk, 1); + + return 0; +} + static inline void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb) { struct sock *sk = sco_chan_get(conn); @@ -276,7 +335,7 @@ if (sk->sk_state != BT_CONNECTED) goto drop; - if (!sock_queue_rcv_skb(sk, skb)) + if (!sco_sock_queue_rcv_skb(sk, skb)) return; drop: @@ -331,7 +390,6 @@ BT_DBG("sk %p", sk); skb_queue_purge(&sk->sk_receive_queue); - skb_queue_purge(&sk->sk_write_queue); } static void sco_sock_cleanup_listen(struct sock *parent) @@ -429,6 +487,10 @@ INIT_LIST_HEAD(&bt_sk(sk)->accept_q); sk->sk_destruct = sco_sock_destruct; + sk->sk_write_space = sco_sock_write_space; + + sk->sk_sndbuf = DEFAULT_SCO_TXBUFS; + sk->sk_rcvbuf = DEFAULT_SCO_RXBUFS; sk->sk_sndtimeo = SCO_CONN_TIMEOUT; sock_reset_flag(sk, SOCK_ZAPPED); @@ -659,6 +721,7 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) { struct sock *sk = sock->sk; + u32 opt; int err = 0; BT_DBG("sk %p", sk); @@ -666,6 +729,32 @@ lock_sock(sk); switch (optname) { + case SO_SNDBUF: + if (get_user(opt, (u32 __user *) optval)) { + err = -EFAULT; + break; + } + if (opt > MAX_SCO_TXBUFS) { + err = -EINVAL; + break; + } + + sk->sk_sndbuf = opt; + /* Wake up sending tasks if we upped the value */ + sk->sk_write_space(sk); + break; + case SO_RCVBUF: + if (get_user(opt, (u32 __user *) optval)) { + err = -EFAULT; + break; + } + if (opt > MAX_SCO_RXBUFS) { + err = -EINVAL; + break; + } + + sk->sk_rcvbuf = opt; + break; default: err = -ENOPROTOOPT; break; @@ -681,6 +770,7 @@ struct sco_options opts; struct sco_conninfo cinfo; int len, err = 0; + int val; BT_DBG("sk %p", sk); @@ -690,6 +780,24 @@ lock_sock(sk); switch (optname) { + case SO_RCVBUF: + val = sk->sk_rcvbuf; + + len = min_t(unsigned int, len, sizeof(val)); + if (copy_to_user(optval, (char *) &val, len)) + err = -EFAULT; + + break; + + case SO_SNDBUF: + val = sk->sk_sndbuf; + + len = min_t(unsigned int, len, sizeof(val)); + if (copy_to_user(optval, (char *) &val, len)) + err = -EFAULT; + + break; + case SCO_OPTIONS: if (sk->sk_state != BT_CONNECTED) { err = -ENOTCONN; @@ -701,7 +809,7 @@ BT_DBG("mtu %d", opts.mtu); len = min_t(unsigned int, len, sizeof(opts)); - if (copy_to_user(optval, (char *)&opts, len)) + if (copy_to_user(optval, (char *) &opts, len)) err = -EFAULT; break; @@ -716,7 +824,7 @@ memcpy(cinfo.dev_class, sco_pi(sk)->conn->hcon->dev_class, 3); len = min_t(unsigned int, len, sizeof(cinfo)); - if (copy_to_user(optval, (char *)&cinfo, len)) + if (copy_to_user(optval, (char *) &cinfo, len)) err = -EFAULT; break; --- linux-2.6.24.orig/net/bluetooth/hci_core.c +++ linux-2.6.24/net/bluetooth/hci_core.c @@ -624,7 +624,8 @@ hdev->flush(hdev); atomic_set(&hdev->cmd_cnt, 1); - hdev->acl_cnt = 0; hdev->sco_cnt = 0; + atomic_set(&hdev->sco_cnt, 0); + hdev->acl_cnt = 0; if (!test_bit(HCI_RAW, &hdev->flags)) ret = __hci_request(hdev, hci_reset_req, 0, @@ -901,8 +902,6 @@ BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); - hci_unregister_sysfs(hdev); - write_lock_bh(&hci_dev_list_lock); list_del(&hdev->list); write_unlock_bh(&hci_dev_list_lock); @@ -914,6 +913,8 @@ hci_notify(hdev, HCI_DEV_UNREG); + hci_unregister_sysfs(hdev); + __hci_dev_put(hdev); return 0; @@ -1230,6 +1231,7 @@ { struct hci_dev *hdev = conn->hdev; struct hci_sco_hdr hdr; + ktime_t now; BT_DBG("%s len %d", hdev->name, skb->len); @@ -1238,6 +1240,13 @@ return -EINVAL; } + now = conn->tx_timer.base->get_time(); + + /* force a clean start for 100 ms or later underrun */ + if (conn->tx_timer.expires.tv64 + NSEC_PER_SEC / 10 <= now.tv64) { + conn->tx_timer.expires = now; + } + hdr.handle = cpu_to_le16(conn->handle); hdr.dlen = skb->len; @@ -1255,12 +1264,12 @@ /* ---- HCI TX task (outgoing data) ---- */ -/* HCI Connection scheduler */ -static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote) +/* HCI ACL Connection scheduler */ +static inline struct hci_conn *hci_low_sent_acl(struct hci_dev *hdev, int *quote) { struct hci_conn_hash *h = &hdev->conn_hash; struct hci_conn *conn = NULL; - int num = 0, min = ~0; + unsigned int num = 0, min = ~0; struct list_head *p; /* We don't have to lock device here. Connections are always @@ -1269,20 +1278,22 @@ struct hci_conn *c; c = list_entry(p, struct hci_conn, list); - if (c->type != type || c->state != BT_CONNECTED + BT_DBG("c->type %d c->state %d len(c->data_q) %d min %d c->sent %d", + c->type, c->state, skb_queue_len(&c->data_q), min, atomic_read(&c->sent)); + + if (c->type != ACL_LINK || c->state != BT_CONNECTED || skb_queue_empty(&c->data_q)) continue; num++; - if (c->sent < min) { - min = c->sent; + if (atomic_read(&c->sent) < min) { + min = atomic_read(&c->sent); conn = c; } } if (conn) { - int cnt = (type == ACL_LINK ? hdev->acl_cnt : hdev->sco_cnt); - int q = cnt / num; + int q = hdev->acl_cnt / num; *quote = q ? q : 1; } else *quote = 0; @@ -1302,7 +1313,7 @@ /* Kill stalled connections */ list_for_each(p, &h->list) { c = list_entry(p, struct hci_conn, list); - if (c->type == ACL_LINK && c->sent) { + if (c->type == ACL_LINK && atomic_read(&c->sent)) { BT_ERR("%s killing stalled ACL connection %s", hdev->name, batostr(&c->dst)); hci_acl_disconn(c, 0x13); @@ -1325,7 +1336,7 @@ hci_acl_tx_to(hdev); } - while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, "e))) { + while (hdev->acl_cnt && (conn = hci_low_sent_acl(hdev, "e))) { while (quote-- && (skb = skb_dequeue(&conn->data_q))) { BT_DBG("skb %p len %d", skb, skb->len); @@ -1335,48 +1346,61 @@ hdev->acl_last_tx = jiffies; hdev->acl_cnt--; - conn->sent++; + atomic_inc(&conn->sent); } } } -/* Schedule SCO */ +/* HCI SCO Connection scheduler */ + static inline void hci_sched_sco(struct hci_dev *hdev) { - struct hci_conn *conn; + struct hci_conn_hash *h = &hdev->conn_hash; struct sk_buff *skb; - int quote; - + struct list_head *p; + struct hci_conn *c; + ktime_t now, pkt_time; + BT_DBG("%s", hdev->name); + + /* We don't have to lock device here. Connections are always + added and removed with TX task disabled. */ + list_for_each(p, &h->list) { + c = list_entry(p, struct hci_conn, list); + + /* SCO scheduling algorithm makes sure there is never more than + 1 outstanding packet for each connection */ - while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { - while (quote-- && (skb = skb_dequeue(&conn->data_q))) { - BT_DBG("skb %p len %d", skb, skb->len); - hci_send_frame(skb); + if (c->type == ACL_LINK) + continue; - conn->sent++; - if (conn->sent == ~0) - conn->sent = 0; - } - } -} + if (atomic_read(&c->sent) >= 1) + continue; -static inline void hci_sched_esco(struct hci_dev *hdev) -{ - struct hci_conn *conn; - struct sk_buff *skb; - int quote; + if (c->state != BT_CONNECTED) + continue; - BT_DBG("%s", hdev->name); + if (atomic_read(&hdev->sco_cnt) <= 0) + continue; - while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, "e))) { - while (quote-- && (skb = skb_dequeue(&conn->data_q))) { - BT_DBG("skb %p len %d", skb, skb->len); - hci_send_frame(skb); + if ((skb = skb_dequeue(&c->data_q)) == NULL) + continue; - conn->sent++; - if (conn->sent == ~0) - conn->sent = 0; + hci_send_frame(skb); + + atomic_inc(&c->sent); + atomic_dec(&hdev->sco_cnt); + + pkt_time = ktime_set(0, NSEC_PER_SEC / 16000 * (skb->len - HCI_SCO_HDR_SIZE)); + now = c->tx_timer.base->get_time(); + + c->tx_timer.expires.tv64 += pkt_time.tv64; + if (c->tx_timer.expires.tv64 > now.tv64) { + hrtimer_restart(&c->tx_timer); + } else { + /* Timer is to expire in the past - force timer expiration. + this can happen if timer base precision is less than pkt_time */ + c->tx_timer.function(&c->tx_timer); } } } @@ -1388,15 +1412,13 @@ read_lock(&hci_task_lock); - BT_DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, hdev->sco_cnt); + BT_DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, atomic_read(&hdev->sco_cnt)); /* Schedule queues and send stuff to HCI driver */ - hci_sched_acl(hdev); - hci_sched_sco(hdev); - hci_sched_esco(hdev); + hci_sched_acl(hdev); /* Send next queued raw (unknown type) packet */ while ((skb = skb_dequeue(&hdev->raw_q))) --- linux-2.6.24.orig/net/bluetooth/hci_event.c +++ linux-2.6.24/net/bluetooth/hci_event.c @@ -434,7 +434,7 @@ } hdev->acl_cnt = hdev->acl_pkts; - hdev->sco_cnt = hdev->sco_pkts; + atomic_set(&hdev->sco_cnt, hdev->sco_pkts); BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu, hdev->acl_pkts, @@ -1157,14 +1157,11 @@ conn = hci_conn_hash_lookup_handle(hdev, handle); if (conn) { - conn->sent -= count; + atomic_sub(count, &conn->sent); if (conn->type == ACL_LINK) { if ((hdev->acl_cnt += count) > hdev->acl_pkts) hdev->acl_cnt = hdev->acl_pkts; - } else { - if ((hdev->sco_cnt += count) > hdev->sco_pkts) - hdev->sco_cnt = hdev->sco_pkts; } } } --- linux-2.6.24.orig/net/bluetooth/hci_conn.c +++ linux-2.6.24/net/bluetooth/hci_conn.c @@ -188,6 +188,26 @@ hci_conn_enter_sniff_mode(conn); } +static enum hrtimer_restart hci_sco_tx_timer(struct hrtimer *timer) +{ + struct hci_conn *conn = container_of(timer, struct hci_conn, tx_timer); +#ifdef CONFIG_BT_HCI_CORE_DEBUG + ktime_t now = timer->base->get_time(); + + BT_DBG("%s, conn %p, time %5lu.%06lu", conn->hdev->name, conn, + (unsigned long) now.tv64, + do_div(now.tv64, NSEC_PER_SEC) / 1000); +#endif + + if (atomic_read(&conn->sent) > 0) { + atomic_dec(&conn->sent); + atomic_inc(&conn->hdev->sco_cnt); + hci_sched_tx(conn->hdev); + } + return HRTIMER_NORESTART; +} + + struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) { struct hci_conn *conn; @@ -208,6 +228,11 @@ skb_queue_head_init(&conn->data_q); + hrtimer_init(&conn->tx_timer, CLOCK_MONOTONIC, HRTIMER_NORESTART); + + if(type == SCO_LINK) + conn->tx_timer.function = hci_sco_tx_timer; + init_timer(&conn->disc_timer); conn->disc_timer.function = hci_conn_timeout; conn->disc_timer.data = (unsigned long) conn; @@ -217,6 +242,7 @@ conn->idle_timer.data = (unsigned long) conn; atomic_set(&conn->refcnt, 0); + atomic_set(&conn->sent, 0); hci_dev_hold(hdev); @@ -243,13 +269,15 @@ del_timer(&conn->disc_timer); + hrtimer_cancel(&conn->tx_timer); + if (conn->type == ACL_LINK) { struct hci_conn *sco = conn->link; if (sco) sco->link = NULL; /* Unacked frames */ - hdev->acl_cnt += conn->sent; + hdev->acl_cnt += atomic_read(&conn->sent); } else { struct hci_conn *acl = conn->link; if (acl) { --- linux-2.6.24.orig/net/bluetooth/hidp/core.c +++ linux-2.6.24/net/bluetooth/hidp/core.c @@ -592,6 +592,12 @@ hid_free_device(session->hid); } + /* Wakeup user-space polling for socket errors */ + session->intr_sock->sk->sk_err = EUNATCH; + session->ctrl_sock->sk->sk_err = EUNATCH; + + hidp_schedule(session); + fput(session->intr_sock->file); wait_event_timeout(*(ctrl_sk->sk_sleep), @@ -688,6 +694,8 @@ } hidp_blacklist[] = { /* Apple wireless Mighty Mouse */ { 0x05ac, 0x030c, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL }, + /* Apple Wireless Aluminum Keyboard */ + { 0x05ac, 0x022c, HID_QUIRK_APPLE_HAS_FN }, { } /* Terminating entry */ }; @@ -891,6 +899,10 @@ skb_queue_purge(&session->ctrl_transmit); skb_queue_purge(&session->intr_transmit); + /* Wakeup user-space polling for socket errors */ + session->intr_sock->sk->sk_err = EUNATCH; + session->ctrl_sock->sk->sk_err = EUNATCH; + /* Kill session thread */ atomic_inc(&session->terminate); hidp_schedule(session); --- linux-2.6.24.orig/net/dccp/feat.c +++ linux-2.6.24/net/dccp/feat.c @@ -30,7 +30,7 @@ } if (!dccp_feat_is_valid_length(type, feature, len)) { DCCP_WARN("invalid length %d\n", len); - return 1; + return -EINVAL; } /* XXX add further sanity checks */ --- linux-2.6.24.orig/net/dccp/proto.c +++ linux-2.6.24/net/dccp/proto.c @@ -458,6 +458,11 @@ if (copy_from_user(&opt, optval, sizeof(opt))) return -EFAULT; + /* + * rfc4340: 6.1. Change Options + */ + if (opt.dccpsf_len < 1) + return -EINVAL; val = kmalloc(opt.dccpsf_len, GFP_KERNEL); if (!val) --- linux-2.6.24.orig/net/rfkill/rfkill-input.c +++ linux-2.6.24/net/rfkill/rfkill-input.c @@ -84,6 +84,7 @@ static DEFINE_RFKILL_TASK(rfkill_wlan, RFKILL_TYPE_WLAN); static DEFINE_RFKILL_TASK(rfkill_bt, RFKILL_TYPE_BLUETOOTH); static DEFINE_RFKILL_TASK(rfkill_uwb, RFKILL_TYPE_UWB); +static DEFINE_RFKILL_TASK(rfkill_wimax, RFKILL_TYPE_WIMAX); static void rfkill_event(struct input_handle *handle, unsigned int type, unsigned int code, int down) @@ -99,6 +100,9 @@ case KEY_UWB: rfkill_schedule_toggle(&rfkill_uwb); break; + case KEY_WIMAX: + rfkill_schedule_toggle(&rfkill_wimax); + break; default: break; } @@ -159,6 +163,11 @@ .evbit = { BIT_MASK(EV_KEY) }, .keybit = { [BIT_WORD(KEY_UWB)] = BIT_MASK(KEY_UWB) }, }, + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, + .evbit = { BIT_MASK(EV_KEY) }, + .keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) }, + }, { } }; --- linux-2.6.24.orig/net/rfkill/rfkill.c +++ linux-2.6.24/net/rfkill/rfkill.c @@ -126,6 +126,9 @@ case RFKILL_TYPE_UWB: type = "ultrawideband"; break; + case RFKILL_TYPE_WIMAX: + type = "wimax"; + break; default: BUG(); } @@ -229,7 +232,7 @@ struct rfkill *rfkill = to_rfkill(dev); if (dev->power.power_state.event != state.event) { - if (state.event == PM_EVENT_SUSPEND) { + if (state.event & PM_EVENT_SLEEP) { mutex_lock(&rfkill->mutex); if (rfkill->state == RFKILL_STATE_ON) --- linux-2.6.24.orig/net/core/netpoll.c +++ linux-2.6.24/net/core/netpoll.c @@ -219,10 +219,12 @@ while (clist != NULL) { struct sk_buff *skb = clist; clist = clist->next; - if (skb->destructor) + if (skb->destructor) { + atomic_inc(&skb->users); dev_kfree_skb_any(skb); /* put this one back */ - else + } else { __kfree_skb(skb); + } } } --- linux-2.6.24.orig/net/core/scm.c +++ linux-2.6.24/net/core/scm.c @@ -75,6 +75,7 @@ if (!fpl) return -ENOMEM; *fplp = fpl; + INIT_LIST_HEAD(&fpl->list); fpl->count = 0; } fpp = &fpl->fp[fpl->count]; @@ -106,9 +107,25 @@ if (fpl) { scm->fp = NULL; - for (i=fpl->count-1; i>=0; i--) - fput(fpl->fp[i]); - kfree(fpl); + if (current->scm_work_list) { + list_add_tail(&fpl->list, current->scm_work_list); + } else { + LIST_HEAD(work_list); + + current->scm_work_list = &work_list; + + list_add(&fpl->list, &work_list); + while (!list_empty(&work_list)) { + fpl = list_first_entry(&work_list, struct scm_fp_list, list); + + list_del(&fpl->list); + for (i=fpl->count-1; i>=0; i--) + fput(fpl->fp[i]); + kfree(fpl); + } + + current->scm_work_list = NULL; + } } } @@ -284,6 +301,7 @@ new_fpl = kmalloc(sizeof(*fpl), GFP_KERNEL); if (new_fpl) { + INIT_LIST_HEAD(&new_fpl->list); for (i=fpl->count-1; i>=0; i--) get_file(fpl->fp[i]); memcpy(new_fpl, fpl, sizeof(*fpl)); --- linux-2.6.24.orig/net/core/skbuff.c +++ linux-2.6.24/net/core/skbuff.c @@ -2215,6 +2215,34 @@ return elt; } +/** + * skb_partial_csum_set - set up and verify partial csum values for packet + * @skb: the skb to set + * @start: the number of bytes after skb->data to start checksumming. + * @off: the offset from start to place the checksum. + * + * For untrusted partially-checksummed packets, we need to make sure the values + * for skb->csum_start and skb->csum_offset are valid so we don't oops. + * + * This function checks and sets those values and skb->ip_summed: if this + * returns false you should drop the packet. + */ +bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off) +{ + if (unlikely(start > skb->len - 2) || + unlikely((int)start + off > skb->len - 2)) { + if (net_ratelimit()) + printk(KERN_WARNING + "bad partial csum: csum=%u/%u len=%u\n", + start, off, skb->len); + return false; + } + skb->ip_summed = CHECKSUM_PARTIAL; + skb->csum_start = skb_headroom(skb) + start; + skb->csum_offset = off; + return true; +} + EXPORT_SYMBOL(___pskb_trim); EXPORT_SYMBOL(__kfree_skb); EXPORT_SYMBOL(kfree_skb); @@ -2251,3 +2279,4 @@ EXPORT_SYMBOL_GPL(skb_to_sgvec); EXPORT_SYMBOL_GPL(skb_cow_data); +EXPORT_SYMBOL_GPL(skb_partial_csum_set); --- linux-2.6.24.orig/net/core/dev.c +++ linux-2.6.24/net/core/dev.c @@ -1068,8 +1068,6 @@ */ call_netdevice_notifiers(NETDEV_GOING_DOWN, dev); - dev_deactivate(dev); - clear_bit(__LINK_STATE_START, &dev->state); /* Synchronize to scheduled poll. We cannot touch poll list, @@ -1080,6 +1078,8 @@ */ smp_mb__after_clear_bit(); /* Commit netif_running(). */ + dev_deactivate(dev); + /* * Call the device specific close. This cannot fail. * Only if device is UP @@ -2906,7 +2906,7 @@ } } - da = kmalloc(sizeof(*da), GFP_ATOMIC); + da = kzalloc(sizeof(*da), GFP_ATOMIC); if (da == NULL) return -ENOMEM; memcpy(da->da_addr, addr, alen); @@ -3240,7 +3240,7 @@ return -EOPNOTSUPP; case SIOCADDMULTI: - if (!dev->set_multicast_list || + if ((!dev->set_multicast_list && !dev->set_rx_mode) || ifr->ifr_hwaddr.sa_family != AF_UNSPEC) return -EINVAL; if (!netif_device_present(dev)) @@ -3249,7 +3249,7 @@ dev->addr_len, 1); case SIOCDELMULTI: - if (!dev->set_multicast_list || + if ((!dev->set_multicast_list && !dev->set_rx_mode) || ifr->ifr_hwaddr.sa_family != AF_UNSPEC) return -EINVAL; if (!netif_device_present(dev)) --- linux-2.6.24.orig/net/netfilter/nfnetlink_log.c +++ linux-2.6.24/net/netfilter/nfnetlink_log.c @@ -594,7 +594,7 @@ /* FIXME: do we want to make the size calculation conditional based on * what is actually present? way more branches and checks, but more * memory efficient... */ - size = NLMSG_ALIGN(sizeof(struct nfgenmsg)) + size = NLMSG_SPACE(sizeof(struct nfgenmsg)) + nla_total_size(sizeof(struct nfulnl_msg_packet_hdr)) + nla_total_size(sizeof(u_int32_t)) /* ifindex */ + nla_total_size(sizeof(u_int32_t)) /* ifindex */ --- linux-2.6.24.orig/net/netfilter/xt_time.c +++ linux-2.6.24/net/netfilter/xt_time.c @@ -95,8 +95,11 @@ */ r->dse = time / 86400; - /* 1970-01-01 (w=0) was a Thursday (4). */ - r->weekday = (4 + r->dse) % 7; + /* + * 1970-01-01 (w=0) was a Thursday (4). + * -1 and +1 map Sunday properly onto 7. + */ + r->weekday = (4 + r->dse - 1) % 7 + 1; } static void localtime_3(struct xtm *r, time_t time) --- linux-2.6.24.orig/net/netfilter/nfnetlink_queue.c +++ linux-2.6.24/net/netfilter/nfnetlink_queue.c @@ -353,7 +353,7 @@ QDEBUG("entered\n"); - size = NLMSG_ALIGN(sizeof(struct nfgenmsg)) + size = NLMSG_SPACE(sizeof(struct nfgenmsg)) + nla_total_size(sizeof(struct nfqnl_msg_packet_hdr)) + nla_total_size(sizeof(u_int32_t)) /* ifindex */ + nla_total_size(sizeof(u_int32_t)) /* ifindex */ @@ -616,8 +616,8 @@ static int nfqnl_mangle(void *data, int data_len, struct nfqnl_queue_entry *e) { + struct sk_buff *nskb; int diff; - int err; diff = data_len - e->skb->len; if (diff < 0) { @@ -627,14 +627,16 @@ if (data_len > 0xFFFF) return -EINVAL; if (diff > skb_tailroom(e->skb)) { - err = pskb_expand_head(e->skb, 0, + nskb = skb_copy_expand(e->skb, 0, diff - skb_tailroom(e->skb), GFP_ATOMIC); - if (err) { + if (!nskb) { printk(KERN_WARNING "nf_queue: OOM " "in mangle, dropping packet\n"); - return err; + return -ENOMEM; } + kfree_skb(e->skb); + e->skb = nskb; } skb_put(e->skb, diff); } --- linux-2.6.24.orig/net/netfilter/nf_conntrack_proto_tcp.c +++ linux-2.6.24/net/netfilter/nf_conntrack_proto_tcp.c @@ -135,7 +135,7 @@ * CLOSE_WAIT: ACK seen (after FIN) * LAST_ACK: FIN seen (after FIN) * TIME_WAIT: last ACK seen - * CLOSE: closed connection + * CLOSE: closed connection (RST) * * LISTEN state is not used. * @@ -834,8 +834,21 @@ case TCP_CONNTRACK_SYN_SENT: if (old_state < TCP_CONNTRACK_TIME_WAIT) break; - if ((conntrack->proto.tcp.seen[!dir].flags & - IP_CT_TCP_FLAG_CLOSE_INIT) + /* RFC 1122: "When a connection is closed actively, + * it MUST linger in TIME-WAIT state for a time 2xMSL + * (Maximum Segment Lifetime). However, it MAY accept + * a new SYN from the remote TCP to reopen the connection + * directly from TIME-WAIT state, if..." + * We ignore the conditions because we are in the + * TIME-WAIT state anyway. + * + * Handle aborted connections: we and the server + * think there is an existing connection but the client + * aborts it and starts a new one. + */ + if (((conntrack->proto.tcp.seen[dir].flags + | conntrack->proto.tcp.seen[!dir].flags) + & IP_CT_TCP_FLAG_CLOSE_INIT) || (conntrack->proto.tcp.last_dir == dir && conntrack->proto.tcp.last_index == TCP_RST_SET)) { /* Attempt to reopen a closed/aborted connection. @@ -848,18 +861,25 @@ } /* Fall through */ case TCP_CONNTRACK_IGNORE: - /* Ignored packets: + /* Ignored packets: + * + * Our connection entry may be out of sync, so ignore + * packets which may signal the real connection between + * the client and the server. * * a) SYN in ORIGINAL * b) SYN/ACK in REPLY * c) ACK in reply direction after initial SYN in original. + * + * If the ignored packet is invalid, the receiver will send + * a RST we'll catch below. */ if (index == TCP_SYNACK_SET && conntrack->proto.tcp.last_index == TCP_SYN_SET && conntrack->proto.tcp.last_dir != dir && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) { - /* This SYN/ACK acknowledges a SYN that we earlier + /* b) This SYN/ACK acknowledges a SYN that we earlier * ignored as invalid. This means that the client and * the server are both in sync, while the firewall is * not. We kill this session and block the SYN/ACK so @@ -884,7 +904,7 @@ write_unlock_bh(&tcp_lock); if (LOG_INVALID(IPPROTO_TCP)) nf_log_packet(pf, 0, skb, NULL, NULL, NULL, - "nf_ct_tcp: invalid packed ignored "); + "nf_ct_tcp: invalid packet ignored "); return NF_ACCEPT; case TCP_CONNTRACK_MAX: /* Invalid packet */ @@ -938,8 +958,7 @@ conntrack->proto.tcp.state = new_state; if (old_state != new_state - && (new_state == TCP_CONNTRACK_FIN_WAIT - || new_state == TCP_CONNTRACK_CLOSE)) + && new_state == TCP_CONNTRACK_FIN_WAIT) conntrack->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT; timeout = conntrack->proto.tcp.retrans >= nf_ct_tcp_max_retrans && *tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans --- linux-2.6.24.orig/net/sched/sch_htb.c +++ linux-2.6.24/net/sched/sch_htb.c @@ -708,9 +708,11 @@ */ static psched_time_t htb_do_events(struct htb_sched *q, int level) { - int i; - - for (i = 0; i < 500; i++) { + /* don't run for longer than 2 jiffies; 2 is used instead of + 1 to simplify things when jiffy is going to be incremented + too soon */ + unsigned long stop_at = jiffies + 2; + while (time_before(jiffies, stop_at)) { struct htb_class *cl; long diff; struct rb_node *p = rb_first(&q->wait_pq[level]); @@ -728,9 +730,8 @@ if (cl->cmode != HTB_CAN_SEND) htb_add_to_wait_tree(q, cl, diff); } - if (net_ratelimit()) - printk(KERN_WARNING "htb: too many events !\n"); - return q->now + PSCHED_TICKS_PER_SEC / 10; + /* too much load - let's continue on next jiffie */ + return q->now + PSCHED_TICKS_PER_SEC / HZ; } /* Returns class->node+prio from id-tree where classe's id is >= id. NULL --- linux-2.6.24.orig/net/sched/sch_generic.c +++ linux-2.6.24/net/sched/sch_generic.c @@ -178,10 +178,22 @@ void __qdisc_run(struct net_device *dev) { - do { - if (!qdisc_restart(dev)) + unsigned long start_time = jiffies; + + while (qdisc_restart(dev)) { + if (netif_queue_stopped(dev)) + break; + + /* + * Postpone processing if + * 1. another process needs the CPU; + * 2. we've been doing it for too long. + */ + if (need_resched() || jiffies != start_time) { + netif_schedule(dev); break; - } while (!netif_queue_stopped(dev)); + } + } clear_bit(__LINK_STATE_QDISC_RUNNING, &dev->state); } --- linux-2.6.24.orig/net/sched/em_meta.c +++ linux-2.6.24/net/sched/em_meta.c @@ -719,11 +719,13 @@ static inline void meta_delete(struct meta_match *meta) { - struct meta_type_ops *ops = meta_type_ops(&meta->lvalue); + if (meta) { + struct meta_type_ops *ops = meta_type_ops(&meta->lvalue); - if (ops && ops->destroy) { - ops->destroy(&meta->lvalue); - ops->destroy(&meta->rvalue); + if (ops && ops->destroy) { + ops->destroy(&meta->lvalue); + ops->destroy(&meta->rvalue); + } } kfree(meta); --- linux-2.6.24.orig/net/sched/ematch.c +++ linux-2.6.24/net/sched/ematch.c @@ -305,10 +305,9 @@ struct tcf_ematch_tree_hdr *tree_hdr; struct tcf_ematch *em; - if (!rta) { - memset(tree, 0, sizeof(*tree)); + memset(tree, 0, sizeof(*tree)); + if (!rta) return 0; - } if (rtattr_parse_nested(tb, TCA_EMATCH_TREE_MAX, rta) < 0) goto errout; --- linux-2.6.24.orig/net/sctp/bind_addr.c +++ linux-2.6.24/net/sctp/bind_addr.c @@ -209,6 +209,7 @@ int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr) { struct sctp_sockaddr_entry *addr, *temp; + int found = 0; /* We hold the socket lock when calling this function, * and that acts as a writer synchronizing lock. @@ -216,13 +217,14 @@ list_for_each_entry_safe(addr, temp, &bp->address_list, list) { if (sctp_cmp_addr_exact(&addr->a, del_addr)) { /* Found the exact match. */ + found = 1; addr->valid = 0; list_del_rcu(&addr->list); break; } } - if (addr && !addr->valid) { + if (found) { call_rcu(&addr->rcu, sctp_local_addr_free); SCTP_DBG_OBJCNT_DEC(addr); return 0; --- linux-2.6.24.orig/net/sctp/auth.c +++ linux-2.6.24/net/sctp/auth.c @@ -80,6 +80,10 @@ { struct sctp_auth_bytes *key; + /* Verify that we are not going to overflow INT_MAX */ + if ((INT_MAX - key_len) < sizeof(struct sctp_auth_bytes)) + return NULL; + /* Allocate the shared key */ key = kmalloc(sizeof(struct sctp_auth_bytes) + key_len, gfp); if (!key) @@ -782,6 +786,9 @@ for (i = 0; i < hmacs->shmac_num_idents; i++) { id = hmacs->shmac_idents[i]; + if (id > SCTP_AUTH_HMAC_ID_MAX) + return -EOPNOTSUPP; + if (SCTP_AUTH_HMAC_ID_SHA1 == id) has_sha1 = 1; --- linux-2.6.24.orig/net/sctp/sm_statefuns.c +++ linux-2.6.24/net/sctp/sm_statefuns.c @@ -121,7 +121,7 @@ const struct sctp_endpoint *ep, const struct sctp_association *asoc, const sctp_subtype_t type, - void *arg, + void *arg, void *ext, sctp_cmd_seq_t *commands); static sctp_disposition_t sctp_sf_violation_ctsn( @@ -3388,7 +3388,7 @@ addr_param = (union sctp_addr_param *)hdr->params; length = ntohs(addr_param->p.length); if (length < sizeof(sctp_paramhdr_t)) - return sctp_sf_violation_paramlen(ep, asoc, type, + return sctp_sf_violation_paramlen(ep, asoc, type, arg, (void *)addr_param, commands); /* Verify the ASCONF chunk before processing it. */ @@ -3396,8 +3396,8 @@ (sctp_paramhdr_t *)((void *)addr_param + length), (void *)chunk->chunk_end, &err_param)) - return sctp_sf_violation_paramlen(ep, asoc, type, - (void *)&err_param, commands); + return sctp_sf_violation_paramlen(ep, asoc, type, arg, + (void *)err_param, commands); /* ADDIP 4.2 C1) Compare the value of the serial number to the value * the endpoint stored in a new association variable @@ -3476,8 +3476,8 @@ (sctp_paramhdr_t *)addip_hdr->params, (void *)asconf_ack->chunk_end, &err_param)) - return sctp_sf_violation_paramlen(ep, asoc, type, - (void *)&err_param, commands); + return sctp_sf_violation_paramlen(ep, asoc, type, arg, + (void *)err_param, commands); if (last_asconf) { addip_hdr = (sctp_addiphdr_t *)last_asconf->subh.addip_hdr; @@ -4152,12 +4152,38 @@ const struct sctp_endpoint *ep, const struct sctp_association *asoc, const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) { - char err_str[] = "The following parameter had invalid length:"; + void *arg, void *ext, + sctp_cmd_seq_t *commands) +{ + struct sctp_chunk *chunk = arg; + struct sctp_paramhdr *param = ext; + struct sctp_chunk *abort = NULL; - return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str, - sizeof(err_str)); + if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc)) + goto discard; + + /* Make the abort chunk. */ + abort = sctp_make_violation_paramlen(asoc, chunk, param); + if (!abort) + goto nomem; + + sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); + SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); + + sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, + SCTP_ERROR(ECONNABORTED)); + sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, + SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION)); + SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); + +discard: + sctp_sf_pdiscard(ep, asoc, SCTP_ST_CHUNK(0), arg, commands); + + SCTP_INC_STATS(SCTP_MIB_ABORTEDS); + + return SCTP_DISPOSITION_ABORT; +nomem: + return SCTP_DISPOSITION_NOMEM; } /* Handle a protocol violation when the peer trying to advance the --- linux-2.6.24.orig/net/sctp/endpointola.c +++ linux-2.6.24/net/sctp/endpointola.c @@ -107,6 +107,7 @@ /* Initialize the CHUNKS parameter */ auth_chunks->param_hdr.type = SCTP_PARAM_CHUNKS; + auth_chunks->param_hdr.length = htons(sizeof(sctp_paramhdr_t)); /* If the Add-IP functionality is enabled, we must * authenticate, ASCONF and ASCONF-ACK chunks @@ -114,8 +115,7 @@ if (sctp_addip_enable) { auth_chunks->chunks[0] = SCTP_CID_ASCONF; auth_chunks->chunks[1] = SCTP_CID_ASCONF_ACK; - auth_chunks->param_hdr.length = - htons(sizeof(sctp_paramhdr_t) + 2); + auth_chunks->param_hdr.length += htons(2); } } --- linux-2.6.24.orig/net/sctp/ipv6.c +++ linux-2.6.24/net/sctp/ipv6.c @@ -89,6 +89,7 @@ struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr; struct sctp_sockaddr_entry *addr = NULL; struct sctp_sockaddr_entry *temp; + int found = 0; switch (ev) { case NETDEV_UP: @@ -111,13 +112,14 @@ &sctp_local_addr_list, list) { if (ipv6_addr_equal(&addr->a.v6.sin6_addr, &ifa->addr)) { + found = 1; addr->valid = 0; list_del_rcu(&addr->list); break; } } spin_unlock_bh(&sctp_local_addr_lock); - if (addr && !addr->valid) + if (found) call_rcu(&addr->rcu, sctp_local_addr_free); break; } @@ -889,6 +891,10 @@ dev = dev_get_by_index(&init_net, addr->v6.sin6_scope_id); if (!dev) return 0; + if (!ipv6_chk_addr(&addr->v6.sin6_addr, dev, 0)) { + dev_put(dev); + return 0; + } dev_put(dev); } af = opt->pf->af; --- linux-2.6.24.orig/net/sctp/socket.c +++ linux-2.6.24/net/sctp/socket.c @@ -2959,6 +2959,9 @@ { struct sctp_authchunk val; + if (!sctp_auth_enable) + return -EACCES; + if (optlen != sizeof(struct sctp_authchunk)) return -EINVAL; if (copy_from_user(&val, optval, optlen)) @@ -2987,8 +2990,12 @@ int optlen) { struct sctp_hmacalgo *hmacs; + u32 idents; int err; + if (!sctp_auth_enable) + return -EACCES; + if (optlen < sizeof(struct sctp_hmacalgo)) return -EINVAL; @@ -3001,8 +3008,9 @@ goto out; } - if (hmacs->shmac_num_idents == 0 || - hmacs->shmac_num_idents > SCTP_AUTH_NUM_HMACS) { + idents = hmacs->shmac_num_idents; + if (idents == 0 || idents > SCTP_AUTH_NUM_HMACS || + (idents * sizeof(u16)) > (optlen - sizeof(struct sctp_hmacalgo))) { err = -EINVAL; goto out; } @@ -3027,6 +3035,9 @@ struct sctp_association *asoc; int ret; + if (!sctp_auth_enable) + return -EACCES; + if (optlen <= sizeof(struct sctp_authkey)) return -EINVAL; @@ -3039,6 +3050,11 @@ goto out; } + if (authkey->sca_keylen > optlen) { + ret = -EINVAL; + goto out; + } + asoc = sctp_id2assoc(sk, authkey->sca_assoc_id); if (!asoc && authkey->sca_assoc_id && sctp_style(sk, UDP)) { ret = -EINVAL; @@ -3064,6 +3080,9 @@ struct sctp_authkeyid val; struct sctp_association *asoc; + if (!sctp_auth_enable) + return -EACCES; + if (optlen != sizeof(struct sctp_authkeyid)) return -EINVAL; if (copy_from_user(&val, optval, optlen)) @@ -3089,6 +3108,9 @@ struct sctp_authkeyid val; struct sctp_association *asoc; + if (!sctp_auth_enable) + return -EACCES; + if (optlen != sizeof(struct sctp_authkeyid)) return -EINVAL; if (copy_from_user(&val, optval, optlen)) @@ -4391,7 +4413,9 @@ if (copy_from_user(&getaddrs, optval, len)) return -EFAULT; - if (getaddrs.addr_num <= 0) return -EINVAL; + if (getaddrs.addr_num <= 0 || + getaddrs.addr_num >= (INT_MAX / sizeof(union sctp_addr))) + return -EINVAL; /* * For UDP-style sockets, id specifies the association to query. * If the id field is set to the value '0' then the locally bound @@ -5016,19 +5040,29 @@ static int sctp_getsockopt_hmac_ident(struct sock *sk, int len, char __user *optval, int __user *optlen) { + struct sctp_hmacalgo __user *p = (void __user *)optval; struct sctp_hmac_algo_param *hmacs; - __u16 param_len; + __u16 data_len = 0; + u32 num_idents; + + if (!sctp_auth_enable) + return -EACCES; hmacs = sctp_sk(sk)->ep->auth_hmacs_list; - param_len = ntohs(hmacs->param_hdr.length); + data_len = ntohs(hmacs->param_hdr.length) - sizeof(sctp_paramhdr_t); - if (len < param_len) + if (len < sizeof(struct sctp_hmacalgo) + data_len) return -EINVAL; + + len = sizeof(struct sctp_hmacalgo) + data_len; + num_idents = data_len / sizeof(u16); + if (put_user(len, optlen)) return -EFAULT; - if (copy_to_user(optval, hmacs->hmac_ids, len)) + if (put_user(num_idents, &p->shmac_num_idents)) + return -EFAULT; + if (copy_to_user(p->shmac_idents, hmacs->hmac_ids, data_len)) return -EFAULT; - return 0; } @@ -5038,6 +5072,9 @@ struct sctp_authkeyid val; struct sctp_association *asoc; + if (!sctp_auth_enable) + return -EACCES; + if (len < sizeof(struct sctp_authkeyid)) return -EINVAL; if (copy_from_user(&val, optval, sizeof(struct sctp_authkeyid))) @@ -5052,6 +5089,12 @@ else val.scact_keynumber = sctp_sk(sk)->ep->active_key_id; + len = sizeof(struct sctp_authkeyid); + if (put_user(len, optlen)) + return -EFAULT; + if (copy_to_user(optval, &val, len)) + return -EFAULT; + return 0; } @@ -5062,12 +5105,16 @@ struct sctp_authchunks val; struct sctp_association *asoc; struct sctp_chunks_param *ch; + u32 num_chunks = 0; char __user *to; - if (len <= sizeof(struct sctp_authchunks)) + if (!sctp_auth_enable) + return -EACCES; + + if (len < sizeof(struct sctp_authchunks)) return -EINVAL; - if (copy_from_user(&val, p, sizeof(struct sctp_authchunks))) + if (copy_from_user(&val, optval, sizeof(struct sctp_authchunks))) return -EFAULT; to = p->gauth_chunks; @@ -5076,16 +5123,19 @@ return -EINVAL; ch = asoc->peer.peer_chunks; + if (!ch) + goto num; /* See if the user provided enough room for all the data */ - if (len < ntohs(ch->param_hdr.length)) + num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t); + if (len < num_chunks) return -EINVAL; - len = ntohs(ch->param_hdr.length); - if (put_user(len, optlen)) - return -EFAULT; - if (copy_to_user(to, ch->chunks, len)) + if (copy_to_user(to, ch->chunks, num_chunks)) return -EFAULT; +num: + len = sizeof(struct sctp_authchunks) + num_chunks; + if (put_user(len, optlen)) return -EFAULT; return 0; } @@ -5097,12 +5147,16 @@ struct sctp_authchunks val; struct sctp_association *asoc; struct sctp_chunks_param *ch; + u32 num_chunks = 0; char __user *to; - if (len <= sizeof(struct sctp_authchunks)) + if (!sctp_auth_enable) + return -EACCES; + + if (len < sizeof(struct sctp_authchunks)) return -EINVAL; - if (copy_from_user(&val, p, sizeof(struct sctp_authchunks))) + if (copy_from_user(&val, optval, sizeof(struct sctp_authchunks))) return -EFAULT; to = p->gauth_chunks; @@ -5115,13 +5169,18 @@ else ch = sctp_sk(sk)->ep->auth_chunk_list; - if (len < ntohs(ch->param_hdr.length)) + if (!ch) + goto num; + + num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t); + if (len < sizeof(struct sctp_authchunks) + num_chunks) return -EINVAL; - len = ntohs(ch->param_hdr.length); - if (put_user(len, optlen)) + if (copy_to_user(to, ch->chunks, num_chunks)) return -EFAULT; - if (copy_to_user(to, ch->chunks, len)) +num: + len = sizeof(struct sctp_authchunks) + num_chunks; + if (put_user(len, optlen)) return -EFAULT; return 0; --- linux-2.6.24.orig/net/sctp/associola.c +++ linux-2.6.24/net/sctp/associola.c @@ -589,11 +589,12 @@ /* Check to see if this is a duplicate. */ peer = sctp_assoc_lookup_paddr(asoc, addr); if (peer) { + /* An UNKNOWN state is only set on transports added by + * user in sctp_connectx() call. Such transports should be + * considered CONFIRMED per RFC 4960, Section 5.4. + */ if (peer->state == SCTP_UNKNOWN) { - if (peer_state == SCTP_ACTIVE) - peer->state = SCTP_ACTIVE; - if (peer_state == SCTP_UNCONFIRMED) - peer->state = SCTP_UNCONFIRMED; + peer->state = SCTP_ACTIVE; } return peer; } --- linux-2.6.24.orig/net/sctp/sm_make_chunk.c +++ linux-2.6.24/net/sctp/sm_make_chunk.c @@ -1012,6 +1012,29 @@ return retval; } +struct sctp_chunk *sctp_make_violation_paramlen( + const struct sctp_association *asoc, + const struct sctp_chunk *chunk, + struct sctp_paramhdr *param) +{ + struct sctp_chunk *retval; + static const char error[] = "The following parameter had invalid length:"; + size_t payload_len = sizeof(error) + sizeof(sctp_errhdr_t) + + sizeof(sctp_paramhdr_t); + + retval = sctp_make_abort(asoc, chunk, payload_len); + if (!retval) + goto nodata; + + sctp_init_cause(retval, SCTP_ERROR_PROTO_VIOLATION, + sizeof(error) + sizeof(sctp_paramhdr_t)); + sctp_addto_chunk(retval, sizeof(error), error); + sctp_addto_param(retval, sizeof(sctp_paramhdr_t), param); + +nodata: + return retval; +} + /* Make a HEARTBEAT chunk. */ struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc, const struct sctp_transport *transport, @@ -1782,11 +1805,6 @@ const struct sctp_chunk *chunk, struct sctp_chunk **errp) { - char error[] = "The following parameter had invalid length:"; - size_t payload_len = WORD_ROUND(sizeof(error)) + - sizeof(sctp_paramhdr_t); - - /* This is a fatal error. Any accumulated non-fatal errors are * not reported. */ @@ -1794,14 +1812,7 @@ sctp_chunk_free(*errp); /* Create an error chunk and fill it in with our payload. */ - *errp = sctp_make_op_error_space(asoc, chunk, payload_len); - - if (*errp) { - sctp_init_cause(*errp, SCTP_ERROR_PROTO_VIOLATION, - sizeof(error) + sizeof(sctp_paramhdr_t)); - sctp_addto_chunk(*errp, sizeof(error), error); - sctp_addto_param(*errp, sizeof(sctp_paramhdr_t), param); - } + *errp = sctp_make_violation_paramlen(asoc, chunk, param); return 0; } @@ -2252,12 +2263,10 @@ /* Release the transport structures. */ list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { transport = list_entry(pos, struct sctp_transport, transports); - list_del_init(pos); - sctp_transport_free(transport); + if (transport->state != SCTP_ACTIVE) + sctp_assoc_rm_peer(asoc, transport); } - asoc->peer.transport_count = 0; - nomem: return 0; } --- linux-2.6.24.orig/net/sctp/protocol.c +++ linux-2.6.24/net/sctp/protocol.c @@ -626,6 +626,7 @@ struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; struct sctp_sockaddr_entry *addr = NULL; struct sctp_sockaddr_entry *temp; + int found = 0; switch (ev) { case NETDEV_UP: @@ -645,13 +646,14 @@ list_for_each_entry_safe(addr, temp, &sctp_local_addr_list, list) { if (addr->a.v4.sin_addr.s_addr == ifa->ifa_local) { + found = 1; addr->valid = 0; list_del_rcu(&addr->list); break; } } spin_unlock_bh(&sctp_local_addr_lock); - if (addr && !addr->valid) + if (found) call_rcu(&addr->rcu, sctp_local_addr_free); break; } --- linux-2.6.24.orig/net/sunrpc/rpcb_clnt.c +++ linux-2.6.24/net/sunrpc/rpcb_clnt.c @@ -112,9 +112,9 @@ u32 r_vers; u32 r_prot; unsigned short r_port; - char * r_netid; - char r_addr[RPCB_MAXADDRLEN]; - char * r_owner; + const char * r_netid; + const char * r_addr; + const char * r_owner; }; static struct rpc_procinfo rpcb_procedures2[]; @@ -390,9 +390,7 @@ map->r_port = 0; map->r_xprt = xprt_get(xprt); map->r_netid = rpc_peeraddr2str(clnt, RPC_DISPLAY_NETID); - memcpy(map->r_addr, - rpc_peeraddr2str(rpcb_clnt, RPC_DISPLAY_UNIVERSAL_ADDR), - sizeof(map->r_addr)); + map->r_addr = rpc_peeraddr2str(rpcb_clnt, RPC_DISPLAY_UNIVERSAL_ADDR); map->r_owner = RPCB_OWNER_STRING; /* ignored for GETADDR */ child = rpc_run_task(rpcb_clnt, RPC_TASK_ASYNC, &rpcb_getport_ops, map); --- linux-2.6.24.orig/net/ipv4/ipcomp.c +++ linux-2.6.24/net/ipv4/ipcomp.c @@ -74,6 +74,7 @@ static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) { + int nexthdr; int err = -ENOMEM; struct ip_comp_hdr *ipch; @@ -84,13 +85,15 @@ /* Remove ipcomp header and decompress original payload */ ipch = (void *)skb->data; + nexthdr = ipch->nexthdr; + skb->transport_header = skb->network_header + sizeof(*ipch); __skb_pull(skb, sizeof(*ipch)); err = ipcomp_decompress(x, skb); if (err) goto out; - err = ipch->nexthdr; + err = nexthdr; out: return err; @@ -105,8 +108,11 @@ const int cpu = get_cpu(); u8 *scratch = *per_cpu_ptr(ipcomp_scratches, cpu); struct crypto_comp *tfm = *per_cpu_ptr(ipcd->tfms, cpu); - int err = crypto_comp_compress(tfm, start, plen, scratch, &dlen); + int err; + local_bh_disable(); + err = crypto_comp_compress(tfm, start, plen, scratch, &dlen); + local_bh_enable(); if (err) goto out; --- linux-2.6.24.orig/net/ipv4/fib_trie.c +++ linux-2.6.24/net/ipv4/fib_trie.c @@ -1203,20 +1203,45 @@ * and we need to allocate a new one of those as well. */ - if (fa && fa->fa_info->fib_priority == fi->fib_priority) { - struct fib_alias *fa_orig; + if (fa && fa->fa_tos == tos && + fa->fa_info->fib_priority == fi->fib_priority) { + struct fib_alias *fa_first, *fa_match; err = -EEXIST; if (cfg->fc_nlflags & NLM_F_EXCL) goto out; + /* We have 2 goals: + * 1. Find exact match for type, scope, fib_info to avoid + * duplicate routes + * 2. Find next 'fa' (or head), NLM_F_APPEND inserts before it + */ + fa_match = NULL; + fa_first = fa; + fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list); + list_for_each_entry_continue(fa, fa_head, fa_list) { + if (fa->fa_tos != tos) + break; + if (fa->fa_info->fib_priority != fi->fib_priority) + break; + if (fa->fa_type == cfg->fc_type && + fa->fa_scope == cfg->fc_scope && + fa->fa_info == fi) { + fa_match = fa; + break; + } + } + if (cfg->fc_nlflags & NLM_F_REPLACE) { struct fib_info *fi_drop; u8 state; - if (fi->fib_treeref > 1) + fa = fa_first; + if (fa_match) { + if (fa == fa_match) + err = 0; goto out; - + } err = -ENOBUFS; new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL); if (new_fa == NULL) @@ -1228,7 +1253,7 @@ new_fa->fa_type = cfg->fc_type; new_fa->fa_scope = cfg->fc_scope; state = fa->fa_state; - new_fa->fa_state &= ~FA_S_ACCESSED; + new_fa->fa_state = state & ~FA_S_ACCESSED; list_replace_rcu(&fa->fa_list, &new_fa->fa_list); alias_free_mem_rcu(fa); @@ -1245,20 +1270,11 @@ * uses the same scope, type, and nexthop * information. */ - fa_orig = fa; - list_for_each_entry(fa, fa_orig->fa_list.prev, fa_list) { - if (fa->fa_tos != tos) - break; - if (fa->fa_info->fib_priority != fi->fib_priority) - break; - if (fa->fa_type == cfg->fc_type && - fa->fa_scope == cfg->fc_scope && - fa->fa_info == fi) { - goto out; - } - } + if (fa_match) + goto out; + if (!(cfg->fc_nlflags & NLM_F_APPEND)) - fa = fa_orig; + fa = fa_first; } err = -ENOENT; if (!(cfg->fc_nlflags & NLM_F_CREATE)) @@ -1614,9 +1630,8 @@ pr_debug("Deleting %08x/%d tos=%d t=%p\n", key, plen, tos, t); fa_to_delete = NULL; - fa_head = fa->fa_list.prev; - - list_for_each_entry(fa, fa_head, fa_list) { + fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list); + list_for_each_entry_continue(fa, fa_head, fa_list) { struct fib_info *fi = fa->fa_info; if (fa->fa_tos != tos) --- linux-2.6.24.orig/net/ipv4/tcp.c +++ linux-2.6.24/net/ipv4/tcp.c @@ -583,7 +583,7 @@ if (!(psize -= copy)) goto out; - if (skb->len < mss_now || (flags & MSG_OOB)) + if (skb->len < size_goal || (flags & MSG_OOB)) continue; if (forced_push(tp)) { @@ -829,7 +829,7 @@ if ((seglen -= copy) == 0 && iovlen == 0) goto out; - if (skb->len < mss_now || (flags & MSG_OOB)) + if (skb->len < size_goal || (flags & MSG_OOB)) continue; if (forced_push(tp)) { --- linux-2.6.24.orig/net/ipv4/ip_sockglue.c +++ linux-2.6.24/net/ipv4/ip_sockglue.c @@ -514,11 +514,6 @@ val &= ~3; val |= inet->tos & 3; } - if (IPTOS_PREC(val) >= IPTOS_PREC_CRITIC_ECP && - !capable(CAP_NET_ADMIN)) { - err = -EPERM; - break; - } if (inet->tos != val) { inet->tos = val; sk->sk_priority = rt_tos2priority(val); --- linux-2.6.24.orig/net/ipv4/tcp_output.c +++ linux-2.6.24/net/ipv4/tcp_output.c @@ -258,7 +258,7 @@ * * Relax Will Robinson. */ - new_win = cur_win; + new_win = ALIGN(cur_win, 1 << tp->rx_opt.rcv_wscale); } tp->rcv_wnd = new_win; tp->rcv_wup = tp->rcv_nxt; --- linux-2.6.24.orig/net/ipv4/xfrm4_tunnel.c +++ linux-2.6.24/net/ipv4/xfrm4_tunnel.c @@ -50,7 +50,7 @@ static int xfrm_tunnel_rcv(struct sk_buff *skb) { - return xfrm4_rcv_spi(skb, IPPROTO_IP, ip_hdr(skb)->saddr); + return xfrm4_rcv_spi(skb, IPPROTO_IPIP, ip_hdr(skb)->saddr); } static int xfrm_tunnel_err(struct sk_buff *skb, u32 info) --- linux-2.6.24.orig/net/ipv4/ip_output.c +++ linux-2.6.24/net/ipv4/ip_output.c @@ -462,6 +462,7 @@ if (skb_shinfo(skb)->frag_list) { struct sk_buff *frag; int first_len = skb_pagelen(skb); + int truesizes = 0; if (first_len - hlen > mtu || ((first_len - hlen) & 7) || @@ -485,7 +486,7 @@ sock_hold(skb->sk); frag->sk = skb->sk; frag->destructor = sock_wfree; - skb->truesize -= frag->truesize; + truesizes += frag->truesize; } } @@ -496,6 +497,7 @@ frag = skb_shinfo(skb)->frag_list; skb_shinfo(skb)->frag_list = NULL; skb->data_len = first_len - skb_headlen(skb); + skb->truesize -= truesizes; skb->len = first_len; iph->tot_len = htons(first_len); iph->frag_off = htons(IP_MF); --- linux-2.6.24.orig/net/ipv4/inet_diag.c +++ linux-2.6.24/net/ipv4/inet_diag.c @@ -259,8 +259,10 @@ const struct inet_diag_handler *handler; handler = inet_diag_lock_handler(nlh->nlmsg_type); - if (!handler) - return -ENOENT; + if (IS_ERR(handler)) { + err = PTR_ERR(handler); + goto unlock; + } hashinfo = handler->idiag_hashinfo; err = -EINVAL; @@ -708,8 +710,8 @@ struct inet_hashinfo *hashinfo; handler = inet_diag_lock_handler(cb->nlh->nlmsg_type); - if (!handler) - goto no_handler; + if (IS_ERR(handler)) + goto unlock; hashinfo = handler->idiag_hashinfo; @@ -838,7 +840,6 @@ cb->args[2] = num; unlock: inet_diag_unlock_handler(handler); -no_handler: return skb->len; } --- linux-2.6.24.orig/net/ipv4/fib_hash.c +++ linux-2.6.24/net/ipv4/fib_hash.c @@ -434,19 +434,43 @@ if (fa && fa->fa_tos == tos && fa->fa_info->fib_priority == fi->fib_priority) { - struct fib_alias *fa_orig; + struct fib_alias *fa_first, *fa_match; err = -EEXIST; if (cfg->fc_nlflags & NLM_F_EXCL) goto out; + /* We have 2 goals: + * 1. Find exact match for type, scope, fib_info to avoid + * duplicate routes + * 2. Find next 'fa' (or head), NLM_F_APPEND inserts before it + */ + fa_match = NULL; + fa_first = fa; + fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list); + list_for_each_entry_continue(fa, &f->fn_alias, fa_list) { + if (fa->fa_tos != tos) + break; + if (fa->fa_info->fib_priority != fi->fib_priority) + break; + if (fa->fa_type == cfg->fc_type && + fa->fa_scope == cfg->fc_scope && + fa->fa_info == fi) { + fa_match = fa; + break; + } + } + if (cfg->fc_nlflags & NLM_F_REPLACE) { struct fib_info *fi_drop; u8 state; - if (fi->fib_treeref > 1) + fa = fa_first; + if (fa_match) { + if (fa == fa_match) + err = 0; goto out; - + } write_lock_bh(&fib_hash_lock); fi_drop = fa->fa_info; fa->fa_info = fi; @@ -469,20 +493,11 @@ * uses the same scope, type, and nexthop * information. */ - fa_orig = fa; - fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list); - list_for_each_entry_continue(fa, &f->fn_alias, fa_list) { - if (fa->fa_tos != tos) - break; - if (fa->fa_info->fib_priority != fi->fib_priority) - break; - if (fa->fa_type == cfg->fc_type && - fa->fa_scope == cfg->fc_scope && - fa->fa_info == fi) - goto out; - } + if (fa_match) + goto out; + if (!(cfg->fc_nlflags & NLM_F_APPEND)) - fa = fa_orig; + fa = fa_first; } err = -ENOENT; --- linux-2.6.24.orig/net/ipv4/sysctl_net_ipv4.c +++ linux-2.6.24/net/ipv4/sysctl_net_ipv4.c @@ -248,7 +248,7 @@ tcp_get_available_congestion_control(tbl.data, tbl.maxlen); ret = sysctl_string(&tbl, name, nlen, oldval, oldlenp, newval, newlen); - if (ret == 0 && newval && newlen) + if (ret == 1 && newval && newlen) ret = tcp_set_allowed_congestion_control(tbl.data); kfree(tbl.data); --- linux-2.6.24.orig/net/ipv4/ipconfig.c +++ linux-2.6.24/net/ipv4/ipconfig.c @@ -739,9 +739,9 @@ printk("Unknown ARP type 0x%04x for device %s\n", dev->type, dev->name); b->htype = dev->type; /* can cause undefined behavior */ } + + /* server_ip and your_ip address are both already zero per RFC2131 */ b->hlen = dev->addr_len; - b->your_ip = NONE; - b->server_ip = NONE; memcpy(b->hw_addr, dev->dev_addr, dev->addr_len); b->secs = htons(jiffies_diff / HZ); b->xid = d->xid; --- linux-2.6.24.orig/net/ipv4/esp4.c +++ linux-2.6.24/net/ipv4/esp4.c @@ -165,7 +165,7 @@ int padlen; int err; - if (!pskb_may_pull(skb, sizeof(*esph))) + if (!pskb_may_pull(skb, sizeof(*esph) + esp->conf.ivlen)) goto out; if (elen <= 0 || (elen & (blksize-1))) --- linux-2.6.24.orig/net/ipv4/netfilter/nf_nat_snmp_basic.c +++ linux-2.6.24/net/ipv4/netfilter/nf_nat_snmp_basic.c @@ -231,6 +231,11 @@ } } } + + /* don't trust len bigger than ctx buffer */ + if (*len > ctx->end - ctx->pointer) + return 0; + return 1; } @@ -249,6 +254,10 @@ if (!asn1_length_decode(ctx, &def, &len)) return 0; + /* primitive shall be definite, indefinite shall be constructed */ + if (*con == ASN1_PRI && !def) + return 0; + if (def) *eoc = ctx->pointer + len; else @@ -429,10 +438,15 @@ unsigned int *len) { unsigned long subid; - unsigned int size; unsigned long *optr; + size_t size; size = eoc - ctx->pointer + 1; + + /* first subid actually encodes first two subids */ + if (size < 2 || size > ULONG_MAX/sizeof(unsigned long)) + return 0; + *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC); if (*oid == NULL) { if (net_ratelimit()) --- linux-2.6.24.orig/net/ipv4/netfilter/arpt_mangle.c +++ linux-2.6.24/net/ipv4/netfilter/arpt_mangle.c @@ -19,7 +19,7 @@ unsigned char *arpptr; int pln, hln; - if (skb_make_writable(skb, skb->len)) + if (!skb_make_writable(skb, skb->len)) return NF_DROP; arp = arp_hdr(skb); --- linux-2.6.24.orig/net/ipv4/netfilter/ip_queue.c +++ linux-2.6.24/net/ipv4/netfilter/ip_queue.c @@ -336,8 +336,8 @@ ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct ipq_queue_entry *e) { int diff; - int err; struct iphdr *user_iph = (struct iphdr *)v->payload; + struct sk_buff *nskb; if (v->data_len < sizeof(*user_iph)) return 0; @@ -349,14 +349,16 @@ if (v->data_len > 0xFFFF) return -EINVAL; if (diff > skb_tailroom(e->skb)) { - err = pskb_expand_head(e->skb, 0, + nskb = skb_copy_expand(e->skb, 0, diff - skb_tailroom(e->skb), GFP_ATOMIC); - if (err) { + if (!nskb) { printk(KERN_WARNING "ip_queue: error " - "in mangle, dropping packet: %d\n", -err); - return err; + "in mangle, dropping packet\n"); + return -ENOMEM; } + kfree_skb(e->skb); + e->skb = nskb; } skb_put(e->skb, diff); } --- linux-2.6.24.orig/net/ipv6/sit.c +++ linux-2.6.24/net/ipv6/sit.c @@ -395,9 +395,9 @@ } icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); - kfree_skb(skb); read_unlock(&ipip6_lock); out: + kfree_skb(skb); return 0; } --- linux-2.6.24.orig/net/ipv6/ip6_tunnel.c +++ linux-2.6.24/net/ipv6/ip6_tunnel.c @@ -550,6 +550,7 @@ ip_rt_put(rt); goto out; } + skb2->dst = (struct dst_entry *)rt; } else { ip_rt_put(rt); if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos, --- linux-2.6.24.orig/net/ipv6/ip6_output.c +++ linux-2.6.24/net/ipv6/ip6_output.c @@ -593,7 +593,7 @@ * or if the skb it not generated by a local socket. (This last * check should be redundant, but it's free.) */ - if (!np || np->pmtudisc >= IPV6_PMTUDISC_DO) { + if (!skb->local_df) { skb->dev = skb->dst->dev; icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); @@ -609,6 +609,7 @@ if (skb_shinfo(skb)->frag_list) { int first_len = skb_pagelen(skb); + int truesizes = 0; if (first_len - hlen > mtu || ((first_len - hlen) & 7) || @@ -631,7 +632,7 @@ sock_hold(skb->sk); frag->sk = skb->sk; frag->destructor = sock_wfree; - skb->truesize -= frag->truesize; + truesizes += frag->truesize; } } @@ -662,6 +663,7 @@ first_len = skb_pagelen(skb); skb->data_len = first_len - skb_headlen(skb); + skb->truesize -= truesizes; skb->len = first_len; ipv6_hdr(skb)->payload_len = htons(first_len - sizeof(struct ipv6hdr)); @@ -1387,6 +1389,10 @@ tmp_skb->sk = NULL; } + /* Allow local fragmentation. */ + if (np->pmtudisc < IPV6_PMTUDISC_DO) + skb->local_df = 1; + ipv6_addr_copy(final_dst, &fl->fl6_dst); __skb_pull(skb, skb_network_header_len(skb)); if (opt && opt->opt_flen) --- linux-2.6.24.orig/net/ipv6/esp6.c +++ linux-2.6.24/net/ipv6/esp6.c @@ -155,7 +155,7 @@ int nfrags; int ret = 0; - if (!pskb_may_pull(skb, sizeof(*esph))) { + if (!pskb_may_pull(skb, sizeof(*esph) + esp->conf.ivlen)) { ret = -EINVAL; goto out; } --- linux-2.6.24.orig/net/ipv6/xfrm6_output.c +++ linux-2.6.24/net/ipv6/xfrm6_output.c @@ -34,7 +34,7 @@ if (mtu < IPV6_MIN_MTU) mtu = IPV6_MIN_MTU; - if (skb->len > mtu) { + if (!skb->local_df && skb->len > mtu) { skb->dev = dst->dev; icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); ret = -EMSGSIZE; --- linux-2.6.24.orig/net/ipv6/anycast.c +++ linux-2.6.24/net/ipv6/anycast.c @@ -67,6 +67,7 @@ break; } read_unlock_bh(&idev->lock); + in6_dev_put(idev); } rcu_read_unlock(); return onlink; --- linux-2.6.24.orig/net/ipv6/ipcomp6.c +++ linux-2.6.24/net/ipv6/ipcomp6.c @@ -64,6 +64,7 @@ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) { + int nexthdr; int err = -ENOMEM; struct ip_comp_hdr *ipch; int plen, dlen; @@ -79,6 +80,8 @@ /* Remove ipcomp header and decompress original payload */ ipch = (void *)skb->data; + nexthdr = ipch->nexthdr; + skb->transport_header = skb->network_header + sizeof(*ipch); __skb_pull(skb, sizeof(*ipch)); @@ -108,7 +111,7 @@ skb->truesize += dlen - plen; __skb_put(skb, dlen - plen); skb_copy_to_linear_data(skb, scratch, dlen); - err = ipch->nexthdr; + err = nexthdr; out_put_cpu: put_cpu(); @@ -143,7 +146,9 @@ scratch = *per_cpu_ptr(ipcomp6_scratches, cpu); tfm = *per_cpu_ptr(ipcd->tfms, cpu); + local_bh_disable(); err = crypto_comp_compress(tfm, start, plen, scratch, &dlen); + local_bh_enable(); if (err || (dlen + sizeof(*ipch)) >= plen) { put_cpu(); goto out_ok; --- linux-2.6.24.orig/net/ipv6/addrconf.c +++ linux-2.6.24/net/ipv6/addrconf.c @@ -752,6 +752,7 @@ struct inet6_dev *idev = ifp->idev; struct in6_addr addr, *tmpaddr; unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp; + unsigned long regen_advance; int tmp_plen; int ret = 0; int max_addresses; @@ -812,8 +813,23 @@ tmp_tstamp = ifp->tstamp; spin_unlock_bh(&ifp->lock); + regen_advance = idev->cnf.regen_max_retry * + idev->cnf.dad_transmits * + idev->nd_parms->retrans_time / HZ; write_unlock(&idev->lock); + /* A temporary address is created only if this calculated Preferred + * Lifetime is greater than REGEN_ADVANCE time units. In particular, + * an implementation must not create a temporary address with a zero + * Preferred Lifetime. + */ + if (tmp_prefered_lft <= regen_advance) { + in6_ifa_put(ifp); + in6_dev_put(idev); + ret = -1; + goto out; + } + addr_flags = IFA_F_TEMPORARY; /* set in addrconf_prefix_rcv() */ if (ifp->flags & IFA_F_OPTIMISTIC) @@ -1817,6 +1833,9 @@ * lifetimes of an existing temporary address * when processing a Prefix Information Option. */ + if (ifp != ift->ifpub) + continue; + spin_lock(&ift->lock); flags = ift->flags; if (ift->valid_lft > valid_lft && --- linux-2.6.24.orig/net/ipv6/netfilter/ip6_queue.c +++ linux-2.6.24/net/ipv6/netfilter/ip6_queue.c @@ -333,8 +333,8 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct ipq_queue_entry *e) { int diff; - int err; struct ipv6hdr *user_iph = (struct ipv6hdr *)v->payload; + struct sk_buff *nskb; if (v->data_len < sizeof(*user_iph)) return 0; @@ -346,14 +346,16 @@ if (v->data_len > 0xFFFF) return -EINVAL; if (diff > skb_tailroom(e->skb)) { - err = pskb_expand_head(e->skb, 0, + nskb = skb_copy_expand(e->skb, 0, diff - skb_tailroom(e->skb), GFP_ATOMIC); - if (err) { + if (!nskb) { printk(KERN_WARNING "ip6_queue: OOM " "in mangle, dropping packet\n"); - return err; + return -ENOMEM; } + kfree_skb(e->skb); + e->skb = nskb; } skb_put(e->skb, diff); } --- linux-2.6.24.orig/net/ipv6/netfilter/nf_conntrack_reasm.c +++ linux-2.6.24/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -147,7 +147,9 @@ static void nf_ct_frag6_evictor(void) { + local_bh_disable(); inet_frag_evictor(&nf_frags); + local_bh_enable(); } static void nf_ct_frag6_expire(unsigned long data) --- linux-2.6.24.orig/net/unix/af_unix.c +++ linux-2.6.24/net/unix/af_unix.c @@ -839,7 +839,7 @@ */ mode = S_IFSOCK | (SOCK_INODE(sock)->i_mode & ~current->fs->umask); - err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0); + err = vfs_mknod(nd.dentry->d_inode, dentry, nd.mnt, mode, 0); if (err) goto out_mknod_dput; mutex_unlock(&nd.dentry->d_inode->i_mutex); @@ -1311,14 +1311,23 @@ sock_wfree(skb); } -static void unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) +static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) { int i; + + /* + * Need to duplicate file references for the sake of garbage + * collection. Otherwise a socket in the fps might become a + * candidate for GC while the skb is not yet queued. + */ + UNIXCB(skb).fp = scm_fp_dup(scm->fp); + if (!UNIXCB(skb).fp) + return -ENOMEM; + for (i=scm->fp->count-1; i>=0; i--) unix_inflight(scm->fp->fp[i]); - UNIXCB(skb).fp = scm->fp; skb->destructor = unix_destruct_fds; - scm->fp = NULL; + return 0; } /* @@ -1376,8 +1385,11 @@ goto out; memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); - if (siocb->scm->fp) - unix_attach_fds(siocb->scm, skb); + if (siocb->scm->fp) { + err = unix_attach_fds(siocb->scm, skb); + if (err) + goto out_free; + } unix_get_secdata(siocb->scm, skb); skb_reset_transport_header(skb); @@ -1548,8 +1560,13 @@ size = min_t(int, size, skb_tailroom(skb)); memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); - if (siocb->scm->fp) - unix_attach_fds(siocb->scm, skb); + if (siocb->scm->fp) { + err = unix_attach_fds(siocb->scm, skb); + if (err) { + kfree_skb(skb); + goto out_err; + } + } if ((err = memcpy_fromiovec(skb_put(skb,size), msg->msg_iov, size)) != 0) { kfree_skb(skb); --- linux-2.6.24.orig/net/unix/garbage.c +++ linux-2.6.24/net/unix/garbage.c @@ -186,8 +186,17 @@ */ struct sock *sk = unix_get_socket(*fp++); if (sk) { - hit = true; - func(unix_sk(sk)); + struct unix_sock *u = unix_sk(sk); + + /* + * Ignore non-candidates, they could + * have been added to the queues after + * starting the garbage collection + */ + if (u->gc_candidate) { + hit = true; + func(u); + } } } if (hit && hitlist != NULL) { @@ -249,11 +258,11 @@ { atomic_inc(&u->inflight); /* - * If this is still a candidate, move it to the end of the - * list, so that it's checked even if it was already passed - * over + * If this still might be part of a cycle, move it to the end + * of the list, so that it's checked even if it was already + * passed over */ - if (u->gc_candidate) + if (u->gc_maybe_cycle) list_move_tail(&u->link, &gc_candidates); } @@ -267,6 +276,7 @@ struct unix_sock *next; struct sk_buff_head hitlist; struct list_head cursor; + LIST_HEAD(not_cycle_list); spin_lock(&unix_gc_lock); @@ -282,10 +292,14 @@ * * Holding unix_gc_lock will protect these candidates from * being detached, and hence from gaining an external - * reference. This also means, that since there are no - * possible receivers, the receive queues of these sockets are - * static during the GC, even though the dequeue is done - * before the detach without atomicity guarantees. + * reference. Since there are no possible receivers, all + * buffers currently on the candidates' queues stay there + * during the garbage collection. + * + * We also know that no new candidate can be added onto the + * receive queues. Other, non candidate sockets _can_ be + * added to queue, so we must make sure only to touch + * candidates. */ list_for_each_entry_safe(u, next, &gc_inflight_list, link) { int total_refs; @@ -299,6 +313,7 @@ if (total_refs == inflight_refs) { list_move_tail(&u->link, &gc_candidates); u->gc_candidate = 1; + u->gc_maybe_cycle = 1; } } @@ -325,14 +340,24 @@ list_move(&cursor, &u->link); if (atomic_read(&u->inflight) > 0) { - list_move_tail(&u->link, &gc_inflight_list); - u->gc_candidate = 0; + list_move_tail(&u->link, ¬_cycle_list); + u->gc_maybe_cycle = 0; scan_children(&u->sk, inc_inflight_move_tail, NULL); } } list_del(&cursor); /* + * not_cycle_list contains those sockets which do not make up a + * cycle. Restore these to the inflight list. + */ + while (!list_empty(¬_cycle_list)) { + u = list_entry(not_cycle_list.next, struct unix_sock, link); + u->gc_candidate = 0; + list_move_tail(&u->link, &gc_inflight_list); + } + + /* * Now gc_candidates contains only garbage. Restore original * inflight counters for these as well, and remove the skbuffs * which are creating the cycle(s). --- linux-2.6.24.orig/net/9p/trans_virtio.c +++ linux-2.6.24/net/9p/trans_virtio.c @@ -199,14 +199,12 @@ kfree(trans); } -static bool p9_virtio_intr(struct virtqueue *q) +static void p9_virtio_intr(struct virtqueue *q) { struct virtio_chan *chan = q->vdev->priv; P9_DPRINTK(P9_DEBUG_TRANS, "9p poll_wakeup: %p\n", &chan->wq); wake_up_interruptible(&chan->wq); - - return true; } static int p9_virtio_probe(struct virtio_device *dev) @@ -236,13 +234,13 @@ /* Find the input queue. */ dev->priv = chan; - chan->in_vq = dev->config->find_vq(dev, p9_virtio_intr); + chan->in_vq = dev->config->find_vq(dev, 0, p9_virtio_intr); if (IS_ERR(chan->in_vq)) { err = PTR_ERR(chan->in_vq); goto free; } - chan->out_vq = dev->config->find_vq(dev, NULL); + chan->out_vq = dev->config->find_vq(dev, 1, NULL); if (IS_ERR(chan->out_vq)) { err = PTR_ERR(chan->out_vq); goto free_in_vq; --- linux-2.6.24.orig/net/bridge/netfilter/ebt_dnat.c +++ linux-2.6.24/net/bridge/netfilter/ebt_dnat.c @@ -20,8 +20,8 @@ { struct ebt_nat_info *info = (struct ebt_nat_info *)data; - if (skb_make_writable(skb, 0)) - return NF_DROP; + if (!skb_make_writable(skb, 0)) + return EBT_DROP; memcpy(eth_hdr(skb)->h_dest, info->mac, ETH_ALEN); return info->target; --- linux-2.6.24.orig/net/bridge/netfilter/ebt_redirect.c +++ linux-2.6.24/net/bridge/netfilter/ebt_redirect.c @@ -21,8 +21,8 @@ { struct ebt_redirect_info *info = (struct ebt_redirect_info *)data; - if (skb_make_writable(skb, 0)) - return NF_DROP; + if (!skb_make_writable(skb, 0)) + return EBT_DROP; if (hooknr != NF_BR_BROUTING) memcpy(eth_hdr(skb)->h_dest, --- linux-2.6.24.orig/net/bridge/netfilter/ebt_snat.c +++ linux-2.6.24/net/bridge/netfilter/ebt_snat.c @@ -22,8 +22,8 @@ { struct ebt_nat_info *info = (struct ebt_nat_info *) data; - if (skb_make_writable(skb, 0)) - return NF_DROP; + if (!skb_make_writable(skb, 0)) + return EBT_DROP; memcpy(eth_hdr(skb)->h_source, info->mac, ETH_ALEN); if (!(info->target & NAT_ARP_BIT) && --- linux-2.6.24.orig/net/ax25/ax25_out.c +++ linux-2.6.24/net/ax25/ax25_out.c @@ -117,6 +117,12 @@ unsigned char *p; int frontlen, len, fragno, ka9qfrag, first = 1; + if (paclen < 16) { + WARN_ON_ONCE(1); + kfree_skb(skb); + return; + } + if ((skb->len - 1) > paclen) { if (*skb->data == AX25_P_TEXT) { skb_pull(skb, 1); /* skip PID */ @@ -251,8 +257,6 @@ if (start == end) return; - ax25->vs = start; - /* * Transmit data until either we're out of data to send or * the window is full. Send a poll on the final I frame if @@ -261,8 +265,13 @@ /* * Dequeue the frame and copy it. + * Check for race with ax25_clear_queues(). */ skb = skb_dequeue(&ax25->write_queue); + if (!skb) + return; + + ax25->vs = start; do { if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) { --- linux-2.6.24.orig/net/mac80211/ieee80211_ioctl.c +++ linux-2.6.24/net/mac80211/ieee80211_ioctl.c @@ -218,6 +218,8 @@ IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP); IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN); + range->scan_capa |= IW_SCAN_CAPA_ESSID; + return 0; } --- linux-2.6.24.orig/net/llc/af_llc.c +++ linux-2.6.24/net/llc/af_llc.c @@ -155,6 +155,9 @@ struct sock *sk; int rc = -ESOCKTNOSUPPORT; + if (!capable(CAP_NET_RAW)) + return -EPERM; + if (net != &init_net) return -EAFNOSUPPORT; --- linux-2.6.24.orig/net/8021q/vlan.c +++ linux-2.6.24/net/8021q/vlan.c @@ -326,7 +326,7 @@ int subclass = 0; /* IFF_BROADCAST|IFF_MULTICAST; ??? */ - dev->flags = real_dev->flags & ~IFF_UP; + dev->flags = real_dev->flags & ~(IFF_UP | IFF_PROMISC | IFF_ALLMULTI); dev->iflink = real_dev->ifindex; dev->state = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) | (1<<__LINK_STATE_DORMANT))) | --- linux-2.6.24.orig/fs/attr.c +++ linux-2.6.24/fs/attr.c @@ -100,7 +100,8 @@ } EXPORT_SYMBOL(inode_setattr); -int notify_change(struct dentry * dentry, struct iattr * attr) +int fnotify_change(struct dentry *dentry, struct vfsmount *mnt, + struct iattr *attr, struct file *file) { struct inode *inode = dentry->d_inode; mode_t mode = inode->i_mode; @@ -158,13 +159,17 @@ down_write(&dentry->d_inode->i_alloc_sem); if (inode->i_op && inode->i_op->setattr) { - error = security_inode_setattr(dentry, attr); - if (!error) - error = inode->i_op->setattr(dentry, attr); + error = security_inode_setattr(dentry, mnt, attr); + if (!error) { + if (file && file->f_op && file->f_op->fsetattr) + error = file->f_op->fsetattr(file, attr); + else + error = inode->i_op->setattr(dentry, attr); + } } else { error = inode_change_ok(inode, attr); if (!error) - error = security_inode_setattr(dentry, attr); + error = security_inode_setattr(dentry, mnt, attr); if (!error) { if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) @@ -183,4 +188,10 @@ return error; } +int notify_change(struct dentry *dentry, struct vfsmount *mnt, + struct iattr *attr) +{ + return fnotify_change(dentry, mnt, attr, NULL); +} + EXPORT_SYMBOL(notify_change); --- linux-2.6.24.orig/fs/dcache.c +++ linux-2.6.24/fs/dcache.c @@ -1408,9 +1408,6 @@ if (atomic_read(&dentry->d_count) == 1) { dentry_iput(dentry); fsnotify_nameremove(dentry, isdir); - - /* remove this and other inotify debug checks after 2.6.18 */ - dentry->d_flags &= ~DCACHE_INOTIFY_PARENT_WATCHED; return; } @@ -1764,92 +1761,132 @@ } /** - * d_path - return the path of a dentry + * __d_path - return the path of a dentry * @dentry: dentry to report * @vfsmnt: vfsmnt to which the dentry belongs * @root: root dentry * @rootmnt: vfsmnt to which the root dentry belongs * @buffer: buffer to return value in * @buflen: buffer length + * @fail_deleted: what to return for deleted files * - * Convert a dentry into an ASCII path name. If the entry has been deleted + * Convert a dentry into an ASCII path name. If the entry has been deleted, + * then if @fail_deleted is true, ERR_PTR(-ENOENT) is returned. Otherwise, * the string " (deleted)" is appended. Note that this is ambiguous. * - * Returns the buffer or an error code if the path was too long. + * If @dentry is not connected to @root, the path returned will be relative + * (i.e., it will not start with a slash). * - * "buflen" should be positive. Caller holds the dcache_lock. + * Returns the buffer or an error code. */ -static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt, - struct dentry *root, struct vfsmount *rootmnt, - char *buffer, int buflen) +char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt, + struct dentry *root, struct vfsmount *rootmnt, + char *buffer, int buflen, int fail_deleted) { - char * end = buffer+buflen; - char * retval; - int namelen; + int namelen, is_slash, vfsmount_locked = 0; + + if (buflen < 2) + return ERR_PTR(-ENAMETOOLONG); + buffer += --buflen; + *buffer = '\0'; - *--end = '\0'; - buflen--; + spin_lock(&dcache_lock); if (!IS_ROOT(dentry) && d_unhashed(dentry)) { - buflen -= 10; - end -= 10; - if (buflen < 0) + if (fail_deleted) { + buffer = ERR_PTR(-ENOENT); + goto out; + } + if (buflen < 10) goto Elong; - memcpy(end, " (deleted)", 10); + buflen -= 10; + buffer -= 10; + memcpy(buffer, " (deleted)", 10); } - - if (buflen < 1) - goto Elong; - /* Get '/' right */ - retval = end-1; - *retval = '/'; - - for (;;) { + while (dentry != root || vfsmnt != rootmnt) { struct dentry * parent; - if (dentry == root && vfsmnt == rootmnt) - break; if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) { - /* Global root? */ - spin_lock(&vfsmount_lock); - if (vfsmnt->mnt_parent == vfsmnt) { - spin_unlock(&vfsmount_lock); - goto global_root; + if (!vfsmount_locked) { + spin_lock(&vfsmount_lock); + vfsmount_locked = 1; } + if (vfsmnt->mnt_parent == vfsmnt) + goto global_root; dentry = vfsmnt->mnt_mountpoint; vfsmnt = vfsmnt->mnt_parent; - spin_unlock(&vfsmount_lock); continue; } parent = dentry->d_parent; prefetch(parent); namelen = dentry->d_name.len; - buflen -= namelen + 1; - if (buflen < 0) + if (buflen < namelen + 1) goto Elong; - end -= namelen; - memcpy(end, dentry->d_name.name, namelen); - *--end = '/'; - retval = end; + buflen -= namelen + 1; + buffer -= namelen; + memcpy(buffer, dentry->d_name.name, namelen); + *--buffer = '/'; dentry = parent; } + /* Get '/' right. */ + if (*buffer != '/') + *--buffer = '/'; - return retval; +out: + if (vfsmount_locked) + spin_unlock(&vfsmount_lock); + spin_unlock(&dcache_lock); + return buffer; global_root: + /* + * We went past the (vfsmount, dentry) we were looking for and have + * either hit a root dentry, a lazily unmounted dentry, an + * unconnected dentry, or the file is on a pseudo filesystem. + */ namelen = dentry->d_name.len; - buflen -= namelen; - if (buflen < 0) + is_slash = (namelen == 1 && *dentry->d_name.name == '/'); + if (is_slash || (dentry->d_sb->s_flags & MS_NOUSER)) { + /* + * Make sure we won't return a pathname starting with '/'. + * + * Historically, we also glue together the root dentry and + * remaining name for pseudo filesystems like pipefs, which + * have the MS_NOUSER flag set. This results in pathnames + * like "pipe:[439336]". + */ + if (*buffer == '/') { + buffer++; + buflen++; + } + if (is_slash) + goto out; + } + if (buflen < namelen) goto Elong; - retval -= namelen-1; /* hit the slash */ - memcpy(retval, dentry->d_name.name, namelen); - return retval; + buffer -= namelen; + memcpy(buffer, dentry->d_name.name, namelen); + goto out; + Elong: - return ERR_PTR(-ENAMETOOLONG); + buffer = ERR_PTR(-ENAMETOOLONG); + goto out; +} + +static char *__connect_d_path(char *path, char *buffer) +{ + if (!IS_ERR(path) && *path != '/') { + /* Pretend that disconnected paths are hanging off the root. */ + if (path == buffer) + path = ERR_PTR(-ENAMETOOLONG); + else + *--path = '/'; + } + return path; } /* write full pathname into buffer and return start of pathname */ -char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt, - char *buf, int buflen) +char *d_path(struct dentry *dentry, struct vfsmount *vfsmnt, char *buf, + int buflen) { char *res; struct vfsmount *rootmnt; @@ -1869,9 +1906,8 @@ rootmnt = mntget(current->fs->rootmnt); root = dget(current->fs->root); read_unlock(¤t->fs->lock); - spin_lock(&dcache_lock); - res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen); - spin_unlock(&dcache_lock); + res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen, 0); + res = __connect_d_path(res, buf); dput(root); mntput(rootmnt); return res; @@ -1918,10 +1954,10 @@ */ asmlinkage long sys_getcwd(char __user *buf, unsigned long size) { - int error; + int error, len; struct vfsmount *pwdmnt, *rootmnt; struct dentry *pwd, *root; - char *page = (char *) __get_free_page(GFP_USER); + char *page = (char *) __get_free_page(GFP_USER), *cwd; if (!page) return -ENOMEM; @@ -1933,29 +1969,19 @@ root = dget(current->fs->root); read_unlock(¤t->fs->lock); - error = -ENOENT; - /* Has the current directory has been unlinked? */ - spin_lock(&dcache_lock); - if (pwd->d_parent == pwd || !d_unhashed(pwd)) { - unsigned long len; - char * cwd; - - cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE); - spin_unlock(&dcache_lock); - - error = PTR_ERR(cwd); - if (IS_ERR(cwd)) - goto out; - - error = -ERANGE; - len = PAGE_SIZE + page - cwd; - if (len <= size) { - error = len; - if (copy_to_user(buf, cwd, len)) - error = -EFAULT; - } - } else - spin_unlock(&dcache_lock); + cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE, 1); + cwd = __connect_d_path(cwd, page); + error = PTR_ERR(cwd); + if (IS_ERR(cwd)) + goto out; + + error = -ERANGE; + len = PAGE_SIZE + page - cwd; + if (len <= size) { + error = len; + if (copy_to_user(buf, cwd, len)) + error = -EFAULT; + } out: dput(pwd); --- linux-2.6.24.orig/fs/aio.c +++ linux-2.6.24/fs/aio.c @@ -997,6 +997,14 @@ /* everything turned out well, dispose of the aiocb. */ ret = __aio_put_req(ctx, iocb); + /* + * We have to order our ring_info tail store above and test + * of the wait list below outside the wait lock. This is + * like in wake_up_bit() where clearing a bit has to be + * ordered with the unlocked test. + */ + smp_mb(); + if (waitqueue_active(&ctx->wait)) wake_up(&ctx->wait); --- linux-2.6.24.orig/fs/exec.c +++ linux-2.6.24/fs/exec.c @@ -1790,7 +1790,8 @@ goto close_fail; if (!file->f_op->write) goto close_fail; - if (!ispipe && do_truncate(file->f_path.dentry, 0, 0, file) != 0) + if (!ispipe && + do_truncate(file->f_path.dentry, file->f_path.mnt, 0, 0, file) != 0) goto close_fail; retval = binfmt->core_dump(signr, regs, file, core_limit); --- linux-2.6.24.orig/fs/open.c +++ linux-2.6.24/fs/open.c @@ -194,8 +194,8 @@ return error; } -int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, - struct file *filp) +int do_truncate(struct dentry *dentry, struct vfsmount *mnt, loff_t length, + unsigned int time_attrs, struct file *filp) { int err; struct iattr newattrs; @@ -206,16 +206,15 @@ newattrs.ia_size = length; newattrs.ia_valid = ATTR_SIZE | time_attrs; - if (filp) { - newattrs.ia_file = filp; + + if (filp) newattrs.ia_valid |= ATTR_FILE; - } /* Remove suid/sgid on truncate too */ newattrs.ia_valid |= should_remove_suid(dentry); mutex_lock(&dentry->d_inode->i_mutex); - err = notify_change(dentry, &newattrs); + err = fnotify_change(dentry, mnt, &newattrs, filp); mutex_unlock(&dentry->d_inode->i_mutex); return err; } @@ -271,7 +270,7 @@ error = locks_verify_truncate(inode, NULL, length); if (!error) { DQUOT_INIT(inode); - error = do_truncate(nd.dentry, length, 0, NULL); + error = do_truncate(nd.dentry, nd.mnt, length, 0, NULL); } put_write_and_out: @@ -324,7 +323,8 @@ error = locks_verify_truncate(inode, file, length); if (!error) - error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file); + error = do_truncate(dentry, file->f_path.mnt, length, + ATTR_MTIME|ATTR_CTIME, file); out_putf: fput(file); out: @@ -500,10 +500,8 @@ asmlinkage long sys_fchdir(unsigned int fd) { + struct nameidata nd; struct file *file; - struct dentry *dentry; - struct inode *inode; - struct vfsmount *mnt; int error; error = -EBADF; @@ -511,17 +509,17 @@ if (!file) goto out; - dentry = file->f_path.dentry; - mnt = file->f_path.mnt; - inode = dentry->d_inode; + nd.dentry = file->f_path.dentry; + nd.mnt = file->f_path.mnt; + nd.flags = 0; error = -ENOTDIR; - if (!S_ISDIR(inode->i_mode)) + if (!S_ISDIR(nd.dentry->d_inode->i_mode)) goto out_putf; - error = file_permission(file, MAY_EXEC); + error = vfs_permission(&nd, MAY_EXEC); if (!error) - set_fs_pwd(current->fs, mnt, dentry); + set_fs_pwd(current->fs, nd.mnt, nd.dentry); out_putf: fput(file); out: @@ -581,8 +579,8 @@ if (mode == (mode_t) -1) mode = inode->i_mode; newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); - newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; - err = notify_change(dentry, &newattrs); + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME | ATTR_FILE; + err = fnotify_change(dentry, file->f_path.mnt, &newattrs, file); mutex_unlock(&inode->i_mutex); out_putf: @@ -617,7 +615,7 @@ mode = inode->i_mode; newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; - error = notify_change(nd.dentry, &newattrs); + error = notify_change(nd.dentry, nd.mnt, &newattrs); mutex_unlock(&inode->i_mutex); dput_and_out: @@ -631,7 +629,8 @@ return sys_fchmodat(AT_FDCWD, filename, mode); } -static int chown_common(struct dentry * dentry, uid_t user, gid_t group) +static int chown_common(struct dentry * dentry, struct vfsmount *mnt, + uid_t user, gid_t group, struct file *file) { struct inode * inode; int error; @@ -660,8 +659,10 @@ if (!S_ISDIR(inode->i_mode)) newattrs.ia_valid |= ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; + if (file) + newattrs.ia_valid |= ATTR_FILE; mutex_lock(&inode->i_mutex); - error = notify_change(dentry, &newattrs); + error = fnotify_change(dentry, mnt, &newattrs, file); mutex_unlock(&inode->i_mutex); out: return error; @@ -675,7 +676,7 @@ error = user_path_walk(filename, &nd); if (error) goto out; - error = chown_common(nd.dentry, user, group); + error = chown_common(nd.dentry, nd.mnt, user, group, NULL); path_release(&nd); out: return error; @@ -695,7 +696,7 @@ error = __user_walk_fd(dfd, filename, follow, &nd); if (error) goto out; - error = chown_common(nd.dentry, user, group); + error = chown_common(nd.dentry, nd.mnt, user, group, NULL); path_release(&nd); out: return error; @@ -709,7 +710,7 @@ error = user_path_walk_link(filename, &nd); if (error) goto out; - error = chown_common(nd.dentry, user, group); + error = chown_common(nd.dentry, nd.mnt, user, group, NULL); path_release(&nd); out: return error; @@ -728,7 +729,7 @@ dentry = file->f_path.dentry; audit_inode(NULL, dentry); - error = chown_common(dentry, user, group); + error = chown_common(dentry, file->f_path.mnt, user, group, file); fput(file); out: return error; --- linux-2.6.24.orig/fs/file_table.c +++ linux-2.6.24/fs/file_table.c @@ -302,6 +302,7 @@ file_free(file); } } +EXPORT_SYMBOL(put_filp); void file_move(struct file *file, struct list_head *list) { --- linux-2.6.24.orig/fs/Kconfig +++ linux-2.6.24/fs/Kconfig @@ -2118,6 +2118,29 @@ endif # NETWORK_FILESYSTEMS +config DEFAULT_RELATIME + bool "Mount all filesystems with relatime by default" + default y + help + If you say Y here, all your filesystems will be mounted + with the "relatime" mount option. This eliminates many atime + ('file last accessed' timestamp) updates (which otherwise + is performed on every file access and generates a write + IO to the inode) and thus speeds up IO. Atime is still updated, + but only once per day. + + The mtime ('file last modified') and ctime ('file created') + timestamp are unaffected by this change. + + Use the "norelatime" kernel boot option to turn off this + feature. + +config DEFAULT_RELATIME_VAL + int + default "1" if DEFAULT_RELATIME + default "0" + + if BLOCK menu "Partition Types" --- linux-2.6.24.orig/fs/binfmt_elf.c +++ linux-2.6.24/fs/binfmt_elf.c @@ -45,7 +45,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); static int load_elf_library(struct file *); -static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int); +static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int, unsigned long); /* * If we don't support core dumping, then supply a NULL so we @@ -298,33 +298,70 @@ #ifndef elf_map static unsigned long elf_map(struct file *filep, unsigned long addr, - struct elf_phdr *eppnt, int prot, int type) + struct elf_phdr *eppnt, int prot, int type, + unsigned long total_size) { unsigned long map_addr; - unsigned long pageoffset = ELF_PAGEOFFSET(eppnt->p_vaddr); + unsigned long size = eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr); + unsigned long off = eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr); + addr = ELF_PAGESTART(addr); + size = ELF_PAGEALIGN(size); - down_write(¤t->mm->mmap_sem); /* mmap() will return -EINVAL if given a zero size, but a * segment with zero filesize is perfectly valid */ - if (eppnt->p_filesz + pageoffset) - map_addr = do_mmap(filep, ELF_PAGESTART(addr), - eppnt->p_filesz + pageoffset, prot, type, - eppnt->p_offset - pageoffset); - else - map_addr = ELF_PAGESTART(addr); + if (!size) + return addr; + + down_write(¤t->mm->mmap_sem); + /* + * total_size is the size of the ELF (interpreter) image. + * The _first_ mmap needs to know the full size, otherwise + * randomization might put this image into an overlapping + * position with the ELF binary image. (since size < total_size) + * So we first map the 'big' image - and unmap the remainder at + * the end. (which unmap is needed for ELF images with holes.) + */ + if (total_size) { + total_size = ELF_PAGEALIGN(total_size); + map_addr = do_mmap(filep, addr, total_size, prot, type, off); + if (!BAD_ADDR(map_addr)) + do_munmap(current->mm, map_addr+size, total_size-size); + } else + map_addr = do_mmap(filep, addr, size, prot, type, off); + up_write(¤t->mm->mmap_sem); return(map_addr); } #endif /* !elf_map */ +static unsigned long total_mapping_size(struct elf_phdr *cmds, int nr) +{ + int i, first_idx = -1, last_idx = -1; + + for (i = 0; i < nr; i++) { + if (cmds[i].p_type == PT_LOAD) { + last_idx = i; + if (first_idx == -1) + first_idx = i; + } + } + if (first_idx == -1) + return 0; + + return cmds[last_idx].p_vaddr + cmds[last_idx].p_memsz - + ELF_PAGESTART(cmds[first_idx].p_vaddr); +} + + /* This is much more generalized than the library routine read function, so we keep this separate. Technically the library read function is only provided so that we can read a.out libraries that have an ELF header */ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, - struct file *interpreter, unsigned long *interp_load_addr) + struct file *interpreter, unsigned long *interp_map_addr, + unsigned long no_base) { struct elf_phdr *elf_phdata; struct elf_phdr *eppnt; @@ -332,6 +369,7 @@ int load_addr_set = 0; unsigned long last_bss = 0, elf_bss = 0; unsigned long error = ~0UL; + unsigned long total_size; int retval, i, size; /* First of all, some simple consistency checks */ @@ -370,6 +408,12 @@ goto out_close; } + total_size = total_mapping_size(elf_phdata, interp_elf_ex->e_phnum); + if (!total_size) { + error = -EINVAL; + goto out_close; + } + eppnt = elf_phdata; for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) { if (eppnt->p_type == PT_LOAD) { @@ -387,9 +431,14 @@ vaddr = eppnt->p_vaddr; if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) elf_type |= MAP_FIXED; + else if (no_base && interp_elf_ex->e_type == ET_DYN) + load_addr = -vaddr; map_addr = elf_map(interpreter, load_addr + vaddr, - eppnt, elf_prot, elf_type); + eppnt, elf_prot, elf_type, total_size); + total_size = 0; + if (!*interp_map_addr) + *interp_map_addr = map_addr; error = map_addr; if (BAD_ADDR(map_addr)) goto out_close; @@ -455,8 +504,7 @@ goto out_close; } - *interp_load_addr = load_addr; - error = ((unsigned long)interp_elf_ex->e_entry) + load_addr; + error = load_addr; out_close: kfree(elf_phdata); @@ -553,7 +601,8 @@ int elf_exec_fileno; int retval, i; unsigned int size; - unsigned long elf_entry, interp_load_addr = 0; + unsigned long elf_entry; + unsigned long interp_load_addr = 0; unsigned long start_code, end_code, start_data, end_data; unsigned long reloc_func_desc = 0; char passed_fileno[6]; @@ -825,9 +874,7 @@ current->mm->start_stack = bprm->p; /* Now we do a little grungy work by mmaping the ELF image into - the correct location in memory. At this point, we assume that - the image should be loaded at fixed address, not at a variable - address. */ + the correct location in memory. */ for(i = 0, elf_ppnt = elf_phdata; i < loc->elf_ex.e_phnum; i++, elf_ppnt++) { int elf_prot = 0, elf_flags; @@ -881,11 +928,15 @@ * default mmap base, as well as whatever program they * might try to exec. This is because the brk will * follow the loader, and is not movable. */ +#ifdef CONFIG_X86 + load_bias = 0; +#else load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr); +#endif } error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, - elf_prot, elf_flags); + elf_prot, elf_flags,0); if (BAD_ADDR(error)) { send_sig(SIGKILL, current, 0); retval = IS_ERR((void *)error) ? @@ -961,13 +1012,25 @@ } if (elf_interpreter) { - if (interpreter_type == INTERPRETER_AOUT) + if (interpreter_type == INTERPRETER_AOUT) { elf_entry = load_aout_interp(&loc->interp_ex, interpreter); - else + } else { + unsigned long uninitialized_var(interp_map_addr); + elf_entry = load_elf_interp(&loc->interp_elf_ex, interpreter, - &interp_load_addr); + &interp_map_addr, + load_bias); + if (!IS_ERR((void *)elf_entry)) { + /* + * load_elf_interp() returns relocation + * adjustment + */ + interp_load_addr = elf_entry; + elf_entry += loc->interp_elf_ex.e_entry; + } + } if (BAD_ADDR(elf_entry)) { force_sig(SIGSEGV, current); retval = IS_ERR((void *)elf_entry) ? --- linux-2.6.24.orig/fs/inotify_user.c +++ linux-2.6.24/fs/inotify_user.c @@ -269,7 +269,7 @@ /* we can safely put the watch as we don't reference it while * generating the event */ - if (mask & IN_IGNORED || mask & IN_ONESHOT) + if (mask & IN_IGNORED || w->mask & IN_ONESHOT) put_inotify_watch(w); /* final put */ /* coalescing: drop this event if it is a dupe of the previous */ --- linux-2.6.24.orig/fs/inotify.c +++ linux-2.6.24/fs/inotify.c @@ -168,20 +168,14 @@ struct dentry *child; list_for_each_entry(child, &alias->d_subdirs, d_u.d_child) { - if (!child->d_inode) { - WARN_ON(child->d_flags & DCACHE_INOTIFY_PARENT_WATCHED); + if (!child->d_inode) continue; - } + spin_lock(&child->d_lock); - if (watched) { - WARN_ON(child->d_flags & - DCACHE_INOTIFY_PARENT_WATCHED); + if (watched) child->d_flags |= DCACHE_INOTIFY_PARENT_WATCHED; - } else { - WARN_ON(!(child->d_flags & - DCACHE_INOTIFY_PARENT_WATCHED)); - child->d_flags&=~DCACHE_INOTIFY_PARENT_WATCHED; - } + else + child->d_flags &=~DCACHE_INOTIFY_PARENT_WATCHED; spin_unlock(&child->d_lock); } } @@ -253,7 +247,6 @@ if (!inode) return; - WARN_ON(entry->d_flags & DCACHE_INOTIFY_PARENT_WATCHED); spin_lock(&entry->d_lock); parent = entry->d_parent; if (parent->d_inode && inotify_inode_watched(parent->d_inode)) @@ -627,6 +620,7 @@ struct inode *inode, u32 mask) { int ret = 0; + int newly_watched; /* don't allow invalid bits: we don't want flags set */ mask &= IN_ALL_EVENTS | IN_ONESHOT; @@ -653,12 +647,18 @@ */ watch->inode = igrab(inode); - if (!inotify_inode_watched(inode)) - set_dentry_child_flags(inode, 1); - /* Add the watch to the handle's and the inode's list */ + newly_watched = !inotify_inode_watched(inode); list_add(&watch->h_list, &ih->watches); list_add(&watch->i_list, &inode->inotify_watches); + /* + * Set child flags _after_ adding the watch, so there is no race + * windows where newly instantiated children could miss their parent's + * watched flag. + */ + if (newly_watched) + set_dentry_child_flags(inode, 1); + out: mutex_unlock(&ih->mutex); mutex_unlock(&inode->inotify_mutex); --- linux-2.6.24.orig/fs/namei.c +++ linux-2.6.24/fs/namei.c @@ -313,7 +313,13 @@ */ int file_permission(struct file *file, int mask) { - return permission(file->f_path.dentry->d_inode, mask, NULL); + struct nameidata nd; + + nd.dentry = file->f_path.dentry; + nd.mnt = file->f_path.mnt; + nd.flags = LOOKUP_ACCESS; + + return permission(nd.dentry->d_inode, mask, &nd); } /* @@ -504,7 +510,14 @@ */ result = d_lookup(parent, name); if (!result) { - struct dentry * dentry = d_alloc(parent, name); + struct dentry *dentry; + + /* Don't create child dentry for a dead directory. */ + result = ERR_PTR(-ENOENT); + if (IS_DEADDIR(dir)) + goto out_unlock; + + dentry = d_alloc(parent, name); result = ERR_PTR(-ENOMEM); if (dentry) { result = dir->i_op->lookup(dir, dentry, nd); @@ -513,6 +526,7 @@ else result = dentry; } +out_unlock: mutex_unlock(&dir->i_mutex); return result; } @@ -1147,25 +1161,24 @@ nd->dentry = dget(fs->pwd); read_unlock(&fs->lock); } else { - struct dentry *dentry; - file = fget_light(dfd, &fput_needed); retval = -EBADF; if (!file) goto out_fail; - dentry = file->f_path.dentry; + nd->dentry = file->f_path.dentry; + nd->mnt = file->f_path.mnt; retval = -ENOTDIR; - if (!S_ISDIR(dentry->d_inode->i_mode)) + if (!S_ISDIR(nd->dentry->d_inode->i_mode)) goto fput_fail; - retval = file_permission(file, MAY_EXEC); + retval = vfs_permission(nd, MAY_EXEC); if (retval) goto fput_fail; - nd->mnt = mntget(file->f_path.mnt); - nd->dentry = dget(dentry); + mntget(nd->mnt); + dget(nd->dentry); fput_light(file, fput_needed); } @@ -1288,8 +1301,7 @@ return err; } -static struct dentry *__lookup_hash(struct qstr *name, - struct dentry *base, struct nameidata *nd) +struct dentry *__lookup_hash(struct qstr *name, struct dentry *base, struct nameidata *nd) { struct dentry *dentry; struct inode *inode; @@ -1310,7 +1322,14 @@ dentry = cached_lookup(base, name, nd); if (!dentry) { - struct dentry *new = d_alloc(base, name); + struct dentry *new; + + /* Don't create child dentry for a dead directory. */ + dentry = ERR_PTR(-ENOENT); + if (IS_DEADDIR(inode)) + goto out; + + new = d_alloc(base, name); dentry = ERR_PTR(-ENOMEM); if (!new) goto out; @@ -1508,6 +1527,8 @@ return -EEXIST; if (IS_DEADDIR(dir)) return -ENOENT; + if (nd) + nd->flags |= LOOKUP_CONTINUE; return permission(dir,MAY_WRITE | MAY_EXEC, nd); } @@ -1583,7 +1604,7 @@ return -EACCES; /* shouldn't it be ENOSYS? */ mode &= S_IALLUGO; mode |= S_IFREG; - error = security_inode_create(dir, dentry, mode); + error = security_inode_create(dir, dentry, nd ? nd->mnt : NULL, mode); if (error) return error; DQUOT_INIT(dir); @@ -1660,7 +1681,7 @@ if (!error) { DQUOT_INIT(inode); - error = do_truncate(dentry, 0, + error = do_truncate(dentry, nd->mnt, 0, ATTR_MTIME|ATTR_CTIME|ATTR_OPEN, NULL); } @@ -1918,7 +1939,8 @@ } EXPORT_SYMBOL_GPL(lookup_create); -int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) +int vfs_mknod(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt, + int mode, dev_t dev) { int error = may_create(dir, dentry, NULL); @@ -1931,7 +1953,7 @@ if (!dir->i_op || !dir->i_op->mknod) return -EPERM; - error = security_inode_mknod(dir, dentry, mode, dev); + error = security_inode_mknod(dir, dentry, mnt, mode, dev); if (error) return error; @@ -1970,11 +1992,12 @@ error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd); break; case S_IFCHR: case S_IFBLK: - error = vfs_mknod(nd.dentry->d_inode,dentry,mode, - new_decode_dev(dev)); + error = vfs_mknod(nd.dentry->d_inode, dentry, nd.mnt, + mode, new_decode_dev(dev)); break; case S_IFIFO: case S_IFSOCK: - error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0); + error = vfs_mknod(nd.dentry->d_inode, dentry, nd.mnt, + mode, 0); break; case S_IFDIR: error = -EPERM; @@ -1997,7 +2020,8 @@ return sys_mknodat(AT_FDCWD, filename, mode, dev); } -int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) +int vfs_mkdir(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt, + int mode) { int error = may_create(dir, dentry, NULL); @@ -2008,7 +2032,7 @@ return -EPERM; mode &= (S_IRWXUGO|S_ISVTX); - error = security_inode_mkdir(dir, dentry, mode); + error = security_inode_mkdir(dir, dentry, mnt, mode); if (error) return error; @@ -2041,7 +2065,7 @@ if (!IS_POSIXACL(nd.dentry->d_inode)) mode &= ~current->fs->umask; - error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); + error = vfs_mkdir(nd.dentry->d_inode, dentry, nd.mnt, mode); dput(dentry); out_unlock: mutex_unlock(&nd.dentry->d_inode->i_mutex); @@ -2084,7 +2108,7 @@ spin_unlock(&dcache_lock); } -int vfs_rmdir(struct inode *dir, struct dentry *dentry) +int vfs_rmdir(struct inode *dir, struct dentry *dentry,struct vfsmount *mnt) { int error = may_delete(dir, dentry, 1); @@ -2094,6 +2118,10 @@ if (!dir->i_op || !dir->i_op->rmdir) return -EPERM; + error = security_inode_rmdir(dir, dentry, mnt); + if (error) + return error; + DQUOT_INIT(dir); mutex_lock(&dentry->d_inode->i_mutex); @@ -2101,12 +2129,9 @@ if (d_mountpoint(dentry)) error = -EBUSY; else { - error = security_inode_rmdir(dir, dentry); - if (!error) { - error = dir->i_op->rmdir(dir, dentry); - if (!error) - dentry->d_inode->i_flags |= S_DEAD; - } + error = dir->i_op->rmdir(dir, dentry); + if (!error) + dentry->d_inode->i_flags |= S_DEAD; } mutex_unlock(&dentry->d_inode->i_mutex); if (!error) { @@ -2148,7 +2173,7 @@ error = PTR_ERR(dentry); if (IS_ERR(dentry)) goto exit2; - error = vfs_rmdir(nd.dentry->d_inode, dentry); + error = vfs_rmdir(nd.dentry->d_inode, dentry, nd.mnt); dput(dentry); exit2: mutex_unlock(&nd.dentry->d_inode->i_mutex); @@ -2164,7 +2189,7 @@ return do_rmdir(AT_FDCWD, pathname); } -int vfs_unlink(struct inode *dir, struct dentry *dentry) +int vfs_unlink(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt) { int error = may_delete(dir, dentry, 0); @@ -2180,7 +2205,7 @@ if (d_mountpoint(dentry)) error = -EBUSY; else { - error = security_inode_unlink(dir, dentry); + error = security_inode_unlink(dir, dentry, mnt); if (!error) error = dir->i_op->unlink(dir, dentry); } @@ -2228,7 +2253,7 @@ inode = dentry->d_inode; if (inode) atomic_inc(&inode->i_count); - error = vfs_unlink(nd.dentry->d_inode, dentry); + error = vfs_unlink(nd.dentry->d_inode, dentry, nd.mnt); exit2: dput(dentry); } @@ -2263,7 +2288,8 @@ return do_unlinkat(AT_FDCWD, pathname); } -int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode) +int vfs_symlink(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt, + const char *oldname, int mode) { int error = may_create(dir, dentry, NULL); @@ -2273,7 +2299,7 @@ if (!dir->i_op || !dir->i_op->symlink) return -EPERM; - error = security_inode_symlink(dir, dentry, oldname); + error = security_inode_symlink(dir, dentry, mnt, oldname); if (error) return error; @@ -2309,7 +2335,8 @@ if (IS_ERR(dentry)) goto out_unlock; - error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO); + error = vfs_symlink(nd.dentry->d_inode, dentry, nd.mnt, from, + S_IALLUGO); dput(dentry); out_unlock: mutex_unlock(&nd.dentry->d_inode->i_mutex); @@ -2326,7 +2353,7 @@ return sys_symlinkat(oldname, AT_FDCWD, newname); } -int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) +int vfs_link(struct dentry *old_dentry, struct vfsmount *old_mnt, struct inode *dir, struct dentry *new_dentry, struct vfsmount *new_mnt) { struct inode *inode = old_dentry->d_inode; int error; @@ -2351,7 +2378,8 @@ if (S_ISDIR(old_dentry->d_inode->i_mode)) return -EPERM; - error = security_inode_link(old_dentry, dir, new_dentry); + error = security_inode_link(old_dentry, old_mnt, dir, new_dentry, + new_mnt); if (error) return error; @@ -2404,7 +2432,8 @@ error = PTR_ERR(new_dentry); if (IS_ERR(new_dentry)) goto out_unlock; - error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); + error = vfs_link(old_nd.dentry, old_nd.mnt, nd.dentry->d_inode, + new_dentry, nd.mnt); dput(new_dentry); out_unlock: mutex_unlock(&nd.dentry->d_inode->i_mutex); @@ -2456,7 +2485,8 @@ * locking]. */ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry) + struct vfsmount *old_mnt, struct inode *new_dir, + struct dentry *new_dentry, struct vfsmount *new_mnt) { int error = 0; struct inode *target; @@ -2471,7 +2501,8 @@ return error; } - error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry); + error = security_inode_rename(old_dir, old_dentry, old_mnt, + new_dir, new_dentry, new_mnt); if (error) return error; @@ -2499,12 +2530,14 @@ } static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry) + struct vfsmount *old_mnt, struct inode *new_dir, + struct dentry *new_dentry, struct vfsmount *new_mnt) { struct inode *target; int error; - error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry); + error = security_inode_rename(old_dir, old_dentry, old_mnt, + new_dir, new_dentry, new_mnt); if (error) return error; @@ -2527,7 +2560,8 @@ } int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry) + struct vfsmount *old_mnt, struct inode *new_dir, + struct dentry *new_dentry, struct vfsmount *new_mnt) { int error; int is_dir = S_ISDIR(old_dentry->d_inode->i_mode); @@ -2556,9 +2590,11 @@ old_name = fsnotify_oldname_init(old_dentry->d_name.name); if (is_dir) - error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry); + error = vfs_rename_dir(old_dir, old_dentry, old_mnt, + new_dir, new_dentry, new_mnt); else - error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry); + error = vfs_rename_other(old_dir, old_dentry, old_mnt, + new_dir, new_dentry, new_mnt); if (!error) { const char *new_name = old_dentry->d_name.name; fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir, @@ -2630,8 +2666,8 @@ if (new_dentry == trap) goto exit5; - error = vfs_rename(old_dir->d_inode, old_dentry, - new_dir->d_inode, new_dentry); + error = vfs_rename(old_dir->d_inode, old_dentry, oldnd.mnt, + new_dir->d_inode, new_dentry, newnd.mnt); exit5: dput(new_dentry); exit4: @@ -2806,6 +2842,7 @@ EXPORT_SYMBOL(get_write_access); /* binfmt_aout */ EXPORT_SYMBOL(getname); EXPORT_SYMBOL(lock_rename); +EXPORT_SYMBOL(__lookup_hash); EXPORT_SYMBOL(lookup_one_len); EXPORT_SYMBOL(page_follow_link_light); EXPORT_SYMBOL(page_put_link); @@ -2833,3 +2870,4 @@ EXPORT_SYMBOL(vfs_unlink); EXPORT_SYMBOL(dentry_unhash); EXPORT_SYMBOL(generic_readlink); +EXPORT_SYMBOL(deny_write_access); --- linux-2.6.24.orig/fs/namespace.c +++ linux-2.6.24/fs/namespace.c @@ -38,7 +38,8 @@ static struct list_head *mount_hashtable __read_mostly; static int hash_mask __read_mostly, hash_bits __read_mostly; static struct kmem_cache *mnt_cache __read_mostly; -static struct rw_semaphore namespace_sem; +struct rw_semaphore namespace_sem; +EXPORT_SYMBOL_GPL(namespace_sem); /* /sys/fs */ decl_subsys(fs, NULL, NULL); @@ -1127,6 +1128,7 @@ goto unlock; newmnt->mnt_flags = mnt_flags; + if ((err = graft_tree(newmnt, nd))) goto unlock; @@ -1382,6 +1384,24 @@ } /* + * Allow users to disable (or enable) atime updates via a .config + * option or via the boot line, or via /proc/sys/fs/default_relatime: + */ +int default_relatime __read_mostly = CONFIG_DEFAULT_RELATIME_VAL; + +static int __init set_default_relatime(char *str) +{ + get_option(&str, &default_relatime); + + printk(KERN_INFO "Mount all filesystems with" + "default relative atime updates: %s.\n", + default_relatime ? "enabled" : "disabled"); + + return 1; +} +__setup("default_relatime=", set_default_relatime); + +/* * Flags is a 32-bit value that allows up to 31 non-fs dependent flags to * be given to the mount() call (ie: read-only, no-dev, no-suid etc). * @@ -1429,6 +1449,11 @@ mnt_flags |= MNT_NODIRATIME; if (flags & MS_RELATIME) mnt_flags |= MNT_RELATIME; + else if (default_relatime && + !(flags & (MNT_NOATIME | MNT_NODIRATIME))) { + mnt_flags |= MNT_RELATIME; + flags |= MS_RELATIME; + } flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT); @@ -1883,3 +1908,30 @@ release_mounts(&umount_list); kfree(ns); } + +char *d_namespace_path(struct dentry *dentry, struct vfsmount *vfsmnt, + char *buf, int buflen) +{ + struct vfsmount *rootmnt, *nsrootmnt = NULL; + struct dentry *root = NULL; + char *res; + + read_lock(¤t->fs->lock); + rootmnt = mntget(current->fs->rootmnt); + read_unlock(¤t->fs->lock); + spin_lock(&vfsmount_lock); + if (rootmnt->mnt_ns) + nsrootmnt = mntget(rootmnt->mnt_ns->root); + spin_unlock(&vfsmount_lock); + mntput(rootmnt); + if (nsrootmnt) + root = dget(nsrootmnt->mnt_root); + res = __d_path(dentry, vfsmnt, root, nsrootmnt, buf, buflen, 1); + dput(root); + mntput(nsrootmnt); + /* Prevent empty path for lazily unmounted filesystems. */ + if (!IS_ERR(res) && *res == '\0') + *--res = '.'; + return res; +} +EXPORT_SYMBOL(d_namespace_path); --- linux-2.6.24.orig/fs/utimes.c +++ linux-2.6.24/fs/utimes.c @@ -38,9 +38,14 @@ #endif +static bool nsec_special(long nsec) +{ + return nsec == UTIME_OMIT || nsec == UTIME_NOW; +} + static bool nsec_valid(long nsec) { - if (nsec == UTIME_OMIT || nsec == UTIME_NOW) + if (nsec_special(nsec)) return true; return nsec >= 0 && nsec <= 999999999; @@ -54,7 +59,7 @@ { int error; struct nameidata nd; - struct dentry *dentry; + struct path path; struct inode *inode; struct iattr newattrs; struct file *f = NULL; @@ -77,16 +82,17 @@ f = fget(dfd); if (!f) goto out; - dentry = f->f_path.dentry; + path = f->f_path; } else { error = __user_walk_fd(dfd, filename, (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW, &nd); if (error) goto out; - dentry = nd.dentry; + path.dentry = nd.dentry; + path.mnt = nd.mnt; } - inode = dentry->d_inode; + inode = path.dentry->d_inode; error = -EROFS; if (IS_RDONLY(inode)) @@ -114,7 +120,15 @@ newattrs.ia_mtime.tv_nsec = times[1].tv_nsec; newattrs.ia_valid |= ATTR_MTIME_SET; } - } else { + } + + /* + * If times is NULL or both times are either UTIME_OMIT or + * UTIME_NOW, then need to check permissions, because + * inode_change_ok() won't do it. + */ + if (!times || (nsec_special(times[0].tv_nsec) && + nsec_special(times[1].tv_nsec))) { error = -EACCES; if (IS_IMMUTABLE(inode)) goto dput_and_out; @@ -131,7 +145,7 @@ } } mutex_lock(&inode->i_mutex); - error = notify_change(dentry, &newattrs); + error = fnotify_change(path.dentry, path.mnt, &newattrs, f); mutex_unlock(&inode->i_mutex); dput_and_out: if (f) --- linux-2.6.24.orig/fs/dnotify.c +++ linux-2.6.24/fs/dnotify.c @@ -20,6 +20,7 @@ #include #include #include +#include int dir_notify_enable __read_mostly = 1; @@ -66,6 +67,7 @@ struct dnotify_struct **prev; struct inode *inode; fl_owner_t id = current->files; + struct file *f; int error = 0; if ((arg & ~DN_MULTISHOT) == 0) { @@ -92,6 +94,15 @@ prev = &odn->dn_next; } + rcu_read_lock(); + f = fcheck(fd); + rcu_read_unlock(); + /* we'd lost the race with close(), sod off silently */ + /* note that inode->i_lock prevents reordering problems + * between accesses to descriptor table and ->i_dnotify */ + if (f != filp) + goto out_free; + error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0); if (error) goto out_free; --- linux-2.6.24.orig/fs/splice.c +++ linux-2.6.24/fs/splice.c @@ -314,7 +314,7 @@ break; error = add_to_page_cache_lru(page, mapping, index, - GFP_KERNEL); + mapping_gfp_mask(mapping)); if (unlikely(error)) { page_cache_release(page); if (error == -EEXIST) @@ -775,7 +775,7 @@ ssize_t ret; int err; - err = remove_suid(out->f_path.dentry); + err = remove_suid(&out->f_path); if (unlikely(err)) return err; @@ -835,7 +835,7 @@ if (killpriv) err = security_inode_killpriv(out->f_path.dentry); if (!err && killsuid) - err = __remove_suid(out->f_path.dentry, killsuid); + err = __remove_suid(&out->f_path, killsuid); mutex_unlock(&inode->i_mutex); if (err) return err; @@ -893,8 +893,8 @@ /* * Attempt to initiate a splice from pipe to file. */ -static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, - loff_t *ppos, size_t len, unsigned int flags) +long do_splice_from(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags) { int ret; @@ -904,6 +904,9 @@ if (unlikely(!(out->f_mode & FMODE_WRITE))) return -EBADF; + if (unlikely(out->f_flags & O_APPEND)) + return -EINVAL; + ret = rw_verify_area(WRITE, out, ppos, len); if (unlikely(ret < 0)) return ret; @@ -914,13 +917,14 @@ return out->f_op->splice_write(pipe, out, ppos, len, flags); } +EXPORT_SYMBOL(do_splice_from); /* * Attempt to initiate a splice from a file to a pipe. */ -static long do_splice_to(struct file *in, loff_t *ppos, - struct pipe_inode_info *pipe, size_t len, - unsigned int flags) +long do_splice_to(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags) { int ret; @@ -940,6 +944,7 @@ return in->f_op->splice_read(in, ppos, pipe, len, flags); } +EXPORT_SYMBOL(do_splice_to); /** * splice_direct_to_actor - splices data directly between two non-pipes --- linux-2.6.24.orig/fs/stat.c +++ linux-2.6.24/fs/stat.c @@ -55,6 +55,33 @@ EXPORT_SYMBOL(vfs_getattr); +/* + * Perform getattr on an open file + * + * Fall back to i_op->getattr (or generic_fillattr) if the filesystem + * doesn't define an f_op->fgetattr operation. + */ +static int vfs_fgetattr(struct file *file, struct kstat *stat) +{ + struct vfsmount *mnt = file->f_path.mnt; + struct dentry *dentry = file->f_path.dentry; + struct inode *inode = dentry->d_inode; + int retval; + + retval = security_inode_getattr(mnt, dentry); + if (retval) + return retval; + + if (file->f_op && file->f_op->fgetattr) { + return file->f_op->fgetattr(file, stat); + } else if (inode->i_op->getattr) { + return inode->i_op->getattr(mnt, dentry, stat); + } else { + generic_fillattr(inode, stat); + return 0; + } +} + int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat) { struct nameidata nd; @@ -101,7 +128,7 @@ int error = -EBADF; if (f) { - error = vfs_getattr(f->f_path.mnt, f->f_path.dentry, stat); + error = vfs_fgetattr(f, stat); fput(f); } return error; @@ -306,7 +333,7 @@ error = -EINVAL; if (inode->i_op && inode->i_op->readlink) { - error = security_inode_readlink(nd.dentry); + error = security_inode_readlink(nd.dentry, nd.mnt); if (!error) { touch_atime(nd.mnt, nd.dentry); error = inode->i_op->readlink(nd.dentry, buf, bufsiz); --- linux-2.6.24.orig/fs/xattr.c +++ linux-2.6.24/fs/xattr.c @@ -68,8 +68,8 @@ } int -vfs_setxattr(struct dentry *dentry, char *name, void *value, - size_t size, int flags) +vfs_setxattr(struct dentry *dentry, struct vfsmount *mnt, char *name, + void *value, size_t size, int flags, struct file *file) { struct inode *inode = dentry->d_inode; int error; @@ -79,7 +79,7 @@ return error; mutex_lock(&inode->i_mutex); - error = security_inode_setxattr(dentry, name, value, size, flags); + error = security_inode_setxattr(dentry, mnt, name, value, size, flags, file); if (error) goto out; error = -EOPNOTSUPP; @@ -87,7 +87,7 @@ error = inode->i_op->setxattr(dentry, name, value, size, flags); if (!error) { fsnotify_xattr(dentry); - security_inode_post_setxattr(dentry, name, value, + security_inode_post_setxattr(dentry, mnt, name, value, size, flags); } } else if (!strncmp(name, XATTR_SECURITY_PREFIX, @@ -105,7 +105,8 @@ EXPORT_SYMBOL_GPL(vfs_setxattr); ssize_t -vfs_getxattr(struct dentry *dentry, char *name, void *value, size_t size) +vfs_getxattr(struct dentry *dentry, struct vfsmount *mnt, char *name, + void *value, size_t size, struct file *file) { struct inode *inode = dentry->d_inode; int error; @@ -114,7 +115,7 @@ if (error) return error; - error = security_inode_getxattr(dentry, name); + error = security_inode_getxattr(dentry, mnt, name, file); if (error) return error; @@ -141,18 +142,20 @@ EXPORT_SYMBOL_GPL(vfs_getxattr); ssize_t -vfs_listxattr(struct dentry *d, char *list, size_t size) +vfs_listxattr(struct dentry *dentry, struct vfsmount *mnt, char *list, + size_t size, struct file *file) { + struct inode *inode = dentry->d_inode; ssize_t error; - error = security_inode_listxattr(d); + error = security_inode_listxattr(dentry, mnt, file); if (error) return error; error = -EOPNOTSUPP; - if (d->d_inode->i_op && d->d_inode->i_op->listxattr) { - error = d->d_inode->i_op->listxattr(d, list, size); - } else { - error = security_inode_listsecurity(d->d_inode, list, size); + if (inode->i_op && inode->i_op->listxattr) + error = inode->i_op->listxattr(dentry, list, size); + else { + error = security_inode_listsecurity(inode, list, size); if (size && error > size) error = -ERANGE; } @@ -161,7 +164,8 @@ EXPORT_SYMBOL_GPL(vfs_listxattr); int -vfs_removexattr(struct dentry *dentry, char *name) +vfs_removexattr(struct dentry *dentry, struct vfsmount *mnt, char *name, + struct file *file) { struct inode *inode = dentry->d_inode; int error; @@ -173,7 +177,7 @@ if (error) return error; - error = security_inode_removexattr(dentry, name); + error = security_inode_removexattr(dentry, mnt, name, file); if (error) return error; @@ -192,8 +196,8 @@ * Extended attribute SET operations */ static long -setxattr(struct dentry *d, char __user *name, void __user *value, - size_t size, int flags) +setxattr(struct dentry *dentry, struct vfsmount *mnt, char __user *name, + void __user *value, size_t size, int flags, struct file *file) { int error; void *kvalue = NULL; @@ -220,7 +224,7 @@ } } - error = vfs_setxattr(d, kname, kvalue, size, flags); + error = vfs_setxattr(dentry, mnt, kname, kvalue, size, flags, file); kfree(kvalue); return error; } @@ -235,7 +239,7 @@ error = user_path_walk(path, &nd); if (error) return error; - error = setxattr(nd.dentry, name, value, size, flags); + error = setxattr(nd.dentry, nd.mnt, name, value, size, flags, NULL); path_release(&nd); return error; } @@ -250,7 +254,7 @@ error = user_path_walk_link(path, &nd); if (error) return error; - error = setxattr(nd.dentry, name, value, size, flags); + error = setxattr(nd.dentry, nd.mnt, name, value, size, flags, NULL); path_release(&nd); return error; } @@ -268,7 +272,7 @@ return error; dentry = f->f_path.dentry; audit_inode(NULL, dentry); - error = setxattr(dentry, name, value, size, flags); + error = setxattr(dentry, f->f_vfsmnt, name, value, size, flags, f); fput(f); return error; } @@ -277,7 +281,8 @@ * Extended attribute GET operations */ static ssize_t -getxattr(struct dentry *d, char __user *name, void __user *value, size_t size) +getxattr(struct dentry *dentry, struct vfsmount *mnt, char __user *name, + void __user *value, size_t size, struct file *file) { ssize_t error; void *kvalue = NULL; @@ -297,7 +302,7 @@ return -ENOMEM; } - error = vfs_getxattr(d, kname, kvalue, size); + error = vfs_getxattr(dentry, mnt, kname, kvalue, size, file); if (error > 0) { if (size && copy_to_user(value, kvalue, error)) error = -EFAULT; @@ -320,7 +325,7 @@ error = user_path_walk(path, &nd); if (error) return error; - error = getxattr(nd.dentry, name, value, size); + error = getxattr(nd.dentry, nd.mnt, name, value, size, NULL); path_release(&nd); return error; } @@ -335,7 +340,7 @@ error = user_path_walk_link(path, &nd); if (error) return error; - error = getxattr(nd.dentry, name, value, size); + error = getxattr(nd.dentry, nd.mnt, name, value, size, NULL); path_release(&nd); return error; } @@ -350,7 +355,7 @@ if (!f) return error; audit_inode(NULL, f->f_path.dentry); - error = getxattr(f->f_path.dentry, name, value, size); + error = getxattr(f->f_path.dentry, f->f_path.mnt, name, value, size, f); fput(f); return error; } @@ -359,7 +364,8 @@ * Extended attribute LIST operations */ static ssize_t -listxattr(struct dentry *d, char __user *list, size_t size) +listxattr(struct dentry *dentry, struct vfsmount *mnt, char __user *list, + size_t size, struct file *file) { ssize_t error; char *klist = NULL; @@ -372,7 +378,7 @@ return -ENOMEM; } - error = vfs_listxattr(d, klist, size); + error = vfs_listxattr(dentry, mnt, klist, size, file); if (error > 0) { if (size && copy_to_user(list, klist, error)) error = -EFAULT; @@ -394,7 +400,7 @@ error = user_path_walk(path, &nd); if (error) return error; - error = listxattr(nd.dentry, list, size); + error = listxattr(nd.dentry, nd.mnt, list, size, NULL); path_release(&nd); return error; } @@ -408,7 +414,7 @@ error = user_path_walk_link(path, &nd); if (error) return error; - error = listxattr(nd.dentry, list, size); + error = listxattr(nd.dentry, nd.mnt, list, size, NULL); path_release(&nd); return error; } @@ -423,7 +429,7 @@ if (!f) return error; audit_inode(NULL, f->f_path.dentry); - error = listxattr(f->f_path.dentry, list, size); + error = listxattr(f->f_path.dentry, f->f_path.mnt, list, size, f); fput(f); return error; } @@ -432,7 +438,8 @@ * Extended attribute REMOVE operations */ static long -removexattr(struct dentry *d, char __user *name) +removexattr(struct dentry *dentry, struct vfsmount *mnt, char __user *name, + struct file *file) { int error; char kname[XATTR_NAME_MAX + 1]; @@ -443,7 +450,7 @@ if (error < 0) return error; - return vfs_removexattr(d, kname); + return vfs_removexattr(dentry, mnt, kname, file); } asmlinkage long @@ -455,7 +462,7 @@ error = user_path_walk(path, &nd); if (error) return error; - error = removexattr(nd.dentry, name); + error = removexattr(nd.dentry, nd.mnt, name, NULL); path_release(&nd); return error; } @@ -469,7 +476,7 @@ error = user_path_walk_link(path, &nd); if (error) return error; - error = removexattr(nd.dentry, name); + error = removexattr(nd.dentry, nd.mnt, name, NULL); path_release(&nd); return error; } @@ -486,7 +493,7 @@ return error; dentry = f->f_path.dentry; audit_inode(NULL, dentry); - error = removexattr(dentry, name); + error = removexattr(dentry, f->f_path.mnt, name, f); fput(f); return error; } --- linux-2.6.24.orig/fs/signalfd.c +++ linux-2.6.24/fs/signalfd.c @@ -110,9 +110,14 @@ err |= __put_user(kinfo->si_uid, &uinfo->ssi_uid); err |= __put_user((long) kinfo->si_ptr, &uinfo->ssi_ptr); break; - default: /* this is just in case for now ... */ + default: + /* + * This case catches also the signals queued by sigqueue(). + */ err |= __put_user(kinfo->si_pid, &uinfo->ssi_pid); err |= __put_user(kinfo->si_uid, &uinfo->ssi_uid); + err |= __put_user((long) kinfo->si_ptr, &uinfo->ssi_ptr); + err |= __put_user(kinfo->si_int, &uinfo->ssi_int); break; } --- linux-2.6.24.orig/fs/buffer.c +++ linux-2.6.24/fs/buffer.c @@ -2565,14 +2565,13 @@ struct inode *inode = page->mapping->host; struct buffer_head *head = fsdata; struct buffer_head *bh; + BUG_ON(fsdata != NULL && page_has_buffers(page)); - if (!PageMappedToDisk(page)) { - if (unlikely(copied < len) && !page_has_buffers(page)) - attach_nobh_buffers(page, head); - if (page_has_buffers(page)) - return generic_write_end(file, mapping, pos, len, - copied, page, fsdata); - } + if (unlikely(copied < len) && !page_has_buffers(page)) + attach_nobh_buffers(page, head); + if (page_has_buffers(page)) + return generic_write_end(file, mapping, pos, len, + copied, page, fsdata); SetPageUptodate(page); set_page_dirty(page); --- linux-2.6.24.orig/fs/locks.c +++ linux-2.6.24/fs/locks.c @@ -1754,6 +1754,7 @@ struct file_lock *file_lock = locks_alloc_lock(); struct flock flock; struct inode *inode; + struct file *f; int error; if (file_lock == NULL) @@ -1805,24 +1806,36 @@ if (error) goto out; - for (;;) { - error = vfs_lock_file(filp, cmd, file_lock, NULL); - if (error != -EAGAIN || cmd == F_SETLK) - break; - error = wait_event_interruptible(file_lock->fl_wait, - !file_lock->fl_next); - if (!error) - continue; + if (filp->f_op && filp->f_op->lock != NULL) + error = filp->f_op->lock(filp, cmd, file_lock); + else { + for (;;) { + error = posix_lock_file(filp, file_lock, NULL); + if (error != -EAGAIN || cmd == F_SETLK) + break; + error = wait_event_interruptible(file_lock->fl_wait, + !file_lock->fl_next); + if (!error) + continue; - locks_delete_block(file_lock); - break; + locks_delete_block(file_lock); + break; + } } /* * Attempt to detect a close/fcntl race and recover by * releasing the lock that was just acquired. */ - if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) { + /* + * we need that spin_lock here - it prevents reordering between + * update of inode->i_flock and check for it done in close(). + * rcu_read_lock() wouldn't do. + */ + spin_lock(¤t->files->file_lock); + f = fcheck(fd); + spin_unlock(¤t->files->file_lock); + if (!error && f != filp && flock.l_type != F_UNLCK) { flock.l_type = F_UNLCK; goto again; } @@ -1878,6 +1891,7 @@ struct file_lock *file_lock = locks_alloc_lock(); struct flock64 flock; struct inode *inode; + struct file *f; int error; if (file_lock == NULL) @@ -1929,24 +1943,31 @@ if (error) goto out; - for (;;) { - error = vfs_lock_file(filp, cmd, file_lock, NULL); - if (error != -EAGAIN || cmd == F_SETLK64) - break; - error = wait_event_interruptible(file_lock->fl_wait, - !file_lock->fl_next); - if (!error) - continue; + if (filp->f_op && filp->f_op->lock != NULL) + error = filp->f_op->lock(filp, cmd, file_lock); + else { + for (;;) { + error = posix_lock_file(filp, file_lock, NULL); + if (error != -EAGAIN || cmd == F_SETLK64) + break; + error = wait_event_interruptible(file_lock->fl_wait, + !file_lock->fl_next); + if (!error) + continue; - locks_delete_block(file_lock); - break; + locks_delete_block(file_lock); + break; + } } /* * Attempt to detect a close/fcntl race and recover by * releasing the lock that was just acquired. */ - if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) { + spin_lock(¤t->files->file_lock); + f = fcheck(fd); + spin_unlock(¤t->files->file_lock); + if (!error && f != filp && flock.l_type != F_UNLCK) { flock.l_type = F_UNLCK; goto again; } --- linux-2.6.24.orig/fs/inode.c +++ linux-2.6.24/fs/inode.c @@ -1189,6 +1189,41 @@ } EXPORT_SYMBOL(bmap); +/* + * Relative atime updates frequency (default: 1 day): + */ +int relatime_interval __read_mostly = 24*60*60; + +/* + * With relative atime, only update atime if the + * previous atime is earlier than either the ctime or + * mtime. + */ +static int relatime_need_update(struct inode *inode, struct timespec now) +{ + /* + * Is mtime younger than atime? If yes, update atime: + */ + if (timespec_compare(&inode->i_mtime, &inode->i_atime) >= 0) + return 1; + /* + * Is ctime younger than atime? If yes, update atime: + */ + if (timespec_compare(&inode->i_ctime, &inode->i_atime) >= 0) + return 1; + + /* + * Is the previous atime value older than a day? If yes, + * update atime: + */ + if ((long)(now.tv_sec - inode->i_atime.tv_sec) >= relatime_interval) + return 1; + /* + * Good, we can skip the atime update: + */ + return 0; +} + /** * touch_atime - update the access time * @mnt: mount the inode is accessed on @@ -1218,22 +1253,14 @@ return; if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)) return; - - if (mnt->mnt_flags & MNT_RELATIME) { - /* - * With relative atime, only update atime if the - * previous atime is earlier than either the ctime or - * mtime. - */ - if (timespec_compare(&inode->i_mtime, - &inode->i_atime) < 0 && - timespec_compare(&inode->i_ctime, - &inode->i_atime) < 0) + } + now = current_fs_time(inode->i_sb); + if (mnt) { + if (mnt->mnt_flags & MNT_RELATIME) + if (!relatime_need_update(inode, now)) return; - } } - now = current_fs_time(inode->i_sb); if (timespec_equal(&inode->i_atime, &now)) return; --- linux-2.6.24.orig/fs/dlm/lockspace.c +++ linux-2.6.24/fs/dlm/lockspace.c @@ -24,14 +24,6 @@ #include "recover.h" #include "requestqueue.h" -#ifdef CONFIG_DLM_DEBUG -int dlm_create_debug_file(struct dlm_ls *ls); -void dlm_delete_debug_file(struct dlm_ls *ls); -#else -static inline int dlm_create_debug_file(struct dlm_ls *ls) { return 0; } -static inline void dlm_delete_debug_file(struct dlm_ls *ls) { } -#endif - static int ls_count; static struct mutex ls_lock; static struct list_head lslist; @@ -218,7 +210,7 @@ } -int dlm_lockspace_init(void) +int __init dlm_lockspace_init(void) { int error; @@ -706,9 +698,9 @@ dlm_del_ast(lkb); if (lkb->lkb_lvbptr && lkb->lkb_flags & DLM_IFL_MSTCPY) - free_lvb(lkb->lkb_lvbptr); + dlm_free_lvb(lkb->lkb_lvbptr); - free_lkb(lkb); + dlm_free_lkb(lkb); } } dlm_astd_resume(); @@ -726,7 +718,7 @@ res_hashchain); list_del(&rsb->res_hashchain); - free_rsb(rsb); + dlm_free_rsb(rsb); } head = &ls->ls_rsbtbl[i].toss; @@ -734,7 +726,7 @@ rsb = list_entry(head->next, struct dlm_rsb, res_hashchain); list_del(&rsb->res_hashchain); - free_rsb(rsb); + dlm_free_rsb(rsb); } } --- linux-2.6.24.orig/fs/dlm/midcomms.c +++ linux-2.6.24/fs/dlm/midcomms.c @@ -2,7 +2,7 @@ ******************************************************************************* ** ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. +** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. ** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions @@ -58,8 +58,12 @@ int dlm_process_incoming_buffer(int nodeid, const void *base, unsigned offset, unsigned len, unsigned limit) { - unsigned char __tmp[DLM_INBUF_LEN]; - struct dlm_header *msg = (struct dlm_header *) __tmp; + union { + unsigned char __buf[DLM_INBUF_LEN]; + /* this is to force proper alignment on some arches */ + union dlm_packet p; + } __tmp; + union dlm_packet *p = &__tmp.p; int ret = 0; int err = 0; uint16_t msglen; @@ -71,15 +75,22 @@ message may wrap around the end of the buffer back to the start, so we need to use a temp buffer and copy_from_cb. */ - copy_from_cb(msg, base, offset, sizeof(struct dlm_header), + copy_from_cb(p, base, offset, sizeof(struct dlm_header), limit); - msglen = le16_to_cpu(msg->h_length); - lockspace = msg->h_lockspace; + msglen = le16_to_cpu(p->header.h_length); + lockspace = p->header.h_lockspace; err = -EINVAL; if (msglen < sizeof(struct dlm_header)) break; + if (p->header.h_cmd == DLM_MSG) { + if (msglen < sizeof(struct dlm_message)) + break; + } else { + if (msglen < sizeof(struct dlm_rcom)) + break; + } err = -E2BIG; if (msglen > dlm_config.ci_buffer_size) { log_print("message size %d from %d too big, buf len %d", @@ -100,27 +111,26 @@ in the buffer on the stack (which should work for most ordinary messages). */ - if (msglen > sizeof(__tmp) && - msg == (struct dlm_header *) __tmp) { - msg = kmalloc(dlm_config.ci_buffer_size, GFP_KERNEL); - if (msg == NULL) + if (msglen > sizeof(__tmp) && p == &__tmp.p) { + p = kmalloc(dlm_config.ci_buffer_size, GFP_KERNEL); + if (p == NULL) return ret; } - copy_from_cb(msg, base, offset, msglen, limit); + copy_from_cb(p, base, offset, msglen, limit); - BUG_ON(lockspace != msg->h_lockspace); + BUG_ON(lockspace != p->header.h_lockspace); ret += msglen; offset += msglen; offset &= (limit - 1); len -= msglen; - dlm_receive_buffer(msg, nodeid); + dlm_receive_buffer(p, nodeid); } - if (msg != (struct dlm_header *) __tmp) - kfree(msg); + if (p != &__tmp.p) + kfree(p); return err ? err : ret; } --- linux-2.6.24.orig/fs/dlm/rcom.c +++ linux-2.6.24/fs/dlm/rcom.c @@ -2,7 +2,7 @@ ******************************************************************************* ** ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved. +** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved. ** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions @@ -78,13 +78,14 @@ static void make_config(struct dlm_ls *ls, struct rcom_config *rf) { - rf->rf_lvblen = ls->ls_lvblen; - rf->rf_lsflags = ls->ls_exflags; + rf->rf_lvblen = cpu_to_le32(ls->ls_lvblen); + rf->rf_lsflags = cpu_to_le32(ls->ls_exflags); } static int check_config(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid) { struct rcom_config *rf = (struct rcom_config *) rc->rc_buf; + size_t conf_size = sizeof(struct dlm_rcom) + sizeof(struct rcom_config); if ((rc->rc_header.h_version & 0xFFFF0000) != DLM_HEADER_MAJOR) { log_error(ls, "version mismatch: %x nodeid %d: %x", @@ -93,11 +94,18 @@ return -EPROTO; } - if (rf->rf_lvblen != ls->ls_lvblen || - rf->rf_lsflags != ls->ls_exflags) { + if (rc->rc_header.h_length < conf_size) { + log_error(ls, "config too short: %d nodeid %d", + rc->rc_header.h_length, nodeid); + return -EPROTO; + } + + if (le32_to_cpu(rf->rf_lvblen) != ls->ls_lvblen || + le32_to_cpu(rf->rf_lsflags) != ls->ls_exflags) { log_error(ls, "config mismatch: %d,%x nodeid %d: %d,%x", - ls->ls_lvblen, ls->ls_exflags, - nodeid, rf->rf_lvblen, rf->rf_lsflags); + ls->ls_lvblen, ls->ls_exflags, nodeid, + le32_to_cpu(rf->rf_lvblen), + le32_to_cpu(rf->rf_lsflags)); return -EPROTO; } return 0; @@ -128,7 +136,7 @@ ls->ls_recover_nodeid = nodeid; if (nodeid == dlm_our_nodeid()) { - rc = (struct dlm_rcom *) ls->ls_recover_buf; + rc = ls->ls_recover_buf; rc->rc_result = dlm_recover_status(ls); goto out; } @@ -147,7 +155,7 @@ if (error) goto out; - rc = (struct dlm_rcom *) ls->ls_recover_buf; + rc = ls->ls_recover_buf; if (rc->rc_result == -ESRCH) { /* we pretend the remote lockspace exists with 0 status */ @@ -197,23 +205,21 @@ spin_unlock(&ls->ls_rcom_spin); } -static void receive_rcom_status_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in) -{ - receive_sync_reply(ls, rc_in); -} - int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name, int last_len) { struct dlm_rcom *rc; struct dlm_mhandle *mh; - int error = 0, len = sizeof(struct dlm_rcom); + int error = 0; + int max_size = dlm_config.ci_buffer_size - sizeof(struct dlm_rcom); ls->ls_recover_nodeid = nodeid; if (nodeid == dlm_our_nodeid()) { + ls->ls_recover_buf->rc_header.h_length = + dlm_config.ci_buffer_size; dlm_copy_master_names(ls, last_name, last_len, - ls->ls_recover_buf + len, - dlm_config.ci_buffer_size - len, nodeid); + ls->ls_recover_buf->rc_buf, + max_size, nodeid); goto out; } @@ -254,11 +260,6 @@ send_rcom(ls, mh, rc); } -static void receive_rcom_names_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in) -{ - receive_sync_reply(ls, rc_in); -} - int dlm_send_rcom_lookup(struct dlm_rsb *r, int dir_nodeid) { struct dlm_rcom *rc; @@ -309,22 +310,22 @@ { memset(rl, 0, sizeof(*rl)); - rl->rl_ownpid = lkb->lkb_ownpid; - rl->rl_lkid = lkb->lkb_id; - rl->rl_exflags = lkb->lkb_exflags; - rl->rl_flags = lkb->lkb_flags; - rl->rl_lvbseq = lkb->lkb_lvbseq; + rl->rl_ownpid = cpu_to_le32(lkb->lkb_ownpid); + rl->rl_lkid = cpu_to_le32(lkb->lkb_id); + rl->rl_exflags = cpu_to_le32(lkb->lkb_exflags); + rl->rl_flags = cpu_to_le32(lkb->lkb_flags); + rl->rl_lvbseq = cpu_to_le32(lkb->lkb_lvbseq); rl->rl_rqmode = lkb->lkb_rqmode; rl->rl_grmode = lkb->lkb_grmode; rl->rl_status = lkb->lkb_status; - rl->rl_wait_type = lkb->lkb_wait_type; + rl->rl_wait_type = cpu_to_le16(lkb->lkb_wait_type); - if (lkb->lkb_bastaddr) + if (lkb->lkb_bastfn) rl->rl_asts |= AST_BAST; - if (lkb->lkb_astaddr) + if (lkb->lkb_astfn) rl->rl_asts |= AST_COMP; - rl->rl_namelen = r->res_length; + rl->rl_namelen = cpu_to_le16(r->res_length); memcpy(rl->rl_name, r->res_name, r->res_length); /* FIXME: might we have an lvb without DLM_LKF_VALBLK set ? @@ -358,6 +359,7 @@ return error; } +/* needs at least dlm_rcom + rcom_lock */ static void receive_rcom_lock(struct dlm_ls *ls, struct dlm_rcom *rc_in) { struct dlm_rcom *rc; @@ -381,11 +383,6 @@ send_rcom(ls, mh, rc); } -static void receive_rcom_lock_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in) -{ - dlm_recover_process_copy(ls, rc_in); -} - /* If the lockspace doesn't exist then still send a status message back; it's possible that it just doesn't have its global_id yet. */ @@ -416,7 +413,7 @@ rc->rc_result = -ESRCH; rf = (struct rcom_config *) rc->rc_buf; - rf->rf_lvblen = -1; + rf->rf_lvblen = cpu_to_le32(~0U); dlm_rcom_out(rc); dlm_lowcomms_commit_buffer(mh); @@ -454,6 +451,8 @@ void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid) { + int lock_size = sizeof(struct dlm_rcom) + sizeof(struct rcom_lock); + if (dlm_recovery_stopped(ls) && (rc->rc_type != DLM_RCOM_STATUS)) { log_debug(ls, "ignoring recovery message %x from %d", rc->rc_type, nodeid); @@ -477,15 +476,17 @@ break; case DLM_RCOM_LOCK: + if (rc->rc_header.h_length < lock_size) + goto Eshort; receive_rcom_lock(ls, rc); break; case DLM_RCOM_STATUS_REPLY: - receive_rcom_status_reply(ls, rc); + receive_sync_reply(ls, rc); break; case DLM_RCOM_NAMES_REPLY: - receive_rcom_names_reply(ls, rc); + receive_sync_reply(ls, rc); break; case DLM_RCOM_LOOKUP_REPLY: @@ -493,13 +494,18 @@ break; case DLM_RCOM_LOCK_REPLY: - receive_rcom_lock_reply(ls, rc); + if (rc->rc_header.h_length < lock_size) + goto Eshort; + dlm_recover_process_copy(ls, rc); break; default: - DLM_ASSERT(0, printk("rc_type=%x\n", rc->rc_type);); + log_error(ls, "receive_rcom bad type %d", rc->rc_type); } - out: +out: return; +Eshort: + log_error(ls, "recovery message %x from %d is too short", + rc->rc_type, nodeid); } --- linux-2.6.24.orig/fs/dlm/util.c +++ linux-2.6.24/fs/dlm/util.c @@ -1,7 +1,7 @@ /****************************************************************************** ******************************************************************************* ** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. +** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved. ** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions @@ -14,6 +14,14 @@ #include "rcom.h" #include "util.h" +#define DLM_ERRNO_EDEADLK 35 +#define DLM_ERRNO_EBADR 53 +#define DLM_ERRNO_EBADSLT 57 +#define DLM_ERRNO_EPROTO 71 +#define DLM_ERRNO_EOPNOTSUPP 95 +#define DLM_ERRNO_ETIMEDOUT 110 +#define DLM_ERRNO_EINPROGRESS 115 + static void header_out(struct dlm_header *hd) { hd->h_version = cpu_to_le32(hd->h_version); @@ -30,11 +38,54 @@ hd->h_length = le16_to_cpu(hd->h_length); } -void dlm_message_out(struct dlm_message *ms) +/* higher errno values are inconsistent across architectures, so select + one set of values for on the wire */ + +static int to_dlm_errno(int err) { - struct dlm_header *hd = (struct dlm_header *) ms; + switch (err) { + case -EDEADLK: + return -DLM_ERRNO_EDEADLK; + case -EBADR: + return -DLM_ERRNO_EBADR; + case -EBADSLT: + return -DLM_ERRNO_EBADSLT; + case -EPROTO: + return -DLM_ERRNO_EPROTO; + case -EOPNOTSUPP: + return -DLM_ERRNO_EOPNOTSUPP; + case -ETIMEDOUT: + return -DLM_ERRNO_ETIMEDOUT; + case -EINPROGRESS: + return -DLM_ERRNO_EINPROGRESS; + } + return err; +} + +static int from_dlm_errno(int err) +{ + switch (err) { + case -DLM_ERRNO_EDEADLK: + return -EDEADLK; + case -DLM_ERRNO_EBADR: + return -EBADR; + case -DLM_ERRNO_EBADSLT: + return -EBADSLT; + case -DLM_ERRNO_EPROTO: + return -EPROTO; + case -DLM_ERRNO_EOPNOTSUPP: + return -EOPNOTSUPP; + case -DLM_ERRNO_ETIMEDOUT: + return -ETIMEDOUT; + case -DLM_ERRNO_EINPROGRESS: + return -EINPROGRESS; + } + return err; +} - header_out(hd); +void dlm_message_out(struct dlm_message *ms) +{ + header_out(&ms->m_header); ms->m_type = cpu_to_le32(ms->m_type); ms->m_nodeid = cpu_to_le32(ms->m_nodeid); @@ -53,14 +104,12 @@ ms->m_rqmode = cpu_to_le32(ms->m_rqmode); ms->m_bastmode = cpu_to_le32(ms->m_bastmode); ms->m_asts = cpu_to_le32(ms->m_asts); - ms->m_result = cpu_to_le32(ms->m_result); + ms->m_result = cpu_to_le32(to_dlm_errno(ms->m_result)); } void dlm_message_in(struct dlm_message *ms) { - struct dlm_header *hd = (struct dlm_header *) ms; - - header_in(hd); + header_in(&ms->m_header); ms->m_type = le32_to_cpu(ms->m_type); ms->m_nodeid = le32_to_cpu(ms->m_nodeid); @@ -79,87 +128,27 @@ ms->m_rqmode = le32_to_cpu(ms->m_rqmode); ms->m_bastmode = le32_to_cpu(ms->m_bastmode); ms->m_asts = le32_to_cpu(ms->m_asts); - ms->m_result = le32_to_cpu(ms->m_result); -} - -static void rcom_lock_out(struct rcom_lock *rl) -{ - rl->rl_ownpid = cpu_to_le32(rl->rl_ownpid); - rl->rl_lkid = cpu_to_le32(rl->rl_lkid); - rl->rl_remid = cpu_to_le32(rl->rl_remid); - rl->rl_parent_lkid = cpu_to_le32(rl->rl_parent_lkid); - rl->rl_parent_remid = cpu_to_le32(rl->rl_parent_remid); - rl->rl_exflags = cpu_to_le32(rl->rl_exflags); - rl->rl_flags = cpu_to_le32(rl->rl_flags); - rl->rl_lvbseq = cpu_to_le32(rl->rl_lvbseq); - rl->rl_result = cpu_to_le32(rl->rl_result); - rl->rl_wait_type = cpu_to_le16(rl->rl_wait_type); - rl->rl_namelen = cpu_to_le16(rl->rl_namelen); -} - -static void rcom_lock_in(struct rcom_lock *rl) -{ - rl->rl_ownpid = le32_to_cpu(rl->rl_ownpid); - rl->rl_lkid = le32_to_cpu(rl->rl_lkid); - rl->rl_remid = le32_to_cpu(rl->rl_remid); - rl->rl_parent_lkid = le32_to_cpu(rl->rl_parent_lkid); - rl->rl_parent_remid = le32_to_cpu(rl->rl_parent_remid); - rl->rl_exflags = le32_to_cpu(rl->rl_exflags); - rl->rl_flags = le32_to_cpu(rl->rl_flags); - rl->rl_lvbseq = le32_to_cpu(rl->rl_lvbseq); - rl->rl_result = le32_to_cpu(rl->rl_result); - rl->rl_wait_type = le16_to_cpu(rl->rl_wait_type); - rl->rl_namelen = le16_to_cpu(rl->rl_namelen); -} - -static void rcom_config_out(struct rcom_config *rf) -{ - rf->rf_lvblen = cpu_to_le32(rf->rf_lvblen); - rf->rf_lsflags = cpu_to_le32(rf->rf_lsflags); -} - -static void rcom_config_in(struct rcom_config *rf) -{ - rf->rf_lvblen = le32_to_cpu(rf->rf_lvblen); - rf->rf_lsflags = le32_to_cpu(rf->rf_lsflags); + ms->m_result = from_dlm_errno(le32_to_cpu(ms->m_result)); } void dlm_rcom_out(struct dlm_rcom *rc) { - struct dlm_header *hd = (struct dlm_header *) rc; - int type = rc->rc_type; - - header_out(hd); + header_out(&rc->rc_header); rc->rc_type = cpu_to_le32(rc->rc_type); rc->rc_result = cpu_to_le32(rc->rc_result); rc->rc_id = cpu_to_le64(rc->rc_id); rc->rc_seq = cpu_to_le64(rc->rc_seq); rc->rc_seq_reply = cpu_to_le64(rc->rc_seq_reply); - - if (type == DLM_RCOM_LOCK) - rcom_lock_out((struct rcom_lock *) rc->rc_buf); - - else if (type == DLM_RCOM_STATUS_REPLY) - rcom_config_out((struct rcom_config *) rc->rc_buf); } void dlm_rcom_in(struct dlm_rcom *rc) { - struct dlm_header *hd = (struct dlm_header *) rc; - - header_in(hd); + header_in(&rc->rc_header); rc->rc_type = le32_to_cpu(rc->rc_type); rc->rc_result = le32_to_cpu(rc->rc_result); rc->rc_id = le64_to_cpu(rc->rc_id); rc->rc_seq = le64_to_cpu(rc->rc_seq); rc->rc_seq_reply = le64_to_cpu(rc->rc_seq_reply); - - if (rc->rc_type == DLM_RCOM_LOCK) - rcom_lock_in((struct rcom_lock *) rc->rc_buf); - - else if (rc->rc_type == DLM_RCOM_STATUS_REPLY) - rcom_config_in((struct rcom_config *) rc->rc_buf); } - --- linux-2.6.24.orig/fs/dlm/member.h +++ linux-2.6.24/fs/dlm/member.h @@ -1,7 +1,7 @@ /****************************************************************************** ******************************************************************************* ** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. +** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved. ** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions @@ -19,6 +19,7 @@ void dlm_clear_members_gone(struct dlm_ls *ls); int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv,int *neg_out); int dlm_is_removed(struct dlm_ls *ls, int nodeid); +int dlm_is_member(struct dlm_ls *ls, int nodeid); #endif /* __MEMBER_DOT_H__ */ --- linux-2.6.24.orig/fs/dlm/dlm_internal.h +++ linux-2.6.24/fs/dlm/dlm_internal.h @@ -92,8 +92,6 @@ } \ } -#define DLM_FAKE_USER_AST ERR_PTR(-EINVAL) - struct dlm_direntry { struct list_head list; @@ -146,9 +144,9 @@ struct dlm_args { uint32_t flags; - void *astaddr; - long astparam; - void *bastaddr; + void (*astfn) (void *astparam); + void *astparam; + void (*bastfn) (void *astparam, int mode); int mode; struct dlm_lksb *lksb; unsigned long timeout; @@ -253,9 +251,12 @@ char *lkb_lvbptr; struct dlm_lksb *lkb_lksb; /* caller's status block */ - void *lkb_astaddr; /* caller's ast function */ - void *lkb_bastaddr; /* caller's bast function */ - long lkb_astparam; /* caller's ast arg */ + void (*lkb_astfn) (void *astparam); + void (*lkb_bastfn) (void *astparam, int mode); + union { + void *lkb_astparam; /* caller's ast arg */ + struct dlm_user_args *lkb_ua; + }; }; @@ -403,28 +404,34 @@ char rc_buf[0]; }; +union dlm_packet { + struct dlm_header header; /* common to other two */ + struct dlm_message message; + struct dlm_rcom rcom; +}; + struct rcom_config { - uint32_t rf_lvblen; - uint32_t rf_lsflags; - uint64_t rf_unused; + __le32 rf_lvblen; + __le32 rf_lsflags; + __le64 rf_unused; }; struct rcom_lock { - uint32_t rl_ownpid; - uint32_t rl_lkid; - uint32_t rl_remid; - uint32_t rl_parent_lkid; - uint32_t rl_parent_remid; - uint32_t rl_exflags; - uint32_t rl_flags; - uint32_t rl_lvbseq; - int rl_result; + __le32 rl_ownpid; + __le32 rl_lkid; + __le32 rl_remid; + __le32 rl_parent_lkid; + __le32 rl_parent_remid; + __le32 rl_exflags; + __le32 rl_flags; + __le32 rl_lvbseq; + __le32 rl_result; int8_t rl_rqmode; int8_t rl_grmode; int8_t rl_status; int8_t rl_asts; - uint16_t rl_wait_type; - uint16_t rl_namelen; + __le16 rl_wait_type; + __le16 rl_namelen; char rl_name[DLM_RESNAME_MAXLEN]; char rl_lvb[0]; }; @@ -494,7 +501,7 @@ struct rw_semaphore ls_recv_active; /* block dlm_recv */ struct list_head ls_requestqueue;/* queue remote requests */ struct mutex ls_requestqueue_mutex; - char *ls_recover_buf; + struct dlm_rcom *ls_recover_buf; int ls_recover_nodeid; /* for debugging */ uint64_t ls_rcom_seq; spinlock_t ls_rcom_spin; @@ -570,5 +577,21 @@ return (ls->ls_exflags & DLM_LSFL_NODIR) ? 1 : 0; } +int dlm_netlink_init(void); +void dlm_netlink_exit(void); +void dlm_timeout_warn(struct dlm_lkb *lkb); + +#ifdef CONFIG_DLM_DEBUG +int dlm_register_debugfs(void); +void dlm_unregister_debugfs(void); +int dlm_create_debug_file(struct dlm_ls *ls); +void dlm_delete_debug_file(struct dlm_ls *ls); +#else +static inline int dlm_register_debugfs(void) { return 0; } +static inline void dlm_unregister_debugfs(void) { } +static inline int dlm_create_debug_file(struct dlm_ls *ls) { return 0; } +static inline void dlm_delete_debug_file(struct dlm_ls *ls) { } +#endif + #endif /* __DLM_INTERNAL_DOT_H__ */ --- linux-2.6.24.orig/fs/dlm/lowcomms.c +++ linux-2.6.24/fs/dlm/lowcomms.c @@ -864,7 +864,7 @@ static void tcp_connect_to_sock(struct connection *con) { int result = -EHOSTUNREACH; - struct sockaddr_storage saddr; + struct sockaddr_storage saddr, src_addr; int addr_len; struct socket *sock; @@ -898,6 +898,17 @@ con->connect_action = tcp_connect_to_sock; add_sock(sock, con); + /* Bind to our cluster-known address connecting to avoid + routing problems */ + memcpy(&src_addr, dlm_local_addr[0], sizeof(src_addr)); + make_sockaddr(&src_addr, 0, &addr_len); + result = sock->ops->bind(sock, (struct sockaddr *) &src_addr, + addr_len); + if (result < 0) { + log_print("could not bind for connect: %d", result); + /* This *may* not indicate a critical error */ + } + make_sockaddr(&saddr, dlm_config.ci_tcp_port, &addr_len); log_print("connecting to %d", con->nodeid); @@ -1426,6 +1437,8 @@ con = __nodeid2con(i, 0); if (con) { close_connection(con, true); + if (con->othercon) + kmem_cache_free(con_cache, con->othercon); kmem_cache_free(con_cache, con); } } --- linux-2.6.24.orig/fs/dlm/dir.c +++ linux-2.6.24/fs/dlm/dir.c @@ -49,7 +49,7 @@ spin_unlock(&ls->ls_recover_list_lock); if (!found) - de = allocate_direntry(ls, len); + de = kzalloc(sizeof(struct dlm_direntry) + len, GFP_KERNEL); return de; } @@ -62,7 +62,7 @@ de = list_entry(ls->ls_recover_list.next, struct dlm_direntry, list); list_del(&de->list); - free_direntry(de); + kfree(de); } spin_unlock(&ls->ls_recover_list_lock); } @@ -171,7 +171,7 @@ } list_del(&de->list); - free_direntry(de); + kfree(de); out: write_unlock(&ls->ls_dirtbl[bucket].lock); } @@ -220,6 +220,7 @@ last_len = 0; for (;;) { + int left; error = dlm_recovery_stopped(ls); if (error) goto out_free; @@ -235,12 +236,21 @@ * pick namelen/name pairs out of received buffer */ - b = ls->ls_recover_buf + sizeof(struct dlm_rcom); + b = ls->ls_recover_buf->rc_buf; + left = ls->ls_recover_buf->rc_header.h_length; + left -= sizeof(struct dlm_rcom); for (;;) { - memcpy(&namelen, b, sizeof(uint16_t)); - namelen = be16_to_cpu(namelen); - b += sizeof(uint16_t); + __be16 v; + + error = -EINVAL; + if (left < sizeof(__be16)) + goto out_free; + + memcpy(&v, b, sizeof(__be16)); + namelen = be16_to_cpu(v); + b += sizeof(__be16); + left -= sizeof(__be16); /* namelen of 0xFFFFF marks end of names for this node; namelen of 0 marks end of the @@ -251,6 +261,12 @@ if (!namelen) break; + if (namelen > left) + goto out_free; + + if (namelen > DLM_RESNAME_MAXLEN) + goto out_free; + error = -ENOMEM; de = get_free_de(ls, namelen); if (!de) @@ -262,6 +278,7 @@ memcpy(de->name, b, namelen); memcpy(last_name, b, namelen); b += namelen; + left -= namelen; add_entry_to_hash(ls, de); count++; @@ -302,7 +319,10 @@ write_unlock(&ls->ls_dirtbl[bucket].lock); - de = allocate_direntry(ls, namelen); + if (namelen > DLM_RESNAME_MAXLEN) + return -EINVAL; + + de = kzalloc(sizeof(struct dlm_direntry) + namelen, GFP_KERNEL); if (!de) return -ENOMEM; @@ -313,7 +333,7 @@ write_lock(&ls->ls_dirtbl[bucket].lock); tmp = search_bucket(ls, name, namelen, bucket); if (tmp) { - free_direntry(de); + kfree(de); de = tmp; } else { list_add_tail(&de->list, &ls->ls_dirtbl[bucket].list); @@ -329,49 +349,47 @@ return get_entry(ls, nodeid, name, namelen, r_nodeid); } -/* Copy the names of master rsb's into the buffer provided. - Only select names whose dir node is the given nodeid. */ +static struct dlm_rsb *find_rsb_root(struct dlm_ls *ls, char *name, int len) +{ + struct dlm_rsb *r; + + down_read(&ls->ls_root_sem); + list_for_each_entry(r, &ls->ls_root_list, res_root_list) { + if (len == r->res_length && !memcmp(name, r->res_name, len)) { + up_read(&ls->ls_root_sem); + return r; + } + } + up_read(&ls->ls_root_sem); + return NULL; +} + +/* Find the rsb where we left off (or start again), then send rsb names + for rsb's we're master of and whose directory node matches the requesting + node. inbuf is the rsb name last sent, inlen is the name's length */ void dlm_copy_master_names(struct dlm_ls *ls, char *inbuf, int inlen, char *outbuf, int outlen, int nodeid) { struct list_head *list; - struct dlm_rsb *start_r = NULL, *r = NULL; - int offset = 0, start_namelen, error, dir_nodeid; - char *start_name; + struct dlm_rsb *r; + int offset = 0, dir_nodeid; uint16_t be_namelen; - /* - * Find the rsb where we left off (or start again) - */ - - start_namelen = inlen; - start_name = inbuf; - - if (start_namelen > 1) { - /* - * We could also use a find_rsb_root() function here that - * searched the ls_root_list. - */ - error = dlm_find_rsb(ls, start_name, start_namelen, R_MASTER, - &start_r); - DLM_ASSERT(!error && start_r, - printk("error %d\n", error);); - DLM_ASSERT(!list_empty(&start_r->res_root_list), - dlm_print_rsb(start_r);); - dlm_put_rsb(start_r); - } - - /* - * Send rsb names for rsb's we're master of and whose directory node - * matches the requesting node. - */ - down_read(&ls->ls_root_sem); - if (start_r) - list = start_r->res_root_list.next; - else + + if (inlen > 1) { + r = find_rsb_root(ls, inbuf, inlen); + if (!r) { + inbuf[inlen - 1] = '\0'; + log_error(ls, "copy_master_names from %d start %d %s", + nodeid, inlen, inbuf); + goto out; + } + list = r->res_root_list.next; + } else { list = ls->ls_root_list.next; + } for (offset = 0; list != &ls->ls_root_list; list = list->next) { r = list_entry(list, struct dlm_rsb, res_root_list); --- linux-2.6.24.orig/fs/dlm/lock.c +++ linux-2.6.24/fs/dlm/lock.c @@ -1,7 +1,7 @@ /****************************************************************************** ******************************************************************************* ** -** Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved. +** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved. ** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions @@ -88,7 +88,6 @@ static int receive_extralen(struct dlm_message *ms); static void do_purge(struct dlm_ls *ls, int nodeid, int pid); static void del_timeout(struct dlm_lkb *lkb); -void dlm_timeout_warn(struct dlm_lkb *lkb); /* * Lock compatibilty matrix - thanks Steve @@ -335,7 +334,7 @@ { struct dlm_rsb *r; - r = allocate_rsb(ls, len); + r = dlm_allocate_rsb(ls, len); if (!r) return NULL; @@ -437,11 +436,15 @@ { struct dlm_rsb *r, *tmp; uint32_t hash, bucket; - int error = 0; + int error = -EINVAL; + + if (namelen > DLM_RESNAME_MAXLEN) + goto out; if (dlm_no_directory(ls)) flags |= R_CREATE; + error = 0; hash = jhash(name, namelen, 0); bucket = hash & (ls->ls_rsbtbl_size - 1); @@ -478,7 +481,7 @@ error = _search_rsb(ls, name, namelen, bucket, 0, &tmp); if (!error) { write_unlock(&ls->ls_rsbtbl[bucket].lock); - free_rsb(r); + dlm_free_rsb(r); r = tmp; goto out; } @@ -490,12 +493,6 @@ return error; } -int dlm_find_rsb(struct dlm_ls *ls, char *name, int namelen, - unsigned int flags, struct dlm_rsb **r_ret) -{ - return find_rsb(ls, name, namelen, flags, r_ret); -} - /* This is only called to add a reference when the code already holds a valid reference to the rsb, so there's no need for locking. */ @@ -519,7 +516,7 @@ list_move(&r->res_hashchain, &ls->ls_rsbtbl[r->res_bucket].toss); r->res_toss_time = jiffies; if (r->res_lvbptr) { - free_lvb(r->res_lvbptr); + dlm_free_lvb(r->res_lvbptr); r->res_lvbptr = NULL; } } @@ -589,7 +586,7 @@ uint32_t lkid = 0; uint16_t bucket; - lkb = allocate_lkb(ls); + lkb = dlm_allocate_lkb(ls); if (!lkb) return -ENOMEM; @@ -683,8 +680,8 @@ /* for local/process lkbs, lvbptr points to caller's lksb */ if (lkb->lkb_lvbptr && is_master_copy(lkb)) - free_lvb(lkb->lkb_lvbptr); - free_lkb(lkb); + dlm_free_lvb(lkb->lkb_lvbptr); + dlm_free_lkb(lkb); return 1; } else { write_unlock(&ls->ls_lkbtbl[bucket].lock); @@ -988,7 +985,7 @@ if (is_master(r)) dir_remove(r); - free_rsb(r); + dlm_free_rsb(r); count++; } else { write_unlock(&ls->ls_rsbtbl[b].lock); @@ -1171,7 +1168,7 @@ return; if (!r->res_lvbptr) - r->res_lvbptr = allocate_lvb(r->res_ls); + r->res_lvbptr = dlm_allocate_lvb(r->res_ls); if (!r->res_lvbptr) return; @@ -1203,7 +1200,7 @@ return; if (!r->res_lvbptr) - r->res_lvbptr = allocate_lvb(r->res_ls); + r->res_lvbptr = dlm_allocate_lvb(r->res_ls); if (!r->res_lvbptr) return; @@ -1229,6 +1226,8 @@ b = dlm_lvb_operations[lkb->lkb_grmode + 1][lkb->lkb_rqmode + 1]; if (b == 1) { int len = receive_extralen(ms); + if (len > DLM_RESNAME_MAXLEN) + len = DLM_RESNAME_MAXLEN; memcpy(lkb->lkb_lvbptr, ms->m_extra, len); lkb->lkb_lvbseq = ms->m_lvbseq; } @@ -1782,7 +1781,7 @@ */ list_for_each_entry_safe(lkb, s, &r->res_grantqueue, lkb_statequeue) { - if (lkb->lkb_bastaddr && lock_requires_bast(lkb, high, cw)) { + if (lkb->lkb_bastfn && lock_requires_bast(lkb, high, cw)) { if (cw && high == DLM_LOCK_PR) queue_bast(r, lkb, DLM_LOCK_CW); else @@ -1812,7 +1811,7 @@ struct dlm_lkb *gr; list_for_each_entry(gr, head, lkb_statequeue) { - if (gr->lkb_bastaddr && modes_require_bast(gr, lkb)) { + if (gr->lkb_bastfn && modes_require_bast(gr, lkb)) { queue_bast(r, gr, lkb->lkb_rqmode); gr->lkb_highbast = lkb->lkb_rqmode; } @@ -1852,7 +1851,7 @@ static int set_master(struct dlm_rsb *r, struct dlm_lkb *lkb) { struct dlm_ls *ls = r->res_ls; - int error, dir_nodeid, ret_nodeid, our_nodeid = dlm_our_nodeid(); + int i, error, dir_nodeid, ret_nodeid, our_nodeid = dlm_our_nodeid(); if (rsb_flag(r, RSB_MASTER_UNCERTAIN)) { rsb_clear_flag(r, RSB_MASTER_UNCERTAIN); @@ -1886,7 +1885,7 @@ return 1; } - for (;;) { + for (i = 0; i < 2; i++) { /* It's possible for dlm_scand to remove an old rsb for this same resource from the toss list, us to create a new one, look up the master locally, and find it @@ -1900,6 +1899,8 @@ log_debug(ls, "dir_lookup error %d %s", error, r->res_name); schedule(); } + if (error && error != -EEXIST) + return error; if (ret_nodeid == our_nodeid) { r->res_first_lkid = 0; @@ -1941,8 +1942,11 @@ break; case -EAGAIN: - /* the remote master didn't queue our NOQUEUE request; - make a waiting lkb the first_lkid */ + case -EBADR: + case -ENOTBLK: + /* the remote request failed and won't be retried (it was + a NOQUEUE, or has been canceled/unlocked); make a waiting + lkb the first_lkid */ r->res_first_lkid = 0; @@ -1962,8 +1966,11 @@ } static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags, - int namelen, unsigned long timeout_cs, void *ast, - void *astarg, void *bast, struct dlm_args *args) + int namelen, unsigned long timeout_cs, + void (*ast) (void *astparam), + void *astparam, + void (*bast) (void *astparam, int mode), + struct dlm_args *args) { int rv = -EINVAL; @@ -2013,9 +2020,9 @@ an active lkb cannot be modified before locking the rsb */ args->flags = flags; - args->astaddr = ast; - args->astparam = (long) astarg; - args->bastaddr = bast; + args->astfn = ast; + args->astparam = astparam; + args->bastfn = bast; args->timeout = timeout_cs; args->mode = mode; args->lksb = lksb; @@ -2034,7 +2041,7 @@ return -EINVAL; args->flags = flags; - args->astparam = (long) astarg; + args->astparam = astarg; return 0; } @@ -2064,9 +2071,9 @@ lkb->lkb_exflags = args->flags; lkb->lkb_sbflags = 0; - lkb->lkb_astaddr = args->astaddr; + lkb->lkb_astfn = args->astfn; lkb->lkb_astparam = args->astparam; - lkb->lkb_bastaddr = args->bastaddr; + lkb->lkb_bastfn = args->bastfn; lkb->lkb_rqmode = args->mode; lkb->lkb_lksb = args->lksb; lkb->lkb_lvbptr = args->lksb->sb_lvbptr; @@ -2108,17 +2115,18 @@ /* an lkb may be waiting for an rsb lookup to complete where the lookup was initiated by another lock */ - if (args->flags & (DLM_LKF_CANCEL | DLM_LKF_FORCEUNLOCK)) { - if (!list_empty(&lkb->lkb_rsb_lookup)) { + if (!list_empty(&lkb->lkb_rsb_lookup)) { + if (args->flags & (DLM_LKF_CANCEL | DLM_LKF_FORCEUNLOCK)) { log_debug(ls, "unlock on rsb_lookup %x", lkb->lkb_id); list_del_init(&lkb->lkb_rsb_lookup); queue_cast(lkb->lkb_resource, lkb, args->flags & DLM_LKF_CANCEL ? -DLM_ECANCEL : -DLM_EUNLOCK); unhold_lkb(lkb); /* undoes create_lkb() */ - rv = -EBUSY; - goto out; } + /* caller changes -EBUSY to 0 for CANCEL and FORCEUNLOCK */ + rv = -EBUSY; + goto out; } /* cancel not allowed with another cancel/unlock in progress */ @@ -2712,9 +2720,9 @@ /* m_result and m_bastmode are set from function args, not from lkb fields */ - if (lkb->lkb_bastaddr) + if (lkb->lkb_bastfn) ms->m_asts |= AST_BAST; - if (lkb->lkb_astaddr) + if (lkb->lkb_astfn) ms->m_asts |= AST_COMP; /* compare with switch in create_message; send_remove() doesn't @@ -2986,15 +2994,27 @@ if (lkb->lkb_exflags & DLM_LKF_VALBLK) { if (!lkb->lkb_lvbptr) - lkb->lkb_lvbptr = allocate_lvb(ls); + lkb->lkb_lvbptr = dlm_allocate_lvb(ls); if (!lkb->lkb_lvbptr) return -ENOMEM; len = receive_extralen(ms); + if (len > DLM_RESNAME_MAXLEN) + len = DLM_RESNAME_MAXLEN; memcpy(lkb->lkb_lvbptr, ms->m_extra, len); } return 0; } +static void fake_bastfn(void *astparam, int mode) +{ + log_print("fake_bastfn should not be called"); +} + +static void fake_astfn(void *astparam) +{ + log_print("fake_astfn should not be called"); +} + static int receive_request_args(struct dlm_ls *ls, struct dlm_lkb *lkb, struct dlm_message *ms) { @@ -3003,14 +3023,13 @@ lkb->lkb_remid = ms->m_lkid; lkb->lkb_grmode = DLM_LOCK_IV; lkb->lkb_rqmode = ms->m_rqmode; - lkb->lkb_bastaddr = (void *) (long) (ms->m_asts & AST_BAST); - lkb->lkb_astaddr = (void *) (long) (ms->m_asts & AST_COMP); - DLM_ASSERT(is_master_copy(lkb), dlm_print_lkb(lkb);); + lkb->lkb_bastfn = (ms->m_asts & AST_BAST) ? &fake_bastfn : NULL; + lkb->lkb_astfn = (ms->m_asts & AST_COMP) ? &fake_astfn : NULL; if (lkb->lkb_exflags & DLM_LKF_VALBLK) { /* lkb was just created so there won't be an lvb yet */ - lkb->lkb_lvbptr = allocate_lvb(ls); + lkb->lkb_lvbptr = dlm_allocate_lvb(ls); if (!lkb->lkb_lvbptr) return -ENOMEM; } @@ -3021,16 +3040,6 @@ static int receive_convert_args(struct dlm_ls *ls, struct dlm_lkb *lkb, struct dlm_message *ms) { - if (lkb->lkb_nodeid != ms->m_header.h_nodeid) { - log_error(ls, "convert_args nodeid %d %d lkid %x %x", - lkb->lkb_nodeid, ms->m_header.h_nodeid, - lkb->lkb_id, lkb->lkb_remid); - return -EINVAL; - } - - if (!is_master_copy(lkb)) - return -EINVAL; - if (lkb->lkb_status != DLM_LKSTS_GRANTED) return -EBUSY; @@ -3046,8 +3055,6 @@ static int receive_unlock_args(struct dlm_ls *ls, struct dlm_lkb *lkb, struct dlm_message *ms) { - if (!is_master_copy(lkb)) - return -EINVAL; if (receive_lvb(ls, lkb, ms)) return -ENOMEM; return 0; @@ -3063,6 +3070,50 @@ lkb->lkb_remid = ms->m_lkid; } +/* This is called after the rsb is locked so that we can safely inspect + fields in the lkb. */ + +static int validate_message(struct dlm_lkb *lkb, struct dlm_message *ms) +{ + int from = ms->m_header.h_nodeid; + int error = 0; + + switch (ms->m_type) { + case DLM_MSG_CONVERT: + case DLM_MSG_UNLOCK: + case DLM_MSG_CANCEL: + if (!is_master_copy(lkb) || lkb->lkb_nodeid != from) + error = -EINVAL; + break; + + case DLM_MSG_CONVERT_REPLY: + case DLM_MSG_UNLOCK_REPLY: + case DLM_MSG_CANCEL_REPLY: + case DLM_MSG_GRANT: + case DLM_MSG_BAST: + if (!is_process_copy(lkb) || lkb->lkb_nodeid != from) + error = -EINVAL; + break; + + case DLM_MSG_REQUEST_REPLY: + if (!is_process_copy(lkb)) + error = -EINVAL; + else if (lkb->lkb_nodeid != -1 && lkb->lkb_nodeid != from) + error = -EINVAL; + break; + + default: + error = -EINVAL; + } + + if (error) + log_error(lkb->lkb_resource->res_ls, + "ignore invalid message %d from %d %x %x %x %d", + ms->m_type, from, lkb->lkb_id, lkb->lkb_remid, + lkb->lkb_flags, lkb->lkb_nodeid); + return error; +} + static void receive_request(struct dlm_ls *ls, struct dlm_message *ms) { struct dlm_lkb *lkb; @@ -3124,17 +3175,21 @@ hold_rsb(r); lock_rsb(r); + error = validate_message(lkb, ms); + if (error) + goto out; + receive_flags(lkb, ms); error = receive_convert_args(ls, lkb, ms); if (error) - goto out; + goto out_reply; reply = !down_conversion(lkb); error = do_convert(r, lkb); - out: + out_reply: if (reply) send_convert_reply(r, lkb, error); - + out: unlock_rsb(r); put_rsb(r); dlm_put_lkb(lkb); @@ -3160,15 +3215,19 @@ hold_rsb(r); lock_rsb(r); + error = validate_message(lkb, ms); + if (error) + goto out; + receive_flags(lkb, ms); error = receive_unlock_args(ls, lkb, ms); if (error) - goto out; + goto out_reply; error = do_unlock(r, lkb); - out: + out_reply: send_unlock_reply(r, lkb, error); - + out: unlock_rsb(r); put_rsb(r); dlm_put_lkb(lkb); @@ -3196,9 +3255,13 @@ hold_rsb(r); lock_rsb(r); + error = validate_message(lkb, ms); + if (error) + goto out; + error = do_cancel(r, lkb); send_cancel_reply(r, lkb, error); - + out: unlock_rsb(r); put_rsb(r); dlm_put_lkb(lkb); @@ -3217,22 +3280,26 @@ error = find_lkb(ls, ms->m_remid, &lkb); if (error) { - log_error(ls, "receive_grant no lkb"); + log_debug(ls, "receive_grant from %d no lkb %x", + ms->m_header.h_nodeid, ms->m_remid); return; } - DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb);); r = lkb->lkb_resource; hold_rsb(r); lock_rsb(r); + error = validate_message(lkb, ms); + if (error) + goto out; + receive_flags_reply(lkb, ms); if (is_altmode(lkb)) munge_altmode(lkb, ms); grant_lock_pc(r, lkb, ms); queue_cast(r, lkb, 0); - + out: unlock_rsb(r); put_rsb(r); dlm_put_lkb(lkb); @@ -3246,18 +3313,22 @@ error = find_lkb(ls, ms->m_remid, &lkb); if (error) { - log_error(ls, "receive_bast no lkb"); + log_debug(ls, "receive_bast from %d no lkb %x", + ms->m_header.h_nodeid, ms->m_remid); return; } - DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb);); r = lkb->lkb_resource; hold_rsb(r); lock_rsb(r); - queue_bast(r, lkb, ms->m_bastmode); + error = validate_message(lkb, ms); + if (error) + goto out; + queue_bast(r, lkb, ms->m_bastmode); + out: unlock_rsb(r); put_rsb(r); dlm_put_lkb(lkb); @@ -3323,15 +3394,19 @@ error = find_lkb(ls, ms->m_remid, &lkb); if (error) { - log_error(ls, "receive_request_reply no lkb"); + log_debug(ls, "receive_request_reply from %d no lkb %x", + ms->m_header.h_nodeid, ms->m_remid); return; } - DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb);); r = lkb->lkb_resource; hold_rsb(r); lock_rsb(r); + error = validate_message(lkb, ms); + if (error) + goto out; + mstype = lkb->lkb_wait_type; error = remove_from_waiters(lkb, DLM_MSG_REQUEST_REPLY); if (error) @@ -3383,6 +3458,7 @@ if (is_overlap(lkb)) { /* we'll ignore error in cancel/unlock reply */ queue_cast_overlap(r, lkb); + confirm_master(r, result); unhold_lkb(lkb); /* undoes create_lkb() */ } else _request_lock(r, lkb); @@ -3463,6 +3539,10 @@ hold_rsb(r); lock_rsb(r); + error = validate_message(lkb, ms); + if (error) + goto out; + /* stub reply can happen with waiters_mutex held */ error = remove_from_waiters_ms(lkb, ms); if (error) @@ -3481,10 +3561,10 @@ error = find_lkb(ls, ms->m_remid, &lkb); if (error) { - log_error(ls, "receive_convert_reply no lkb"); + log_debug(ls, "receive_convert_reply from %d no lkb %x", + ms->m_header.h_nodeid, ms->m_remid); return; } - DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb);); _receive_convert_reply(lkb, ms); dlm_put_lkb(lkb); @@ -3498,6 +3578,10 @@ hold_rsb(r); lock_rsb(r); + error = validate_message(lkb, ms); + if (error) + goto out; + /* stub reply can happen with waiters_mutex held */ error = remove_from_waiters_ms(lkb, ms); if (error) @@ -3529,10 +3613,10 @@ error = find_lkb(ls, ms->m_remid, &lkb); if (error) { - log_error(ls, "receive_unlock_reply no lkb"); + log_debug(ls, "receive_unlock_reply from %d no lkb %x", + ms->m_header.h_nodeid, ms->m_remid); return; } - DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb);); _receive_unlock_reply(lkb, ms); dlm_put_lkb(lkb); @@ -3546,6 +3630,10 @@ hold_rsb(r); lock_rsb(r); + error = validate_message(lkb, ms); + if (error) + goto out; + /* stub reply can happen with waiters_mutex held */ error = remove_from_waiters_ms(lkb, ms); if (error) @@ -3577,10 +3665,10 @@ error = find_lkb(ls, ms->m_remid, &lkb); if (error) { - log_error(ls, "receive_cancel_reply no lkb"); + log_debug(ls, "receive_cancel_reply from %d no lkb %x", + ms->m_header.h_nodeid, ms->m_remid); return; } - DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb);); _receive_cancel_reply(lkb, ms); dlm_put_lkb(lkb); @@ -3640,6 +3728,13 @@ static void _receive_message(struct dlm_ls *ls, struct dlm_message *ms) { + if (!dlm_is_member(ls, ms->m_header.h_nodeid)) { + log_debug(ls, "ignore non-member message %d from %d %x %x %d", + ms->m_type, ms->m_header.h_nodeid, ms->m_lkid, + ms->m_remid, ms->m_result); + return; + } + switch (ms->m_type) { /* messages sent to a master node */ @@ -3729,7 +3824,7 @@ int nodeid) { if (dlm_locking_stopped(ls)) { - dlm_add_requestqueue(ls, nodeid, (struct dlm_header *) ms); + dlm_add_requestqueue(ls, nodeid, ms); } else { dlm_wait_requestqueue(ls); _receive_message(ls, ms); @@ -3749,21 +3844,20 @@ standard locking activity) or an RCOM (recovery message sent as part of lockspace recovery). */ -void dlm_receive_buffer(struct dlm_header *hd, int nodeid) +void dlm_receive_buffer(union dlm_packet *p, int nodeid) { - struct dlm_message *ms = (struct dlm_message *) hd; - struct dlm_rcom *rc = (struct dlm_rcom *) hd; + struct dlm_header *hd = &p->header; struct dlm_ls *ls; int type = 0; switch (hd->h_cmd) { case DLM_MSG: - dlm_message_in(ms); - type = ms->m_type; + dlm_message_in(&p->message); + type = p->message.m_type; break; case DLM_RCOM: - dlm_rcom_in(rc); - type = rc->rc_type; + dlm_rcom_in(&p->rcom); + type = p->rcom.rc_type; break; default: log_print("invalid h_cmd %d from %u", hd->h_cmd, nodeid); @@ -3778,11 +3872,12 @@ ls = dlm_find_lockspace_global(hd->h_lockspace); if (!ls) { - log_print("invalid h_lockspace %x from %d cmd %d type %d", - hd->h_lockspace, nodeid, hd->h_cmd, type); + if (dlm_config.ci_log_debug) + log_print("invalid lockspace %x from %d cmd %d type %d", + hd->h_lockspace, nodeid, hd->h_cmd, type); if (hd->h_cmd == DLM_RCOM && type == DLM_RCOM_STATUS) - dlm_send_ls_not_ready(nodeid, rc); + dlm_send_ls_not_ready(nodeid, &p->rcom); return; } @@ -3791,9 +3886,9 @@ down_read(&ls->ls_recv_active); if (hd->h_cmd == DLM_MSG) - dlm_receive_message(ls, ms, nodeid); + dlm_receive_message(ls, &p->message, nodeid); else - dlm_receive_rcom(ls, rc, nodeid); + dlm_receive_rcom(ls, &p->rcom, nodeid); up_read(&ls->ls_recv_active); dlm_put_lockspace(ls); @@ -3806,6 +3901,7 @@ ls->ls_stub_ms.m_type = DLM_MSG_CONVERT_REPLY; ls->ls_stub_ms.m_result = -EINPROGRESS; ls->ls_stub_ms.m_flags = lkb->lkb_flags; + ls->ls_stub_ms.m_header.h_nodeid = lkb->lkb_nodeid; _receive_convert_reply(lkb, &ls->ls_stub_ms); /* Same special case as in receive_rcom_lock_args() */ @@ -3847,6 +3943,7 @@ void dlm_recover_waiters_pre(struct dlm_ls *ls) { struct dlm_lkb *lkb, *safe; + int wait_type, stub_unlock_result, stub_cancel_result; mutex_lock(&ls->ls_waiters_mutex); @@ -3865,7 +3962,33 @@ if (!waiter_needs_recovery(ls, lkb)) continue; - switch (lkb->lkb_wait_type) { + wait_type = lkb->lkb_wait_type; + stub_unlock_result = -DLM_EUNLOCK; + stub_cancel_result = -DLM_ECANCEL; + + /* Main reply may have been received leaving a zero wait_type, + but a reply for the overlapping op may not have been + received. In that case we need to fake the appropriate + reply for the overlap op. */ + + if (!wait_type) { + if (is_overlap_cancel(lkb)) { + wait_type = DLM_MSG_CANCEL; + if (lkb->lkb_grmode == DLM_LOCK_IV) + stub_cancel_result = 0; + } + if (is_overlap_unlock(lkb)) { + wait_type = DLM_MSG_UNLOCK; + if (lkb->lkb_grmode == DLM_LOCK_IV) + stub_unlock_result = -ENOENT; + } + + log_debug(ls, "rwpre overlap %x %x %d %d %d", + lkb->lkb_id, lkb->lkb_flags, wait_type, + stub_cancel_result, stub_unlock_result); + } + + switch (wait_type) { case DLM_MSG_REQUEST: lkb->lkb_flags |= DLM_IFL_RESEND; @@ -3878,8 +4001,9 @@ case DLM_MSG_UNLOCK: hold_lkb(lkb); ls->ls_stub_ms.m_type = DLM_MSG_UNLOCK_REPLY; - ls->ls_stub_ms.m_result = -DLM_EUNLOCK; + ls->ls_stub_ms.m_result = stub_unlock_result; ls->ls_stub_ms.m_flags = lkb->lkb_flags; + ls->ls_stub_ms.m_header.h_nodeid = lkb->lkb_nodeid; _receive_unlock_reply(lkb, &ls->ls_stub_ms); dlm_put_lkb(lkb); break; @@ -3887,15 +4011,16 @@ case DLM_MSG_CANCEL: hold_lkb(lkb); ls->ls_stub_ms.m_type = DLM_MSG_CANCEL_REPLY; - ls->ls_stub_ms.m_result = -DLM_ECANCEL; + ls->ls_stub_ms.m_result = stub_cancel_result; ls->ls_stub_ms.m_flags = lkb->lkb_flags; + ls->ls_stub_ms.m_header.h_nodeid = lkb->lkb_nodeid; _receive_cancel_reply(lkb, &ls->ls_stub_ms); dlm_put_lkb(lkb); break; default: - log_error(ls, "invalid lkb wait_type %d", - lkb->lkb_wait_type); + log_error(ls, "invalid lkb wait_type %d %d", + lkb->lkb_wait_type, wait_type); } schedule(); } @@ -4163,32 +4288,34 @@ return NULL; } +/* needs at least dlm_rcom + rcom_lock */ static int receive_rcom_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb, struct dlm_rsb *r, struct dlm_rcom *rc) { struct rcom_lock *rl = (struct rcom_lock *) rc->rc_buf; - int lvblen; lkb->lkb_nodeid = rc->rc_header.h_nodeid; - lkb->lkb_ownpid = rl->rl_ownpid; - lkb->lkb_remid = rl->rl_lkid; - lkb->lkb_exflags = rl->rl_exflags; - lkb->lkb_flags = rl->rl_flags & 0x0000FFFF; + lkb->lkb_ownpid = le32_to_cpu(rl->rl_ownpid); + lkb->lkb_remid = le32_to_cpu(rl->rl_lkid); + lkb->lkb_exflags = le32_to_cpu(rl->rl_exflags); + lkb->lkb_flags = le32_to_cpu(rl->rl_flags) & 0x0000FFFF; lkb->lkb_flags |= DLM_IFL_MSTCPY; - lkb->lkb_lvbseq = rl->rl_lvbseq; + lkb->lkb_lvbseq = le32_to_cpu(rl->rl_lvbseq); lkb->lkb_rqmode = rl->rl_rqmode; lkb->lkb_grmode = rl->rl_grmode; /* don't set lkb_status because add_lkb wants to itself */ - lkb->lkb_bastaddr = (void *) (long) (rl->rl_asts & AST_BAST); - lkb->lkb_astaddr = (void *) (long) (rl->rl_asts & AST_COMP); + lkb->lkb_bastfn = (rl->rl_asts & AST_BAST) ? &fake_bastfn : NULL; + lkb->lkb_astfn = (rl->rl_asts & AST_COMP) ? &fake_astfn : NULL; if (lkb->lkb_exflags & DLM_LKF_VALBLK) { - lkb->lkb_lvbptr = allocate_lvb(ls); + int lvblen = rc->rc_header.h_length - sizeof(struct dlm_rcom) - + sizeof(struct rcom_lock); + if (lvblen > ls->ls_lvblen) + return -EINVAL; + lkb->lkb_lvbptr = dlm_allocate_lvb(ls); if (!lkb->lkb_lvbptr) return -ENOMEM; - lvblen = rc->rc_header.h_length - sizeof(struct dlm_rcom) - - sizeof(struct rcom_lock); memcpy(lkb->lkb_lvbptr, rl->rl_lvb, lvblen); } @@ -4196,7 +4323,8 @@ The real granted mode of these converting locks cannot be determined until all locks have been rebuilt on the rsb (recover_conversion) */ - if (rl->rl_wait_type == DLM_MSG_CONVERT && middle_conversion(lkb)) { + if (rl->rl_wait_type == cpu_to_le16(DLM_MSG_CONVERT) && + middle_conversion(lkb)) { rl->rl_status = DLM_LKSTS_CONVERT; lkb->lkb_grmode = DLM_LOCK_IV; rsb_set_flag(r, RSB_RECOVER_CONVERT); @@ -4211,6 +4339,7 @@ the given values and send back our lkid. We send back our lkid by sending back the rcom_lock struct we got but with the remid field filled in. */ +/* needs at least dlm_rcom + rcom_lock */ int dlm_recover_master_copy(struct dlm_ls *ls, struct dlm_rcom *rc) { struct rcom_lock *rl = (struct rcom_lock *) rc->rc_buf; @@ -4223,13 +4352,14 @@ goto out; } - error = find_rsb(ls, rl->rl_name, rl->rl_namelen, R_MASTER, &r); + error = find_rsb(ls, rl->rl_name, le16_to_cpu(rl->rl_namelen), + R_MASTER, &r); if (error) goto out; lock_rsb(r); - lkb = search_remid(r, rc->rc_header.h_nodeid, rl->rl_lkid); + lkb = search_remid(r, rc->rc_header.h_nodeid, le32_to_cpu(rl->rl_lkid)); if (lkb) { error = -EEXIST; goto out_remid; @@ -4252,18 +4382,20 @@ out_remid: /* this is the new value returned to the lock holder for saving in its process-copy lkb */ - rl->rl_remid = lkb->lkb_id; + rl->rl_remid = cpu_to_le32(lkb->lkb_id); out_unlock: unlock_rsb(r); put_rsb(r); out: if (error) - log_print("recover_master_copy %d %x", error, rl->rl_lkid); - rl->rl_result = error; + log_debug(ls, "recover_master_copy %d %x", error, + le32_to_cpu(rl->rl_lkid)); + rl->rl_result = cpu_to_le32(error); return error; } +/* needs at least dlm_rcom + rcom_lock */ int dlm_recover_process_copy(struct dlm_ls *ls, struct dlm_rcom *rc) { struct rcom_lock *rl = (struct rcom_lock *) rc->rc_buf; @@ -4271,15 +4403,16 @@ struct dlm_lkb *lkb; int error; - error = find_lkb(ls, rl->rl_lkid, &lkb); + error = find_lkb(ls, le32_to_cpu(rl->rl_lkid), &lkb); if (error) { - log_error(ls, "recover_process_copy no lkid %x", rl->rl_lkid); + log_error(ls, "recover_process_copy no lkid %x", + le32_to_cpu(rl->rl_lkid)); return error; } DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb);); - error = rl->rl_result; + error = le32_to_cpu(rl->rl_result); r = lkb->lkb_resource; hold_rsb(r); @@ -4298,7 +4431,7 @@ log_debug(ls, "master copy exists %x", lkb->lkb_id); /* fall through */ case 0: - lkb->lkb_remid = rl->rl_remid; + lkb->lkb_remid = le32_to_cpu(rl->rl_remid); break; default: log_error(ls, "dlm_recover_process_copy unknown error %d %x", @@ -4342,12 +4475,12 @@ } } - /* After ua is attached to lkb it will be freed by free_lkb(). + /* After ua is attached to lkb it will be freed by dlm_free_lkb(). When DLM_IFL_USER is set, the dlm knows that this is a userspace lock and that lkb_astparam is the dlm_user_args structure. */ error = set_lock_args(mode, &ua->lksb, flags, namelen, timeout_cs, - DLM_FAKE_USER_AST, ua, DLM_FAKE_USER_AST, &args); + fake_astfn, ua, fake_bastfn, &args); lkb->lkb_flags |= DLM_IFL_USER; ua->old_mode = DLM_LOCK_IV; @@ -4400,7 +4533,7 @@ /* user can change the params on its lock when it converts it, or add an lvb that didn't exist before */ - ua = (struct dlm_user_args *)lkb->lkb_astparam; + ua = lkb->lkb_ua; if (flags & DLM_LKF_VALBLK && !ua->lksb.sb_lvbptr) { ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_KERNEL); @@ -4421,7 +4554,7 @@ ua->old_mode = lkb->lkb_grmode; error = set_lock_args(mode, &ua->lksb, flags, 0, timeout_cs, - DLM_FAKE_USER_AST, ua, DLM_FAKE_USER_AST, &args); + fake_astfn, ua, fake_bastfn, &args); if (error) goto out_put; @@ -4451,7 +4584,7 @@ if (error) goto out; - ua = (struct dlm_user_args *)lkb->lkb_astparam; + ua = lkb->lkb_ua; if (lvb_in && ua->lksb.sb_lvbptr) memcpy(ua->lksb.sb_lvbptr, lvb_in, DLM_USER_LVB_LEN); @@ -4500,7 +4633,7 @@ if (error) goto out; - ua = (struct dlm_user_args *)lkb->lkb_astparam; + ua = lkb->lkb_ua; if (ua_tmp->castparam) ua->castparam = ua_tmp->castparam; ua->user_lksb = ua_tmp->user_lksb; @@ -4538,7 +4671,7 @@ if (error) goto out; - ua = (struct dlm_user_args *)lkb->lkb_astparam; + ua = lkb->lkb_ua; error = set_unlock_args(flags, ua, &args); if (error) @@ -4577,7 +4710,6 @@ static int orphan_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb) { - struct dlm_user_args *ua = (struct dlm_user_args *)lkb->lkb_astparam; struct dlm_args args; int error; @@ -4586,7 +4718,7 @@ list_add_tail(&lkb->lkb_ownqueue, &ls->ls_orphans); mutex_unlock(&ls->ls_orphans_mutex); - set_unlock_args(0, ua, &args); + set_unlock_args(0, lkb->lkb_ua, &args); error = cancel_lock(ls, lkb, &args); if (error == -DLM_ECANCEL) @@ -4599,11 +4731,10 @@ static int unlock_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb) { - struct dlm_user_args *ua = (struct dlm_user_args *)lkb->lkb_astparam; struct dlm_args args; int error; - set_unlock_args(DLM_LKF_FORCEUNLOCK, ua, &args); + set_unlock_args(DLM_LKF_FORCEUNLOCK, lkb->lkb_ua, &args); error = unlock_lock(ls, lkb, &args); if (error == -DLM_EUNLOCK) @@ -4679,6 +4810,7 @@ } list_for_each_entry_safe(lkb, safe, &proc->asts, lkb_astqueue) { + lkb->lkb_ast_type = 0; list_del(&lkb->lkb_astqueue); dlm_put_lkb(lkb); } --- linux-2.6.24.orig/fs/dlm/recoverd.c +++ linux-2.6.24/fs/dlm/recoverd.c @@ -67,17 +67,18 @@ dlm_astd_resume(); /* - * This list of root rsb's will be the basis of most of the recovery - * routines. + * Free non-master tossed rsb's. Master rsb's are kept on toss + * list and put on root list to be included in resdir recovery. */ - dlm_create_root_list(ls); + dlm_clear_toss_list(ls); /* - * Free all the tossed rsb's so we don't have to recover them. + * This list of root rsb's will be the basis of most of the recovery + * routines. */ - dlm_clear_toss_list(ls); + dlm_create_root_list(ls); /* * Add or remove nodes from the lockspace's ls_nodes list. --- linux-2.6.24.orig/fs/dlm/user.c +++ linux-2.6.24/fs/dlm/user.c @@ -24,8 +24,7 @@ #include "lvb_table.h" #include "user.h" -static const char *name_prefix="dlm"; -static struct miscdevice ctl_device; +static const char name_prefix[] = "dlm"; static const struct file_operations device_fops; #ifdef CONFIG_COMPAT @@ -82,7 +81,8 @@ }; static void compat_input(struct dlm_write_request *kb, - struct dlm_write_request32 *kb32) + struct dlm_write_request32 *kb32, + size_t count) { kb->version[0] = kb32->version[0]; kb->version[1] = kb32->version[1]; @@ -94,7 +94,8 @@ kb->cmd == DLM_USER_REMOVE_LOCKSPACE) { kb->i.lspace.flags = kb32->i.lspace.flags; kb->i.lspace.minor = kb32->i.lspace.minor; - strcpy(kb->i.lspace.name, kb32->i.lspace.name); + memcpy(kb->i.lspace.name, kb32->i.lspace.name, count - + offsetof(struct dlm_write_request32, i.lspace.name)); } else if (kb->cmd == DLM_USER_PURGE) { kb->i.purge.nodeid = kb32->i.purge.nodeid; kb->i.purge.pid = kb32->i.purge.pid; @@ -112,7 +113,8 @@ kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr; kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb; memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN); - memcpy(kb->i.lock.name, kb32->i.lock.name, kb->i.lock.namelen); + memcpy(kb->i.lock.name, kb32->i.lock.name, count - + offsetof(struct dlm_write_request32, i.lock.name)); } } @@ -193,8 +195,8 @@ if (lkb->lkb_flags & (DLM_IFL_ORPHAN | DLM_IFL_DEAD)) goto out; - DLM_ASSERT(lkb->lkb_astparam, dlm_print_lkb(lkb);); - ua = (struct dlm_user_args *)lkb->lkb_astparam; + DLM_ASSERT(lkb->lkb_ua, dlm_print_lkb(lkb);); + ua = lkb->lkb_ua; proc = ua->proc; if (type == AST_BAST && ua->bastaddr == NULL) @@ -236,12 +238,12 @@ spin_unlock(&proc->asts_spin); if (eol) { - spin_lock(&ua->proc->locks_spin); + spin_lock(&proc->locks_spin); if (!list_empty(&lkb->lkb_ownqueue)) { list_del_init(&lkb->lkb_ownqueue); dlm_put_lkb(lkb); } - spin_unlock(&ua->proc->locks_spin); + spin_unlock(&proc->locks_spin); } out: mutex_unlock(&ls->ls_clear_proc_locks); @@ -504,7 +506,7 @@ #endif return -EINVAL; - kbuf = kmalloc(count, GFP_KERNEL); + kbuf = kzalloc(count + 1, GFP_KERNEL); if (!kbuf) return -ENOMEM; @@ -522,14 +524,14 @@ if (!kbuf->is64bit) { struct dlm_write_request32 *k32buf; k32buf = (struct dlm_write_request32 *)kbuf; - kbuf = kmalloc(count + (sizeof(struct dlm_write_request) - + kbuf = kmalloc(count + 1 + (sizeof(struct dlm_write_request) - sizeof(struct dlm_write_request32)), GFP_KERNEL); if (!kbuf) return -ENOMEM; if (proc) set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags); - compat_input(kbuf, k32buf); + compat_input(kbuf, k32buf, count + 1); kfree(k32buf); } #endif @@ -769,7 +771,6 @@ { struct dlm_user_proc *proc = file->private_data; struct dlm_lkb *lkb; - struct dlm_user_args *ua; DECLARE_WAITQUEUE(wait, current); int error, type=0, bmode=0, removed = 0; @@ -840,8 +841,7 @@ } spin_unlock(&proc->asts_spin); - ua = (struct dlm_user_args *)lkb->lkb_astparam; - error = copy_result_to_user(ua, + error = copy_result_to_user(lkb->lkb_ua, test_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags), type, bmode, buf, count); @@ -896,14 +896,16 @@ .owner = THIS_MODULE, }; -int dlm_user_init(void) +static struct miscdevice ctl_device = { + .name = "dlm-control", + .fops = &ctl_device_fops, + .minor = MISC_DYNAMIC_MINOR, +}; + +int __init dlm_user_init(void) { int error; - ctl_device.name = "dlm-control"; - ctl_device.fops = &ctl_device_fops; - ctl_device.minor = MISC_DYNAMIC_MINOR; - error = misc_register(&ctl_device); if (error) log_print("misc_register failed for control device"); --- linux-2.6.24.orig/fs/dlm/main.c +++ linux-2.6.24/fs/dlm/main.c @@ -18,16 +18,6 @@ #include "memory.h" #include "config.h" -#ifdef CONFIG_DLM_DEBUG -int dlm_register_debugfs(void); -void dlm_unregister_debugfs(void); -#else -static inline int dlm_register_debugfs(void) { return 0; } -static inline void dlm_unregister_debugfs(void) { } -#endif -int dlm_netlink_init(void); -void dlm_netlink_exit(void); - static int __init init_dlm(void) { int error; --- linux-2.6.24.orig/fs/dlm/netlink.c +++ linux-2.6.24/fs/dlm/netlink.c @@ -78,7 +78,7 @@ .doit = user_cmd, }; -int dlm_netlink_init(void) +int __init dlm_netlink_init(void) { int rv; @@ -95,7 +95,7 @@ return rv; } -void dlm_netlink_exit(void) +void __exit dlm_netlink_exit(void) { genl_unregister_ops(&family, &dlm_nl_ops); genl_unregister_family(&family); @@ -104,7 +104,6 @@ static void fill_data(struct dlm_lock_data *data, struct dlm_lkb *lkb) { struct dlm_rsb *r = lkb->lkb_resource; - struct dlm_user_args *ua = (struct dlm_user_args *) lkb->lkb_astparam; memset(data, 0, sizeof(struct dlm_lock_data)); @@ -117,8 +116,8 @@ data->grmode = lkb->lkb_grmode; data->rqmode = lkb->lkb_rqmode; data->timestamp = lkb->lkb_timestamp; - if (ua) - data->xid = ua->xid; + if (lkb->lkb_ua) + data->xid = lkb->lkb_ua->xid; if (r) { data->lockspace_id = r->res_ls->ls_global_id; data->resource_namelen = r->res_length; --- linux-2.6.24.orig/fs/dlm/lock.h +++ linux-2.6.24/fs/dlm/lock.h @@ -17,10 +17,8 @@ void dlm_dump_rsb(struct dlm_rsb *r); void dlm_print_lkb(struct dlm_lkb *lkb); void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms); -void dlm_receive_buffer(struct dlm_header *hd, int nodeid); +void dlm_receive_buffer(union dlm_packet *p, int nodeid); int dlm_modes_compat(int mode1, int mode2); -int dlm_find_rsb(struct dlm_ls *ls, char *name, int namelen, - unsigned int flags, struct dlm_rsb **r_ret); void dlm_put_rsb(struct dlm_rsb *r); void dlm_hold_rsb(struct dlm_rsb *r); int dlm_put_lkb(struct dlm_lkb *lkb); --- linux-2.6.24.orig/fs/dlm/ast.c +++ linux-2.6.24/fs/dlm/ast.c @@ -39,7 +39,6 @@ dlm_user_add_ast(lkb, type); return; } - DLM_ASSERT(lkb->lkb_astaddr != DLM_FAKE_USER_AST, dlm_print_lkb(lkb);); spin_lock(&ast_queue_lock); if (!(lkb->lkb_ast_type & (AST_COMP | AST_BAST))) { @@ -58,8 +57,8 @@ struct dlm_ls *ls = NULL; struct dlm_rsb *r = NULL; struct dlm_lkb *lkb; - void (*cast) (long param); - void (*bast) (long param, int mode); + void (*cast) (void *astparam); + void (*bast) (void *astparam, int mode); int type = 0, found, bmode; for (;;) { @@ -83,8 +82,8 @@ if (!found) break; - cast = lkb->lkb_astaddr; - bast = lkb->lkb_bastaddr; + cast = lkb->lkb_astfn; + bast = lkb->lkb_bastfn; bmode = lkb->lkb_bastmode; if ((type & AST_COMP) && cast) --- linux-2.6.24.orig/fs/dlm/memory.h +++ linux-2.6.24/fs/dlm/memory.h @@ -2,7 +2,7 @@ ******************************************************************************* ** ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. +** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. ** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions @@ -16,14 +16,12 @@ int dlm_memory_init(void); void dlm_memory_exit(void); -struct dlm_rsb *allocate_rsb(struct dlm_ls *ls, int namelen); -void free_rsb(struct dlm_rsb *r); -struct dlm_lkb *allocate_lkb(struct dlm_ls *ls); -void free_lkb(struct dlm_lkb *l); -struct dlm_direntry *allocate_direntry(struct dlm_ls *ls, int namelen); -void free_direntry(struct dlm_direntry *de); -char *allocate_lvb(struct dlm_ls *ls); -void free_lvb(char *l); +struct dlm_rsb *dlm_allocate_rsb(struct dlm_ls *ls, int namelen); +void dlm_free_rsb(struct dlm_rsb *r); +struct dlm_lkb *dlm_allocate_lkb(struct dlm_ls *ls); +void dlm_free_lkb(struct dlm_lkb *l); +char *dlm_allocate_lvb(struct dlm_ls *ls); +void dlm_free_lvb(char *l); #endif /* __MEMORY_DOT_H__ */ --- linux-2.6.24.orig/fs/dlm/memory.c +++ linux-2.6.24/fs/dlm/memory.c @@ -2,7 +2,7 @@ ******************************************************************************* ** ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. +** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. ** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions @@ -18,7 +18,7 @@ static struct kmem_cache *lkb_cache; -int dlm_memory_init(void) +int __init dlm_memory_init(void) { int ret = 0; @@ -35,7 +35,7 @@ kmem_cache_destroy(lkb_cache); } -char *allocate_lvb(struct dlm_ls *ls) +char *dlm_allocate_lvb(struct dlm_ls *ls) { char *p; @@ -43,7 +43,7 @@ return p; } -void free_lvb(char *p) +void dlm_free_lvb(char *p) { kfree(p); } @@ -51,7 +51,7 @@ /* FIXME: have some minimal space built-in to rsb for the name and kmalloc a separate name if needed, like dentries are done */ -struct dlm_rsb *allocate_rsb(struct dlm_ls *ls, int namelen) +struct dlm_rsb *dlm_allocate_rsb(struct dlm_ls *ls, int namelen) { struct dlm_rsb *r; @@ -61,14 +61,14 @@ return r; } -void free_rsb(struct dlm_rsb *r) +void dlm_free_rsb(struct dlm_rsb *r) { if (r->res_lvbptr) - free_lvb(r->res_lvbptr); + dlm_free_lvb(r->res_lvbptr); kfree(r); } -struct dlm_lkb *allocate_lkb(struct dlm_ls *ls) +struct dlm_lkb *dlm_allocate_lkb(struct dlm_ls *ls) { struct dlm_lkb *lkb; @@ -76,11 +76,11 @@ return lkb; } -void free_lkb(struct dlm_lkb *lkb) +void dlm_free_lkb(struct dlm_lkb *lkb) { if (lkb->lkb_flags & DLM_IFL_USER) { struct dlm_user_args *ua; - ua = (struct dlm_user_args *)lkb->lkb_astparam; + ua = lkb->lkb_ua; if (ua) { if (ua->lksb.sb_lvbptr) kfree(ua->lksb.sb_lvbptr); @@ -90,19 +90,3 @@ kmem_cache_free(lkb_cache, lkb); } -struct dlm_direntry *allocate_direntry(struct dlm_ls *ls, int namelen) -{ - struct dlm_direntry *de; - - DLM_ASSERT(namelen <= DLM_RESNAME_MAXLEN, - printk("namelen = %d\n", namelen);); - - de = kzalloc(sizeof(*de) + namelen, GFP_KERNEL); - return de; -} - -void free_direntry(struct dlm_direntry *de) -{ - kfree(de); -} - --- linux-2.6.24.orig/fs/dlm/requestqueue.c +++ linux-2.6.24/fs/dlm/requestqueue.c @@ -20,7 +20,7 @@ struct rq_entry { struct list_head list; int nodeid; - char request[0]; + struct dlm_message request; }; /* @@ -30,10 +30,10 @@ * lockspace is enabled on some while still suspended on others. */ -void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd) +void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_message *ms) { struct rq_entry *e; - int length = hd->h_length; + int length = ms->m_header.h_length - sizeof(struct dlm_message); e = kmalloc(sizeof(struct rq_entry) + length, GFP_KERNEL); if (!e) { @@ -42,7 +42,7 @@ } e->nodeid = nodeid; - memcpy(e->request, hd, length); + memcpy(&e->request, ms, ms->m_header.h_length); mutex_lock(&ls->ls_requestqueue_mutex); list_add_tail(&e->list, &ls->ls_requestqueue); @@ -76,7 +76,7 @@ e = list_entry(ls->ls_requestqueue.next, struct rq_entry, list); mutex_unlock(&ls->ls_requestqueue_mutex); - dlm_receive_message_saved(ls, (struct dlm_message *)e->request); + dlm_receive_message_saved(ls, &e->request); mutex_lock(&ls->ls_requestqueue_mutex); list_del(&e->list); @@ -176,7 +176,7 @@ mutex_lock(&ls->ls_requestqueue_mutex); list_for_each_entry_safe(e, safe, &ls->ls_requestqueue, list) { - ms = (struct dlm_message *) e->request; + ms = &e->request; if (purge_request(ls, ms, e->nodeid)) { list_del(&e->list); --- linux-2.6.24.orig/fs/dlm/member.c +++ linux-2.6.24/fs/dlm/member.c @@ -1,7 +1,7 @@ /****************************************************************************** ******************************************************************************* ** -** Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved. +** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved. ** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions @@ -70,7 +70,7 @@ ls->ls_num_nodes--; } -static int dlm_is_member(struct dlm_ls *ls, int nodeid) +int dlm_is_member(struct dlm_ls *ls, int nodeid) { struct dlm_member *memb; --- linux-2.6.24.orig/fs/dlm/debug_fs.c +++ linux-2.6.24/fs/dlm/debug_fs.c @@ -162,14 +162,12 @@ static void print_lock(struct seq_file *s, struct dlm_lkb *lkb, struct dlm_rsb *r) { - struct dlm_user_args *ua; unsigned int waiting = 0; uint64_t xid = 0; if (lkb->lkb_flags & DLM_IFL_USER) { - ua = (struct dlm_user_args *) lkb->lkb_astparam; - if (ua) - xid = ua->xid; + if (lkb->lkb_ua) + xid = lkb->lkb_ua->xid; } if (lkb->lkb_timestamp) @@ -543,7 +541,7 @@ debugfs_remove(ls->ls_debug_locks_dentry); } -int dlm_register_debugfs(void) +int __init dlm_register_debugfs(void) { mutex_init(&debug_buf_lock); dlm_root = debugfs_create_dir("dlm", NULL); --- linux-2.6.24.orig/fs/dlm/requestqueue.h +++ linux-2.6.24/fs/dlm/requestqueue.h @@ -13,7 +13,7 @@ #ifndef __REQUESTQUEUE_DOT_H__ #define __REQUESTQUEUE_DOT_H__ -void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd); +void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_message *ms); int dlm_process_requestqueue(struct dlm_ls *ls); void dlm_wait_requestqueue(struct dlm_ls *ls); void dlm_purge_requestqueue(struct dlm_ls *ls); --- linux-2.6.24.orig/fs/dlm/recover.c +++ linux-2.6.24/fs/dlm/recover.c @@ -94,7 +94,7 @@ static int wait_status_all(struct dlm_ls *ls, uint32_t wait_status) { - struct dlm_rcom *rc = (struct dlm_rcom *) ls->ls_recover_buf; + struct dlm_rcom *rc = ls->ls_recover_buf; struct dlm_member *memb; int error = 0, delay; @@ -123,7 +123,7 @@ static int wait_status_low(struct dlm_ls *ls, uint32_t wait_status) { - struct dlm_rcom *rc = (struct dlm_rcom *) ls->ls_recover_buf; + struct dlm_rcom *rc = ls->ls_recover_buf; int error = 0, delay = 0, nodeid = ls->ls_low_nodeid; for (;;) { @@ -629,7 +629,7 @@ goto out; if (!r->res_lvbptr) { - r->res_lvbptr = allocate_lvb(r->res_ls); + r->res_lvbptr = dlm_allocate_lvb(r->res_ls); if (!r->res_lvbptr) goto out; } @@ -731,6 +731,20 @@ list_add(&r->res_root_list, &ls->ls_root_list); dlm_hold_rsb(r); } + + /* If we're using a directory, add tossed rsbs to the root + list; they'll have entries created in the new directory, + but no other recovery steps should do anything with them. */ + + if (dlm_no_directory(ls)) { + read_unlock(&ls->ls_rsbtbl[i].lock); + continue; + } + + list_for_each_entry(r, &ls->ls_rsbtbl[i].toss, res_hashchain) { + list_add(&r->res_root_list, &ls->ls_root_list); + dlm_hold_rsb(r); + } read_unlock(&ls->ls_rsbtbl[i].lock); } out: @@ -750,6 +764,11 @@ up_write(&ls->ls_root_sem); } +/* If not using a directory, clear the entire toss list, there's no benefit to + caching the master value since it's fixed. If we are using a dir, keep the + rsb's we're the master of. Recovery will add them to the root list and from + there they'll be entered in the rebuilt directory. */ + void dlm_clear_toss_list(struct dlm_ls *ls) { struct dlm_rsb *r, *safe; @@ -759,8 +778,10 @@ write_lock(&ls->ls_rsbtbl[i].lock); list_for_each_entry_safe(r, safe, &ls->ls_rsbtbl[i].toss, res_hashchain) { - list_del(&r->res_hashchain); - free_rsb(r); + if (dlm_no_directory(ls) || !is_master(r)) { + list_del(&r->res_hashchain); + dlm_free_rsb(r); + } } write_unlock(&ls->ls_rsbtbl[i].lock); } --- linux-2.6.24.orig/fs/dlm/config.c +++ linux-2.6.24/fs/dlm/config.c @@ -604,7 +604,7 @@ }, }; -int dlm_config_init(void) +int __init dlm_config_init(void) { config_group_init(&clusters_root.subsys.su_group); mutex_init(&clusters_root.subsys.su_mutex); --- linux-2.6.24.orig/fs/fat/file.c +++ linux-2.6.24/fs/fat/file.c @@ -92,7 +92,7 @@ } /* This MUST be done before doing anything irreversible... */ - err = notify_change(filp->f_path.dentry, &ia); + err = notify_change(filp->f_path.dentry, filp->f_path.mnt, &ia); if (err) goto up; --- linux-2.6.24.orig/fs/hfs/catalog.c +++ linux-2.6.24/fs/hfs/catalog.c @@ -190,6 +190,10 @@ fd->search_key->cat.ParID = rec.thread.ParID; len = fd->search_key->cat.CName.len = rec.thread.CName.len; + if (len > HFS_NAMELEN) { + printk(KERN_ERR "hfs: bad catalog namelength\n"); + return -EIO; + } memcpy(fd->search_key->cat.CName.name, rec.thread.CName.name, len); return hfs_brec_find(fd); } --- linux-2.6.24.orig/fs/afs/dir.c +++ linux-2.6.24/fs/afs/dir.c @@ -45,6 +45,7 @@ .release = afs_release, .readdir = afs_readdir, .lock = afs_lock, + .fsetattr = afs_fsetattr, }; const struct inode_operations afs_dir_inode_operations = { --- linux-2.6.24.orig/fs/afs/file.c +++ linux-2.6.24/fs/afs/file.c @@ -36,6 +36,7 @@ .fsync = afs_fsync, .lock = afs_lock, .flock = afs_flock, + .fsetattr = afs_fsetattr, }; const struct inode_operations afs_file_inode_operations = { --- linux-2.6.24.orig/fs/afs/internal.h +++ linux-2.6.24/fs/afs/internal.h @@ -550,6 +550,7 @@ extern int afs_validate(struct afs_vnode *, struct key *); extern int afs_getattr(struct vfsmount *, struct dentry *, struct kstat *); extern int afs_setattr(struct dentry *, struct iattr *); +extern int afs_fsetattr(struct file *, struct iattr *); extern void afs_clear_inode(struct inode *); /* --- linux-2.6.24.orig/fs/afs/inode.c +++ linux-2.6.24/fs/afs/inode.c @@ -360,7 +360,8 @@ /* * set the attributes of an inode */ -int afs_setattr(struct dentry *dentry, struct iattr *attr) +static int afs_do_setattr(struct dentry *dentry, struct iattr *attr, + struct file *file) { struct afs_vnode *vnode = AFS_FS_I(dentry->d_inode); struct key *key; @@ -382,8 +383,8 @@ afs_writeback_all(vnode); } - if (attr->ia_valid & ATTR_FILE) { - key = attr->ia_file->private_data; + if (file) { + key = file->private_data; } else { key = afs_request_key(vnode->volume->cell); if (IS_ERR(key)) { @@ -393,10 +394,20 @@ } ret = afs_vnode_setattr(vnode, key, attr); - if (!(attr->ia_valid & ATTR_FILE)) + if (!file) key_put(key); error: _leave(" = %d", ret); return ret; } + +int afs_setattr(struct dentry *dentry, struct iattr *attr) +{ + return afs_do_setattr(dentry, attr, NULL); +} + +int afs_fsetattr(struct file *file, struct iattr *attr) +{ + return afs_do_setattr(file->f_path.dentry, attr, file); +} --- linux-2.6.24.orig/fs/reiserfs/xattr.c +++ linux-2.6.24/fs/reiserfs/xattr.c @@ -485,7 +485,7 @@ newattrs.ia_size = buffer_size; newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; mutex_lock_nested(&xinode->i_mutex, I_MUTEX_XATTR); - err = notify_change(fp->f_path.dentry, &newattrs); + err = notify_change(fp->f_path.dentry, NULL, &newattrs); if (err) goto out_filp; @@ -781,7 +781,7 @@ if (dir->d_inode->i_nlink <= 2) { root = get_xa_root(inode->i_sb, XATTR_REPLACE); reiserfs_write_lock_xattrs(inode->i_sb); - err = vfs_rmdir(root->d_inode, dir); + err = vfs_rmdir(root->d_inode, dir, NULL); reiserfs_write_unlock_xattrs(inode->i_sb); dput(root); } else { @@ -825,7 +825,7 @@ } if (!S_ISDIR(xafile->d_inode->i_mode)) - err = notify_change(xafile, attrs); + err = notify_change(xafile, NULL, attrs); dput(xafile); return err; @@ -877,7 +877,7 @@ goto out_dir; } - err = notify_change(dir, attrs); + err = notify_change(dir, NULL, attrs); unlock_kernel(); out_dir: --- linux-2.6.24.orig/fs/isofs/compress.c +++ linux-2.6.24/fs/isofs/compress.c @@ -72,6 +72,17 @@ offset = index & ~zisofs_block_page_mask; blockindex = offset >> zisofs_block_page_shift; maxpage = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; + + /* + * If this page is wholly outside i_size we just return zero; + * do_generic_file_read() will handle this for us + */ + if (page->index >= maxpage) { + SetPageUptodate(page); + unlock_page(page); + return 0; + } + maxpage = min(zisofs_block_pages, maxpage-offset); for ( i = 0 ; i < maxpage ; i++, offset++ ) { --- linux-2.6.24.orig/fs/jbd/recovery.c +++ linux-2.6.24/fs/jbd/recovery.c @@ -478,7 +478,7 @@ memcpy(nbh->b_data, obh->b_data, journal->j_blocksize); if (flags & JFS_FLAG_ESCAPE) { - *((__be32 *)bh->b_data) = + *((__be32 *)nbh->b_data) = cpu_to_be32(JFS_MAGIC_NUMBER); } --- linux-2.6.24.orig/fs/sysfs/file.c +++ linux-2.6.24/fs/sysfs/file.c @@ -614,7 +614,7 @@ newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; - rc = notify_change(victim, &newattrs); + rc = notify_change(victim, NULL, &newattrs); if (rc == 0) { mutex_lock(&sysfs_mutex); --- linux-2.6.24.orig/fs/cifs/asn1.c +++ linux-2.6.24/fs/cifs/asn1.c @@ -186,6 +186,11 @@ } } } + + /* don't trust len bigger than ctx buffer */ + if (*len > ctx->end - ctx->pointer) + return 0; + return 1; } @@ -203,6 +208,10 @@ if (!asn1_length_decode(ctx, &def, &len)) return 0; + /* primitive shall be definite, indefinite shall be constructed */ + if (*con == ASN1_PRI && !def) + return 0; + if (def) *eoc = ctx->pointer + len; else @@ -389,6 +398,11 @@ unsigned long *optr; size = eoc - ctx->pointer + 1; + + /* first subid actually encodes first two subids */ + if (size < 2 || size > UINT_MAX/sizeof(unsigned long)) + return 0; + *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC); if (*oid == NULL) return 0; --- linux-2.6.24.orig/fs/nfsd/nfs4xdr.c +++ linux-2.6.24/fs/nfsd/nfs4xdr.c @@ -1496,7 +1496,7 @@ } if (bmval0 & (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT | FATTR4_WORD0_SUPPORTED_ATTRS)) { - err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl); + err = nfsd4_get_nfs4_acl(rqstp, dentry, exp->ex_mnt, &acl); aclsupport = (err == 0); if (bmval0 & FATTR4_WORD0_ACL) { if (err == -EOPNOTSUPP) --- linux-2.6.24.orig/fs/nfsd/nfsfh.c +++ linux-2.6.24/fs/nfsd/nfsfh.c @@ -231,6 +231,7 @@ fhp->fh_dentry = dentry; fhp->fh_export = exp; nfsd_nr_verified++; + cache_get(&exp->h); } else { /* * just rechecking permissions @@ -240,6 +241,7 @@ dprintk("nfsd: fh_verify - just checking\n"); dentry = fhp->fh_dentry; exp = fhp->fh_export; + cache_get(&exp->h); /* * Set user creds for this exportpoint; necessary even * in the "just checking" case because this may be a @@ -251,8 +253,6 @@ if (error) goto out; } - cache_get(&exp->h); - error = nfsd_mode_check(rqstp, dentry->d_inode->i_mode, type); if (error) --- linux-2.6.24.orig/fs/nfsd/vfs.c +++ linux-2.6.24/fs/nfsd/vfs.c @@ -388,7 +388,7 @@ err = nfserr_notsync; if (!check_guard || guardtime == inode->i_ctime.tv_sec) { fh_lock(fhp); - host_err = notify_change(dentry, iap); + host_err = notify_change(dentry, fhp->fh_export->ex_mnt, iap); err = nfserrno(host_err); fh_unlock(fhp); } @@ -408,11 +408,12 @@ #if defined(CONFIG_NFSD_V2_ACL) || \ defined(CONFIG_NFSD_V3_ACL) || \ defined(CONFIG_NFSD_V4) -static ssize_t nfsd_getxattr(struct dentry *dentry, char *key, void **buf) +static ssize_t nfsd_getxattr(struct dentry *dentry, struct vfsmount *mnt, + char *key, void **buf) { ssize_t buflen; - buflen = vfs_getxattr(dentry, key, NULL, 0); + buflen = vfs_getxattr(dentry, mnt, key, NULL, 0, NULL); if (buflen <= 0) return buflen; @@ -420,13 +421,14 @@ if (!*buf) return -ENOMEM; - return vfs_getxattr(dentry, key, *buf, buflen); + return vfs_getxattr(dentry, mnt, key, *buf, buflen, NULL); } #endif #if defined(CONFIG_NFSD_V4) static int -set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key) +set_nfsv4_acl_one(struct dentry *dentry, struct vfsmount *mnt, + struct posix_acl *pacl, char *key) { int len; size_t buflen; @@ -445,7 +447,7 @@ goto out; } - error = vfs_setxattr(dentry, key, buf, len, 0); + error = vfs_setxattr(dentry, mnt, key, buf, len, 0, NULL); out: kfree(buf); return error; @@ -458,6 +460,7 @@ __be32 error; int host_error; struct dentry *dentry; + struct vfsmount *mnt; struct inode *inode; struct posix_acl *pacl = NULL, *dpacl = NULL; unsigned int flags = 0; @@ -468,6 +471,7 @@ return error; dentry = fhp->fh_dentry; + mnt = fhp->fh_export->ex_mnt; inode = dentry->d_inode; if (S_ISDIR(inode->i_mode)) flags = NFS4_ACL_DIR; @@ -478,12 +482,14 @@ } else if (host_error < 0) goto out_nfserr; - host_error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS); + host_error = set_nfsv4_acl_one(dentry, mnt, pacl, + POSIX_ACL_XATTR_ACCESS); if (host_error < 0) goto out_release; if (S_ISDIR(inode->i_mode)) - host_error = set_nfsv4_acl_one(dentry, dpacl, POSIX_ACL_XATTR_DEFAULT); + host_error = set_nfsv4_acl_one(dentry, mnt, dpacl, + POSIX_ACL_XATTR_DEFAULT); out_release: posix_acl_release(pacl); @@ -496,13 +502,13 @@ } static struct posix_acl * -_get_posix_acl(struct dentry *dentry, char *key) +_get_posix_acl(struct dentry *dentry, struct vfsmount *mnt, char *key) { void *buf = NULL; struct posix_acl *pacl = NULL; int buflen; - buflen = nfsd_getxattr(dentry, key, &buf); + buflen = nfsd_getxattr(dentry, mnt, key, &buf); if (!buflen) buflen = -ENODATA; if (buflen <= 0) @@ -514,14 +520,15 @@ } int -nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, struct nfs4_acl **acl) +nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, + struct vfsmount *mnt, struct nfs4_acl **acl) { struct inode *inode = dentry->d_inode; int error = 0; struct posix_acl *pacl = NULL, *dpacl = NULL; unsigned int flags = 0; - pacl = _get_posix_acl(dentry, POSIX_ACL_XATTR_ACCESS); + pacl = _get_posix_acl(dentry, mnt, POSIX_ACL_XATTR_ACCESS); if (IS_ERR(pacl) && PTR_ERR(pacl) == -ENODATA) pacl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); if (IS_ERR(pacl)) { @@ -531,7 +538,7 @@ } if (S_ISDIR(inode->i_mode)) { - dpacl = _get_posix_acl(dentry, POSIX_ACL_XATTR_DEFAULT); + dpacl = _get_posix_acl(dentry, mnt, POSIX_ACL_XATTR_DEFAULT); if (IS_ERR(dpacl) && PTR_ERR(dpacl) == -ENODATA) dpacl = NULL; else if (IS_ERR(dpacl)) { @@ -943,13 +950,13 @@ return err; } -static void kill_suid(struct dentry *dentry) +static void kill_suid(struct dentry *dentry, struct vfsmount *mnt) { struct iattr ia; ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; mutex_lock(&dentry->d_inode->i_mutex); - notify_change(dentry, &ia); + notify_change(dentry, mnt, &ia); mutex_unlock(&dentry->d_inode->i_mutex); } @@ -1008,7 +1015,7 @@ /* clear setuid/setgid flag after write */ if (host_err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID))) - kill_suid(dentry); + kill_suid(dentry, exp->ex_mnt); if (host_err >= 0 && stable) { static ino_t last_ino; @@ -1165,6 +1172,7 @@ int type, dev_t rdev, struct svc_fh *resfhp) { struct dentry *dentry, *dchild = NULL; + struct svc_export *exp; struct inode *dirp; __be32 err; int host_err; @@ -1181,6 +1189,7 @@ goto out; dentry = fhp->fh_dentry; + exp = fhp->fh_export; dirp = dentry->d_inode; err = nfserr_notdir; @@ -1197,7 +1206,7 @@ host_err = PTR_ERR(dchild); if (IS_ERR(dchild)) goto out_nfserr; - err = fh_compose(resfhp, fhp->fh_export, dchild, fhp); + err = fh_compose(resfhp, exp, dchild, fhp); if (err) goto out; } else { @@ -1236,13 +1245,14 @@ host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); break; case S_IFDIR: - host_err = vfs_mkdir(dirp, dchild, iap->ia_mode); + host_err = vfs_mkdir(dirp, dchild, exp->ex_mnt, iap->ia_mode); break; case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK: - host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev); + host_err = vfs_mknod(dirp, dchild, exp->ex_mnt, iap->ia_mode, + rdev); break; default: printk("nfsd: bad file type %o in nfsd_create\n", type); @@ -1251,7 +1261,7 @@ if (host_err < 0) goto out_nfserr; - if (EX_ISSYNC(fhp->fh_export)) { + if (EX_ISSYNC(exp)) { err = nfserrno(nfsd_sync_dir(dentry)); write_inode_now(dchild->d_inode, 1); } @@ -1486,6 +1496,7 @@ struct iattr *iap) { struct dentry *dentry, *dnew; + struct svc_export *exp; __be32 err, cerr; int host_err; umode_t mode; @@ -1512,6 +1523,7 @@ if (iap && (iap->ia_valid & ATTR_MODE)) mode = iap->ia_mode & S_IALLUGO; + exp = fhp->fh_export; if (unlikely(path[plen] != 0)) { char *path_alloced = kmalloc(plen+1, GFP_KERNEL); if (path_alloced == NULL) @@ -1519,20 +1531,22 @@ else { strncpy(path_alloced, path, plen); path_alloced[plen] = 0; - host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode); + host_err = vfs_symlink(dentry->d_inode, dnew, + exp->ex_mnt, path_alloced, mode); kfree(path_alloced); } } else - host_err = vfs_symlink(dentry->d_inode, dnew, path, mode); + host_err = vfs_symlink(dentry->d_inode, dnew, exp->ex_mnt, path, + mode); if (!host_err) { - if (EX_ISSYNC(fhp->fh_export)) + if (EX_ISSYNC(exp)) host_err = nfsd_sync_dir(dentry); } err = nfserrno(host_err); fh_unlock(fhp); - cerr = fh_compose(resfhp, fhp->fh_export, dnew, fhp); + cerr = fh_compose(resfhp, exp, dnew, fhp); dput(dnew); if (err==0) err = cerr; out: @@ -1582,7 +1596,8 @@ dold = tfhp->fh_dentry; dest = dold->d_inode; - host_err = vfs_link(dold, dirp, dnew); + host_err = vfs_link(dold, tfhp->fh_export->ex_mnt, dirp, + dnew, ffhp->fh_export->ex_mnt); if (!host_err) { if (EX_ISSYNC(ffhp->fh_export)) { err = nfserrno(nfsd_sync_dir(ddir)); @@ -1675,7 +1690,8 @@ host_err = -EPERM; } else #endif - host_err = vfs_rename(fdir, odentry, tdir, ndentry); + host_err = vfs_rename(fdir, odentry, ffhp->fh_export->ex_mnt, + tdir, ndentry, tfhp->fh_export->ex_mnt); if (!host_err && EX_ISSYNC(tfhp->fh_export)) { host_err = nfsd_sync_dir(tdentry); if (!host_err) @@ -1711,6 +1727,7 @@ char *fname, int flen) { struct dentry *dentry, *rdentry; + struct svc_export *exp; struct inode *dirp; __be32 err; int host_err; @@ -1725,6 +1742,7 @@ fh_lock_nested(fhp, I_MUTEX_PARENT); dentry = fhp->fh_dentry; dirp = dentry->d_inode; + exp = fhp->fh_export; rdentry = lookup_one_len(fname, dentry, flen); host_err = PTR_ERR(rdentry); @@ -1742,21 +1760,21 @@ if (type != S_IFDIR) { /* It's UNLINK */ #ifdef MSNFS - if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) && + if ((exp->ex_flags & NFSEXP_MSNFS) && (atomic_read(&rdentry->d_count) > 1)) { host_err = -EPERM; } else #endif - host_err = vfs_unlink(dirp, rdentry); + host_err = vfs_unlink(dirp, rdentry, exp->ex_mnt); } else { /* It's RMDIR */ - host_err = vfs_rmdir(dirp, rdentry); + host_err = vfs_rmdir(dirp, rdentry, exp->ex_mnt); } dput(rdentry); if (host_err) goto out_nfserr; - if (EX_ISSYNC(fhp->fh_export)) + if (EX_ISSYNC(exp)) host_err = nfsd_sync_dir(dentry); out_nfserr: @@ -1985,7 +2003,8 @@ return ERR_PTR(-EOPNOTSUPP); } - size = nfsd_getxattr(fhp->fh_dentry, name, &value); + size = nfsd_getxattr(fhp->fh_dentry, fhp->fh_export->ex_mnt, name, + &value); if (size < 0) return ERR_PTR(size); @@ -1997,6 +2016,7 @@ int nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl) { + struct vfsmount *mnt; struct inode *inode = fhp->fh_dentry->d_inode; char *name; void *value = NULL; @@ -2029,13 +2049,16 @@ } else size = 0; + mnt = fhp->fh_export->ex_mnt; if (size) - error = vfs_setxattr(fhp->fh_dentry, name, value, size, 0); + error = vfs_setxattr(fhp->fh_dentry, mnt, name, value, size, 0, + NULL); else { if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT) error = 0; else { - error = vfs_removexattr(fhp->fh_dentry, name); + error = vfs_removexattr(fhp->fh_dentry, mnt, name, + NULL); if (error == -ENODATA) error = 0; } --- linux-2.6.24.orig/fs/nfsd/nfs4recover.c +++ linux-2.6.24/fs/nfsd/nfs4recover.c @@ -154,7 +154,8 @@ dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n"); goto out_put; } - status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU); + status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, rec_dir.mnt, + S_IRWXU); out_put: dput(dentry); out_unlock: @@ -258,7 +259,7 @@ return -EINVAL; } mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); - status = vfs_unlink(dir->d_inode, dentry); + status = vfs_unlink(dir->d_inode, dentry, rec_dir.mnt); mutex_unlock(&dir->d_inode->i_mutex); return status; } @@ -273,7 +274,7 @@ * a kernel from the future.... */ nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file); mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); - status = vfs_rmdir(dir->d_inode, dentry); + status = vfs_rmdir(dir->d_inode, dentry, rec_dir.mnt); mutex_unlock(&dir->d_inode->i_mutex); return status; } --- linux-2.6.24.orig/fs/nfsd/nfs4acl.c +++ linux-2.6.24/fs/nfsd/nfs4acl.c @@ -443,7 +443,7 @@ * enough space for either: */ alloc = sizeof(struct posix_ace_state_array) - + cnt*sizeof(struct posix_ace_state); + + cnt*sizeof(struct posix_user_ace_state); state->users = kzalloc(alloc, GFP_KERNEL); if (!state->users) return -ENOMEM; --- linux-2.6.24.orig/fs/proc/base.c +++ linux-2.6.24/fs/proc/base.c @@ -310,6 +310,79 @@ } #endif +#ifdef CONFIG_LATENCYTOP +static int lstats_show_proc(struct seq_file *m, void *v) +{ + int i; + struct task_struct *task = m->private; + seq_puts(m, "Latency Top version : v0.1\n"); + + for (i = 0; i < 32; i++) { + if (task->latency_record[i].backtrace[0]) { + int q; + seq_printf(m, "%i %li %li ", + task->latency_record[i].count, + task->latency_record[i].time, + task->latency_record[i].max); + for (q = 0; q < LT_BACKTRACEDEPTH; q++) { + char sym[KSYM_NAME_LEN]; + char *c; + if (!task->latency_record[i].backtrace[q]) + break; + if (task->latency_record[i].backtrace[q] + == ULONG_MAX) + break; + sprint_symbol(sym, + task->latency_record[i].backtrace[q]); + c = strchr(sym, '+'); + if (c) + *c = 0; + seq_printf(m, "%s ", sym); + } + seq_printf(m, "\n"); + } + + } + return 0; +} + +static int lstats_open(struct inode *inode, struct file *file) +{ + int ret; + struct seq_file *m; + struct task_struct *task = get_proc_task(inode); + + ret = single_open(file, lstats_show_proc, NULL); + if (!ret) { + m = file->private_data; + m->private = task; + } + return ret; +} + +static ssize_t lstats_write(struct file *file, const char __user *buf, + size_t count, loff_t *offs) +{ + struct seq_file *m; + struct task_struct *task; + + m = file->private_data; + task = m->private; + clear_all_latency_tracing(task); + + return count; +} + +static const struct file_operations proc_lstats_operations = { + .open = lstats_open, + .read = seq_read, + .write = lstats_write, + .llseek = seq_lseek, + .release = single_release, +}; + +#endif + /* The badness from the OOM killer */ unsigned long badness(struct task_struct *p, unsigned long uptime); static int proc_oom_score(struct task_struct *task, char *buffer) @@ -2230,6 +2303,9 @@ #ifdef CONFIG_SCHEDSTATS INF("schedstat", S_IRUGO, pid_schedstat), #endif +#ifdef CONFIG_LATENCYTOP + REG("latency", S_IRUGO, lstats), +#endif #ifdef CONFIG_PROC_PID_CPUSET REG("cpuset", S_IRUGO, cpuset), #endif @@ -2555,6 +2631,9 @@ #ifdef CONFIG_SCHEDSTATS INF("schedstat", S_IRUGO, pid_schedstat), #endif +#ifdef CONFIG_LATENCYTOP + REG("latency", S_IRUGO, lstats), +#endif #ifdef CONFIG_PROC_PID_CPUSET REG("cpuset", S_IRUGO, cpuset), #endif --- linux-2.6.24.orig/fs/proc/proc_misc.c +++ linux-2.6.24/fs/proc/proc_misc.c @@ -653,6 +653,19 @@ return proc_calc_metrics(page, start, off, count, eof, len); } +#ifdef CONFIG_VERSION_SIGNATURE +static int version_signature_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len; + + strcpy(page, CONFIG_VERSION_SIGNATURE); + strcat(page, "\n"); + len = strlen(page); + return proc_calc_metrics(page, start, off, count, eof, len); +} +#endif + #ifdef CONFIG_MAGIC_SYSRQ /* * writing 'C' to /proc/sysrq-trigger is like sysrq-C @@ -704,6 +717,9 @@ {"filesystems", filesystems_read_proc}, {"cmdline", cmdline_read_proc}, {"execdomains", execdomains_read_proc}, +#ifdef CONFIG_VERSION_SIGNATURE + {"version_signature", version_signature_read_proc}, +#endif {NULL,} }; for (p = simple_ones; p->name; p++) --- linux-2.6.24.orig/fs/xfs/linux-2.6/xfs_lrw.c +++ linux-2.6.24/fs/xfs/linux-2.6/xfs_lrw.c @@ -727,7 +727,7 @@ !capable(CAP_FSETID)) { error = xfs_write_clear_setuid(xip); if (likely(!error)) - error = -remove_suid(file->f_path.dentry); + error = -remove_suid(&file->f_path); if (unlikely(error)) { goto out_unlock_internal; } --- linux-2.6.24.orig/fs/xfs/linux-2.6/xfs_file.c +++ linux-2.6.24/fs/xfs/linux-2.6/xfs_file.c @@ -350,8 +350,8 @@ size = buf.used; de = (struct hack_dirent *)buf.dirent; - curr_offset = de->offset /* & 0x7fffffff */; while (size > 0) { + curr_offset = de->offset /* & 0x7fffffff */; if (filldir(dirent, de->name, de->namlen, curr_offset & 0x7fffffff, de->ino, de->d_type)) { @@ -362,7 +362,6 @@ sizeof(u64)); size -= reclen; de = (struct hack_dirent *)((char *)de + reclen); - curr_offset = de->offset /* & 0x7fffffff */; } } --- linux-2.6.24.orig/fs/nfs/client.c +++ linux-2.6.24/fs/nfs/client.c @@ -419,6 +419,7 @@ */ static int nfs_start_lockd(struct nfs_server *server) { + static int warned; int error = 0; if (server->nfs_client->cl_nfsversion > 3) @@ -427,9 +428,28 @@ goto out; error = lockd_up((server->flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP); - if (error < 0) + if (error < 0) { + /* + * Ubuntu: fix NFS mounting regression from Edgy->Feisty. + * In 2.6.18 and older kernels any failures to start lockd were + * ignored. This meant an Edgy user could successfully mount + * NFS filesystems without having installed nfs-common. + * + * This behaviour has been changed in 2.6.19 and later kernels, + * and so mounting NFS filesystems without nfs-common fail with + * can't read superblock. + * + * This workaround fixes this by issuing a warning (on the first + * lockd start failure), and then allowing the mount to continue + * without locking. + */ + if (warned++ == 0) { + printk(KERN_ERR "nfs: Starting lockd failed (do you have nfs-common installed?).\n"); + printk(KERN_ERR "nfs: Continuing anyway, but this workaround will go away soon.\n"); + } server->flags |= NFS_MOUNT_NONLM; - else + error = 0; + } else server->destroy = nfs_destroy_server; out: return error; --- linux-2.6.24.orig/fs/nfs/write.c +++ linux-2.6.24/fs/nfs/write.c @@ -701,6 +701,17 @@ } /* + * If the page cache is marked as unsafe or invalid, then we can't rely on + * the PageUptodate() flag. In this case, we will need to turn off + * write optimisations that depend on the page contents being correct. + */ +static int nfs_write_pageuptodate(struct page *page, struct inode *inode) +{ + return PageUptodate(page) && + !(NFS_I(inode)->cache_validity & (NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_DATA)); +} + +/* * Update and possibly write a cached page of an NFS file. * * XXX: Keep an eye on generic_file_read to make sure it doesn't do bad @@ -721,10 +732,13 @@ (long long)(page_offset(page) +offset)); /* If we're not using byte range locks, and we know the page - * is entirely in cache, it may be more efficient to avoid - * fragmenting write requests. + * is up to date, it may be more efficient to extend the write + * to cover the entire page in order to avoid fragmentation + * inefficiencies. */ - if (PageUptodate(page) && inode->i_flock == NULL && !(file->f_mode & O_SYNC)) { + if (nfs_write_pageuptodate(page, inode) && + inode->i_flock == NULL && + !(file->f_mode & O_SYNC)) { count = max(count + offset, nfs_page_length(page)); offset = 0; } --- linux-2.6.24.orig/fs/jffs2/erase.c +++ linux-2.6.24/fs/jffs2/erase.c @@ -419,9 +419,6 @@ if (jffs2_write_nand_cleanmarker(c, jeb)) goto filebad; } - - /* Everything else got zeroed before the erase */ - jeb->free_size = c->sector_size; } else { struct kvec vecs[1]; @@ -449,18 +446,19 @@ goto filebad; } - - /* Everything else got zeroed before the erase */ - jeb->free_size = c->sector_size; - /* FIXME Special case for cleanmarker in empty block */ - jffs2_link_node_ref(c, jeb, jeb->offset | REF_NORMAL, c->cleanmarker_size, NULL); } + /* Everything else got zeroed before the erase */ + jeb->free_size = c->sector_size; down(&c->erase_free_sem); spin_lock(&c->erase_completion_lock); + c->erasing_size -= c->sector_size; - c->free_size += jeb->free_size; - c->used_size += jeb->used_size; + c->free_size += c->sector_size; + + /* Account for cleanmarker now, if it's in-band */ + if (c->cleanmarker_size && !jffs2_cleanmarker_oob(c)) + jffs2_link_node_ref(c, jeb, jeb->offset | REF_NORMAL, c->cleanmarker_size, NULL); jffs2_dbg_acct_sanity_check_nolock(c,jeb); jffs2_dbg_acct_paranoia_check_nolock(c, jeb); --- linux-2.6.24.orig/fs/ufs/util.h +++ linux-2.6.24/fs/ufs/util.h @@ -58,7 +58,7 @@ { switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { case UFS_ST_SUNOS: - if (fs32_to_cpu(sb, usb3->fs_postblformat == UFS_42POSTBLFMT)) { + if (fs32_to_cpu(sb, usb3->fs_postblformat) == UFS_42POSTBLFMT) { usb1->fs_u0.fs_sun.fs_state = cpu_to_fs32(sb, value); break; } --- linux-2.6.24.orig/fs/jbd2/recovery.c +++ linux-2.6.24/fs/jbd2/recovery.c @@ -488,7 +488,7 @@ memcpy(nbh->b_data, obh->b_data, journal->j_blocksize); if (flags & JBD2_FLAG_ESCAPE) { - *((__be32 *)bh->b_data) = + *((__be32 *)nbh->b_data) = cpu_to_be32(JBD2_MAGIC_NUMBER); } --- linux-2.6.24.orig/fs/gfs2/rgrp.h +++ linux-2.6.24/fs/gfs2/rgrp.h @@ -32,7 +32,9 @@ struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip); static inline void gfs2_alloc_put(struct gfs2_inode *ip) { - return; /* So we can see where ip->i_alloc is used */ + BUG_ON(ip->i_alloc == NULL); + kfree(ip->i_alloc); + ip->i_alloc = NULL; } int gfs2_inplace_reserve_i(struct gfs2_inode *ip, --- linux-2.6.24.orig/fs/gfs2/glock.c +++ linux-2.6.24/fs/gfs2/glock.c @@ -1,6 +1,6 @@ /* * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. - * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions @@ -217,7 +217,6 @@ if (atomic_dec_and_test(&gl->gl_ref)) { hlist_del(&gl->gl_list); write_unlock(gl_lock_addr(gl->gl_hash)); - BUG_ON(spin_is_locked(&gl->gl_spin)); gfs2_assert(sdp, gl->gl_state == LM_ST_UNLOCKED); gfs2_assert(sdp, list_empty(&gl->gl_reclaim)); gfs2_assert(sdp, list_empty(&gl->gl_holders)); @@ -346,7 +345,6 @@ gl->gl_object = NULL; gl->gl_sbd = sdp; gl->gl_aspace = NULL; - lops_init_le(&gl->gl_le, &gfs2_glock_lops); INIT_DELAYED_WORK(&gl->gl_work, glock_work_func); /* If this glock protects actual on-disk data or metadata blocks, @@ -461,7 +459,6 @@ static void gfs2_demote_wake(struct gfs2_glock *gl) { - BUG_ON(!spin_is_locked(&gl->gl_spin)); gl->gl_demote_state = LM_ST_EXCLUSIVE; clear_bit(GLF_DEMOTE, &gl->gl_flags); smp_mb__after_clear_bit(); @@ -507,21 +504,12 @@ static int rq_promote(struct gfs2_holder *gh) { struct gfs2_glock *gl = gh->gh_gl; - struct gfs2_sbd *sdp = gl->gl_sbd; if (!relaxed_state_ok(gl->gl_state, gh->gh_state, gh->gh_flags)) { if (list_empty(&gl->gl_holders)) { gl->gl_req_gh = gh; set_bit(GLF_LOCK, &gl->gl_flags); spin_unlock(&gl->gl_spin); - - if (atomic_read(&sdp->sd_reclaim_count) > - gfs2_tune_get(sdp, gt_reclaim_limit) && - !(gh->gh_flags & LM_FLAG_PRIORITY)) { - gfs2_reclaim_glock(sdp); - gfs2_reclaim_glock(sdp); - } - gfs2_glock_xmote_th(gh->gh_gl, gh); spin_lock(&gl->gl_spin); } @@ -567,7 +555,10 @@ gfs2_demote_wake(gl); return 0; } + set_bit(GLF_LOCK, &gl->gl_flags); + set_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags); + if (gl->gl_demote_state == LM_ST_UNLOCKED || gl->gl_state != LM_ST_EXCLUSIVE) { spin_unlock(&gl->gl_spin); @@ -576,7 +567,9 @@ spin_unlock(&gl->gl_spin); gfs2_glock_xmote_th(gl, NULL); } + spin_lock(&gl->gl_spin); + clear_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags); return 0; } @@ -598,23 +591,18 @@ if (!list_empty(&gl->gl_waiters1)) { gh = list_entry(gl->gl_waiters1.next, struct gfs2_holder, gh_list); - - if (test_bit(HIF_MUTEX, &gh->gh_iflags)) - blocked = rq_mutex(gh); - else - gfs2_assert_warn(gl->gl_sbd, 0); - + blocked = rq_mutex(gh); } else if (test_bit(GLF_DEMOTE, &gl->gl_flags)) { blocked = rq_demote(gl); + if (gl->gl_waiters2 && !blocked) { + set_bit(GLF_DEMOTE, &gl->gl_flags); + gl->gl_demote_state = LM_ST_UNLOCKED; + } + gl->gl_waiters2 = 0; } else if (!list_empty(&gl->gl_waiters3)) { gh = list_entry(gl->gl_waiters3.next, struct gfs2_holder, gh_list); - - if (test_bit(HIF_PROMOTE, &gh->gh_iflags)) - blocked = rq_promote(gh); - else - gfs2_assert_warn(gl->gl_sbd, 0); - + blocked = rq_promote(gh); } else break; @@ -632,27 +620,21 @@ static void gfs2_glmutex_lock(struct gfs2_glock *gl) { - struct gfs2_holder gh; - - gfs2_holder_init(gl, 0, 0, &gh); - set_bit(HIF_MUTEX, &gh.gh_iflags); - if (test_and_set_bit(HIF_WAIT, &gh.gh_iflags)) - BUG(); - spin_lock(&gl->gl_spin); if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) { + struct gfs2_holder gh; + + gfs2_holder_init(gl, 0, 0, &gh); + set_bit(HIF_WAIT, &gh.gh_iflags); list_add_tail(&gh.gh_list, &gl->gl_waiters1); + spin_unlock(&gl->gl_spin); + wait_on_holder(&gh); + gfs2_holder_uninit(&gh); } else { gl->gl_owner_pid = current->pid; gl->gl_ip = (unsigned long)__builtin_return_address(0); - clear_bit(HIF_WAIT, &gh.gh_iflags); - smp_mb(); - wake_up_bit(&gh.gh_iflags, HIF_WAIT); + spin_unlock(&gl->gl_spin); } - spin_unlock(&gl->gl_spin); - - wait_on_holder(&gh); - gfs2_holder_uninit(&gh); } /** @@ -691,7 +673,6 @@ gl->gl_owner_pid = 0; gl->gl_ip = 0; run_queue(gl); - BUG_ON(!spin_is_locked(&gl->gl_spin)); spin_unlock(&gl->gl_spin); } @@ -722,7 +703,10 @@ } } else if (gl->gl_demote_state != LM_ST_UNLOCKED && gl->gl_demote_state != state) { - gl->gl_demote_state = LM_ST_UNLOCKED; + if (test_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags)) + gl->gl_waiters2 = 1; + else + gl->gl_demote_state = LM_ST_UNLOCKED; } spin_unlock(&gl->gl_spin); } @@ -943,8 +927,8 @@ const struct gfs2_glock_operations *glops = gl->gl_ops; unsigned int ret; - if (glops->go_drop_th) - glops->go_drop_th(gl); + if (glops->go_xmote_th) + glops->go_xmote_th(gl); gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags)); gfs2_assert_warn(sdp, list_empty(&gl->gl_holders)); @@ -1156,8 +1140,6 @@ return -EIO; } - set_bit(HIF_PROMOTE, &gh->gh_iflags); - spin_lock(&gl->gl_spin); add_to_queue(gh); run_queue(gl); @@ -1248,12 +1230,11 @@ list_del_init(&gh->gh_list); if (list_empty(&gl->gl_holders)) { - spin_unlock(&gl->gl_spin); - - if (glops->go_unlock) + if (glops->go_unlock) { + spin_unlock(&gl->gl_spin); glops->go_unlock(gh); - - spin_lock(&gl->gl_spin); + spin_lock(&gl->gl_spin); + } gl->gl_stamp = jiffies; } @@ -1910,8 +1891,6 @@ print_dbg(gi, " req_bh = %s\n", (gl->gl_req_bh) ? "yes" : "no"); print_dbg(gi, " lvb_count = %d\n", atomic_read(&gl->gl_lvb_count)); print_dbg(gi, " object = %s\n", (gl->gl_object) ? "yes" : "no"); - print_dbg(gi, " le = %s\n", - (list_empty(&gl->gl_le.le_list)) ? "no" : "yes"); print_dbg(gi, " reclaim = %s\n", (list_empty(&gl->gl_reclaim)) ? "no" : "yes"); if (gl->gl_aspace) --- linux-2.6.24.orig/fs/gfs2/incore.h +++ linux-2.6.24/fs/gfs2/incore.h @@ -1,6 +1,6 @@ /* * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. - * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions @@ -131,7 +131,6 @@ struct gfs2_glock_operations { void (*go_xmote_th) (struct gfs2_glock *gl); void (*go_xmote_bh) (struct gfs2_glock *gl); - void (*go_drop_th) (struct gfs2_glock *gl); void (*go_inval) (struct gfs2_glock *gl, int flags); int (*go_demote_ok) (struct gfs2_glock *gl); int (*go_lock) (struct gfs2_holder *gh); @@ -141,10 +140,6 @@ }; enum { - /* Actions */ - HIF_MUTEX = 0, - HIF_PROMOTE = 1, - /* States */ HIF_HOLDER = 6, HIF_FIRST = 7, @@ -171,6 +166,8 @@ GLF_DEMOTE = 3, GLF_PENDING_DEMOTE = 4, GLF_DIRTY = 5, + GLF_DEMOTE_IN_PROGRESS = 6, + GLF_LFLUSH = 7, }; struct gfs2_glock { @@ -190,6 +187,7 @@ struct list_head gl_holders; struct list_head gl_waiters1; /* HIF_MUTEX */ struct list_head gl_waiters3; /* HIF_PROMOTE */ + int gl_waiters2; /* GIF_DEMOTE */ const struct gfs2_glock_operations *gl_ops; @@ -210,7 +208,6 @@ struct gfs2_sbd *gl_sbd; struct inode *gl_aspace; - struct gfs2_log_element gl_le; struct list_head gl_ail_list; atomic_t gl_ail_count; struct delayed_work gl_work; @@ -239,7 +236,6 @@ enum { GIF_INVALID = 0, GIF_QD_LOCKED = 1, - GIF_PAGED = 2, GIF_SW_PAGED = 3, }; @@ -268,14 +264,10 @@ struct gfs2_glock *i_gl; /* Move into i_gh? */ struct gfs2_holder i_iopen_gh; struct gfs2_holder i_gh; /* for prepare/commit_write only */ - struct gfs2_alloc i_alloc; + struct gfs2_alloc *i_alloc; u64 i_last_rg_alloc; - spinlock_t i_spin; struct rw_semaphore i_rw_mutex; - unsigned long i_last_pfault; - - struct buffer_head *i_cache[GFS2_MAX_META_HEIGHT]; }; /* @@ -287,19 +279,12 @@ return container_of(inode, struct gfs2_inode, i_inode); } -/* To be removed? */ -static inline struct gfs2_sbd *GFS2_SB(struct inode *inode) +static inline struct gfs2_sbd *GFS2_SB(const struct inode *inode) { return inode->i_sb->s_fs_info; } -enum { - GFF_DID_DIRECT_ALLOC = 0, - GFF_EXLOCK = 1, -}; - struct gfs2_file { - unsigned long f_flags; /* GFF_... */ struct mutex f_fl_mutex; struct gfs2_holder f_fl_gh; }; @@ -373,8 +358,17 @@ u64 ai_sync_gen; }; +struct gfs2_journal_extent { + struct list_head extent_list; + + unsigned int lblock; /* First logical block */ + u64 dblock; /* First disk block */ + u64 blocks; +}; + struct gfs2_jdesc { struct list_head jd_list; + struct list_head extent_list; struct inode *jd_inode; unsigned int jd_jid; @@ -421,13 +415,9 @@ struct gfs2_tune { spinlock_t gt_spin; - unsigned int gt_ilimit; - unsigned int gt_ilimit_tries; - unsigned int gt_ilimit_min; unsigned int gt_demote_secs; /* Cache retention for unheld glock */ unsigned int gt_incore_log_blocks; unsigned int gt_log_flush_secs; - unsigned int gt_jindex_refresh_secs; /* Check for new journal index */ unsigned int gt_recoverd_secs; unsigned int gt_logd_secs; @@ -443,10 +433,8 @@ unsigned int gt_new_files_jdata; unsigned int gt_new_files_directio; unsigned int gt_max_readahead; /* Max bytes to read-ahead from disk */ - unsigned int gt_lockdump_size; unsigned int gt_stall_secs; /* Detects trouble! */ unsigned int gt_complain_secs; - unsigned int gt_reclaim_limit; /* Max num of glocks in reclaim list */ unsigned int gt_statfs_quantum; unsigned int gt_statfs_slow; }; @@ -539,7 +527,6 @@ /* StatFS stuff */ spinlock_t sd_statfs_spin; - struct mutex sd_statfs_mutex; struct gfs2_statfs_change_host sd_statfs_master; struct gfs2_statfs_change_host sd_statfs_local; unsigned long sd_statfs_sync_time; @@ -602,20 +589,18 @@ unsigned int sd_log_commited_databuf; unsigned int sd_log_commited_revoke; - unsigned int sd_log_num_gl; unsigned int sd_log_num_buf; unsigned int sd_log_num_revoke; unsigned int sd_log_num_rg; unsigned int sd_log_num_databuf; - struct list_head sd_log_le_gl; struct list_head sd_log_le_buf; struct list_head sd_log_le_revoke; struct list_head sd_log_le_rg; struct list_head sd_log_le_databuf; struct list_head sd_log_le_ordered; - unsigned int sd_log_blks_free; + atomic_t sd_log_blks_free; struct mutex sd_log_reserve_mutex; u64 sd_log_sequence; --- linux-2.6.24.orig/fs/gfs2/ops_inode.c +++ linux-2.6.24/fs/gfs2/ops_inode.c @@ -61,7 +61,7 @@ inode = gfs2_createi(ghs, &dentry->d_name, S_IFREG | mode, 0); if (!IS_ERR(inode)) { gfs2_trans_end(sdp); - if (dip->i_alloc.al_rgd) + if (dip->i_alloc->al_rgd) gfs2_inplace_release(dip); gfs2_quota_unlock(dip); gfs2_alloc_put(dip); @@ -113,8 +113,18 @@ if (inode && IS_ERR(inode)) return ERR_PTR(PTR_ERR(inode)); - if (inode) + if (inode) { + struct gfs2_glock *gl = GFS2_I(inode)->i_gl; + struct gfs2_holder gh; + int error; + error = gfs2_glock_nq_init(gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); + if (error) { + iput(inode); + return ERR_PTR(error); + } + gfs2_glock_dq_uninit(&gh); return d_splice_alias(inode, dentry); + } d_add(dentry, inode); return NULL; @@ -366,7 +376,7 @@ } gfs2_trans_end(sdp); - if (dip->i_alloc.al_rgd) + if (dip->i_alloc->al_rgd) gfs2_inplace_release(dip); gfs2_quota_unlock(dip); gfs2_alloc_put(dip); @@ -442,7 +452,7 @@ gfs2_assert_withdraw(sdp, !error); /* dip already pinned */ gfs2_trans_end(sdp); - if (dip->i_alloc.al_rgd) + if (dip->i_alloc->al_rgd) gfs2_inplace_release(dip); gfs2_quota_unlock(dip); gfs2_alloc_put(dip); @@ -548,7 +558,7 @@ } gfs2_trans_end(sdp); - if (dip->i_alloc.al_rgd) + if (dip->i_alloc->al_rgd) gfs2_inplace_release(dip); gfs2_quota_unlock(dip); gfs2_alloc_put(dip); --- linux-2.6.24.orig/fs/gfs2/glops.c +++ linux-2.6.24/fs/gfs2/glops.c @@ -56,7 +56,7 @@ bd = list_entry(head->next, struct gfs2_bufdata, bd_ail_gl_list); bh = bd->bd_bh; - gfs2_remove_from_ail(NULL, bd); + gfs2_remove_from_ail(bd); bd->bd_bh = NULL; bh->b_private = NULL; bd->bd_blkno = bh->b_blocknr; @@ -86,15 +86,10 @@ if (!ip || !S_ISREG(inode->i_mode)) return; - if (!test_bit(GIF_PAGED, &ip->i_flags)) - return; - unmap_shared_mapping_range(inode->i_mapping, 0, 0); - if (test_bit(GIF_SW_PAGED, &ip->i_flags)) set_bit(GLF_DIRTY, &gl->gl_flags); - clear_bit(GIF_SW_PAGED, &ip->i_flags); } /** @@ -143,44 +138,34 @@ static void inode_go_sync(struct gfs2_glock *gl) { struct gfs2_inode *ip = gl->gl_object; + struct address_space *metamapping = gl->gl_aspace->i_mapping; + int error; + + if (gl->gl_state != LM_ST_UNLOCKED) + gfs2_pte_inval(gl); + if (gl->gl_state != LM_ST_EXCLUSIVE) + return; if (ip && !S_ISREG(ip->i_inode.i_mode)) ip = NULL; if (test_bit(GLF_DIRTY, &gl->gl_flags)) { - if (ip && !gfs2_is_jdata(ip)) - filemap_fdatawrite(ip->i_inode.i_mapping); gfs2_log_flush(gl->gl_sbd, gl); - if (ip && gfs2_is_jdata(ip)) - filemap_fdatawrite(ip->i_inode.i_mapping); - gfs2_meta_sync(gl); + filemap_fdatawrite(metamapping); if (ip) { struct address_space *mapping = ip->i_inode.i_mapping; - int error = filemap_fdatawait(mapping); + filemap_fdatawrite(mapping); + error = filemap_fdatawait(mapping); mapping_set_error(mapping, error); } + error = filemap_fdatawait(metamapping); + mapping_set_error(metamapping, error); clear_bit(GLF_DIRTY, &gl->gl_flags); gfs2_ail_empty_gl(gl); } } /** - * inode_go_xmote_th - promote/demote a glock - * @gl: the glock - * @state: the requested state - * @flags: - * - */ - -static void inode_go_xmote_th(struct gfs2_glock *gl) -{ - if (gl->gl_state != LM_ST_UNLOCKED) - gfs2_pte_inval(gl); - if (gl->gl_state == LM_ST_EXCLUSIVE) - inode_go_sync(gl); -} - -/** * inode_go_xmote_bh - After promoting/demoting a glock * @gl: the glock * @@ -201,22 +186,6 @@ } /** - * inode_go_drop_th - unlock a glock - * @gl: the glock - * - * Invoked from rq_demote(). - * Another node needs the lock in EXCLUSIVE mode, or lock (unused for too long) - * is being purged from our node's glock cache; we're dropping lock. - */ - -static void inode_go_drop_th(struct gfs2_glock *gl) -{ - gfs2_pte_inval(gl); - if (gl->gl_state == LM_ST_EXCLUSIVE) - inode_go_sync(gl); -} - -/** * inode_go_inval - prepare a inode glock to be released * @gl: the glock * @flags: @@ -234,10 +203,8 @@ set_bit(GIF_INVALID, &ip->i_flags); } - if (ip && S_ISREG(ip->i_inode.i_mode)) { + if (ip && S_ISREG(ip->i_inode.i_mode)) truncate_inode_pages(ip->i_inode.i_mapping, 0); - clear_bit(GIF_PAGED, &ip->i_flags); - } } /** @@ -294,23 +261,6 @@ } /** - * inode_go_unlock - operation done before an inode lock is unlocked by a - * process - * @gl: the glock - * @flags: - * - */ - -static void inode_go_unlock(struct gfs2_holder *gh) -{ - struct gfs2_glock *gl = gh->gh_gl; - struct gfs2_inode *ip = gl->gl_object; - - if (ip) - gfs2_meta_cache_flush(ip); -} - -/** * rgrp_go_demote_ok - Check to see if it's ok to unlock a RG's glock * @gl: the glock * @@ -350,14 +300,14 @@ } /** - * trans_go_xmote_th - promote/demote the transaction glock + * trans_go_sync - promote/demote the transaction glock * @gl: the glock * @state: the requested state * @flags: * */ -static void trans_go_xmote_th(struct gfs2_glock *gl) +static void trans_go_sync(struct gfs2_glock *gl) { struct gfs2_sbd *sdp = gl->gl_sbd; @@ -384,7 +334,6 @@ if (gl->gl_state != LM_ST_UNLOCKED && test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { - gfs2_meta_cache_flush(GFS2_I(sdp->sd_jdesc->jd_inode)); j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); error = gfs2_find_jhead(sdp->sd_jdesc, &head); @@ -402,24 +351,6 @@ } /** - * trans_go_drop_th - unlock the transaction glock - * @gl: the glock - * - * We want to sync the device even with localcaching. Remember - * that localcaching journal replay only marks buffers dirty. - */ - -static void trans_go_drop_th(struct gfs2_glock *gl) -{ - struct gfs2_sbd *sdp = gl->gl_sbd; - - if (test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { - gfs2_meta_syncfs(sdp); - gfs2_log_shutdown(sdp); - } -} - -/** * quota_go_demote_ok - Check to see if it's ok to unlock a quota glock * @gl: the glock * @@ -433,25 +364,21 @@ const struct gfs2_glock_operations gfs2_meta_glops = { .go_xmote_th = meta_go_sync, - .go_drop_th = meta_go_sync, .go_type = LM_TYPE_META, }; const struct gfs2_glock_operations gfs2_inode_glops = { - .go_xmote_th = inode_go_xmote_th, + .go_xmote_th = inode_go_sync, .go_xmote_bh = inode_go_xmote_bh, - .go_drop_th = inode_go_drop_th, .go_inval = inode_go_inval, .go_demote_ok = inode_go_demote_ok, .go_lock = inode_go_lock, - .go_unlock = inode_go_unlock, .go_type = LM_TYPE_INODE, .go_min_hold_time = HZ / 10, }; const struct gfs2_glock_operations gfs2_rgrp_glops = { .go_xmote_th = meta_go_sync, - .go_drop_th = meta_go_sync, .go_inval = meta_go_inval, .go_demote_ok = rgrp_go_demote_ok, .go_lock = rgrp_go_lock, @@ -461,9 +388,8 @@ }; const struct gfs2_glock_operations gfs2_trans_glops = { - .go_xmote_th = trans_go_xmote_th, + .go_xmote_th = trans_go_sync, .go_xmote_bh = trans_go_xmote_bh, - .go_drop_th = trans_go_drop_th, .go_type = LM_TYPE_NONDISK, }; --- linux-2.6.24.orig/fs/gfs2/recovery.c +++ linux-2.6.24/fs/gfs2/recovery.c @@ -391,7 +391,7 @@ lblock = head->lh_blkno; gfs2_replay_incr_blk(sdp, &lblock); bh_map.b_size = 1 << ip->i_inode.i_blkbits; - error = gfs2_block_map(&ip->i_inode, lblock, 0, &bh_map); + error = gfs2_block_map(&ip->i_inode, lblock, &bh_map, 0); if (error) return error; if (!bh_map.b_blocknr) { @@ -504,13 +504,21 @@ if (!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) ro = 1; } else { - if (sdp->sd_vfs->s_flags & MS_RDONLY) - ro = 1; + if (sdp->sd_vfs->s_flags & MS_RDONLY) { + /* check if device itself is read-only */ + ro = bdev_read_only(sdp->sd_vfs->s_bdev); + if (!ro) { + fs_info(sdp, "recovery required on " + "read-only filesystem.\n"); + fs_info(sdp, "write access will be " + "enabled during recovery.\n"); + } + } } if (ro) { - fs_warn(sdp, "jid=%u: Can't replay: read-only FS\n", - jd->jd_jid); + fs_warn(sdp, "jid=%u: Can't replay: read-only block " + "device\n", jd->jd_jid); error = -EROFS; goto fail_gunlock_tr; } --- linux-2.6.24.orig/fs/gfs2/super.c +++ linux-2.6.24/fs/gfs2/super.c @@ -1,6 +1,6 @@ /* * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. - * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions @@ -51,13 +51,9 @@ { spin_lock_init(>->gt_spin); - gt->gt_ilimit = 100; - gt->gt_ilimit_tries = 3; - gt->gt_ilimit_min = 1; gt->gt_demote_secs = 300; gt->gt_incore_log_blocks = 1024; gt->gt_log_flush_secs = 60; - gt->gt_jindex_refresh_secs = 60; gt->gt_recoverd_secs = 60; gt->gt_logd_secs = 1; gt->gt_quotad_secs = 5; @@ -71,10 +67,8 @@ gt->gt_new_files_jdata = 0; gt->gt_new_files_directio = 0; gt->gt_max_readahead = 1 << 18; - gt->gt_lockdump_size = 131072; gt->gt_stall_secs = 600; gt->gt_complain_secs = 10; - gt->gt_reclaim_limit = 5000; gt->gt_statfs_quantum = 30; gt->gt_statfs_slow = 0; } @@ -393,6 +387,7 @@ if (!jd) break; + INIT_LIST_HEAD(&jd->extent_list); jd->jd_inode = gfs2_lookupi(sdp->sd_jindex, &name, 1, NULL); if (!jd->jd_inode || IS_ERR(jd->jd_inode)) { if (!jd->jd_inode) @@ -422,8 +417,9 @@ void gfs2_jindex_free(struct gfs2_sbd *sdp) { - struct list_head list; + struct list_head list, *head; struct gfs2_jdesc *jd; + struct gfs2_journal_extent *jext; spin_lock(&sdp->sd_jindex_spin); list_add(&list, &sdp->sd_jindex_list); @@ -433,6 +429,14 @@ while (!list_empty(&list)) { jd = list_entry(list.next, struct gfs2_jdesc, jd_list); + head = &jd->extent_list; + while (!list_empty(head)) { + jext = list_entry(head->next, + struct gfs2_journal_extent, + extent_list); + list_del(&jext->extent_list); + kfree(jext); + } list_del(&jd->jd_list); iput(jd->jd_inode); kfree(jd); @@ -543,7 +547,6 @@ if (error) return error; - gfs2_meta_cache_flush(ip); j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); error = gfs2_find_jhead(sdp->sd_jdesc, &head); @@ -686,9 +689,7 @@ if (error) return; - mutex_lock(&sdp->sd_statfs_mutex); gfs2_trans_add_bh(l_ip->i_gl, l_bh, 1); - mutex_unlock(&sdp->sd_statfs_mutex); spin_lock(&sdp->sd_statfs_spin); l_sc->sc_total += total; @@ -736,9 +737,7 @@ if (error) goto out_bh2; - mutex_lock(&sdp->sd_statfs_mutex); gfs2_trans_add_bh(l_ip->i_gl, l_bh, 1); - mutex_unlock(&sdp->sd_statfs_mutex); spin_lock(&sdp->sd_statfs_spin); m_sc->sc_total += l_sc->sc_total; --- linux-2.6.24.orig/fs/gfs2/dir.c +++ linux-2.6.24/fs/gfs2/dir.c @@ -1876,7 +1876,7 @@ if (error) goto out; - error = gfs2_rindex_hold(sdp, &dip->i_alloc.al_ri_gh); + error = gfs2_rindex_hold(sdp, &dip->i_alloc->al_ri_gh); if (error) goto out_qs; @@ -1949,7 +1949,7 @@ gfs2_glock_dq_m(rlist.rl_rgrps, rlist.rl_ghs); out_rlist: gfs2_rlist_free(&rlist); - gfs2_glock_dq_uninit(&dip->i_alloc.al_ri_gh); + gfs2_glock_dq_uninit(&dip->i_alloc->al_ri_gh); out_qs: gfs2_quota_unhold(dip); out: --- linux-2.6.24.orig/fs/gfs2/daemon.h +++ linux-2.6.24/fs/gfs2/daemon.h @@ -12,7 +12,6 @@ int gfs2_glockd(void *data); int gfs2_recoverd(void *data); -int gfs2_logd(void *data); int gfs2_quotad(void *data); #endif /* __DAEMON_DOT_H__ */ --- linux-2.6.24.orig/fs/gfs2/ops_address.c +++ linux-2.6.24/fs/gfs2/ops_address.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include "gfs2.h" #include "incore.h" @@ -32,7 +34,6 @@ #include "quota.h" #include "trans.h" #include "rgrp.h" -#include "ops_file.h" #include "super.h" #include "util.h" #include "glops.h" @@ -58,22 +59,6 @@ } /** - * gfs2_get_block - Fills in a buffer head with details about a block - * @inode: The inode - * @lblock: The block number to look up - * @bh_result: The buffer head to return the result in - * @create: Non-zero if we may add block to the file - * - * Returns: errno - */ - -int gfs2_get_block(struct inode *inode, sector_t lblock, - struct buffer_head *bh_result, int create) -{ - return gfs2_block_map(inode, lblock, create, bh_result); -} - -/** * gfs2_get_block_noalloc - Fills in a buffer head with details about a block * @inode: The inode * @lblock: The block number to look up @@ -88,7 +73,7 @@ { int error; - error = gfs2_block_map(inode, lblock, 0, bh_result); + error = gfs2_block_map(inode, lblock, bh_result, 0); if (error) return error; if (!buffer_mapped(bh_result)) @@ -99,20 +84,19 @@ static int gfs2_get_block_direct(struct inode *inode, sector_t lblock, struct buffer_head *bh_result, int create) { - return gfs2_block_map(inode, lblock, 0, bh_result); + return gfs2_block_map(inode, lblock, bh_result, 0); } /** - * gfs2_writepage - Write complete page - * @page: Page to write + * gfs2_writepage_common - Common bits of writepage + * @page: The page to be written + * @wbc: The writeback control * - * Returns: errno - * - * Some of this is copied from block_write_full_page() although we still - * call it to do most of the work. + * Returns: 1 if writepage is ok, otherwise an error code or zero if no error. */ -static int gfs2_writepage(struct page *page, struct writeback_control *wbc) +static int gfs2_writepage_common(struct page *page, + struct writeback_control *wbc) { struct inode *inode = page->mapping->host; struct gfs2_inode *ip = GFS2_I(inode); @@ -120,41 +104,133 @@ loff_t i_size = i_size_read(inode); pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT; unsigned offset; - int error; - int done_trans = 0; + int ret = -EIO; - if (gfs2_assert_withdraw(sdp, gfs2_glock_is_held_excl(ip->i_gl))) { - unlock_page(page); - return -EIO; - } + if (gfs2_assert_withdraw(sdp, gfs2_glock_is_held_excl(ip->i_gl))) + goto out; + ret = 0; if (current->journal_info) - goto out_ignore; - + goto redirty; /* Is the page fully outside i_size? (truncate in progress) */ - offset = i_size & (PAGE_CACHE_SIZE-1); + offset = i_size & (PAGE_CACHE_SIZE-1); if (page->index > end_index || (page->index == end_index && !offset)) { page->mapping->a_ops->invalidatepage(page, 0); - unlock_page(page); - return 0; /* don't care */ + goto out; + } + return 1; +redirty: + redirty_page_for_writepage(wbc, page); +out: + unlock_page(page); + return 0; +} + +/** + * gfs2_writeback_writepage - Write page for writeback mappings + * @page: The page + * @wbc: The writeback control + * + */ + +static int gfs2_writeback_writepage(struct page *page, + struct writeback_control *wbc) +{ + int ret; + + ret = gfs2_writepage_common(page, wbc); + if (ret <= 0) + return ret; + + ret = mpage_writepage(page, gfs2_get_block_noalloc, wbc); + if (ret == -EAGAIN) + ret = block_write_full_page(page, gfs2_get_block_noalloc, wbc); + return ret; +} + +/** + * gfs2_ordered_writepage - Write page for ordered data files + * @page: The page to write + * @wbc: The writeback control + * + */ + +static int gfs2_ordered_writepage(struct page *page, + struct writeback_control *wbc) +{ + struct inode *inode = page->mapping->host; + struct gfs2_inode *ip = GFS2_I(inode); + int ret; + + ret = gfs2_writepage_common(page, wbc); + if (ret <= 0) + return ret; + + if (!page_has_buffers(page)) { + create_empty_buffers(page, inode->i_sb->s_blocksize, + (1 << BH_Dirty)|(1 << BH_Uptodate)); } + gfs2_page_add_databufs(ip, page, 0, inode->i_sb->s_blocksize-1); + return block_write_full_page(page, gfs2_get_block_noalloc, wbc); +} + +/** + * __gfs2_jdata_writepage - The core of jdata writepage + * @page: The page to write + * @wbc: The writeback control + * + * This is shared between writepage and writepages and implements the + * core of the writepage operation. If a transaction is required then + * PageChecked will have been set and the transaction will have + * already been started before this is called. + */ - if ((sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) && - PageChecked(page)) { +static int __gfs2_jdata_writepage(struct page *page, struct writeback_control *wbc) +{ + struct inode *inode = page->mapping->host; + struct gfs2_inode *ip = GFS2_I(inode); + struct gfs2_sbd *sdp = GFS2_SB(inode); + + if (PageChecked(page)) { ClearPageChecked(page); - error = gfs2_trans_begin(sdp, RES_DINODE + 1, 0); - if (error) - goto out_ignore; if (!page_has_buffers(page)) { create_empty_buffers(page, inode->i_sb->s_blocksize, (1 << BH_Dirty)|(1 << BH_Uptodate)); } gfs2_page_add_databufs(ip, page, 0, sdp->sd_vfs->s_blocksize-1); + } + return block_write_full_page(page, gfs2_get_block_noalloc, wbc); +} + +/** + * gfs2_jdata_writepage - Write complete page + * @page: Page to write + * + * Returns: errno + * + */ + +static int gfs2_jdata_writepage(struct page *page, struct writeback_control *wbc) +{ + struct inode *inode = page->mapping->host; + struct gfs2_sbd *sdp = GFS2_SB(inode); + int error; + int done_trans = 0; + + error = gfs2_writepage_common(page, wbc); + if (error <= 0) + return error; + + if (PageChecked(page)) { + if (wbc->sync_mode != WB_SYNC_ALL) + goto out_ignore; + error = gfs2_trans_begin(sdp, RES_DINODE + 1, 0); + if (error) + goto out_ignore; done_trans = 1; } - error = block_write_full_page(page, gfs2_get_block_noalloc, wbc); + error = __gfs2_jdata_writepage(page, wbc); if (done_trans) gfs2_trans_end(sdp); - gfs2_meta_cache_flush(ip); return error; out_ignore: @@ -164,29 +240,190 @@ } /** - * gfs2_writepages - Write a bunch of dirty pages back to disk + * gfs2_writeback_writepages - Write a bunch of dirty pages back to disk * @mapping: The mapping to write * @wbc: Write-back control * - * For journaled files and/or ordered writes this just falls back to the - * kernel's default writepages path for now. We will probably want to change - * that eventually (i.e. when we look at allocate on flush). - * - * For the data=writeback case though we can already ignore buffer heads + * For the data=writeback case we can already ignore buffer heads * and write whole extents at once. This is a big reduction in the * number of I/O requests we send and the bmap calls we make in this case. */ -static int gfs2_writepages(struct address_space *mapping, - struct writeback_control *wbc) +static int gfs2_writeback_writepages(struct address_space *mapping, + struct writeback_control *wbc) +{ + return mpage_writepages(mapping, wbc, gfs2_get_block_noalloc); +} + +/** + * gfs2_write_jdata_pagevec - Write back a pagevec's worth of pages + * @mapping: The mapping + * @wbc: The writeback control + * @writepage: The writepage function to call for each page + * @pvec: The vector of pages + * @nr_pages: The number of pages to write + * + * Returns: non-zero if loop should terminate, zero otherwise + */ + +static int gfs2_write_jdata_pagevec(struct address_space *mapping, + struct writeback_control *wbc, + struct pagevec *pvec, + int nr_pages, pgoff_t end) { struct inode *inode = mapping->host; - struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_sbd *sdp = GFS2_SB(inode); + loff_t i_size = i_size_read(inode); + pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT; + unsigned offset = i_size & (PAGE_CACHE_SIZE-1); + unsigned nrblocks = nr_pages * (PAGE_CACHE_SIZE/inode->i_sb->s_blocksize); + struct backing_dev_info *bdi = mapping->backing_dev_info; + int i; + int ret; + + ret = gfs2_trans_begin(sdp, nrblocks, 0); + if (ret < 0) + return ret; + + for(i = 0; i < nr_pages; i++) { + struct page *page = pvec->pages[i]; + + lock_page(page); + + if (unlikely(page->mapping != mapping)) { + unlock_page(page); + continue; + } + + if (!wbc->range_cyclic && page->index > end) { + ret = 1; + unlock_page(page); + continue; + } + + if (wbc->sync_mode != WB_SYNC_NONE) + wait_on_page_writeback(page); + + if (PageWriteback(page) || + !clear_page_dirty_for_io(page)) { + unlock_page(page); + continue; + } + + /* Is the page fully outside i_size? (truncate in progress) */ + if (page->index > end_index || (page->index == end_index && !offset)) { + page->mapping->a_ops->invalidatepage(page, 0); + unlock_page(page); + continue; + } + + ret = __gfs2_jdata_writepage(page, wbc); + + if (ret || (--(wbc->nr_to_write) <= 0)) + ret = 1; + if (wbc->nonblocking && bdi_write_congested(bdi)) { + wbc->encountered_congestion = 1; + ret = 1; + } + + } + gfs2_trans_end(sdp); + return ret; +} + +/** + * gfs2_write_cache_jdata - Like write_cache_pages but different + * @mapping: The mapping to write + * @wbc: The writeback control + * @writepage: The writepage function to call + * @data: The data to pass to writepage + * + * The reason that we use our own function here is that we need to + * start transactions before we grab page locks. This allows us + * to get the ordering right. + */ + +static int gfs2_write_cache_jdata(struct address_space *mapping, + struct writeback_control *wbc) +{ + struct backing_dev_info *bdi = mapping->backing_dev_info; + int ret = 0; + int done = 0; + struct pagevec pvec; + int nr_pages; + pgoff_t index; + pgoff_t end; + int scanned = 0; + int range_whole = 0; + + if (wbc->nonblocking && bdi_write_congested(bdi)) { + wbc->encountered_congestion = 1; + return 0; + } + + pagevec_init(&pvec, 0); + if (wbc->range_cyclic) { + index = mapping->writeback_index; /* Start from prev offset */ + end = -1; + } else { + index = wbc->range_start >> PAGE_CACHE_SHIFT; + end = wbc->range_end >> PAGE_CACHE_SHIFT; + if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) + range_whole = 1; + scanned = 1; + } + +retry: + while (!done && (index <= end) && + (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, + PAGECACHE_TAG_DIRTY, + min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) { + scanned = 1; + ret = gfs2_write_jdata_pagevec(mapping, wbc, &pvec, nr_pages, end); + if (ret) + done = 1; + if (ret > 0) + ret = 0; + + pagevec_release(&pvec); + cond_resched(); + } + + if (!scanned && !done) { + /* + * We hit the last page and there is more work to be done: wrap + * back to the start of the file + */ + scanned = 1; + index = 0; + goto retry; + } + + if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) + mapping->writeback_index = index; + return ret; +} + + +/** + * gfs2_jdata_writepages - Write a bunch of dirty pages back to disk + * @mapping: The mapping to write + * @wbc: The writeback control + * + */ - if (sdp->sd_args.ar_data == GFS2_DATA_WRITEBACK && !gfs2_is_jdata(ip)) - return mpage_writepages(mapping, wbc, gfs2_get_block_noalloc); +static int gfs2_jdata_writepages(struct address_space *mapping, + struct writeback_control *wbc) +{ + struct gfs2_inode *ip = GFS2_I(mapping->host); + struct gfs2_sbd *sdp = GFS2_SB(mapping->host); + int ret; - return generic_writepages(mapping, wbc); + ret = gfs2_write_cache_jdata(mapping, wbc); + if (ret == 0 && wbc->sync_mode == WB_SYNC_ALL) { + gfs2_log_flush(sdp, ip->i_gl); + ret = gfs2_write_cache_jdata(mapping, wbc); + } + return ret; } /** @@ -231,62 +468,107 @@ /** - * gfs2_readpage - readpage with locking - * @file: The file to read a page for. N.B. This may be NULL if we are - * reading an internal file. + * __gfs2_readpage - readpage + * @file: The file to read a page for * @page: The page to read * - * Returns: errno + * This is the core of gfs2's readpage. Its used by the internal file + * reading code as in that case we already hold the glock. Also its + * called by gfs2_readpage() once the required lock has been granted. + * */ -static int gfs2_readpage(struct file *file, struct page *page) +static int __gfs2_readpage(void *file, struct page *page) { struct gfs2_inode *ip = GFS2_I(page->mapping->host); struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host); - struct gfs2_file *gf = NULL; - struct gfs2_holder gh; int error; - int do_unlock = 0; - if (likely(file != &gfs2_internal_file_sentinel)) { - if (file) { - gf = file->private_data; - if (test_bit(GFF_EXLOCK, &gf->f_flags)) - /* gfs2_sharewrite_fault has grabbed the ip->i_gl already */ - goto skip_lock; - } - gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME|LM_FLAG_TRY_1CB, &gh); - do_unlock = 1; - error = gfs2_glock_nq_atime(&gh); - if (unlikely(error)) - goto out_unlock; - } - -skip_lock: if (gfs2_is_stuffed(ip)) { error = stuffed_readpage(ip, page); unlock_page(page); - } else - error = mpage_readpage(page, gfs2_get_block); + } else { + error = mpage_readpage(page, gfs2_block_map); + } if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) - error = -EIO; + return -EIO; + + return error; +} + +/** + * gfs2_readpage - read a page of a file + * @file: The file to read + * @page: The page of the file + * + * This deals with the locking required. We use a trylock in order to + * avoid the page lock / glock ordering problems returning AOP_TRUNCATED_PAGE + * in the event that we are unable to get the lock. + */ + +static int gfs2_readpage(struct file *file, struct page *page) +{ + struct gfs2_inode *ip = GFS2_I(page->mapping->host); + struct gfs2_holder gh; + int error; - if (do_unlock) { - gfs2_glock_dq_m(1, &gh); - gfs2_holder_uninit(&gh); + gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME|LM_FLAG_TRY_1CB, &gh); + error = gfs2_glock_nq_atime(&gh); + if (unlikely(error)) { + unlock_page(page); + goto out; } + error = __gfs2_readpage(file, page); + gfs2_glock_dq(&gh); out: - return error; -out_unlock: - unlock_page(page); + gfs2_holder_uninit(&gh); if (error == GLR_TRYFAILED) { - error = AOP_TRUNCATED_PAGE; yield(); + return AOP_TRUNCATED_PAGE; } - if (do_unlock) - gfs2_holder_uninit(&gh); - goto out; + return error; +} + +/** + * gfs2_internal_read - read an internal file + * @ip: The gfs2 inode + * @ra_state: The readahead state (or NULL for no readahead) + * @buf: The buffer to fill + * @pos: The file position + * @size: The amount to read + * + */ + +int gfs2_internal_read(struct gfs2_inode *ip, struct file_ra_state *ra_state, + char *buf, loff_t *pos, unsigned size) +{ + struct address_space *mapping = ip->i_inode.i_mapping; + unsigned long index = *pos / PAGE_CACHE_SIZE; + unsigned offset = *pos & (PAGE_CACHE_SIZE - 1); + unsigned copied = 0; + unsigned amt; + struct page *page; + void *p; + + do { + amt = size - copied; + if (offset + size > PAGE_CACHE_SIZE) + amt = PAGE_CACHE_SIZE - offset; + page = read_cache_page(mapping, index, __gfs2_readpage, NULL); + if (IS_ERR(page)) + return PTR_ERR(page); + p = kmap_atomic(page, KM_USER0); + memcpy(buf + copied, p + offset, amt); + kunmap_atomic(p, KM_USER0); + mark_page_accessed(page); + page_cache_release(page); + copied += amt; + index++; + offset = 0; + } while(copied < size); + (*pos) += size; + return size; } /** @@ -300,10 +582,9 @@ * Any I/O we ignore at this time will be done via readpage later. * 2. We don't handle stuffed files here we let readpage do the honours. * 3. mpage_readpages() does most of the heavy lifting in the common case. - * 4. gfs2_get_block() is relied upon to set BH_Boundary in the right places. - * 5. We use LM_FLAG_TRY_1CB here, effectively we then have lock-ahead as - * well as read-ahead. + * 4. gfs2_block_map() is relied upon to set BH_Boundary in the right places. */ + static int gfs2_readpages(struct file *file, struct address_space *mapping, struct list_head *pages, unsigned nr_pages) { @@ -311,42 +592,20 @@ struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_sbd *sdp = GFS2_SB(inode); struct gfs2_holder gh; - int ret = 0; - int do_unlock = 0; + int ret; - if (likely(file != &gfs2_internal_file_sentinel)) { - if (file) { - struct gfs2_file *gf = file->private_data; - if (test_bit(GFF_EXLOCK, &gf->f_flags)) - goto skip_lock; - } - gfs2_holder_init(ip->i_gl, LM_ST_SHARED, - LM_FLAG_TRY_1CB|GL_ATIME, &gh); - do_unlock = 1; - ret = gfs2_glock_nq_atime(&gh); - if (ret == GLR_TRYFAILED) - goto out_noerror; - if (unlikely(ret)) - goto out_unlock; - } -skip_lock: + gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); + ret = gfs2_glock_nq_atime(&gh); + if (unlikely(ret)) + goto out_uninit; if (!gfs2_is_stuffed(ip)) - ret = mpage_readpages(mapping, pages, nr_pages, gfs2_get_block); - - if (do_unlock) { - gfs2_glock_dq_m(1, &gh); - gfs2_holder_uninit(&gh); - } -out: + ret = mpage_readpages(mapping, pages, nr_pages, gfs2_block_map); + gfs2_glock_dq(&gh); +out_uninit: + gfs2_holder_uninit(&gh); if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) ret = -EIO; return ret; -out_noerror: - ret = 0; -out_unlock: - if (do_unlock) - gfs2_holder_uninit(&gh); - goto out; } /** @@ -382,20 +641,11 @@ if (unlikely(error)) goto out_uninit; - error = -ENOMEM; - page = __grab_cache_page(mapping, index); - *pagep = page; - if (!page) - goto out_unlock; - gfs2_write_calc_reserv(ip, len, &data_blocks, &ind_blocks); - error = gfs2_write_alloc_required(ip, pos, len, &alloc_required); if (error) - goto out_putpage; - + goto out_unlock; - ip->i_alloc.al_requested = 0; if (alloc_required) { al = gfs2_alloc_get(ip); @@ -424,40 +674,47 @@ if (error) goto out_trans_fail; + error = -ENOMEM; + page = __grab_cache_page(mapping, index); + *pagep = page; + if (unlikely(!page)) + goto out_endtrans; + if (gfs2_is_stuffed(ip)) { + error = 0; if (pos + len > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) { error = gfs2_unstuff_dinode(ip, page); if (error == 0) goto prepare_write; - } else if (!PageUptodate(page)) + } else if (!PageUptodate(page)) { error = stuffed_readpage(ip, page); + } goto out; } prepare_write: - error = block_prepare_write(page, from, to, gfs2_get_block); - + error = block_prepare_write(page, from, to, gfs2_block_map); out: - if (error) { - gfs2_trans_end(sdp); + if (error == 0) + return 0; + + page_cache_release(page); + if (pos + len > ip->i_inode.i_size) + vmtruncate(&ip->i_inode, ip->i_inode.i_size); +out_endtrans: + gfs2_trans_end(sdp); out_trans_fail: - if (alloc_required) { - gfs2_inplace_release(ip); + if (alloc_required) { + gfs2_inplace_release(ip); out_qunlock: - gfs2_quota_unlock(ip); + gfs2_quota_unlock(ip); out_alloc_put: - gfs2_alloc_put(ip); - } -out_putpage: - page_cache_release(page); - if (pos + len > ip->i_inode.i_size) - vmtruncate(&ip->i_inode, ip->i_inode.i_size); + gfs2_alloc_put(ip); + } out_unlock: - gfs2_glock_dq_m(1, &ip->i_gh); + gfs2_glock_dq(&ip->i_gh); out_uninit: - gfs2_holder_uninit(&ip->i_gh); - } - + gfs2_holder_uninit(&ip->i_gh); return error; } @@ -565,7 +822,7 @@ struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_sbd *sdp = GFS2_SB(inode); struct buffer_head *dibh; - struct gfs2_alloc *al = &ip->i_alloc; + struct gfs2_alloc *al = ip->i_alloc; struct gfs2_dinode *di; unsigned int from = pos & (PAGE_CACHE_SIZE - 1); unsigned int to = from + len; @@ -585,19 +842,16 @@ if (gfs2_is_stuffed(ip)) return gfs2_stuffed_write_end(inode, dibh, pos, len, copied, page); - if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) + if (!gfs2_is_writeback(ip)) gfs2_page_add_databufs(ip, page, from, to); ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata); - if (likely(ret >= 0)) { - copied = ret; - if ((pos + copied) > inode->i_size) { - di = (struct gfs2_dinode *)dibh->b_data; - ip->i_di.di_size = inode->i_size; - di->di_size = cpu_to_be64(inode->i_size); - mark_inode_dirty(inode); - } + if (likely(ret >= 0) && (inode->i_size > ip->i_di.di_size)) { + di = (struct gfs2_dinode *)dibh->b_data; + ip->i_di.di_size = inode->i_size; + di->di_size = cpu_to_be64(inode->i_size); + mark_inode_dirty(inode); } if (inode == sdp->sd_rindex) @@ -606,7 +860,7 @@ brelse(dibh); gfs2_trans_end(sdp); failed: - if (al->al_requested) { + if (al) { gfs2_inplace_release(ip); gfs2_quota_unlock(ip); gfs2_alloc_put(ip); @@ -625,11 +879,7 @@ static int gfs2_set_page_dirty(struct page *page) { - struct gfs2_inode *ip = GFS2_I(page->mapping->host); - struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host); - - if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) - SetPageChecked(page); + SetPageChecked(page); return __set_page_dirty_buffers(page); } @@ -653,7 +903,7 @@ return 0; if (!gfs2_is_stuffed(ip)) - dblock = generic_block_bmap(mapping, lblock, gfs2_get_block); + dblock = generic_block_bmap(mapping, lblock, gfs2_block_map); gfs2_glock_dq_uninit(&i_gh); @@ -719,13 +969,9 @@ { /* * Should we return an error here? I can't see that O_DIRECT for - * a journaled file makes any sense. For now we'll silently fall - * back to buffered I/O, likewise we do the same for stuffed - * files since they are (a) small and (b) unaligned. + * a stuffed file makes any sense. For now we'll silently fall + * back to buffered I/O */ - if (gfs2_is_jdata(ip)) - return 0; - if (gfs2_is_stuffed(ip)) return 0; @@ -836,9 +1082,23 @@ return 0; } -const struct address_space_operations gfs2_file_aops = { - .writepage = gfs2_writepage, - .writepages = gfs2_writepages, +static const struct address_space_operations gfs2_writeback_aops = { + .writepage = gfs2_writeback_writepage, + .writepages = gfs2_writeback_writepages, + .readpage = gfs2_readpage, + .readpages = gfs2_readpages, + .sync_page = block_sync_page, + .write_begin = gfs2_write_begin, + .write_end = gfs2_write_end, + .bmap = gfs2_bmap, + .invalidatepage = gfs2_invalidatepage, + .releasepage = gfs2_releasepage, + .direct_IO = gfs2_direct_IO, + .migratepage = buffer_migrate_page, +}; + +static const struct address_space_operations gfs2_ordered_aops = { + .writepage = gfs2_ordered_writepage, .readpage = gfs2_readpage, .readpages = gfs2_readpages, .sync_page = block_sync_page, @@ -849,5 +1109,34 @@ .invalidatepage = gfs2_invalidatepage, .releasepage = gfs2_releasepage, .direct_IO = gfs2_direct_IO, + .migratepage = buffer_migrate_page, }; +static const struct address_space_operations gfs2_jdata_aops = { + .writepage = gfs2_jdata_writepage, + .writepages = gfs2_jdata_writepages, + .readpage = gfs2_readpage, + .readpages = gfs2_readpages, + .sync_page = block_sync_page, + .write_begin = gfs2_write_begin, + .write_end = gfs2_write_end, + .set_page_dirty = gfs2_set_page_dirty, + .bmap = gfs2_bmap, + .invalidatepage = gfs2_invalidatepage, + .releasepage = gfs2_releasepage, +}; + +void gfs2_set_aops(struct inode *inode) +{ + struct gfs2_inode *ip = GFS2_I(inode); + + if (gfs2_is_writeback(ip)) + inode->i_mapping->a_ops = &gfs2_writeback_aops; + else if (gfs2_is_ordered(ip)) + inode->i_mapping->a_ops = &gfs2_ordered_aops; + else if (gfs2_is_jdata(ip)) + inode->i_mapping->a_ops = &gfs2_jdata_aops; + else + BUG(); +} + --- linux-2.6.24.orig/fs/gfs2/quota.c +++ linux-2.6.24/fs/gfs2/quota.c @@ -1,6 +1,6 @@ /* * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. - * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions @@ -59,7 +59,6 @@ #include "super.h" #include "trans.h" #include "inode.h" -#include "ops_file.h" #include "ops_address.h" #include "util.h" @@ -274,10 +273,10 @@ } block = qd->qd_slot / sdp->sd_qc_per_block; - offset = qd->qd_slot % sdp->sd_qc_per_block;; + offset = qd->qd_slot % sdp->sd_qc_per_block; bh_map.b_size = 1 << ip->i_inode.i_blkbits; - error = gfs2_block_map(&ip->i_inode, block, 0, &bh_map); + error = gfs2_block_map(&ip->i_inode, block, &bh_map, 0); if (error) goto fail; error = gfs2_meta_read(ip->i_gl, bh_map.b_blocknr, DIO_WAIT, &bh); @@ -454,7 +453,7 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); - struct gfs2_alloc *al = &ip->i_alloc; + struct gfs2_alloc *al = ip->i_alloc; struct gfs2_quota_data **qd = al->al_qd; int error; @@ -502,7 +501,7 @@ void gfs2_quota_unhold(struct gfs2_inode *ip) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); - struct gfs2_alloc *al = &ip->i_alloc; + struct gfs2_alloc *al = ip->i_alloc; unsigned int x; gfs2_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &ip->i_flags)); @@ -646,7 +645,7 @@ } if (!buffer_mapped(bh)) { - gfs2_get_block(inode, iblock, bh, 1); + gfs2_block_map(inode, iblock, bh, 1); if (!buffer_mapped(bh)) goto unlock; } @@ -793,11 +792,9 @@ struct gfs2_holder i_gh; struct gfs2_quota_host q; char buf[sizeof(struct gfs2_quota)]; - struct file_ra_state ra_state; int error; struct gfs2_quota_lvb *qlvb; - file_ra_state_init(&ra_state, sdp->sd_quota_inode->i_mapping); restart: error = gfs2_glock_nq_init(qd->qd_gl, LM_ST_SHARED, 0, q_gh); if (error) @@ -820,8 +817,8 @@ memset(buf, 0, sizeof(struct gfs2_quota)); pos = qd2offset(qd); - error = gfs2_internal_read(ip, &ra_state, buf, - &pos, sizeof(struct gfs2_quota)); + error = gfs2_internal_read(ip, NULL, buf, &pos, + sizeof(struct gfs2_quota)); if (error < 0) goto fail_gunlock; @@ -856,7 +853,7 @@ int gfs2_quota_lock(struct gfs2_inode *ip, u32 uid, u32 gid) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); - struct gfs2_alloc *al = &ip->i_alloc; + struct gfs2_alloc *al = ip->i_alloc; unsigned int x; int error = 0; @@ -924,7 +921,7 @@ void gfs2_quota_unlock(struct gfs2_inode *ip) { - struct gfs2_alloc *al = &ip->i_alloc; + struct gfs2_alloc *al = ip->i_alloc; struct gfs2_quota_data *qda[4]; unsigned int count = 0; unsigned int x; @@ -972,7 +969,7 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); - struct gfs2_alloc *al = &ip->i_alloc; + struct gfs2_alloc *al = ip->i_alloc; struct gfs2_quota_data *qd; s64 value; unsigned int x; @@ -1016,10 +1013,9 @@ void gfs2_quota_change(struct gfs2_inode *ip, s64 change, u32 uid, u32 gid) { - struct gfs2_alloc *al = &ip->i_alloc; + struct gfs2_alloc *al = ip->i_alloc; struct gfs2_quota_data *qd; unsigned int x; - unsigned int found = 0; if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), change)) return; @@ -1032,7 +1028,6 @@ if ((qd->qd_id == uid && test_bit(QDF_USER, &qd->qd_flags)) || (qd->qd_id == gid && !test_bit(QDF_USER, &qd->qd_flags))) { do_qc(qd, change); - found++; } } } --- linux-2.6.24.orig/fs/gfs2/main.c +++ linux-2.6.24/fs/gfs2/main.c @@ -29,9 +29,8 @@ struct gfs2_inode *ip = foo; inode_init_once(&ip->i_inode); - spin_lock_init(&ip->i_spin); init_rwsem(&ip->i_rw_mutex); - memset(ip->i_cache, 0, sizeof(ip->i_cache)); + ip->i_alloc = NULL; } static void gfs2_init_glock_once(struct kmem_cache *cachep, void *foo) --- linux-2.6.24.orig/fs/gfs2/log.h +++ linux-2.6.24/fs/gfs2/log.h @@ -48,8 +48,6 @@ unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, unsigned int ssize); -int gfs2_ail1_empty(struct gfs2_sbd *sdp, int flags); - int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks); void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks); void gfs2_log_incr_head(struct gfs2_sbd *sdp); @@ -57,11 +55,19 @@ struct buffer_head *gfs2_log_get_buf(struct gfs2_sbd *sdp); struct buffer_head *gfs2_log_fake_buf(struct gfs2_sbd *sdp, struct buffer_head *real); -void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl); +void __gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl); + +static inline void gfs2_log_flush(struct gfs2_sbd *sbd, struct gfs2_glock *gl) +{ + if (!gl || test_bit(GLF_LFLUSH, &gl->gl_flags)) + __gfs2_log_flush(sbd, gl); +} + void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans); -void gfs2_remove_from_ail(struct address_space *mapping, struct gfs2_bufdata *bd); +void gfs2_remove_from_ail(struct gfs2_bufdata *bd); void gfs2_log_shutdown(struct gfs2_sbd *sdp); void gfs2_meta_syncfs(struct gfs2_sbd *sdp); +int gfs2_logd(void *data); #endif /* __LOG_DOT_H__ */ --- linux-2.6.24.orig/fs/gfs2/bmap.c +++ linux-2.6.24/fs/gfs2/bmap.c @@ -59,7 +59,6 @@ static int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh, u64 block, struct page *page) { - struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct inode *inode = &ip->i_inode; struct buffer_head *bh; int release = 0; @@ -95,7 +94,7 @@ set_buffer_uptodate(bh); if (!gfs2_is_jdata(ip)) mark_buffer_dirty(bh); - if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) + if (!gfs2_is_writeback(ip)) gfs2_trans_add_bh(ip->i_gl, bh, 0); if (release) { @@ -453,8 +452,8 @@ * Returns: errno */ -int gfs2_block_map(struct inode *inode, u64 lblock, int create, - struct buffer_head *bh_map) +int gfs2_block_map(struct inode *inode, sector_t lblock, + struct buffer_head *bh_map, int create) { struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_sbd *sdp = GFS2_SB(inode); @@ -470,6 +469,7 @@ unsigned int maxlen = bh_map->b_size >> inode->i_blkbits; struct metapath mp; u64 size; + struct buffer_head *dibh = NULL; BUG_ON(maxlen == 0); @@ -500,6 +500,8 @@ error = gfs2_meta_inode_buffer(ip, &bh); if (error) goto out_fail; + dibh = bh; + get_bh(dibh); for (x = 0; x < end_of_metadata; x++) { lookup_block(ip, bh, x, &mp, create, &new, &dblock); @@ -518,13 +520,8 @@ if (boundary) set_buffer_boundary(bh_map); if (new) { - struct buffer_head *dibh; - error = gfs2_meta_inode_buffer(ip, &dibh); - if (!error) { - gfs2_trans_add_bh(ip->i_gl, dibh, 1); - gfs2_dinode_out(ip, dibh->b_data); - brelse(dibh); - } + gfs2_trans_add_bh(ip->i_gl, dibh, 1); + gfs2_dinode_out(ip, dibh->b_data); set_buffer_new(bh_map); goto out_brelse; } @@ -545,6 +542,8 @@ out_ok: error = 0; out_fail: + if (dibh) + brelse(dibh); bmap_unlock(inode, create); return error; } @@ -560,7 +559,7 @@ BUG_ON(!new); bh.b_size = 1 << (inode->i_blkbits + 5); - ret = gfs2_block_map(inode, lblock, create, &bh); + ret = gfs2_block_map(inode, lblock, &bh, create); *extlen = bh.b_size >> inode->i_blkbits; *dblock = bh.b_blocknr; if (buffer_new(&bh)) @@ -684,7 +683,7 @@ if (metadata) revokes = (height) ? sdp->sd_inptrs : sdp->sd_diptrs; - error = gfs2_rindex_hold(sdp, &ip->i_alloc.al_ri_gh); + error = gfs2_rindex_hold(sdp, &ip->i_alloc->al_ri_gh); if (error) return error; @@ -786,7 +785,7 @@ out_rlist: gfs2_rlist_free(&rlist); out: - gfs2_glock_dq_uninit(&ip->i_alloc.al_ri_gh); + gfs2_glock_dq_uninit(&ip->i_alloc->al_ri_gh); return error; } @@ -879,7 +878,6 @@ { struct inode *inode = mapping->host; struct gfs2_inode *ip = GFS2_I(inode); - struct gfs2_sbd *sdp = GFS2_SB(inode); loff_t from = inode->i_size; unsigned long index = from >> PAGE_CACHE_SHIFT; unsigned offset = from & (PAGE_CACHE_SIZE-1); @@ -911,7 +909,7 @@ err = 0; if (!buffer_mapped(bh)) { - gfs2_get_block(inode, iblock, bh, 0); + gfs2_block_map(inode, iblock, bh, 0); /* unmapped? It's a hole - nothing to do */ if (!buffer_mapped(bh)) goto unlock; @@ -931,7 +929,7 @@ err = 0; } - if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) + if (!gfs2_is_writeback(ip)) gfs2_trans_add_bh(ip->i_gl, bh, 0); zero_user_page(page, offset, length, KM_USER0); @@ -1224,8 +1222,13 @@ do_div(lblock_stop, bsize); } else { unsigned int shift = sdp->sd_sb.sb_bsize_shift; + u64 end_of_file = (ip->i_di.di_size + sdp->sd_sb.sb_bsize - 1) >> shift; lblock = offset >> shift; lblock_stop = (offset + len + sdp->sd_sb.sb_bsize - 1) >> shift; + if (lblock_stop > end_of_file) { + *alloc_required = 1; + return 0; + } } for (; lblock < lblock_stop; lblock += extlen) { --- linux-2.6.24.orig/fs/gfs2/meta_io.h +++ linux-2.6.24/fs/gfs2/meta_io.h @@ -56,7 +56,6 @@ void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen); -void gfs2_meta_cache_flush(struct gfs2_inode *ip); int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num, int new, struct buffer_head **bhp); --- linux-2.6.24.orig/fs/gfs2/ops_file.c +++ linux-2.6.24/fs/gfs2/ops_file.c @@ -33,57 +33,12 @@ #include "lm.h" #include "log.h" #include "meta_io.h" -#include "ops_file.h" -#include "ops_vm.h" #include "quota.h" #include "rgrp.h" #include "trans.h" #include "util.h" #include "eaops.h" - -/* - * Most fields left uninitialised to catch anybody who tries to - * use them. f_flags set to prevent file_accessed() from touching - * any other part of this. Its use is purely as a flag so that we - * know (in readpage()) whether or not do to locking. - */ -struct file gfs2_internal_file_sentinel = { - .f_flags = O_NOATIME|O_RDONLY, -}; - -static int gfs2_read_actor(read_descriptor_t *desc, struct page *page, - unsigned long offset, unsigned long size) -{ - char *kaddr; - unsigned long count = desc->count; - - if (size > count) - size = count; - - kaddr = kmap(page); - memcpy(desc->arg.data, kaddr + offset, size); - kunmap(page); - - desc->count = count - size; - desc->written += size; - desc->arg.buf += size; - return size; -} - -int gfs2_internal_read(struct gfs2_inode *ip, struct file_ra_state *ra_state, - char *buf, loff_t *pos, unsigned size) -{ - struct inode *inode = &ip->i_inode; - read_descriptor_t desc; - desc.written = 0; - desc.arg.data = buf; - desc.count = size; - desc.error = 0; - do_generic_mapping_read(inode->i_mapping, ra_state, - &gfs2_internal_file_sentinel, pos, &desc, - gfs2_read_actor); - return desc.written ? desc.written : desc.error; -} +#include "ops_address.h" /** * gfs2_llseek - seek to a location in a file @@ -214,7 +169,7 @@ if (put_user(fsflags, ptr)) error = -EFAULT; - gfs2_glock_dq_m(1, &gh); + gfs2_glock_dq(&gh); gfs2_holder_uninit(&gh); return error; } @@ -291,7 +246,16 @@ if (error) goto out; } - + if ((flags ^ new_flags) & GFS2_DIF_JDATA) { + if (flags & GFS2_DIF_JDATA) + gfs2_log_flush(sdp, ip->i_gl); + error = filemap_fdatawrite(inode->i_mapping); + if (error) + goto out; + error = filemap_fdatawait(inode->i_mapping); + if (error) + goto out; + } error = gfs2_trans_begin(sdp, RES_DINODE, 0); if (error) goto out; @@ -303,6 +267,7 @@ gfs2_dinode_out(ip, bh->b_data); brelse(bh); gfs2_set_inode_flags(inode); + gfs2_set_aops(inode); out_trans_end: gfs2_trans_end(sdp); out: @@ -338,6 +303,128 @@ return -ENOTTY; } +/** + * gfs2_allocate_page_backing - Use bmap to allocate blocks + * @page: The (locked) page to allocate backing for + * + * We try to allocate all the blocks required for the page in + * one go. This might fail for various reasons, so we keep + * trying until all the blocks to back this page are allocated. + * If some of the blocks are already allocated, thats ok too. + */ + +static int gfs2_allocate_page_backing(struct page *page) +{ + struct inode *inode = page->mapping->host; + struct buffer_head bh; + unsigned long size = PAGE_CACHE_SIZE; + u64 lblock = page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits); + + do { + bh.b_state = 0; + bh.b_size = size; + gfs2_block_map(inode, lblock, &bh, 1); + if (!buffer_mapped(&bh)) + return -EIO; + size -= bh.b_size; + lblock += (bh.b_size >> inode->i_blkbits); + } while(size > 0); + return 0; +} + +/** + * gfs2_page_mkwrite - Make a shared, mmap()ed, page writable + * @vma: The virtual memory area + * @page: The page which is about to become writable + * + * When the page becomes writable, we need to ensure that we have + * blocks allocated on disk to back that page. + */ + +static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page) +{ + struct inode *inode = vma->vm_file->f_path.dentry->d_inode; + struct gfs2_inode *ip = GFS2_I(inode); + struct gfs2_sbd *sdp = GFS2_SB(inode); + unsigned long last_index; + u64 pos = page->index << (PAGE_CACHE_SIZE - inode->i_blkbits); + unsigned int data_blocks, ind_blocks, rblocks; + int alloc_required = 0; + struct gfs2_holder gh; + struct gfs2_alloc *al; + int ret; + + gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ATIME, &gh); + ret = gfs2_glock_nq_atime(&gh); + if (ret) + goto out; + + set_bit(GIF_SW_PAGED, &ip->i_flags); + gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks); + ret = gfs2_write_alloc_required(ip, pos, PAGE_CACHE_SIZE, &alloc_required); + if (ret || !alloc_required) + goto out_unlock; + ret = -ENOMEM; + al = gfs2_alloc_get(ip); + if (al == NULL) + goto out_unlock; + + ret = gfs2_quota_lock(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (ret) + goto out_alloc_put; + ret = gfs2_quota_check(ip, ip->i_inode.i_uid, ip->i_inode.i_gid); + if (ret) + goto out_quota_unlock; + al->al_requested = data_blocks + ind_blocks; + ret = gfs2_inplace_reserve(ip); + if (ret) + goto out_quota_unlock; + + rblocks = RES_DINODE + ind_blocks; + if (gfs2_is_jdata(ip)) + rblocks += data_blocks ? data_blocks : 1; + if (ind_blocks || data_blocks) + rblocks += RES_STATFS + RES_QUOTA; + ret = gfs2_trans_begin(sdp, rblocks, 0); + if (ret) + goto out_trans_fail; + + lock_page(page); + ret = -EINVAL; + last_index = ip->i_inode.i_size >> PAGE_CACHE_SHIFT; + if (page->index > last_index) + goto out_unlock_page; + ret = 0; + if (!PageUptodate(page) || page->mapping != ip->i_inode.i_mapping) + goto out_unlock_page; + if (gfs2_is_stuffed(ip)) { + ret = gfs2_unstuff_dinode(ip, page); + if (ret) + goto out_unlock_page; + } + ret = gfs2_allocate_page_backing(page); + +out_unlock_page: + unlock_page(page); + gfs2_trans_end(sdp); +out_trans_fail: + gfs2_inplace_release(ip); +out_quota_unlock: + gfs2_quota_unlock(ip); +out_alloc_put: + gfs2_alloc_put(ip); +out_unlock: + gfs2_glock_dq(&gh); +out: + gfs2_holder_uninit(&gh); + return ret; +} + +static struct vm_operations_struct gfs2_vm_ops = { + .fault = filemap_fault, + .page_mkwrite = gfs2_page_mkwrite, +}; + /** * gfs2_mmap - @@ -360,14 +447,7 @@ return error; } - /* This is VM_MAYWRITE instead of VM_WRITE because a call - to mprotect() can turn on VM_WRITE later. */ - - if ((vma->vm_flags & (VM_MAYSHARE | VM_MAYWRITE)) == - (VM_MAYSHARE | VM_MAYWRITE)) - vma->vm_ops = &gfs2_vm_ops_sharewrite; - else - vma->vm_ops = &gfs2_vm_ops_private; + vma->vm_ops = &gfs2_vm_ops; gfs2_glock_dq_uninit(&i_gh); @@ -538,15 +618,6 @@ if (__mandatory_lock(&ip->i_inode)) return -ENOLCK; - if (sdp->sd_args.ar_localflocks) { - if (IS_GETLK(cmd)) { - posix_test_lock(file, fl); - return 0; - } else { - return posix_lock_file_wait(file, fl); - } - } - if (cmd == F_CANCELLK) { /* Hack: */ cmd = F_SETLK; @@ -632,16 +703,12 @@ static int gfs2_flock(struct file *file, int cmd, struct file_lock *fl) { struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); - struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host); if (!(fl->fl_flags & FL_FLOCK)) return -ENOLCK; if (__mandatory_lock(&ip->i_inode)) return -ENOLCK; - if (sdp->sd_args.ar_localflocks) - return flock_lock_file_wait(file, fl); - if (fl->fl_type == F_UNLCK) { do_unflock(file, fl); return 0; @@ -678,3 +745,27 @@ .flock = gfs2_flock, }; +const struct file_operations gfs2_file_fops_nolock = { + .llseek = gfs2_llseek, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, + .unlocked_ioctl = gfs2_ioctl, + .mmap = gfs2_mmap, + .open = gfs2_open, + .release = gfs2_close, + .fsync = gfs2_fsync, + .splice_read = generic_file_splice_read, + .splice_write = generic_file_splice_write, + .setlease = gfs2_setlease, +}; + +const struct file_operations gfs2_dir_fops_nolock = { + .readdir = gfs2_readdir, + .unlocked_ioctl = gfs2_ioctl, + .open = gfs2_open, + .release = gfs2_close, + .fsync = gfs2_fsync, +}; + --- linux-2.6.24.orig/fs/gfs2/inode.h +++ linux-2.6.24/fs/gfs2/inode.h @@ -20,6 +20,18 @@ return ip->i_di.di_flags & GFS2_DIF_JDATA; } +static inline int gfs2_is_writeback(const struct gfs2_inode *ip) +{ + const struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); + return (sdp->sd_args.ar_data == GFS2_DATA_WRITEBACK) && !gfs2_is_jdata(ip); +} + +static inline int gfs2_is_ordered(const struct gfs2_inode *ip) +{ + const struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); + return (sdp->sd_args.ar_data == GFS2_DATA_ORDERED) && !gfs2_is_jdata(ip); +} + static inline int gfs2_is_dir(const struct gfs2_inode *ip) { return S_ISDIR(ip->i_inode.i_mode); --- linux-2.6.24.orig/fs/gfs2/rgrp.c +++ linux-2.6.24/fs/gfs2/rgrp.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "gfs2.h" #include "incore.h" @@ -25,14 +26,24 @@ #include "rgrp.h" #include "super.h" #include "trans.h" -#include "ops_file.h" #include "util.h" #include "log.h" #include "inode.h" +#include "ops_address.h" #define BFITNOENT ((u32)~0) #define NO_BLOCK ((u64)~0) +#if BITS_PER_LONG == 32 +#define LBITMASK (0x55555555UL) +#define LBITSKIP55 (0x55555555UL) +#define LBITSKIP00 (0x00000000UL) +#else +#define LBITMASK (0x5555555555555555UL) +#define LBITSKIP55 (0x5555555555555555UL) +#define LBITSKIP00 (0x0000000000000000UL) +#endif + /* * These routines are used by the resource group routines (rgrp.c) * to keep track of block allocation. Each block is represented by two @@ -126,45 +137,66 @@ * Return: the block number (bitmap buffer scope) that was found */ -static u32 gfs2_bitfit(struct gfs2_rgrpd *rgd, unsigned char *buffer, - unsigned int buflen, u32 goal, - unsigned char old_state) +static u32 gfs2_bitfit(const u8 *buffer, unsigned int buflen, u32 goal, + u8 old_state) { - unsigned char *byte, *end, alloc; - u32 blk = goal; - unsigned int bit; - - byte = buffer + (goal / GFS2_NBBY); - bit = (goal % GFS2_NBBY) * GFS2_BIT_SIZE; + const u8 *byte, *start, *end; + int bit, startbit; + u32 g1, g2, misaligned; + unsigned long *plong; + unsigned long lskipval; + + lskipval = (old_state & GFS2_BLKST_USED) ? LBITSKIP00 : LBITSKIP55; + g1 = (goal / GFS2_NBBY); + start = buffer + g1; + byte = start; end = buffer + buflen; - alloc = (old_state == GFS2_BLKST_FREE) ? 0x55 : 0; - + g2 = ALIGN(g1, sizeof(unsigned long)); + plong = (unsigned long *)(buffer + g2); + startbit = bit = (goal % GFS2_NBBY) * GFS2_BIT_SIZE; + misaligned = g2 - g1; + if (!misaligned) + goto ulong_aligned; +/* parse the bitmap a byte at a time */ +misaligned: while (byte < end) { - /* If we're looking for a free block we can eliminate all - bitmap settings with 0x55, which represents four data - blocks in a row. If we're looking for a data block, we can - eliminate 0x00 which corresponds to four free blocks. */ - if ((*byte & 0x55) == alloc) { - blk += (8 - bit) >> 1; - - bit = 0; - byte++; - - continue; + if (((*byte >> bit) & GFS2_BIT_MASK) == old_state) { + return goal + + (((byte - start) * GFS2_NBBY) + + ((bit - startbit) >> 1)); } - - if (((*byte >> bit) & GFS2_BIT_MASK) == old_state) - return blk; - bit += GFS2_BIT_SIZE; - if (bit >= 8) { + if (bit >= GFS2_NBBY * GFS2_BIT_SIZE) { bit = 0; byte++; + misaligned--; + if (!misaligned) { + plong = (unsigned long *)byte; + goto ulong_aligned; + } } - - blk++; } + return BFITNOENT; +/* parse the bitmap a unsigned long at a time */ +ulong_aligned: + /* Stop at "end - 1" or else prefetch can go past the end and segfault. + We could "if" it but we'd lose some of the performance gained. + This way will only slow down searching the very last 4/8 bytes + depending on architecture. I've experimented with several ways + of writing this section such as using an else before the goto + but this one seems to be the fastest. */ + while ((unsigned char *)plong < end - sizeof(unsigned long)) { + prefetch(plong + 1); + if (((*plong) & LBITMASK) != lskipval) + break; + plong++; + } + if ((unsigned char *)plong < end) { + byte = (const u8 *)plong; + misaligned += sizeof(unsigned long) - 1; + goto misaligned; + } return BFITNOENT; } @@ -817,11 +849,9 @@ struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip) { - struct gfs2_alloc *al = &ip->i_alloc; - - /* FIXME: Should assert that the correct locks are held here... */ - memset(al, 0, sizeof(*al)); - return al; + BUG_ON(ip->i_alloc != NULL); + ip->i_alloc = kzalloc(sizeof(struct gfs2_alloc), GFP_KERNEL); + return ip->i_alloc; } /** @@ -1059,26 +1089,34 @@ struct inode *inode = NULL; struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct gfs2_rgrpd *rgd, *begin = NULL; - struct gfs2_alloc *al = &ip->i_alloc; + struct gfs2_alloc *al = ip->i_alloc; int flags = LM_FLAG_TRY; int skipped = 0; int loops = 0; - int error; + int error, rg_locked; /* Try recently successful rgrps */ rgd = recent_rgrp_first(sdp, ip->i_last_rg_alloc); while (rgd) { - error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, - LM_FLAG_TRY, &al->al_rgd_gh); + rg_locked = 0; + + if (gfs2_glock_is_locked_by_me(rgd->rd_gl)) { + rg_locked = 1; + error = 0; + } else { + error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, + LM_FLAG_TRY, &al->al_rgd_gh); + } switch (error) { case 0: if (try_rgrp_fit(rgd, al)) goto out; if (rgd->rd_flags & GFS2_RDF_CHECK) inode = try_rgrp_unlink(rgd, last_unlinked); - gfs2_glock_dq_uninit(&al->al_rgd_gh); + if (!rg_locked) + gfs2_glock_dq_uninit(&al->al_rgd_gh); if (inode) return inode; rgd = recent_rgrp_next(rgd, 1); @@ -1098,15 +1136,23 @@ begin = rgd = forward_rgrp_get(sdp); for (;;) { - error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, flags, - &al->al_rgd_gh); + rg_locked = 0; + + if (gfs2_glock_is_locked_by_me(rgd->rd_gl)) { + rg_locked = 1; + error = 0; + } else { + error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, flags, + &al->al_rgd_gh); + } switch (error) { case 0: if (try_rgrp_fit(rgd, al)) goto out; if (rgd->rd_flags & GFS2_RDF_CHECK) inode = try_rgrp_unlink(rgd, last_unlinked); - gfs2_glock_dq_uninit(&al->al_rgd_gh); + if (!rg_locked) + gfs2_glock_dq_uninit(&al->al_rgd_gh); if (inode) return inode; break; @@ -1158,7 +1204,7 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); - struct gfs2_alloc *al = &ip->i_alloc; + struct gfs2_alloc *al = ip->i_alloc; struct inode *inode; int error = 0; u64 last_unlinked = NO_BLOCK; @@ -1204,7 +1250,7 @@ void gfs2_inplace_release(struct gfs2_inode *ip) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); - struct gfs2_alloc *al = &ip->i_alloc; + struct gfs2_alloc *al = ip->i_alloc; if (gfs2_assert_warn(sdp, al->al_alloced <= al->al_requested) == -1) fs_warn(sdp, "al_alloced = %u, al_requested = %u " @@ -1213,7 +1259,8 @@ al->al_line); al->al_rgd = NULL; - gfs2_glock_dq_uninit(&al->al_rgd_gh); + if (al->al_rgd_gh.gh_gl) + gfs2_glock_dq_uninit(&al->al_rgd_gh); if (ip != GFS2_I(sdp->sd_rindex)) gfs2_glock_dq_uninit(&al->al_ri_gh); } @@ -1301,11 +1348,10 @@ /* The GFS2_BLKST_UNLINKED state doesn't apply to the clone bitmaps, so we must search the originals for that. */ if (old_state != GFS2_BLKST_UNLINKED && bi->bi_clone) - blk = gfs2_bitfit(rgd, bi->bi_clone + bi->bi_offset, + blk = gfs2_bitfit(bi->bi_clone + bi->bi_offset, bi->bi_len, goal, old_state); else - blk = gfs2_bitfit(rgd, - bi->bi_bh->b_data + bi->bi_offset, + blk = gfs2_bitfit(bi->bi_bh->b_data + bi->bi_offset, bi->bi_len, goal, old_state); if (blk != BFITNOENT) break; @@ -1394,7 +1440,7 @@ u64 gfs2_alloc_data(struct gfs2_inode *ip) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); - struct gfs2_alloc *al = &ip->i_alloc; + struct gfs2_alloc *al = ip->i_alloc; struct gfs2_rgrpd *rgd = al->al_rgd; u32 goal, blk; u64 block; @@ -1439,7 +1485,7 @@ u64 gfs2_alloc_meta(struct gfs2_inode *ip) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); - struct gfs2_alloc *al = &ip->i_alloc; + struct gfs2_alloc *al = ip->i_alloc; struct gfs2_rgrpd *rgd = al->al_rgd; u32 goal, blk; u64 block; @@ -1485,7 +1531,7 @@ u64 gfs2_alloc_di(struct gfs2_inode *dip, u64 *generation) { struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); - struct gfs2_alloc *al = &dip->i_alloc; + struct gfs2_alloc *al = dip->i_alloc; struct gfs2_rgrpd *rgd = al->al_rgd; u32 blk; u64 block; --- linux-2.6.24.orig/fs/gfs2/meta_io.c +++ linux-2.6.24/fs/gfs2/meta_io.c @@ -50,6 +50,7 @@ static const struct address_space_operations aspace_aops = { .writepage = gfs2_aspace_writepage, .releasepage = gfs2_releasepage, + .sync_page = block_sync_page, }; /** @@ -221,13 +222,14 @@ struct buffer_head **bhp) { *bhp = getbuf(gl, blkno, CREATE); - if (!buffer_uptodate(*bhp)) + if (!buffer_uptodate(*bhp)) { ll_rw_block(READ_META, 1, bhp); - if (flags & DIO_WAIT) { - int error = gfs2_meta_wait(gl->gl_sbd, *bhp); - if (error) { - brelse(*bhp); - return error; + if (flags & DIO_WAIT) { + int error = gfs2_meta_wait(gl->gl_sbd, *bhp); + if (error) { + brelse(*bhp); + return error; + } } } @@ -282,7 +284,7 @@ return; } - bd = kmem_cache_zalloc(gfs2_bufdata_cachep, GFP_NOFS | __GFP_NOFAIL), + bd = kmem_cache_zalloc(gfs2_bufdata_cachep, GFP_NOFS | __GFP_NOFAIL); bd->bd_bh = bh; bd->bd_gl = gl; @@ -317,7 +319,7 @@ } if (bd) { if (bd->bd_ail) { - gfs2_remove_from_ail(NULL, bd); + gfs2_remove_from_ail(bd); bh->b_private = NULL; bd->bd_bh = NULL; bd->bd_blkno = bh->b_blocknr; @@ -358,32 +360,6 @@ } /** - * gfs2_meta_cache_flush - get rid of any references on buffers for this inode - * @ip: The GFS2 inode - * - * This releases buffers that are in the most-recently-used array of - * blocks used for indirect block addressing for this inode. - */ - -void gfs2_meta_cache_flush(struct gfs2_inode *ip) -{ - struct buffer_head **bh_slot; - unsigned int x; - - spin_lock(&ip->i_spin); - - for (x = 0; x < GFS2_MAX_META_HEIGHT; x++) { - bh_slot = &ip->i_cache[x]; - if (*bh_slot) { - brelse(*bh_slot); - *bh_slot = NULL; - } - } - - spin_unlock(&ip->i_spin); -} - -/** * gfs2_meta_indirect_buffer - Get a metadata buffer * @ip: The GFS2 inode * @height: The level of this buf in the metadata (indir addr) tree (if any) @@ -391,8 +367,6 @@ * @new: Non-zero if we may create a new buffer * @bhp: the buffer is returned here * - * Try to use the gfs2_inode's MRU metadata tree cache. - * * Returns: errno */ @@ -401,58 +375,25 @@ { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct gfs2_glock *gl = ip->i_gl; - struct buffer_head *bh = NULL, **bh_slot = ip->i_cache + height; - int in_cache = 0; - - BUG_ON(!gl); - BUG_ON(!sdp); - - spin_lock(&ip->i_spin); - if (*bh_slot && (*bh_slot)->b_blocknr == num) { - bh = *bh_slot; - get_bh(bh); - in_cache = 1; - } - spin_unlock(&ip->i_spin); - - if (!bh) - bh = getbuf(gl, num, CREATE); - - if (!bh) - return -ENOBUFS; + struct buffer_head *bh; + int ret = 0; if (new) { - if (gfs2_assert_warn(sdp, height)) - goto err; - meta_prep_new(bh); + BUG_ON(height == 0); + bh = gfs2_meta_new(gl, num); gfs2_trans_add_bh(ip->i_gl, bh, 1); gfs2_metatype_set(bh, GFS2_METATYPE_IN, GFS2_FORMAT_IN); gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header)); } else { u32 mtype = height ? GFS2_METATYPE_IN : GFS2_METATYPE_DI; - if (!buffer_uptodate(bh)) { - ll_rw_block(READ_META, 1, &bh); - if (gfs2_meta_wait(sdp, bh)) - goto err; + ret = gfs2_meta_read(gl, num, DIO_WAIT, &bh); + if (ret == 0 && gfs2_metatype_check(sdp, bh, mtype)) { + brelse(bh); + ret = -EIO; } - if (gfs2_metatype_check(sdp, bh, mtype)) - goto err; - } - - if (!in_cache) { - spin_lock(&ip->i_spin); - if (*bh_slot) - brelse(*bh_slot); - *bh_slot = bh; - get_bh(bh); - spin_unlock(&ip->i_spin); } - *bhp = bh; - return 0; -err: - brelse(bh); - return -EIO; + return ret; } /** --- linux-2.6.24.orig/fs/gfs2/lops.c +++ linux-2.6.24/fs/gfs2/lops.c @@ -87,6 +87,7 @@ } bd->bd_ail = ai; list_add(&bd->bd_ail_st_list, &ai->ai_ail1_list); + clear_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); gfs2_log_unlock(sdp); unlock_buffer(bh); } @@ -124,49 +125,6 @@ return bh; } -static void __glock_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le) -{ - struct gfs2_glock *gl; - struct gfs2_trans *tr = current->journal_info; - - tr->tr_touched = 1; - - gl = container_of(le, struct gfs2_glock, gl_le); - if (gfs2_assert_withdraw(sdp, gfs2_glock_is_held_excl(gl))) - return; - - if (!list_empty(&le->le_list)) - return; - - gfs2_glock_hold(gl); - set_bit(GLF_DIRTY, &gl->gl_flags); - sdp->sd_log_num_gl++; - list_add(&le->le_list, &sdp->sd_log_le_gl); -} - -static void glock_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le) -{ - gfs2_log_lock(sdp); - __glock_lo_add(sdp, le); - gfs2_log_unlock(sdp); -} - -static void glock_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai) -{ - struct list_head *head = &sdp->sd_log_le_gl; - struct gfs2_glock *gl; - - while (!list_empty(head)) { - gl = list_entry(head->next, struct gfs2_glock, gl_le.le_list); - list_del_init(&gl->gl_le.le_list); - sdp->sd_log_num_gl--; - - gfs2_assert_withdraw(sdp, gfs2_glock_is_held_excl(gl)); - gfs2_glock_put(gl); - } - gfs2_assert_warn(sdp, !sdp->sd_log_num_gl); -} - static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le) { struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le); @@ -182,7 +140,8 @@ list_add(&bd->bd_list_tr, &tr->tr_list_buf); if (!list_empty(&le->le_list)) goto out; - __glock_lo_add(sdp, &bd->bd_gl->gl_le); + set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); + set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); gfs2_meta_check(sdp, bd->bd_bh); gfs2_pin(sdp, bd->bd_bh); sdp->sd_log_num_buf++; @@ -556,17 +515,20 @@ lock_buffer(bd->bd_bh); gfs2_log_lock(sdp); - if (!list_empty(&bd->bd_list_tr)) - goto out; - tr->tr_touched = 1; - if (gfs2_is_jdata(ip)) { - tr->tr_num_buf++; - list_add(&bd->bd_list_tr, &tr->tr_list_buf); + if (tr) { + if (!list_empty(&bd->bd_list_tr)) + goto out; + tr->tr_touched = 1; + if (gfs2_is_jdata(ip)) { + tr->tr_num_buf++; + list_add(&bd->bd_list_tr, &tr->tr_list_buf); + } } if (!list_empty(&le->le_list)) goto out; - __glock_lo_add(sdp, &bd->bd_gl->gl_le); + set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); + set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); if (gfs2_is_jdata(ip)) { gfs2_pin(sdp, bd->bd_bh); tr->tr_num_databuf_new++; @@ -773,12 +735,6 @@ } -const struct gfs2_log_operations gfs2_glock_lops = { - .lo_add = glock_lo_add, - .lo_after_commit = glock_lo_after_commit, - .lo_name = "glock", -}; - const struct gfs2_log_operations gfs2_buf_lops = { .lo_add = buf_lo_add, .lo_incore_commit = buf_lo_incore_commit, @@ -816,7 +772,6 @@ }; const struct gfs2_log_operations *gfs2_log_ops[] = { - &gfs2_glock_lops, &gfs2_databuf_lops, &gfs2_buf_lops, &gfs2_rg_lops, --- linux-2.6.24.orig/fs/gfs2/Makefile +++ linux-2.6.24/fs/gfs2/Makefile @@ -2,7 +2,7 @@ gfs2-y := acl.o bmap.o daemon.o dir.o eaops.o eattr.o glock.o \ glops.o inode.o lm.o log.o lops.o locking.o main.o meta_io.o \ mount.o ops_address.o ops_dentry.o ops_export.o ops_file.o \ - ops_fstype.o ops_inode.o ops_super.o ops_vm.o quota.o \ + ops_fstype.o ops_inode.o ops_super.o quota.o \ recovery.o rgrp.o super.o sys.o trans.o util.o obj-$(CONFIG_GFS2_FS_LOCKING_NOLOCK) += locking/nolock/ --- linux-2.6.24.orig/fs/gfs2/eattr.c +++ linux-2.6.24/fs/gfs2/eattr.c @@ -1418,7 +1418,7 @@ static int ea_dealloc_block(struct gfs2_inode *ip) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); - struct gfs2_alloc *al = &ip->i_alloc; + struct gfs2_alloc *al = ip->i_alloc; struct gfs2_rgrpd *rgd; struct buffer_head *dibh; int error; --- linux-2.6.24.orig/fs/gfs2/ops_inode.h +++ linux-2.6.24/fs/gfs2/ops_inode.h @@ -16,5 +16,11 @@ extern const struct inode_operations gfs2_dir_iops; extern const struct inode_operations gfs2_symlink_iops; extern const struct inode_operations gfs2_dev_iops; +extern const struct file_operations gfs2_file_fops; +extern const struct file_operations gfs2_dir_fops; +extern const struct file_operations gfs2_file_fops_nolock; +extern const struct file_operations gfs2_dir_fops_nolock; + +extern void gfs2_set_inode_flags(struct inode *inode); #endif /* __OPS_INODE_DOT_H__ */ --- linux-2.6.24.orig/fs/gfs2/daemon.c +++ linux-2.6.24/fs/gfs2/daemon.c @@ -83,56 +83,6 @@ } /** - * gfs2_logd - Update log tail as Active Items get flushed to in-place blocks - * @sdp: Pointer to GFS2 superblock - * - * Also, periodically check to make sure that we're using the most recent - * journal index. - */ - -int gfs2_logd(void *data) -{ - struct gfs2_sbd *sdp = data; - struct gfs2_holder ji_gh; - unsigned long t; - int need_flush; - - while (!kthread_should_stop()) { - /* Advance the log tail */ - - t = sdp->sd_log_flush_time + - gfs2_tune_get(sdp, gt_log_flush_secs) * HZ; - - gfs2_ail1_empty(sdp, DIO_ALL); - gfs2_log_lock(sdp); - need_flush = sdp->sd_log_num_buf > gfs2_tune_get(sdp, gt_incore_log_blocks); - gfs2_log_unlock(sdp); - if (need_flush || time_after_eq(jiffies, t)) { - gfs2_log_flush(sdp, NULL); - sdp->sd_log_flush_time = jiffies; - } - - /* Check for latest journal index */ - - t = sdp->sd_jindex_refresh_time + - gfs2_tune_get(sdp, gt_jindex_refresh_secs) * HZ; - - if (time_after_eq(jiffies, t)) { - if (!gfs2_jindex_hold(sdp, &ji_gh)) - gfs2_glock_dq_uninit(&ji_gh); - sdp->sd_jindex_refresh_time = jiffies; - } - - t = gfs2_tune_get(sdp, gt_logd_secs) * HZ; - if (freezing(current)) - refrigerator(); - schedule_timeout_interruptible(t); - } - - return 0; -} - -/** * gfs2_quotad - Write cached quota changes into the quota file * @sdp: Pointer to GFS2 superblock * --- linux-2.6.24.orig/fs/gfs2/ops_fstype.c +++ linux-2.6.24/fs/gfs2/ops_fstype.c @@ -1,6 +1,6 @@ /* * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. - * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions @@ -21,6 +21,7 @@ #include "gfs2.h" #include "incore.h" +#include "bmap.h" #include "daemon.h" #include "glock.h" #include "glops.h" @@ -59,7 +60,6 @@ mutex_init(&sdp->sd_inum_mutex); spin_lock_init(&sdp->sd_statfs_spin); - mutex_init(&sdp->sd_statfs_mutex); spin_lock_init(&sdp->sd_rindex_spin); mutex_init(&sdp->sd_rindex_mutex); @@ -77,7 +77,6 @@ spin_lock_init(&sdp->sd_log_lock); - INIT_LIST_HEAD(&sdp->sd_log_le_gl); INIT_LIST_HEAD(&sdp->sd_log_le_buf); INIT_LIST_HEAD(&sdp->sd_log_le_revoke); INIT_LIST_HEAD(&sdp->sd_log_le_rg); @@ -303,6 +302,67 @@ return error; } +/** + * map_journal_extents - create a reusable "extent" mapping from all logical + * blocks to all physical blocks for the given journal. This will save + * us time when writing journal blocks. Most journals will have only one + * extent that maps all their logical blocks. That's because gfs2.mkfs + * arranges the journal blocks sequentially to maximize performance. + * So the extent would map the first block for the entire file length. + * However, gfs2_jadd can happen while file activity is happening, so + * those journals may not be sequential. Less likely is the case where + * the users created their own journals by mounting the metafs and + * laying it out. But it's still possible. These journals might have + * several extents. + * + * TODO: This should be done in bigger chunks rather than one block at a time, + * but since it's only done at mount time, I'm not worried about the + * time it takes. + */ +static int map_journal_extents(struct gfs2_sbd *sdp) +{ + struct gfs2_jdesc *jd = sdp->sd_jdesc; + unsigned int lb; + u64 db, prev_db; /* logical block, disk block, prev disk block */ + struct gfs2_inode *ip = GFS2_I(jd->jd_inode); + struct gfs2_journal_extent *jext = NULL; + struct buffer_head bh; + int rc = 0; + + prev_db = 0; + + for (lb = 0; lb < ip->i_di.di_size >> sdp->sd_sb.sb_bsize_shift; lb++) { + bh.b_state = 0; + bh.b_blocknr = 0; + bh.b_size = 1 << ip->i_inode.i_blkbits; + rc = gfs2_block_map(jd->jd_inode, lb, &bh, 0); + db = bh.b_blocknr; + if (rc || !db) { + printk(KERN_INFO "GFS2 journal mapping error %d: lb=" + "%u db=%llu\n", rc, lb, (unsigned long long)db); + break; + } + if (!prev_db || db != prev_db + 1) { + jext = kzalloc(sizeof(struct gfs2_journal_extent), + GFP_KERNEL); + if (!jext) { + printk(KERN_INFO "GFS2 error: out of memory " + "mapping journal extents.\n"); + rc = -ENOMEM; + break; + } + jext->dblock = db; + jext->lblock = lb; + jext->blocks = 1; + list_add_tail(&jext->extent_list, &jd->extent_list); + } else { + jext->blocks++; + } + prev_db = db; + } + return rc; +} + static int init_journal(struct gfs2_sbd *sdp, int undo) { struct gfs2_holder ji_gh; @@ -340,7 +400,7 @@ if (sdp->sd_args.ar_spectator) { sdp->sd_jdesc = gfs2_jdesc_find(sdp, 0); - sdp->sd_log_blks_free = sdp->sd_jdesc->jd_blocks; + atomic_set(&sdp->sd_log_blks_free, sdp->sd_jdesc->jd_blocks); } else { if (sdp->sd_lockstruct.ls_jid >= gfs2_jindex_size(sdp)) { fs_err(sdp, "can't mount journal #%u\n", @@ -377,7 +437,10 @@ sdp->sd_jdesc->jd_jid, error); goto fail_jinode_gh; } - sdp->sd_log_blks_free = sdp->sd_jdesc->jd_blocks; + atomic_set(&sdp->sd_log_blks_free, sdp->sd_jdesc->jd_blocks); + + /* Map the extents for this journal's blocks */ + map_journal_extents(sdp); } if (sdp->sd_lockstruct.ls_first) { --- linux-2.6.24.orig/fs/gfs2/trans.c +++ linux-2.6.24/fs/gfs2/trans.c @@ -114,11 +114,6 @@ gfs2_log_flush(sdp, NULL); } -void gfs2_trans_add_gl(struct gfs2_glock *gl) -{ - lops_add(gl->gl_sbd, &gl->gl_le); -} - /** * gfs2_trans_add_bh - Add a to-be-modified buffer to the current transaction * @gl: the glock the buffer belongs to --- linux-2.6.24.orig/fs/gfs2/ops_address.h +++ linux-2.6.24/fs/gfs2/ops_address.h @@ -14,9 +14,10 @@ #include #include -extern const struct address_space_operations gfs2_file_aops; -extern int gfs2_get_block(struct inode *inode, sector_t lblock, - struct buffer_head *bh_result, int create); extern int gfs2_releasepage(struct page *page, gfp_t gfp_mask); +extern int gfs2_internal_read(struct gfs2_inode *ip, + struct file_ra_state *ra_state, + char *buf, loff_t *pos, unsigned size); +extern void gfs2_set_aops(struct inode *inode); #endif /* __OPS_ADDRESS_DOT_H__ */ --- linux-2.6.24.orig/fs/gfs2/ops_super.c +++ linux-2.6.24/fs/gfs2/ops_super.c @@ -487,7 +487,6 @@ if (ip) { ip->i_flags = 0; ip->i_gl = NULL; - ip->i_last_pfault = jiffies; } return &ip->i_inode; } --- linux-2.6.24.orig/fs/gfs2/log.c +++ linux-2.6.24/fs/gfs2/log.c @@ -1,6 +1,6 @@ /* * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. - * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include "gfs2.h" #include "incore.h" @@ -68,14 +70,12 @@ * */ -void gfs2_remove_from_ail(struct address_space *mapping, struct gfs2_bufdata *bd) +void gfs2_remove_from_ail(struct gfs2_bufdata *bd) { bd->bd_ail = NULL; list_del_init(&bd->bd_ail_st_list); list_del_init(&bd->bd_ail_gl_list); atomic_dec(&bd->bd_gl->gl_ail_count); - if (mapping) - gfs2_meta_cache_flush(GFS2_I(mapping->host)); brelse(bd->bd_bh); } @@ -92,8 +92,6 @@ struct buffer_head *bh; int retry; - BUG_ON(!spin_is_locked(&sdp->sd_log_lock)); - do { retry = 0; @@ -210,7 +208,7 @@ gfs2_log_unlock(sdp); } -int gfs2_ail1_empty(struct gfs2_sbd *sdp, int flags) +static int gfs2_ail1_empty(struct gfs2_sbd *sdp, int flags) { struct gfs2_ail *ai, *s; int ret; @@ -248,7 +246,7 @@ bd = list_entry(head->prev, struct gfs2_bufdata, bd_ail_st_list); gfs2_assert(sdp, bd->bd_ail == ai); - gfs2_remove_from_ail(bd->bd_bh->b_page->mapping, bd); + gfs2_remove_from_ail(bd); } } @@ -303,7 +301,7 @@ mutex_lock(&sdp->sd_log_reserve_mutex); gfs2_log_lock(sdp); - while(sdp->sd_log_blks_free <= (blks + reserved_blks)) { + while(atomic_read(&sdp->sd_log_blks_free) <= (blks + reserved_blks)) { gfs2_log_unlock(sdp); gfs2_ail1_empty(sdp, 0); gfs2_log_flush(sdp, NULL); @@ -312,7 +310,7 @@ gfs2_ail1_start(sdp, 0); gfs2_log_lock(sdp); } - sdp->sd_log_blks_free -= blks; + atomic_sub(blks, &sdp->sd_log_blks_free); gfs2_log_unlock(sdp); mutex_unlock(&sdp->sd_log_reserve_mutex); @@ -332,27 +330,23 @@ { gfs2_log_lock(sdp); - sdp->sd_log_blks_free += blks; + atomic_add(blks, &sdp->sd_log_blks_free); gfs2_assert_withdraw(sdp, - sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks); + atomic_read(&sdp->sd_log_blks_free) <= sdp->sd_jdesc->jd_blocks); gfs2_log_unlock(sdp); up_read(&sdp->sd_log_flush_lock); } static u64 log_bmap(struct gfs2_sbd *sdp, unsigned int lbn) { - struct inode *inode = sdp->sd_jdesc->jd_inode; - int error; - struct buffer_head bh_map = { .b_state = 0, .b_blocknr = 0 }; - - bh_map.b_size = 1 << inode->i_blkbits; - error = gfs2_block_map(inode, lbn, 0, &bh_map); - if (error || !bh_map.b_blocknr) - printk(KERN_INFO "error=%d, dbn=%llu lbn=%u", error, - (unsigned long long)bh_map.b_blocknr, lbn); - gfs2_assert_withdraw(sdp, !error && bh_map.b_blocknr); + struct gfs2_journal_extent *je; + + list_for_each_entry(je, &sdp->sd_jdesc->extent_list, extent_list) { + if (lbn >= je->lblock && lbn < je->lblock + je->blocks) + return je->dblock + lbn - je->lblock; + } - return bh_map.b_blocknr; + return -1; } /** @@ -561,8 +555,8 @@ ail2_empty(sdp, new_tail); gfs2_log_lock(sdp); - sdp->sd_log_blks_free += dist; - gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks); + atomic_add(dist, &sdp->sd_log_blks_free); + gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <= sdp->sd_jdesc->jd_blocks); gfs2_log_unlock(sdp); sdp->sd_log_tail = new_tail; @@ -652,7 +646,7 @@ get_bh(bh); gfs2_log_unlock(sdp); lock_buffer(bh); - if (test_clear_buffer_dirty(bh)) { + if (buffer_mapped(bh) && test_clear_buffer_dirty(bh)) { bh->b_end_io = end_buffer_write_sync; submit_bh(WRITE, bh); } else { @@ -694,20 +688,16 @@ * */ -void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) +void __gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) { struct gfs2_ail *ai; down_write(&sdp->sd_log_flush_lock); - if (gl) { - gfs2_log_lock(sdp); - if (list_empty(&gl->gl_le.le_list)) { - gfs2_log_unlock(sdp); - up_write(&sdp->sd_log_flush_lock); - return; - } - gfs2_log_unlock(sdp); + /* Log might have been flushed while we waited for the flush lock */ + if (gl && !test_bit(GLF_LFLUSH, &gl->gl_flags)) { + up_write(&sdp->sd_log_flush_lock); + return; } ai = kzalloc(sizeof(struct gfs2_ail), GFP_NOFS | __GFP_NOFAIL); @@ -739,7 +729,7 @@ log_flush_commit(sdp); else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){ gfs2_log_lock(sdp); - sdp->sd_log_blks_free--; /* Adjust for unreserved buffer */ + atomic_dec(&sdp->sd_log_blks_free); /* Adjust for unreserved buffer */ gfs2_log_unlock(sdp); log_write_header(sdp, 0, PULL); } @@ -767,7 +757,7 @@ static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) { unsigned int reserved; - unsigned int old; + unsigned int unused; gfs2_log_lock(sdp); @@ -779,14 +769,11 @@ sdp->sd_log_commited_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm; gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_revoke) >= 0); reserved = calc_reserved(sdp); - old = sdp->sd_log_blks_free; - sdp->sd_log_blks_free += tr->tr_reserved - - (reserved - sdp->sd_log_blks_reserved); - - gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free >= old); - gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free <= + unused = sdp->sd_log_blks_reserved - reserved + tr->tr_reserved; + gfs2_assert_withdraw(sdp, unused >= 0); + atomic_add(unused, &sdp->sd_log_blks_free); + gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <= sdp->sd_jdesc->jd_blocks); - sdp->sd_log_blks_reserved = reserved; gfs2_log_unlock(sdp); @@ -825,7 +812,6 @@ down_write(&sdp->sd_log_flush_lock); gfs2_assert_withdraw(sdp, !sdp->sd_log_blks_reserved); - gfs2_assert_withdraw(sdp, !sdp->sd_log_num_gl); gfs2_assert_withdraw(sdp, !sdp->sd_log_num_buf); gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); gfs2_assert_withdraw(sdp, !sdp->sd_log_num_rg); @@ -838,7 +824,7 @@ log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT, (sdp->sd_log_tail == current_tail(sdp)) ? 0 : PULL); - gfs2_assert_warn(sdp, sdp->sd_log_blks_free == sdp->sd_jdesc->jd_blocks); + gfs2_assert_warn(sdp, atomic_read(&sdp->sd_log_blks_free) == sdp->sd_jdesc->jd_blocks); gfs2_assert_warn(sdp, sdp->sd_log_head == sdp->sd_log_tail); gfs2_assert_warn(sdp, list_empty(&sdp->sd_ail2_list)); @@ -866,3 +852,42 @@ } } + +/** + * gfs2_logd - Update log tail as Active Items get flushed to in-place blocks + * @sdp: Pointer to GFS2 superblock + * + * Also, periodically check to make sure that we're using the most recent + * journal index. + */ + +int gfs2_logd(void *data) +{ + struct gfs2_sbd *sdp = data; + unsigned long t; + int need_flush; + + while (!kthread_should_stop()) { + /* Advance the log tail */ + + t = sdp->sd_log_flush_time + + gfs2_tune_get(sdp, gt_log_flush_secs) * HZ; + + gfs2_ail1_empty(sdp, DIO_ALL); + gfs2_log_lock(sdp); + need_flush = sdp->sd_log_num_buf > gfs2_tune_get(sdp, gt_incore_log_blocks); + gfs2_log_unlock(sdp); + if (need_flush || time_after_eq(jiffies, t)) { + gfs2_log_flush(sdp, NULL); + sdp->sd_log_flush_time = jiffies; + } + + t = gfs2_tune_get(sdp, gt_logd_secs) * HZ; + if (freezing(current)) + refrigerator(); + schedule_timeout_interruptible(t); + } + + return 0; +} + --- linux-2.6.24.orig/fs/gfs2/sys.c +++ linux-2.6.24/fs/gfs2/sys.c @@ -32,7 +32,8 @@ static ssize_t id_show(struct gfs2_sbd *sdp, char *buf) { - return snprintf(buf, PAGE_SIZE, "%s\n", sdp->sd_vfs->s_id); + return snprintf(buf, PAGE_SIZE, "%u:%u\n", + MAJOR(sdp->sd_vfs->s_dev), MINOR(sdp->sd_vfs->s_dev)); } static ssize_t fsname_show(struct gfs2_sbd *sdp, char *buf) @@ -427,13 +428,11 @@ TUNE_ATTR(demote_secs, 0); TUNE_ATTR(incore_log_blocks, 0); TUNE_ATTR(log_flush_secs, 0); -TUNE_ATTR(jindex_refresh_secs, 0); TUNE_ATTR(quota_warn_period, 0); TUNE_ATTR(quota_quantum, 0); TUNE_ATTR(atime_quantum, 0); TUNE_ATTR(max_readahead, 0); TUNE_ATTR(complain_secs, 0); -TUNE_ATTR(reclaim_limit, 0); TUNE_ATTR(statfs_slow, 0); TUNE_ATTR(new_files_jdata, 0); TUNE_ATTR(new_files_directio, 0); @@ -450,13 +449,11 @@ &tune_attr_demote_secs.attr, &tune_attr_incore_log_blocks.attr, &tune_attr_log_flush_secs.attr, - &tune_attr_jindex_refresh_secs.attr, &tune_attr_quota_warn_period.attr, &tune_attr_quota_quantum.attr, &tune_attr_atime_quantum.attr, &tune_attr_max_readahead.attr, &tune_attr_complain_secs.attr, - &tune_attr_reclaim_limit.attr, &tune_attr_statfs_slow.attr, &tune_attr_quota_simul_sync.attr, &tune_attr_quota_cache_secs.attr, --- linux-2.6.24.orig/fs/gfs2/inode.c +++ linux-2.6.24/fs/gfs2/inode.c @@ -31,7 +31,6 @@ #include "log.h" #include "meta_io.h" #include "ops_address.h" -#include "ops_file.h" #include "ops_inode.h" #include "quota.h" #include "rgrp.h" @@ -132,15 +131,21 @@ void gfs2_set_iop(struct inode *inode) { + struct gfs2_sbd *sdp = GFS2_SB(inode); umode_t mode = inode->i_mode; if (S_ISREG(mode)) { inode->i_op = &gfs2_file_iops; - inode->i_fop = &gfs2_file_fops; - inode->i_mapping->a_ops = &gfs2_file_aops; + if (sdp->sd_args.ar_localflocks) + inode->i_fop = &gfs2_file_fops_nolock; + else + inode->i_fop = &gfs2_file_fops; } else if (S_ISDIR(mode)) { inode->i_op = &gfs2_dir_iops; - inode->i_fop = &gfs2_dir_fops; + if (sdp->sd_args.ar_localflocks) + inode->i_fop = &gfs2_dir_fops_nolock; + else + inode->i_fop = &gfs2_dir_fops; } else if (S_ISLNK(mode)) { inode->i_op = &gfs2_symlink_iops; } else { @@ -291,12 +296,10 @@ di->di_entries = be32_to_cpu(str->di_entries); di->di_eattr = be64_to_cpu(str->di_eattr); - return 0; -} + if (S_ISREG(ip->i_inode.i_mode)) + gfs2_set_aops(&ip->i_inode); -static void gfs2_inode_bh(struct gfs2_inode *ip, struct buffer_head *bh) -{ - ip->i_cache[0] = bh; + return 0; } /** @@ -366,7 +369,8 @@ if (error) goto out_rg_gunlock; - gfs2_trans_add_gl(ip->i_gl); + set_bit(GLF_DIRTY, &ip->i_gl->gl_flags); + set_bit(GLF_LFLUSH, &ip->i_gl->gl_flags); gfs2_free_di(rgd, ip); @@ -707,9 +711,10 @@ struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); int error; - gfs2_alloc_get(dip); + if (gfs2_alloc_get(dip) == NULL) + return -ENOMEM; - dip->i_alloc.al_requested = RES_DINODE; + dip->i_alloc->al_requested = RES_DINODE; error = gfs2_inplace_reserve(dip); if (error) goto out; @@ -855,7 +860,7 @@ error = alloc_required = gfs2_diradd_alloc_required(&dip->i_inode, name); if (alloc_required < 0) - goto fail; + goto fail_quota_locks; if (alloc_required) { error = gfs2_quota_check(dip, dip->i_inode.i_uid, dip->i_inode.i_gid); if (error) @@ -896,7 +901,7 @@ gfs2_trans_end(sdp); fail_ipreserv: - if (dip->i_alloc.al_rgd) + if (dip->i_alloc->al_rgd) gfs2_inplace_release(dip); fail_quota_locks: @@ -966,7 +971,7 @@ struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 }; int error; u64 generation; - struct buffer_head *bh=NULL; + struct buffer_head *bh = NULL; if (!name->len || name->len > GFS2_FNAMESIZE) return ERR_PTR(-ENAMETOOLONG); @@ -1003,8 +1008,6 @@ if (IS_ERR(inode)) goto fail_gunlock2; - gfs2_inode_bh(GFS2_I(inode), bh); - error = gfs2_inode_refresh(GFS2_I(inode)); if (error) goto fail_gunlock2; @@ -1021,6 +1024,8 @@ if (error) goto fail_gunlock2; + if (bh) + brelse(bh); if (!inode) return ERR_PTR(-ENOMEM); return inode; @@ -1032,6 +1037,8 @@ fail_gunlock: gfs2_glock_dq(ghs); fail: + if (bh) + brelse(bh); return ERR_PTR(error); } --- linux-2.6.24.orig/fs/gfs2/locking.c +++ linux-2.6.24/fs/gfs2/locking.c @@ -181,4 +181,7 @@ EXPORT_SYMBOL_GPL(gfs2_register_lockproto); EXPORT_SYMBOL_GPL(gfs2_unregister_lockproto); +EXPORT_SYMBOL_GPL(gfs2_unmount_lockproto); +EXPORT_SYMBOL_GPL(gfs2_mount_lockproto); +EXPORT_SYMBOL_GPL(gfs2_withdraw_lockproto); --- linux-2.6.24.orig/fs/gfs2/trans.h +++ linux-2.6.24/fs/gfs2/trans.h @@ -30,7 +30,6 @@ void gfs2_trans_end(struct gfs2_sbd *sdp); -void gfs2_trans_add_gl(struct gfs2_glock *gl); void gfs2_trans_add_bh(struct gfs2_glock *gl, struct buffer_head *bh, int meta); void gfs2_trans_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd); void gfs2_trans_add_unrevoke(struct gfs2_sbd *sdp, u64 blkno); --- linux-2.6.24.orig/fs/gfs2/bmap.h +++ linux-2.6.24/fs/gfs2/bmap.h @@ -15,7 +15,7 @@ struct page; int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page); -int gfs2_block_map(struct inode *inode, u64 lblock, int create, struct buffer_head *bh); +int gfs2_block_map(struct inode *inode, sector_t lblock, struct buffer_head *bh, int create); int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen); int gfs2_truncatei(struct gfs2_inode *ip, u64 size); --- linux-2.6.24.orig/fs/gfs2/eaops.c +++ linux-2.6.24/fs/gfs2/eaops.c @@ -56,46 +56,6 @@ return type; } -static int user_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er) -{ - struct inode *inode = &ip->i_inode; - int error = permission(inode, MAY_READ, NULL); - if (error) - return error; - - return gfs2_ea_get_i(ip, er); -} - -static int user_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er) -{ - struct inode *inode = &ip->i_inode; - - if (S_ISREG(inode->i_mode) || - (S_ISDIR(inode->i_mode) && !(inode->i_mode & S_ISVTX))) { - int error = permission(inode, MAY_WRITE, NULL); - if (error) - return error; - } else - return -EPERM; - - return gfs2_ea_set_i(ip, er); -} - -static int user_eo_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er) -{ - struct inode *inode = &ip->i_inode; - - if (S_ISREG(inode->i_mode) || - (S_ISDIR(inode->i_mode) && !(inode->i_mode & S_ISVTX))) { - int error = permission(inode, MAY_WRITE, NULL); - if (error) - return error; - } else - return -EPERM; - - return gfs2_ea_remove_i(ip, er); -} - static int system_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er) { if (!GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len) && @@ -108,8 +68,6 @@ GFS2_ACL_IS_DEFAULT(er->er_name, er->er_name_len))) return -EOPNOTSUPP; - - return gfs2_ea_get_i(ip, er); } @@ -170,40 +128,10 @@ return gfs2_ea_remove_i(ip, er); } -static int security_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er) -{ - struct inode *inode = &ip->i_inode; - int error = permission(inode, MAY_READ, NULL); - if (error) - return error; - - return gfs2_ea_get_i(ip, er); -} - -static int security_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er) -{ - struct inode *inode = &ip->i_inode; - int error = permission(inode, MAY_WRITE, NULL); - if (error) - return error; - - return gfs2_ea_set_i(ip, er); -} - -static int security_eo_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er) -{ - struct inode *inode = &ip->i_inode; - int error = permission(inode, MAY_WRITE, NULL); - if (error) - return error; - - return gfs2_ea_remove_i(ip, er); -} - static const struct gfs2_eattr_operations gfs2_user_eaops = { - .eo_get = user_eo_get, - .eo_set = user_eo_set, - .eo_remove = user_eo_remove, + .eo_get = gfs2_ea_get_i, + .eo_set = gfs2_ea_set_i, + .eo_remove = gfs2_ea_remove_i, .eo_name = "user", }; @@ -215,9 +143,9 @@ }; static const struct gfs2_eattr_operations gfs2_security_eaops = { - .eo_get = security_eo_get, - .eo_set = security_eo_set, - .eo_remove = security_eo_remove, + .eo_get = gfs2_ea_get_i, + .eo_set = gfs2_ea_set_i, + .eo_remove = gfs2_ea_remove_i, .eo_name = "security", }; --- linux-2.6.24.orig/fs/gfs2/locking/dlm/thread.c +++ linux-2.6.24/fs/gfs2/locking/dlm/thread.c @@ -273,18 +273,13 @@ struct gdlm_ls *ls = (struct gdlm_ls *) data; struct gdlm_lock *lp = NULL; uint8_t complete, blocking, submit, drop; - DECLARE_WAITQUEUE(wait, current); /* Only thread1 is allowed to do blocking callbacks since gfs may wait for a completion callback within a blocking cb. */ while (!kthread_should_stop()) { - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&ls->thread_wait, &wait); - if (no_work(ls, blist)) - schedule(); - remove_wait_queue(&ls->thread_wait, &wait); - set_current_state(TASK_RUNNING); + wait_event_interruptible(ls->thread_wait, + !no_work(ls, blist) || kthread_should_stop()); complete = blocking = submit = drop = 0; --- linux-2.6.24.orig/fs/gfs2/locking/dlm/mount.c +++ linux-2.6.24/fs/gfs2/locking/dlm/mount.c @@ -67,6 +67,11 @@ memset(data, 0, 256); strncpy(data, data_arg, 255); + if (!strlen(data)) { + log_error("no mount options, (u)mount helpers not installed"); + return -EINVAL; + } + for (options = data; (x = strsep(&options, ":")); ) { if (!*x) continue; --- linux-2.6.24.orig/fs/gfs2/locking/dlm/plock.c +++ linux-2.6.24/fs/gfs2/locking/dlm/plock.c @@ -89,15 +89,19 @@ op->info.number = name->ln_number; op->info.start = fl->fl_start; op->info.end = fl->fl_end; - op->info.owner = (__u64)(long) fl->fl_owner; if (fl->fl_lmops && fl->fl_lmops->fl_grant) { + /* fl_owner is lockd which doesn't distinguish + processes on the nfs client */ + op->info.owner = (__u64) fl->fl_pid; xop->callback = fl->fl_lmops->fl_grant; locks_init_lock(&xop->flc); locks_copy_lock(&xop->flc, fl); xop->fl = fl; xop->file = file; - } else + } else { + op->info.owner = (__u64)(long) fl->fl_owner; xop->callback = NULL; + } send_op(op); @@ -203,7 +207,10 @@ op->info.number = name->ln_number; op->info.start = fl->fl_start; op->info.end = fl->fl_end; - op->info.owner = (__u64)(long) fl->fl_owner; + if (fl->fl_lmops && fl->fl_lmops->fl_grant) + op->info.owner = (__u64) fl->fl_pid; + else + op->info.owner = (__u64)(long) fl->fl_owner; send_op(op); wait_event(recv_wq, (op->done != 0)); @@ -242,7 +249,10 @@ op->info.number = name->ln_number; op->info.start = fl->fl_start; op->info.end = fl->fl_end; - op->info.owner = (__u64)(long) fl->fl_owner; + if (fl->fl_lmops && fl->fl_lmops->fl_grant) + op->info.owner = (__u64) fl->fl_pid; + else + op->info.owner = (__u64)(long) fl->fl_owner; send_op(op); wait_event(recv_wq, (op->done != 0)); --- linux-2.6.24.orig/fs/ntfs/file.c +++ linux-2.6.24/fs/ntfs/file.c @@ -2120,7 +2120,7 @@ goto out; if (!count) goto out; - err = remove_suid(file->f_path.dentry); + err = remove_suid(&file->f_path); if (err) goto out; file_update_time(file); --- linux-2.6.24.orig/fs/fuse/dir.c +++ linux-2.6.24/fs/fuse/dir.c @@ -905,7 +905,7 @@ } if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { - int err = generic_permission(inode, mask, NULL); + err = generic_permission(inode, mask, NULL); /* If permission is denied, try to refresh file attributes. This is also needed, because the root @@ -1063,21 +1063,22 @@ return file ? fuse_fsync_common(file, de, datasync, 1) : 0; } -static bool update_mtime(unsigned ivalid) +static bool update_mtime(unsigned ivalid, bool have_file) { /* Always update if mtime is explicitly set */ if (ivalid & ATTR_MTIME_SET) return true; /* If it's an open(O_TRUNC) or an ftruncate(), don't update */ - if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE))) + if ((ivalid & ATTR_SIZE) && ((ivalid & ATTR_OPEN) || have_file)) return false; /* In all other cases update */ return true; } -static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg) +static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg, + bool have_file) { unsigned ivalid = iattr->ia_valid; @@ -1096,7 +1097,7 @@ if (!(ivalid & ATTR_ATIME_SET)) arg->valid |= FATTR_ATIME_NOW; } - if ((ivalid & ATTR_MTIME) && update_mtime(ivalid)) { + if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, have_file)) { arg->valid |= FATTR_MTIME; arg->mtime = iattr->ia_mtime.tv_sec; arg->mtimensec = iattr->ia_mtime.tv_nsec; @@ -1113,8 +1114,8 @@ * vmtruncate() doesn't allow for this case, so do the rlimit checking * and the actual truncation by hand. */ -static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, - struct file *file) +int fuse_do_setattr(struct dentry *entry, struct iattr *attr, + struct file *file) { struct inode *inode = entry->d_inode; struct fuse_conn *fc = get_fuse_conn(inode); @@ -1152,7 +1153,7 @@ memset(&inarg, 0, sizeof(inarg)); memset(&outarg, 0, sizeof(outarg)); - iattr_to_fattr(attr, &inarg); + iattr_to_fattr(attr, &inarg, file != NULL); if (file) { struct fuse_file *ff = file->private_data; inarg.valid |= FATTR_FH; @@ -1194,13 +1195,10 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr) { - if (attr->ia_valid & ATTR_FILE) - return fuse_do_setattr(entry, attr, attr->ia_file); - else - return fuse_do_setattr(entry, attr, NULL); + return fuse_do_setattr(entry, attr, NULL); } -static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, +int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, struct kstat *stat) { struct inode *inode = entry->d_inode; --- linux-2.6.24.orig/fs/fuse/file.c +++ linux-2.6.24/fs/fuse/file.c @@ -871,6 +871,17 @@ return err; } +static int fuse_file_fgetattr(struct file *file, struct kstat *stat) +{ + struct inode *inode = file->f_dentry->d_inode; + struct fuse_conn *fc = get_fuse_conn(inode); + + if (!fuse_allow_task(fc, current)) + return -EACCES; + + return fuse_getattr(file->f_vfsmnt, file->f_dentry, stat); +} + static sector_t fuse_bmap(struct address_space *mapping, sector_t block) { struct inode *inode = mapping->host; @@ -907,6 +918,11 @@ return err ? 0 : outarg.block; } +static int fuse_fsetattr(struct file *file, struct iattr *attr) +{ + return fuse_do_setattr(file->f_path.dentry, attr, file); +} + static const struct file_operations fuse_file_operations = { .llseek = generic_file_llseek, .read = do_sync_read, @@ -920,6 +936,8 @@ .fsync = fuse_fsync, .lock = fuse_file_lock, .flock = fuse_file_flock, + .fgetattr = fuse_file_fgetattr, + .fsetattr = fuse_fsetattr, .splice_read = generic_file_splice_read, }; @@ -933,6 +951,8 @@ .fsync = fuse_fsync, .lock = fuse_file_lock, .flock = fuse_file_flock, + .fgetattr = fuse_file_fgetattr, + .fsetattr = fuse_fsetattr, /* no mmap and splice_read */ }; --- linux-2.6.24.orig/fs/fuse/fuse_i.h +++ linux-2.6.24/fs/fuse/fuse_i.h @@ -505,6 +505,10 @@ */ int fuse_dev_init(void); + +int fuse_do_setattr(struct dentry *entry, struct iattr *attr, + struct file *file); + /** * Cleanup the client device */ @@ -596,3 +600,6 @@ int fuse_update_attributes(struct inode *inode, struct kstat *stat, struct file *file, bool *refreshed); + +int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, + struct kstat *stat); --- linux-2.6.24.orig/fs/hpfs/namei.c +++ linux-2.6.24/fs/hpfs/namei.c @@ -426,7 +426,7 @@ /*printk("HPFS: truncating file before delete.\n");*/ newattrs.ia_size = 0; newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; - err = notify_change(dentry, &newattrs); + err = notify_change(dentry, NULL, &newattrs); put_write_access(inode); if (!err) goto again; --- linux-2.6.24.orig/fs/hfsplus/bitmap.c +++ linux-2.6.24/fs/hfsplus/bitmap.c @@ -32,6 +32,10 @@ mutex_lock(&HFSPLUS_SB(sb).alloc_file->i_mutex); mapping = HFSPLUS_SB(sb).alloc_file->i_mapping; page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS, NULL); + if (IS_ERR(page)) { + start = size; + goto out; + } pptr = kmap(page); curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32; i = offset % 32; @@ -73,6 +77,10 @@ break; page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS, NULL); + if (IS_ERR(page)) { + start = size; + goto out; + } curr = pptr = kmap(page); if ((size ^ offset) / PAGE_CACHE_BITS) end = pptr + PAGE_CACHE_BITS / 32; @@ -120,6 +128,10 @@ offset += PAGE_CACHE_BITS; page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS, NULL); + if (IS_ERR(page)) { + start = size; + goto out; + } pptr = kmap(page); curr = pptr; end = pptr + PAGE_CACHE_BITS / 32; --- linux-2.6.24.orig/fs/hfsplus/catalog.c +++ linux-2.6.24/fs/hfsplus/catalog.c @@ -168,6 +168,11 @@ return -EIO; } + if (be16_to_cpu(tmp.thread.nodeName.length) > 255) { + printk(KERN_ERR "hfs: catalog name length corrupted\n"); + return -EIO; + } + hfsplus_cat_build_key_uni(fd->search_key, be32_to_cpu(tmp.thread.parentID), &tmp.thread.nodeName); return hfs_brec_find(fd); --- linux-2.6.24.orig/fs/hfsplus/dir.c +++ linux-2.6.24/fs/hfsplus/dir.c @@ -340,16 +340,23 @@ if (inode->i_nlink > 0) drop_nlink(inode); - hfsplus_delete_inode(inode); - if (inode->i_ino != cnid && !inode->i_nlink) { - if (!atomic_read(&HFSPLUS_I(inode).opencnt)) { - res = hfsplus_delete_cat(inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL); - if (!res) - hfsplus_delete_inode(inode); + if (inode->i_ino == cnid) + clear_nlink(inode); + if (!inode->i_nlink) { + if (inode->i_ino != cnid) { + HFSPLUS_SB(sb).file_count--; + if (!atomic_read(&HFSPLUS_I(inode).opencnt)) { + res = hfsplus_delete_cat(inode->i_ino, + HFSPLUS_SB(sb).hidden_dir, + NULL); + if (!res) + hfsplus_delete_inode(inode); + } else + inode->i_flags |= S_DEAD; } else - inode->i_flags |= S_DEAD; + hfsplus_delete_inode(inode); } else - clear_nlink(inode); + HFSPLUS_SB(sb).file_count--; inode->i_ctime = CURRENT_TIME_SEC; mark_inode_dirty(inode); --- linux-2.6.24.orig/fs/ecryptfs/mmap.c +++ linux-2.6.24/fs/ecryptfs/mmap.c @@ -263,52 +263,102 @@ return 0; } -/* This function must zero any hole we create */ +/** + * ecryptfs_prepare_write + * @file: The eCryptfs file + * @page: The eCryptfs page + * @from: The start byte from which we will write + * @to: The end byte to which we will write + * + * This function must zero any hole we create + * + * Returns zero on success; non-zero otherwise + */ static int ecryptfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) { - int rc = 0; loff_t prev_page_end_size; + int rc = 0; if (!PageUptodate(page)) { - rc = ecryptfs_read_lower_page_segment(page, page->index, 0, - PAGE_CACHE_SIZE, - page->mapping->host); - if (rc) { - printk(KERN_ERR "%s: Error attemping to read lower " - "page segment; rc = [%d]\n", __FUNCTION__, rc); - ClearPageUptodate(page); - goto out; - } else + struct ecryptfs_crypt_stat *crypt_stat = + &ecryptfs_inode_to_private( + file->f_path.dentry->d_inode)->crypt_stat; + + if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED) + || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) { + rc = ecryptfs_read_lower_page_segment( + page, page->index, 0, PAGE_CACHE_SIZE, + page->mapping->host); + if (rc) { + printk(KERN_ERR "%s: Error attemping to read " + "lower page segment; rc = [%d]\n", + __FUNCTION__, rc); + ClearPageUptodate(page); + goto out; + } else + SetPageUptodate(page); + } else if (crypt_stat->flags & ECRYPTFS_VIEW_AS_ENCRYPTED) { + if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) { + rc = ecryptfs_copy_up_encrypted_with_header( + page, crypt_stat); + if (rc) { + printk(KERN_ERR "%s: Error attempting " + "to copy the encrypted content " + "from the lower file whilst " + "inserting the metadata from " + "the xattr into the header; rc " + "= [%d]\n", __FUNCTION__, rc); + ClearPageUptodate(page); + goto out; + } + SetPageUptodate(page); + } else { + rc = ecryptfs_read_lower_page_segment( + page, page->index, 0, PAGE_CACHE_SIZE, + page->mapping->host); + if (rc) { + printk(KERN_ERR "%s: Error reading " + "page; rc = [%d]\n", + __FUNCTION__, rc); + ClearPageUptodate(page); + goto out; + } + SetPageUptodate(page); + } + } else { + rc = ecryptfs_decrypt_page(page); + if (rc) { + printk(KERN_ERR "%s: Error decrypting page " + "at index [%ld]; rc = [%d]\n", + __FUNCTION__, page->index, rc); + ClearPageUptodate(page); + goto out; + } SetPageUptodate(page); + } } - prev_page_end_size = ((loff_t)page->index << PAGE_CACHE_SHIFT); - - /* - * If creating a page or more of holes, zero them out via truncate. - * Note, this will increase i_size. - */ + /* If creating a page or more of holes, zero them out via truncate. + * Note, this will increase i_size. */ if (page->index != 0) { if (prev_page_end_size > i_size_read(page->mapping->host)) { rc = ecryptfs_truncate(file->f_path.dentry, prev_page_end_size); if (rc) { - printk(KERN_ERR "Error on attempt to " + printk(KERN_ERR "%s: Error on attempt to " "truncate to (higher) offset [%lld];" - " rc = [%d]\n", prev_page_end_size, rc); + " rc = [%d]\n", __FUNCTION__, + prev_page_end_size, rc); goto out; } } } - /* - * Writing to a new page, and creating a small hole from start of page? - * Zero it out. - */ - if ((i_size_read(page->mapping->host) == prev_page_end_size) && - (from != 0)) { + /* Writing to a new page, and creating a small hole from start + * of page? Zero it out. */ + if ((i_size_read(page->mapping->host) == prev_page_end_size) + && (from != 0)) zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); - } out: return rc; } --- linux-2.6.24.orig/fs/ecryptfs/crypto.c +++ linux-2.6.24/fs/ecryptfs/crypto.c @@ -472,8 +472,8 @@ { struct inode *ecryptfs_inode; struct ecryptfs_crypt_stat *crypt_stat; - char *enc_extent_virt = NULL; - struct page *enc_extent_page; + char *enc_extent_virt; + struct page *enc_extent_page = NULL; loff_t extent_offset; int rc = 0; @@ -489,14 +489,14 @@ page->index); goto out; } - enc_extent_virt = kmalloc(PAGE_CACHE_SIZE, GFP_USER); - if (!enc_extent_virt) { + enc_extent_page = alloc_page(GFP_USER); + if (!enc_extent_page) { rc = -ENOMEM; ecryptfs_printk(KERN_ERR, "Error allocating memory for " "encrypted extent\n"); goto out; } - enc_extent_page = virt_to_page(enc_extent_virt); + enc_extent_virt = kmap(enc_extent_page); for (extent_offset = 0; extent_offset < (PAGE_CACHE_SIZE / crypt_stat->extent_size); extent_offset++) { @@ -524,7 +524,10 @@ } } out: - kfree(enc_extent_virt); + if (enc_extent_page) { + kunmap(enc_extent_page); + __free_page(enc_extent_page); + } return rc; } @@ -606,8 +609,8 @@ { struct inode *ecryptfs_inode; struct ecryptfs_crypt_stat *crypt_stat; - char *enc_extent_virt = NULL; - struct page *enc_extent_page; + char *enc_extent_virt; + struct page *enc_extent_page = NULL; unsigned long extent_offset; int rc = 0; @@ -624,14 +627,14 @@ page->index); goto out; } - enc_extent_virt = kmalloc(PAGE_CACHE_SIZE, GFP_USER); - if (!enc_extent_virt) { + enc_extent_page = alloc_page(GFP_USER); + if (!enc_extent_page) { rc = -ENOMEM; ecryptfs_printk(KERN_ERR, "Error allocating memory for " "encrypted extent\n"); goto out; } - enc_extent_page = virt_to_page(enc_extent_virt); + enc_extent_virt = kmap(enc_extent_page); for (extent_offset = 0; extent_offset < (PAGE_CACHE_SIZE / crypt_stat->extent_size); extent_offset++) { @@ -659,7 +662,10 @@ } } out: - kfree(enc_extent_virt); + if (enc_extent_page) { + kunmap(enc_extent_page); + __free_page(enc_extent_page); + } return rc; } --- linux-2.6.24.orig/fs/ecryptfs/inode.c +++ linux-2.6.24/fs/ecryptfs/inode.c @@ -389,19 +389,24 @@ struct dentry *new_dentry) { struct dentry *lower_old_dentry; + struct vfsmount *lower_old_mnt; struct dentry *lower_new_dentry; + struct vfsmount *lower_new_mnt; struct dentry *lower_dir_dentry; u64 file_size_save; int rc; file_size_save = i_size_read(old_dentry->d_inode); lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); + lower_old_mnt = ecryptfs_dentry_to_lower_mnt(old_dentry); lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); + lower_new_mnt = ecryptfs_dentry_to_lower_mnt(new_dentry); dget(lower_old_dentry); dget(lower_new_dentry); lower_dir_dentry = lock_parent(lower_new_dentry); - rc = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode, - lower_new_dentry); + rc = vfs_link(lower_old_dentry, lower_old_mnt, + lower_dir_dentry->d_inode, lower_new_dentry, + lower_new_mnt); if (rc || !lower_new_dentry->d_inode) goto out_lock; rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0); @@ -426,10 +431,11 @@ { int rc = 0; struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); + struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir); lock_parent(lower_dentry); - rc = vfs_unlink(lower_dir_inode, lower_dentry); + rc = vfs_unlink(lower_dir_inode, lower_dentry, lower_mnt); if (rc) { printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); goto out_unlock; @@ -449,6 +455,7 @@ { int rc; struct dentry *lower_dentry; + struct vfsmount *lower_mnt; struct dentry *lower_dir_dentry; umode_t mode; char *encoded_symname; @@ -457,6 +464,7 @@ lower_dentry = ecryptfs_dentry_to_lower(dentry); dget(lower_dentry); + lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); lower_dir_dentry = lock_parent(lower_dentry); mode = S_IALLUGO; encoded_symlen = ecryptfs_encode_filename(crypt_stat, symname, @@ -466,7 +474,7 @@ rc = encoded_symlen; goto out_lock; } - rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry, + rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry, lower_mnt, encoded_symname, mode); kfree(encoded_symname); if (rc || !lower_dentry->d_inode) @@ -488,11 +496,14 @@ { int rc; struct dentry *lower_dentry; + struct vfsmount *lower_mnt; struct dentry *lower_dir_dentry; lower_dentry = ecryptfs_dentry_to_lower(dentry); + lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); lower_dir_dentry = lock_parent(lower_dentry); - rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, mode); + rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, lower_mnt, + mode); if (rc || !lower_dentry->d_inode) goto out; rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); @@ -511,14 +522,16 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) { struct dentry *lower_dentry; + struct vfsmount *lower_mnt; struct dentry *lower_dir_dentry; int rc; lower_dentry = ecryptfs_dentry_to_lower(dentry); + lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); dget(dentry); lower_dir_dentry = lock_parent(lower_dentry); dget(lower_dentry); - rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry); + rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry, lower_mnt); dput(lower_dentry); if (!rc) d_delete(lower_dentry); @@ -536,11 +549,14 @@ { int rc; struct dentry *lower_dentry; + struct vfsmount *lower_mnt; struct dentry *lower_dir_dentry; lower_dentry = ecryptfs_dentry_to_lower(dentry); + lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); lower_dir_dentry = lock_parent(lower_dentry); - rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev); + rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, lower_mnt, mode, + dev); if (rc || !lower_dentry->d_inode) goto out; rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); @@ -561,19 +577,24 @@ { int rc; struct dentry *lower_old_dentry; + struct vfsmount *lower_old_mnt; struct dentry *lower_new_dentry; + struct vfsmount *lower_new_mnt; struct dentry *lower_old_dir_dentry; struct dentry *lower_new_dir_dentry; lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); + lower_old_mnt = ecryptfs_dentry_to_lower_mnt(old_dentry); lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); + lower_new_mnt = ecryptfs_dentry_to_lower_mnt(new_dentry); dget(lower_old_dentry); dget(lower_new_dentry); lower_old_dir_dentry = dget_parent(lower_old_dentry); lower_new_dir_dentry = dget_parent(lower_new_dentry); lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); rc = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry, - lower_new_dir_dentry->d_inode, lower_new_dentry); + lower_old_mnt, lower_new_dir_dentry->d_inode, + lower_new_dentry, lower_new_mnt); if (rc) goto out_lock; fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode, NULL); @@ -850,6 +871,7 @@ { int rc = 0; struct dentry *lower_dentry; + struct vfsmount *lower_mnt; struct inode *inode; struct inode *lower_inode; struct ecryptfs_crypt_stat *crypt_stat; @@ -860,6 +882,7 @@ inode = dentry->d_inode; lower_inode = ecryptfs_inode_to_lower(inode); lower_dentry = ecryptfs_dentry_to_lower(dentry); + lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); mutex_lock(&crypt_stat->cs_mutex); if (S_ISDIR(dentry->d_inode->i_mode)) crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); @@ -910,7 +933,7 @@ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) ia->ia_valid &= ~ATTR_MODE; - rc = notify_change(lower_dentry, ia); + rc = notify_change(lower_dentry, lower_mnt, ia); out: fsstack_copy_attr_all(inode, lower_inode, NULL); return rc; --- linux-2.6.24.orig/init/initramfs.c +++ linux-2.6.24/init/initramfs.c @@ -541,6 +541,28 @@ #endif +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD +/* Tries to read the initramfs if it's already there, for ACPI Table Overiding */ +void __init early_populate_rootfs(void) +{ + char *err = unpack_to_rootfs(__initramfs_start, + __initramfs_end - __initramfs_start, 0); + if (err) + return; +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) { + printk(KERN_INFO "Early unpacking initramfs..."); + err = unpack_to_rootfs((char *)initrd_start, + initrd_end - initrd_start, 0); + if (err) + return; + printk(" done\n"); + } +#endif + return; +} +#endif /* CONFIG_ACPI_CUSTOM_DSDT_INITRD */ + static int __init populate_rootfs(void) { char *err = unpack_to_rootfs(__initramfs_start, --- linux-2.6.24.orig/init/main.c +++ linux-2.6.24/init/main.c @@ -91,8 +91,12 @@ extern void free_initmem(void); #ifdef CONFIG_ACPI extern void acpi_early_init(void); +#ifdef CONFIG_BLK_DEV_INITRD +extern void early_populate_rootfs(void); +#endif #else static inline void acpi_early_init(void) { } +static inline void early_populate_rootfs(void) { } #endif #ifndef CONFIG_DEBUG_RODATA static inline void mark_rodata_ro(void) { } @@ -642,6 +646,9 @@ check_bugs(); +#ifdef CONFIG_BLK_DEV_INITRD + early_populate_rootfs(); /* For DSDT override from initramfs */ +#endif acpi_early_init(); /* before LAPIC and SMP init */ /* Do the rest non-__init'ed, we're now alive */ --- linux-2.6.24.orig/init/Kconfig +++ linux-2.6.24/init/Kconfig @@ -92,6 +92,15 @@ which is done within the script "scripts/setlocalversion".) +config VERSION_SIGNATURE + string "Arbitrary version signature" + help + This string will be created in a file, /proc/version_signature. It + is useful in determining arbitrary data about your kernel. For instance, + if you have several kernels of the same version, but need to keep track + of a revision of the same kernel, but not affect it's ability to load + compatible modules, this is the easiest way to do that. + config SWAP bool "Support for paging of anonymous memory (swap)" depends on MMU && BLOCK --- linux-2.6.24.orig/init/version.c +++ linux-2.6.24/init/version.c @@ -36,7 +36,11 @@ /* FIXED STRINGS! Don't touch! */ const char linux_banner[] = "Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@" - LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n"; + LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION +#ifdef CONFIG_VERSION_SIGNATURE + " (" CONFIG_VERSION_SIGNATURE ")" +#endif + "\n"; const char linux_proc_banner[] = "%s version %s" --- linux-2.6.24.orig/block/ll_rw_blk.c +++ linux-2.6.24/block/ll_rw_blk.c @@ -2667,8 +2667,10 @@ static void bio_end_empty_barrier(struct bio *bio, int err) { - if (err) + if (err) { + set_bit(BIO_EOPNOTSUPP, &bio->bi_flags); clear_bit(BIO_UPTODATE, &bio->bi_flags); + } complete(bio->bi_private); } @@ -2717,7 +2719,9 @@ *error_sector = bio->bi_sector; ret = 0; - if (!bio_flagged(bio, BIO_UPTODATE)) + if (bio_flagged(bio, BIO_EOPNOTSUPP)) + ret = -EOPNOTSUPP; + else if (!bio_flagged(bio, BIO_UPTODATE)) ret = -EIO; bio_put(bio); --- linux-2.6.24.orig/block/scsi_ioctl.c +++ linux-2.6.24/block/scsi_ioctl.c @@ -546,8 +546,14 @@ return __blk_send_generic(q, bd_disk, GPCMD_START_STOP_UNIT, data); } -int scsi_cmd_ioctl(struct file *file, struct request_queue *q, - struct gendisk *bd_disk, unsigned int cmd, void __user *arg) +static inline int blk_send_allow_medium_removal(struct request_queue *q, + struct gendisk *bd_disk) +{ + return __blk_send_generic(q, bd_disk, + GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL, 0); +} + +int scsi_cmd_ioctl(struct file *file, struct request_queue *q, struct gendisk *bd_disk, unsigned int cmd, void __user *arg) { int err; @@ -666,7 +672,11 @@ err = blk_send_start_stop(q, bd_disk, 0x03); break; case CDROMEJECT: - err = blk_send_start_stop(q, bd_disk, 0x02); + err = 0; + + err |= blk_send_allow_medium_removal(q, bd_disk); + err |= blk_send_start_stop(q, bd_disk, 0x01); + err |= blk_send_start_stop(q, bd_disk, 0x02); break; default: err = -ENOTTY; --- linux-2.6.24.orig/mm/allocpercpu.c +++ linux-2.6.24/mm/allocpercpu.c @@ -6,6 +6,10 @@ #include #include +#ifndef cache_line_size +#define cache_line_size() L1_CACHE_BYTES +#endif + /** * percpu_depopulate - depopulate per-cpu data for given cpu * @__pdata: per-cpu data to depopulate @@ -52,6 +56,11 @@ struct percpu_data *pdata = __percpu_disguise(__pdata); int node = cpu_to_node(cpu); + /* + * We should make sure each CPU gets private memory. + */ + size = roundup(size, cache_line_size()); + BUG_ON(pdata->ptrs[cpu]); if (node_online(node)) pdata->ptrs[cpu] = kmalloc_node(size, gfp|__GFP_ZERO, node); @@ -98,7 +107,11 @@ */ void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask) { - void *pdata = kzalloc(sizeof(struct percpu_data), gfp); + /* + * We allocate whole cache lines to avoid false sharing + */ + size_t sz = roundup(nr_cpu_ids * sizeof(void *), cache_line_size()); + void *pdata = kzalloc(sz, gfp); void *__pdata = __percpu_disguise(pdata); if (unlikely(!pdata)) --- linux-2.6.24.orig/mm/filemap.c +++ linux-2.6.24/mm/filemap.c @@ -1622,26 +1622,26 @@ } EXPORT_SYMBOL(should_remove_suid); -int __remove_suid(struct dentry *dentry, int kill) +int __remove_suid(struct path *path, int kill) { struct iattr newattrs; newattrs.ia_valid = ATTR_FORCE | kill; - return notify_change(dentry, &newattrs); + return notify_change(path->dentry, path->mnt, &newattrs); } -int remove_suid(struct dentry *dentry) +int remove_suid(struct path *path) { - int killsuid = should_remove_suid(dentry); - int killpriv = security_inode_need_killpriv(dentry); + int killsuid = should_remove_suid(path->dentry); + int killpriv = security_inode_need_killpriv(path->dentry); int error = 0; if (killpriv < 0) return killpriv; if (killpriv) - error = security_inode_killpriv(dentry); + error = security_inode_killpriv(path->dentry); if (!error && killsuid) - error = __remove_suid(dentry, killsuid); + error = __remove_suid(path, killsuid); return error; } @@ -1725,21 +1725,27 @@ } EXPORT_SYMBOL(iov_iter_copy_from_user); -static void __iov_iter_advance_iov(struct iov_iter *i, size_t bytes) +void iov_iter_advance(struct iov_iter *i, size_t bytes) { + BUG_ON(i->count < bytes); + if (likely(i->nr_segs == 1)) { i->iov_offset += bytes; + i->count -= bytes; } else { const struct iovec *iov = i->iov; size_t base = i->iov_offset; /* * The !iov->iov_len check ensures we skip over unlikely - * zero-length segments. + * zero-length segments (without overruning the iovec). */ - while (bytes || !iov->iov_len) { - int copy = min(bytes, iov->iov_len - base); + while (bytes || unlikely(i->count && !iov->iov_len)) { + int copy; + copy = min(bytes, iov->iov_len - base); + BUG_ON(!i->count || i->count < copy); + i->count -= copy; bytes -= copy; base += copy; if (iov->iov_len == base) { @@ -1751,14 +1757,6 @@ i->iov_offset = base; } } - -void iov_iter_advance(struct iov_iter *i, size_t bytes) -{ - BUG_ON(i->count < bytes); - - __iov_iter_advance_iov(i, bytes); - i->count -= bytes; -} EXPORT_SYMBOL(iov_iter_advance); /* @@ -2358,7 +2356,7 @@ if (count == 0) goto out; - err = remove_suid(file->f_path.dentry); + err = remove_suid(&file->f_path); if (err) goto out; --- linux-2.6.24.orig/mm/slab.c +++ linux-2.6.24/mm/slab.c @@ -1484,7 +1484,7 @@ list_add(&cache_cache.next, &cache_chain); cache_cache.colour_off = cache_line_size(); cache_cache.array[smp_processor_id()] = &initarray_cache.cache; - cache_cache.nodelists[node] = &initkmem_list3[CACHE_CACHE]; + cache_cache.nodelists[node] = &initkmem_list3[CACHE_CACHE + node]; /* * struct kmem_cache size depends on nr_node_ids, which @@ -1605,7 +1605,7 @@ int nid; for_each_online_node(nid) { - init_list(&cache_cache, &initkmem_list3[CACHE_CACHE], nid); + init_list(&cache_cache, &initkmem_list3[CACHE_CACHE + nid], nid); init_list(malloc_sizes[INDEX_AC].cs_cachep, &initkmem_list3[SIZE_AC + nid], nid); @@ -2961,11 +2961,10 @@ struct array_cache *ac; int node; - node = numa_node_id(); - +retry: check_irq_off(); + node = numa_node_id(); ac = cpu_cache_get(cachep); -retry: batchcount = ac->batchcount; if (!ac->touched && batchcount > BATCHREFILL_LIMIT) { /* --- linux-2.6.24.orig/mm/hugetlb.c +++ linux-2.6.24/mm/hugetlb.c @@ -119,6 +119,7 @@ struct address_space *mapping; mapping = (struct address_space *) page_private(page); + set_page_private(page, 0); BUG_ON(page_count(page)); INIT_LIST_HEAD(&page->lru); @@ -133,7 +134,6 @@ spin_unlock(&hugetlb_lock); if (mapping) hugetlb_put_quota(mapping, 1); - set_page_private(page, 0); } /* @@ -605,6 +605,16 @@ return 0; } +int hugetlb_overcommit_handler(struct ctl_table *table, int write, + struct file *file, void __user *buffer, + size_t *length, loff_t *ppos) +{ + spin_lock(&hugetlb_lock); + proc_doulongvec_minmax(table, write, file, buffer, length, ppos); + spin_unlock(&hugetlb_lock); + return 0; +} + #endif /* CONFIG_SYSCTL */ int hugetlb_report_meminfo(char *buf) --- linux-2.6.24.orig/mm/slub.c +++ linux-2.6.24/mm/slub.c @@ -2592,6 +2592,7 @@ void kfree(const void *x) { struct page *page; + void *object = (void *)x; if (unlikely(ZERO_OR_NULL_PTR(x))) return; @@ -2601,7 +2602,7 @@ put_page(page); return; } - slab_free(page->slab, page, (void *)x, __builtin_return_address(0)); + slab_free(page->slab, page, object, __builtin_return_address(0)); } EXPORT_SYMBOL(kfree); --- linux-2.6.24.orig/mm/filemap_xip.c +++ linux-2.6.24/mm/filemap_xip.c @@ -379,7 +379,7 @@ if (count == 0) goto out_backing; - ret = remove_suid(filp->f_path.dentry); + ret = remove_suid(&filp->f_path); if (ret) goto out_backing; --- linux-2.6.24.orig/mm/tiny-shmem.c +++ linux-2.6.24/mm/tiny-shmem.c @@ -81,7 +81,7 @@ inode->i_nlink = 0; /* It is unlinked */ /* notify everyone as to the change of file size */ - error = do_truncate(dentry, size, 0, file); + error = do_truncate(dentry, file->f_path.mnt, size, 0, file); if (error < 0) goto close_file; --- linux-2.6.24.orig/mm/memory.c +++ linux-2.6.24/mm/memory.c @@ -934,17 +934,15 @@ } ptep = pte_offset_map_lock(mm, pmd, address, &ptl); - if (!ptep) - goto out; pte = *ptep; if (!pte_present(pte)) - goto unlock; + goto no_page; if ((flags & FOLL_WRITE) && !pte_write(pte)) goto unlock; page = vm_normal_page(vma, address, pte); if (unlikely(!page)) - goto unlock; + goto bad_page; if (flags & FOLL_GET) get_page(page); @@ -959,6 +957,15 @@ out: return page; +bad_page: + pte_unmap_unlock(ptep, ptl); + return ERR_PTR(-EFAULT); + +no_page: + pte_unmap_unlock(ptep, ptl); + if (!pte_none(pte)) + return page; + /* Fall through to ZERO_PAGE handling */ no_page_table: /* * When core dumping an enormous anonymous area that nobody @@ -973,6 +980,27 @@ return page; } +/* Can we do the FOLL_ANON optimization? */ +static inline int use_zero_page(struct vm_area_struct *vma) +{ + /* + * We don't want to optimize FOLL_ANON for make_pages_present() + * when it tries to page in a VM_LOCKED region. As to VM_SHARED, + * we want to get the page from the page tables to make sure + * that we serialize and update with any other user of that + * mapping. + */ + if (vma->vm_flags & (VM_LOCKED | VM_SHARED)) + return 0; + /* + * And if we have a fault or a nopfn or a nopage routine, it's not an + * anonymous region. + */ + return !vma->vm_ops || + (!vma->vm_ops->fault && !vma->vm_ops->nopfn && + !vma->vm_ops->nopage); +} + int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, int len, int write, int force, struct page **pages, struct vm_area_struct **vmas) @@ -980,6 +1008,8 @@ int i; unsigned int vm_flags; + if (len <= 0) + return 0; /* * Require read or write permissions. * If 'force' is set, we only require the "MAY" flags. @@ -1045,9 +1075,7 @@ foll_flags = FOLL_TOUCH; if (pages) foll_flags |= FOLL_GET; - if (!write && !(vma->vm_flags & VM_LOCKED) && - (!vma->vm_ops || (!vma->vm_ops->nopage && - !vma->vm_ops->fault))) + if (!write && use_zero_page(vma)) foll_flags |= FOLL_ANON; do { @@ -1093,6 +1121,8 @@ cond_resched(); } + if (IS_ERR(page)) + return i ? i : PTR_ERR(page); if (pages) { pages[i] = page; --- linux-2.6.24.orig/mm/shmem.c +++ linux-2.6.24/mm/shmem.c @@ -1415,7 +1415,6 @@ inode->i_uid = current->fsuid; inode->i_gid = current->fsgid; inode->i_blocks = 0; - inode->i_mapping->a_ops = &shmem_aops; inode->i_mapping->backing_dev_info = &shmem_backing_dev_info; inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; inode->i_generation = get_seconds(); @@ -1430,6 +1429,7 @@ init_special_inode(inode, mode, dev); break; case S_IFREG: + inode->i_mapping->a_ops = &shmem_aops; inode->i_op = &shmem_inode_operations; inode->i_fop = &shmem_file_operations; mpol_shared_policy_init(&info->policy, sbinfo->policy, @@ -1526,7 +1526,7 @@ if (err || !count) goto out; - err = remove_suid(file->f_path.dentry); + err = remove_suid(&file->f_path); if (err) goto out; @@ -1924,6 +1924,7 @@ iput(inode); return error; } + inode->i_mapping->a_ops = &shmem_aops; inode->i_op = &shmem_symlink_inode_operations; kaddr = kmap_atomic(page, KM_USER0); memcpy(kaddr, symname, len); --- linux-2.6.24.orig/mm/migrate.c +++ linux-2.6.24/mm/migrate.c @@ -823,6 +823,11 @@ goto set_status; page = follow_page(vma, pp->addr, FOLL_GET); + + err = PTR_ERR(page); + if (IS_ERR(page)) + goto set_status; + err = -ENOENT; if (!page) goto set_status; @@ -886,6 +891,11 @@ goto set_status; page = follow_page(vma, pm->addr, 0); + + err = PTR_ERR(page); + if (IS_ERR(page)) + goto set_status; + err = -ENOENT; /* Use PageReserved to check for zero page */ if (!page || PageReserved(page)) --- linux-2.6.24.orig/ipc/mqueue.c +++ linux-2.6.24/ipc/mqueue.c @@ -744,7 +744,7 @@ if (inode) atomic_inc(&inode->i_count); - err = vfs_unlink(dentry->d_parent->d_inode, dentry); + err = vfs_unlink(dentry->d_parent->d_inode, dentry, mqueue_mnt); out_err: dput(dentry); --- linux-2.6.24.orig/kernel/fork.c +++ linux-2.6.24/kernel/fork.c @@ -392,6 +392,7 @@ destroy_context(mm); free_mm(mm); } +EXPORT_SYMBOL_GPL(__mmdrop); /* * Decrement the use count and release all resources for an mm. @@ -1196,6 +1197,7 @@ #ifdef TIF_SYSCALL_EMU clear_tsk_thread_flag(p, TIF_SYSCALL_EMU); #endif + clear_all_latency_tracing(p); /* Our parent execution domain becomes current domain These must match for thread signalling to apply */ --- linux-2.6.24.orig/kernel/posix-timers.c +++ linux-2.6.24/kernel/posix-timers.c @@ -766,9 +766,11 @@ /* SIGEV_NONE timers are not queued ! See common_timer_get */ if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) { /* Setup correct expiry time for relative timers */ - if (mode == HRTIMER_MODE_REL) - timer->expires = ktime_add(timer->expires, - timer->base->get_time()); + if (mode == HRTIMER_MODE_REL) { + timer->expires = + ktime_add_safe(timer->expires, + timer->base->get_time()); + } return 0; } @@ -981,20 +983,9 @@ static int common_nsleep(const clockid_t which_clock, int flags, struct timespec *tsave, struct timespec __user *rmtp) { - struct timespec rmt; - int ret; - - ret = hrtimer_nanosleep(tsave, rmtp ? &rmt : NULL, - flags & TIMER_ABSTIME ? - HRTIMER_MODE_ABS : HRTIMER_MODE_REL, - which_clock); - - if (ret && rmtp) { - if (copy_to_user(rmtp, &rmt, sizeof(*rmtp))) - return -EFAULT; - } - - return ret; + return hrtimer_nanosleep(tsave, rmtp, flags & TIMER_ABSTIME ? + HRTIMER_MODE_ABS : HRTIMER_MODE_REL, + which_clock); } asmlinkage long --- linux-2.6.24.orig/kernel/cgroup.c +++ linux-2.6.24/kernel/cgroup.c @@ -2611,7 +2611,7 @@ } /* Create the cgroup directory, which also creates the cgroup */ - ret = vfs_mkdir(inode, dentry, S_IFDIR | 0755); + ret = vfs_mkdir(inode, dentry, NULL, S_IFDIR | 0755); child = __d_cgrp(dentry); dput(dentry); if (ret) { --- linux-2.6.24.orig/kernel/relay.c +++ linux-2.6.24/kernel/relay.c @@ -1072,7 +1072,7 @@ unsigned int flags, int *nonpad_ret) { - unsigned int pidx, poff, total_len, subbuf_pages, ret; + unsigned int pidx, poff, total_len, subbuf_pages, nr_pages, ret; struct rchan_buf *rbuf = in->private_data; unsigned int subbuf_size = rbuf->chan->subbuf_size; uint64_t pos = (uint64_t) *ppos; @@ -1103,8 +1103,9 @@ subbuf_pages = rbuf->chan->alloc_size >> PAGE_SHIFT; pidx = (read_start / PAGE_SIZE) % subbuf_pages; poff = read_start & ~PAGE_MASK; + nr_pages = min_t(unsigned int, subbuf_pages, PIPE_BUFFERS); - for (total_len = 0; spd.nr_pages < subbuf_pages; spd.nr_pages++) { + for (total_len = 0; spd.nr_pages < nr_pages; spd.nr_pages++) { unsigned int this_len, this_end, private; unsigned int cur_pos = read_start + total_len; --- linux-2.6.24.orig/kernel/sched_fair.c +++ linux-2.6.24/kernel/sched_fair.c @@ -20,6 +20,8 @@ * Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra */ +#include + /* * Targeted preemption latency for CPU-bound tasks: * (default: 20ms * (1 + ilog(ncpus)), units: nanoseconds) @@ -434,6 +436,7 @@ #ifdef CONFIG_SCHEDSTATS if (se->sleep_start) { u64 delta = rq_of(cfs_rq)->clock - se->sleep_start; + struct task_struct *tsk = task_of(se); if ((s64)delta < 0) delta = 0; @@ -443,9 +446,12 @@ se->sleep_start = 0; se->sum_sleep_runtime += delta; + + account_scheduler_latency(tsk, delta >> 10, 1); } if (se->block_start) { u64 delta = rq_of(cfs_rq)->clock - se->block_start; + struct task_struct *tsk = task_of(se); if ((s64)delta < 0) delta = 0; @@ -462,11 +468,11 @@ * time that the task spent sleeping: */ if (unlikely(prof_on == SLEEP_PROFILING)) { - struct task_struct *tsk = task_of(se); profile_hits(SLEEP_PROFILING, (void *)get_wchan(tsk), delta >> 20); } + account_scheduler_latency(tsk, delta >> 10, 0); } #endif } @@ -1104,6 +1110,16 @@ set_next_entity(cfs_rq_of(se), se); } +#ifdef CONFIG_FAIR_GROUP_SCHED +static void moved_group_fair(struct task_struct *p) +{ + struct cfs_rq *cfs_rq = task_cfs_rq(p); + + update_curr(cfs_rq); + place_entity(cfs_rq, &p->se, 1); +} +#endif + /* * All the scheduling class methods: */ @@ -1126,6 +1142,10 @@ .set_curr_task = set_curr_task_fair, .task_tick = task_tick_fair, .task_new = task_new_fair, + +#ifdef CONFIG_FAIR_GROUP_SCHED + .moved_group = moved_group_fair, +#endif }; #ifdef CONFIG_SCHED_DEBUG --- linux-2.6.24.orig/kernel/cpu.c +++ linux-2.6.24/kernel/cpu.c @@ -219,6 +219,7 @@ mutex_unlock(&cpu_add_remove_lock); return err; } +EXPORT_SYMBOL(cpu_down); #endif /*CONFIG_HOTPLUG_CPU*/ /* Requires cpu_add_remove_lock to be held */ --- linux-2.6.24.orig/kernel/futex.c +++ linux-2.6.24/kernel/futex.c @@ -60,6 +60,8 @@ #include "rtmutex_common.h" +int __read_mostly futex_cmpxchg_enabled; + #define FUTEX_HASHBITS (CONFIG_BASE_SMALL ? 4 : 8) /* @@ -466,6 +468,8 @@ struct futex_hash_bucket *hb; union futex_key key; + if (!futex_cmpxchg_enabled) + return; /* * We are a ZOMBIE and nobody can enqueue itself on * pi_state_list anymore, but we have to be careful @@ -1854,6 +1858,8 @@ sys_set_robust_list(struct robust_list_head __user *head, size_t len) { + if (!futex_cmpxchg_enabled) + return -ENOSYS; /* * The kernel knows only one size for now: */ @@ -1878,6 +1884,9 @@ struct robust_list_head __user *head; unsigned long ret; + if (!futex_cmpxchg_enabled) + return -ENOSYS; + if (!pid) head = current->robust_list; else { @@ -1980,6 +1989,9 @@ unsigned long futex_offset; int rc; + if (!futex_cmpxchg_enabled) + return; + /* * Fetch the list head (which was registered earlier, via * sys_set_robust_list()): @@ -2034,7 +2046,7 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, u32 __user *uaddr2, u32 val2, u32 val3) { - int ret; + int ret = -ENOSYS; int cmd = op & FUTEX_CMD_MASK; struct rw_semaphore *fshared = NULL; @@ -2062,13 +2074,16 @@ ret = futex_wake_op(uaddr, fshared, uaddr2, val, val2, val3); break; case FUTEX_LOCK_PI: - ret = futex_lock_pi(uaddr, fshared, val, timeout, 0); + if (futex_cmpxchg_enabled) + ret = futex_lock_pi(uaddr, fshared, val, timeout, 0); break; case FUTEX_UNLOCK_PI: - ret = futex_unlock_pi(uaddr, fshared); + if (futex_cmpxchg_enabled) + ret = futex_unlock_pi(uaddr, fshared); break; case FUTEX_TRYLOCK_PI: - ret = futex_lock_pi(uaddr, fshared, 0, timeout, 1); + if (futex_cmpxchg_enabled) + ret = futex_lock_pi(uaddr, fshared, 0, timeout, 1); break; default: ret = -ENOSYS; @@ -2094,7 +2109,7 @@ t = timespec_to_ktime(ts); if (cmd == FUTEX_WAIT) - t = ktime_add(ktime_get(), t); + t = ktime_add_safe(ktime_get(), t); tp = &t; } /* @@ -2123,8 +2138,29 @@ static int __init init(void) { - int i = register_filesystem(&futex_fs_type); + u32 curval; + int i; + + /* + * This will fail and we want it. Some arch implementations do + * runtime detection of the futex_atomic_cmpxchg_inatomic() + * functionality. We want to know that before we call in any + * of the complex code paths. Also we want to prevent + * registration of robust lists in that case. NULL is + * guaranteed to fault and we get -EFAULT on functional + * implementation, the non functional ones will return + * -ENOSYS. + */ + curval = cmpxchg_futex_value_locked(NULL, 0, 0); + if (curval == -EFAULT) + futex_cmpxchg_enabled = 1; + for (i = 0; i < ARRAY_SIZE(futex_queues); i++) { + plist_head_init(&futex_queues[i].chain, &futex_queues[i].lock); + spin_lock_init(&futex_queues[i].lock); + } + + i = register_filesystem(&futex_fs_type); if (i) return i; @@ -2134,10 +2170,6 @@ return PTR_ERR(futex_mnt); } - for (i = 0; i < ARRAY_SIZE(futex_queues); i++) { - plist_head_init(&futex_queues[i].chain, &futex_queues[i].lock); - spin_lock_init(&futex_queues[i].lock); - } return 0; } __initcall(init); --- linux-2.6.24.orig/kernel/hrtimer.c +++ linux-2.6.24/kernel/hrtimer.c @@ -325,6 +325,24 @@ } #endif /* BITS_PER_LONG >= 64 */ +/* + * Add two ktime values and do a safety check for overflow: + */ + +ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs) +{ + ktime_t res = ktime_add(lhs, rhs); + + /* + * We use KTIME_SEC_MAX here, the maximum timeout which we can + * return to user space in a timespec: + */ + if (res.tv64 < 0 || res.tv64 < lhs.tv64 || res.tv64 < rhs.tv64) + res = ktime_set(KTIME_SEC_MAX, 0); + + return res; +} + /* High resolution timer related functions */ #ifdef CONFIG_HIGH_RES_TIMERS @@ -409,6 +427,8 @@ ktime_t expires = ktime_sub(timer->expires, base->offset); int res; + WARN_ON_ONCE(timer->expires.tv64 < 0); + /* * When the callback is running, we do not reprogram the clock event * device. The timer callback is either running on a different CPU or @@ -419,6 +439,15 @@ if (hrtimer_callback_running(timer)) return 0; + /* + * CLOCK_REALTIME timer might be requested with an absolute + * expiry time which is less than base->offset. Nothing wrong + * about that, just avoid to call into the tick code, which + * has now objections against negative expiry values. + */ + if (expires.tv64 < 0) + return -ETIME; + if (expires.tv64 >= expires_next->tv64) return 0; @@ -682,13 +711,7 @@ */ orun++; } - timer->expires = ktime_add(timer->expires, interval); - /* - * Make sure, that the result did not wrap with a very large - * interval. - */ - if (timer->expires.tv64 < 0) - timer->expires = ktime_set(KTIME_SEC_MAX, 0); + timer->expires = ktime_add_safe(timer->expires, interval); return orun; } @@ -839,7 +862,7 @@ new_base = switch_hrtimer_base(timer, base); if (mode == HRTIMER_MODE_REL) { - tim = ktime_add(tim, new_base->get_time()); + tim = ktime_add_safe(tim, new_base->get_time()); /* * CONFIG_TIME_LOW_RES is a temporary way for architectures * to signal that they simply return xtime in @@ -848,16 +871,8 @@ * timeouts. This will go away with the GTOD framework. */ #ifdef CONFIG_TIME_LOW_RES - tim = ktime_add(tim, base->resolution); + tim = ktime_add_safe(tim, base->resolution); #endif - /* - * Careful here: User space might have asked for a - * very long sleep, so the add above might result in a - * negative number, which enqueues the timer in front - * of the queue. - */ - if (tim.tv64 < 0) - tim.tv64 = KTIME_MAX; } timer->expires = tim; @@ -1291,11 +1306,26 @@ return t->task == NULL; } +static int update_rmtp(struct hrtimer *timer, struct timespec __user *rmtp) +{ + struct timespec rmt; + ktime_t rem; + + rem = ktime_sub(timer->expires, timer->base->get_time()); + if (rem.tv64 <= 0) + return 0; + rmt = ktime_to_timespec(rem); + + if (copy_to_user(rmtp, &rmt, sizeof(*rmtp))) + return -EFAULT; + + return 1; +} + long __sched hrtimer_nanosleep_restart(struct restart_block *restart) { struct hrtimer_sleeper t; - struct timespec *rmtp; - ktime_t time; + struct timespec __user *rmtp; restart->fn = do_no_restart_syscall; @@ -1305,12 +1335,11 @@ if (do_nanosleep(&t, HRTIMER_MODE_ABS)) return 0; - rmtp = (struct timespec *)restart->arg1; + rmtp = (struct timespec __user *)restart->arg1; if (rmtp) { - time = ktime_sub(t.timer.expires, t.timer.base->get_time()); - if (time.tv64 <= 0) - return 0; - *rmtp = ktime_to_timespec(time); + int ret = update_rmtp(&t.timer, rmtp); + if (ret <= 0) + return ret; } restart->fn = hrtimer_nanosleep_restart; @@ -1319,12 +1348,11 @@ return -ERESTART_RESTARTBLOCK; } -long hrtimer_nanosleep(struct timespec *rqtp, struct timespec *rmtp, +long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, const enum hrtimer_mode mode, const clockid_t clockid) { struct restart_block *restart; struct hrtimer_sleeper t; - ktime_t rem; hrtimer_init(&t.timer, clockid, mode); t.timer.expires = timespec_to_ktime(*rqtp); @@ -1336,10 +1364,9 @@ return -ERESTARTNOHAND; if (rmtp) { - rem = ktime_sub(t.timer.expires, t.timer.base->get_time()); - if (rem.tv64 <= 0) - return 0; - *rmtp = ktime_to_timespec(rem); + int ret = update_rmtp(&t.timer, rmtp); + if (ret <= 0) + return ret; } restart = ¤t_thread_info()->restart_block; @@ -1355,8 +1382,7 @@ asmlinkage long sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp) { - struct timespec tu, rmt; - int ret; + struct timespec tu; if (copy_from_user(&tu, rqtp, sizeof(tu))) return -EFAULT; @@ -1364,15 +1390,7 @@ if (!timespec_valid(&tu)) return -EINVAL; - ret = hrtimer_nanosleep(&tu, rmtp ? &rmt : NULL, HRTIMER_MODE_REL, - CLOCK_MONOTONIC); - - if (ret && rmtp) { - if (copy_to_user(rmtp, &rmt, sizeof(*rmtp))) - return -EFAULT; - } - - return ret; + return hrtimer_nanosleep(&tu, rmtp, HRTIMER_MODE_REL, CLOCK_MONOTONIC); } /* --- linux-2.6.24.orig/kernel/sysctl.c +++ linux-2.6.24/kernel/sysctl.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -53,6 +54,7 @@ #ifdef CONFIG_X86 #include #include +#include #endif static int deprecated_sysctl_warning(struct __sysctl_args *args); @@ -81,6 +83,7 @@ extern int maps_protect; extern int sysctl_stat_interval; extern int audit_argv_kb; +extern int latencytop_enabled; /* Constants used for minimum and maximum */ #ifdef CONFIG_DETECT_SOFTLOCKUP @@ -306,7 +309,7 @@ .procname = "sched_nr_migrate", .data = &sysctl_sched_nr_migrate, .maxlen = sizeof(unsigned int), - .mode = 644, + .mode = 0644, .proc_handler = &proc_dointvec, }, #endif @@ -382,6 +385,15 @@ .proc_handler = &proc_dointvec_taint, }, #endif +#ifdef CONFIG_LATENCYTOP + { + .procname = "latencytop", + .data = &latencytop_enabled, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, +#endif #ifdef CONFIG_SECURITY_CAPABILITIES { .procname = "cap-bound", @@ -683,6 +695,14 @@ .mode = 0644, .proc_handler = &proc_dointvec, }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "io_delay_type", + .data = &io_delay_type, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, #endif #if defined(CONFIG_MMU) { @@ -910,7 +930,7 @@ .data = &nr_overcommit_huge_pages, .maxlen = sizeof(nr_overcommit_huge_pages), .mode = 0644, - .proc_handler = &proc_doulongvec_minmax, + .proc_handler = &hugetlb_overcommit_handler, }, #endif { @@ -1217,6 +1237,22 @@ .mode = 0644, .proc_handler = &proc_dointvec, }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "default_relatime", + .data = &default_relatime, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "relatime_interval", + .data = &relatime_interval, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE) { .ctl_name = CTL_UNNUMBERED, @@ -1327,6 +1363,33 @@ return NULL; } +char *sysctl_pathname(ctl_table *table, char *buffer, int buflen) +{ + if (buflen < 1) + return NULL; + buffer += --buflen; + *buffer = '\0'; + + while (table) { + int namelen = strlen(table->procname); + + if (buflen < namelen + 1) + return NULL; + buflen -= namelen + 1; + buffer -= namelen; + memcpy(buffer, table->procname, namelen); + *--buffer = '/'; + table = table->parent; + } + if (buflen < 4) + return NULL; + buffer -= 4; + memcpy(buffer, "/sys", 4); + + return buffer; +} +EXPORT_SYMBOL(sysctl_pathname); + #ifdef CONFIG_SYSCTL_SYSCALL int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, void __user *newval, size_t newlen) --- linux-2.6.24.orig/kernel/audit.c +++ linux-2.6.24/kernel/audit.c @@ -1200,13 +1200,17 @@ static inline int audit_expand(struct audit_buffer *ab, int extra) { struct sk_buff *skb = ab->skb; - int ret = pskb_expand_head(skb, skb_headroom(skb), extra, - ab->gfp_mask); + int oldtail = skb_tailroom(skb); + int ret = pskb_expand_head(skb, 0, extra, ab->gfp_mask); + int newtail = skb_tailroom(skb); + if (ret < 0) { audit_log_lost("out of memory in audit_expand"); return 0; } - return skb_tailroom(skb); + + skb->truesize += newtail - oldtail; + return newtail; } /* @@ -1215,8 +1219,7 @@ * will be called a second time. Currently, we assume that a printk * can't format message larger than 1024 bytes, so we don't either. */ -static void audit_log_vformat(struct audit_buffer *ab, const char *fmt, - va_list args) +void audit_log_vformat(struct audit_buffer *ab, const char *fmt, va_list args) { int len, avail; struct sk_buff *skb; @@ -1471,3 +1474,6 @@ EXPORT_SYMBOL(audit_log_end); EXPORT_SYMBOL(audit_log_format); EXPORT_SYMBOL(audit_log); +EXPORT_SYMBOL_GPL(audit_log_vformat); +EXPORT_SYMBOL_GPL(audit_log_untrustedstring); +EXPORT_SYMBOL_GPL(audit_log_d_path); --- linux-2.6.24.orig/kernel/Makefile +++ linux-2.6.24/kernel/Makefile @@ -57,6 +57,7 @@ obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o obj-$(CONFIG_MARKERS) += marker.o +obj-$(CONFIG_LATENCYTOP) += latencytop.o ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y) # According to Alan Modra , the -fno-omit-frame-pointer is --- linux-2.6.24.orig/kernel/timer.c +++ linux-2.6.24/kernel/timer.c @@ -453,10 +453,18 @@ spin_lock_irqsave(&base->lock, flags); timer_set_base(timer, base); internal_add_timer(base, timer); + /* + * Check whether the other CPU is idle and needs to be + * triggered to reevaluate the timer wheel when nohz is + * active. We are protected against the other CPU fiddling + * with the timer by holding the timer base lock. This also + * makes sure that a CPU on the way to idle can not evaluate + * the timer wheel. + */ + wake_up_idle_cpu(cpu); spin_unlock_irqrestore(&base->lock, flags); } - /** * mod_timer - modify a timer's timeout * @timer: the timer to be modified --- linux-2.6.24.orig/kernel/latencytop.c +++ linux-2.6.24/kernel/latencytop.c @@ -0,0 +1,241 @@ +/* + * latencytop.c: Latency display infrastructure + * + * (C) Copyright 2008 Intel Corporation + * Author: Arjan van de Ven + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static DEFINE_SPINLOCK(latency_lock); + +#define MAXLR 128 +static struct latency_record latency_record[MAXLR]; + +int latencytop_enabled; + +void clear_all_latency_tracing(struct task_struct *p) +{ + unsigned long flags; + + if (!latencytop_enabled) + return; + + spin_lock_irqsave(&latency_lock, flags); + memset(&p->latency_record, 0, sizeof(p->latency_record)); + p->latency_record_count = 0; + spin_unlock_irqrestore(&latency_lock, flags); +} + +static void clear_global_latency_tracing(void) +{ + unsigned long flags; + + spin_lock_irqsave(&latency_lock, flags); + memset(&latency_record, 0, sizeof(latency_record)); + spin_unlock_irqrestore(&latency_lock, flags); +} + +static void __sched account_global_scheduler_latency(struct task_struct *tsk, + struct latency_record *lat) +{ + int firstnonnull = MAXLR + 1; + int i; + + if (!latencytop_enabled) + return; + + /* skip kernel threads for now */ + if (!tsk->mm) + return; + + for (i = 0; i < MAXLR; i++) { + int q; + int same = 1; + /* Nothing stored: */ + if (!latency_record[i].backtrace[0]) { + if (firstnonnull > i) + firstnonnull = i; + continue; + } + for (q = 0 ; q < LT_BACKTRACEDEPTH ; q++) { + if (latency_record[i].backtrace[q] != + lat->backtrace[q]) + same = 0; + if (same && lat->backtrace[q] == 0) + break; + if (same && lat->backtrace[q] == ULONG_MAX) + break; + } + if (same) { + latency_record[i].count++; + latency_record[i].time += lat->time; + if (lat->time > latency_record[i].max) + latency_record[i].max = lat->time; + return; + } + } + + i = firstnonnull; + if (i >= MAXLR - 1) + return; + + /* Allocted a new one: */ + memcpy(&latency_record[i], lat, sizeof(struct latency_record)); +} + +static inline void +store_stacktrace(struct task_struct *tsk, struct latency_record *lat) +{ + struct stack_trace trace; + + memset(&trace, 0, sizeof(trace)); + trace.max_entries = LT_BACKTRACEDEPTH; + trace.entries = &lat->backtrace[0]; + trace.skip = 0; + save_stack_trace_tsk(tsk, &trace); +} + +void __sched +account_scheduler_latency(struct task_struct *tsk, int usecs, int inter) +{ + unsigned long flags; + int i, q; + struct latency_record lat; + + if (!latencytop_enabled) + return; + + /* Long interruptible waits are generally user requested... */ + if (inter && usecs > 5000) + return; + + memset(&lat, 0, sizeof(lat)); + lat.count = 1; + lat.time = usecs; + lat.max = usecs; + store_stacktrace(tsk, &lat); + + spin_lock_irqsave(&latency_lock, flags); + + account_global_scheduler_latency(tsk, &lat); + + /* + * short term hack; if we're > 32 we stop; future we recycle: + */ + tsk->latency_record_count++; + if (tsk->latency_record_count >= LT_SAVECOUNT) + goto out_unlock; + + for (i = 0; i < LT_SAVECOUNT ; i++) { + struct latency_record *mylat; + int same = 1; + mylat = &tsk->latency_record[i]; + for (q = 0 ; q < LT_BACKTRACEDEPTH ; q++) { + if (mylat->backtrace[q] != + lat.backtrace[q]) + same = 0; + if (same && lat.backtrace[q] == 0) + break; + if (same && lat.backtrace[q] == ULONG_MAX) + break; + } + if (same) { + mylat->count++; + mylat->time += lat.time; + if (lat.time > mylat->max) + mylat->max = lat.time; + goto out_unlock; + } + } + + /* Allocated a new one: */ + i = tsk->latency_record_count; + memcpy(&tsk->latency_record[i], &lat, sizeof(struct latency_record)); + +out_unlock: + spin_unlock_irqrestore(&latency_lock, flags); +} + +static int lstats_show(struct seq_file *m, void *v) +{ + int i; + + seq_puts(m, "Latency Top version : v0.1\n"); + + for (i = 0; i < MAXLR; i++) { + if (latency_record[i].backtrace[0]) { + int q; + seq_printf(m, "%i %li %li ", + latency_record[i].count, + latency_record[i].time, + latency_record[i].max); + for (q = 0; q < LT_BACKTRACEDEPTH; q++) { + char sym[KSYM_NAME_LEN]; + char *c; + if (!latency_record[i].backtrace[q]) + break; + if (latency_record[i].backtrace[q] == ULONG_MAX) + break; + sprint_symbol(sym, + latency_record[i].backtrace[q]); + c = strchr(sym, '+'); + if (c) + *c = 0; + seq_printf(m, "%s ", sym); + } + seq_printf(m, "\n"); + } + } + return 0; +} + +static ssize_t +lstats_write(struct file *file, const char __user *buf, size_t count, + loff_t *offs) +{ + clear_global_latency_tracing(); + + return count; +} + +static int lstats_open(struct inode *inode, struct file *filp) +{ + return single_open(filp, lstats_show, NULL); +} + +static struct file_operations lstats_fops = { + .open = lstats_open, + .read = seq_read, + .write = lstats_write, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init init_lstats_procfs(void) +{ + struct proc_dir_entry *pe; + + pe = create_proc_entry("latency_stats", 0644, NULL); + if (!pe) + return -ENOMEM; + + pe->proc_fops = &lstats_fops; + + return 0; +} +__initcall(init_lstats_procfs); --- linux-2.6.24.orig/kernel/compat.c +++ linux-2.6.24/kernel/compat.c @@ -40,10 +40,36 @@ __put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0; } +static long compat_nanosleep_restart(struct restart_block *restart) +{ + struct compat_timespec __user *rmtp; + struct timespec rmt; + mm_segment_t oldfs; + long ret; + + rmtp = (struct compat_timespec __user *)(restart->arg1); + restart->arg1 = (unsigned long)&rmt; + oldfs = get_fs(); + set_fs(KERNEL_DS); + ret = hrtimer_nanosleep_restart(restart); + set_fs(oldfs); + + if (ret) { + restart->fn = compat_nanosleep_restart; + restart->arg1 = (unsigned long)rmtp; + + if (rmtp && put_compat_timespec(&rmt, rmtp)) + return -EFAULT; + } + + return ret; +} + asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp, struct compat_timespec __user *rmtp) { struct timespec tu, rmt; + mm_segment_t oldfs; long ret; if (get_compat_timespec(&tu, rqtp)) @@ -52,11 +78,21 @@ if (!timespec_valid(&tu)) return -EINVAL; - ret = hrtimer_nanosleep(&tu, rmtp ? &rmt : NULL, HRTIMER_MODE_REL, - CLOCK_MONOTONIC); + oldfs = get_fs(); + set_fs(KERNEL_DS); + ret = hrtimer_nanosleep(&tu, + rmtp ? (struct timespec __user *)&rmt : NULL, + HRTIMER_MODE_REL, CLOCK_MONOTONIC); + set_fs(oldfs); + + if (ret) { + struct restart_block *restart + = ¤t_thread_info()->restart_block; + + restart->fn = compat_nanosleep_restart; + restart->arg1 = (unsigned long)rmtp; - if (ret && rmtp) { - if (put_compat_timespec(&rmt, rmtp)) + if (rmtp && put_compat_timespec(&rmt, rmtp)) return -EFAULT; } --- linux-2.6.24.orig/kernel/futex_compat.c +++ linux-2.6.24/kernel/futex_compat.c @@ -54,6 +54,9 @@ compat_long_t futex_offset; int rc; + if (!futex_cmpxchg_enabled) + return; + /* * Fetch the list head (which was registered earlier, via * sys_set_robust_list()): @@ -115,6 +118,9 @@ compat_sys_set_robust_list(struct compat_robust_list_head __user *head, compat_size_t len) { + if (!futex_cmpxchg_enabled) + return -ENOSYS; + if (unlikely(len != sizeof(*head))) return -EINVAL; @@ -130,6 +136,9 @@ struct compat_robust_list_head __user *head; unsigned long ret; + if (!futex_cmpxchg_enabled) + return -ENOSYS; + if (!pid) head = current->compat_robust_list; else { @@ -175,7 +184,7 @@ t = timespec_to_ktime(ts); if (cmd == FUTEX_WAIT) - t = ktime_add(ktime_get(), t); + t = ktime_add_safe(ktime_get(), t); tp = &t; } if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE) --- linux-2.6.24.orig/kernel/sched.c +++ linux-2.6.24/kernel/sched.c @@ -727,6 +727,49 @@ resched_task(cpu_curr(cpu)); spin_unlock_irqrestore(&rq->lock, flags); } + +#ifdef CONFIG_NO_HZ +/* + * When add_timer_on() enqueues a timer into the timer wheel of an + * idle CPU then this timer might expire before the next timer event + * which is scheduled to wake up that CPU. In case of a completely + * idle system the next event might even be infinite time into the + * future. wake_up_idle_cpu() ensures that the CPU is woken up and + * leaves the inner idle loop so the newly added timer is taken into + * account when the CPU goes back to idle and evaluates the timer + * wheel for the next timer event. + */ +void wake_up_idle_cpu(int cpu) +{ + struct rq *rq = cpu_rq(cpu); + + if (cpu == smp_processor_id()) + return; + + /* + * This is safe, as this function is called with the timer + * wheel base lock of (cpu) held. When the CPU is on the way + * to idle and has not yet set rq->curr to idle then it will + * be serialized on the timer wheel base lock and take the new + * timer into account automatically. + */ + if (rq->curr != rq->idle) + return; + + /* + * We can set TIF_RESCHED on the idle task of the other CPU + * lockless. The worst case is that the other CPU runs the + * idle task through an additional NOOP schedule() + */ + set_tsk_thread_flag(rq->idle, TIF_NEED_RESCHED); + + /* NEED_RESCHED must be visible before we test polling */ + smp_mb(); + if (!tsk_is_polling(rq->idle)) + smp_send_reschedule(cpu); +} +#endif + #else static inline void resched_task(struct task_struct *p) { @@ -4028,11 +4071,10 @@ oldprio = p->prio; on_rq = p->se.on_rq; running = task_current(rq, p); - if (on_rq) { + if (on_rq) dequeue_task(rq, p, 0); - if (running) - p->sched_class->put_prev_task(rq, p); - } + if (running) + p->sched_class->put_prev_task(rq, p); if (rt_prio(prio)) p->sched_class = &rt_sched_class; @@ -4041,9 +4083,9 @@ p->prio = prio; + if (running) + p->sched_class->set_curr_task(rq); if (on_rq) { - if (running) - p->sched_class->set_curr_task(rq); enqueue_task(rq, p, 0); /* * Reschedule if we are currently running on this runqueue and @@ -4339,18 +4381,17 @@ update_rq_clock(rq); on_rq = p->se.on_rq; running = task_current(rq, p); - if (on_rq) { + if (on_rq) deactivate_task(rq, p, 0); - if (running) - p->sched_class->put_prev_task(rq, p); - } + if (running) + p->sched_class->put_prev_task(rq, p); oldprio = p->prio; __setscheduler(rq, p, policy, param->sched_priority); + if (running) + p->sched_class->set_curr_task(rq); if (on_rq) { - if (running) - p->sched_class->set_curr_task(rq); activate_task(rq, p, 0); /* * Reschedule if we are currently running on this runqueue and @@ -7110,19 +7151,22 @@ running = task_current(rq, tsk); on_rq = tsk->se.on_rq; - if (on_rq) { + if (on_rq) dequeue_task(rq, tsk, 0); - if (unlikely(running)) - tsk->sched_class->put_prev_task(rq, tsk); - } + if (unlikely(running)) + tsk->sched_class->put_prev_task(rq, tsk); set_task_cfs_rq(tsk, task_cpu(tsk)); - if (on_rq) { - if (unlikely(running)) - tsk->sched_class->set_curr_task(rq); +#ifdef CONFIG_FAIR_GROUP_SCHED + if (tsk->sched_class->moved_group) + tsk->sched_class->moved_group(tsk); +#endif + + if (unlikely(running)) + tsk->sched_class->set_curr_task(rq); + if (on_rq) enqueue_task(rq, tsk, 0); - } done: task_rq_unlock(rq, &flags); --- linux-2.6.24.orig/kernel/time/timekeeping.c +++ linux-2.6.24/kernel/time/timekeeping.c @@ -189,6 +189,7 @@ if (clock == new) return; + new->cycle_last = 0; now = clocksource_read(new); nsec = __get_nsec_offset(); timespec_add_ns(&xtime, nsec); @@ -301,6 +302,7 @@ /* Make sure that we have the correct xtime reference */ timespec_add_ns(&xtime, timekeeping_suspend_nsecs); /* re-base the last cycle value */ + clock->cycle_last = 0; clock->cycle_last = clocksource_read(clock); clock->error = 0; timekeeping_suspended = 0; --- linux-2.6.24.orig/kernel/irq/chip.c +++ linux-2.6.24/kernel/irq/chip.c @@ -246,6 +246,17 @@ } /* + * default shutdown function + */ +static void default_shutdown(unsigned int irq) +{ + struct irq_desc *desc = irq_desc + irq; + + desc->chip->mask(irq); + desc->status |= IRQ_MASKED; +} + +/* * Fixup enable/disable function pointers */ void irq_chip_set_defaults(struct irq_chip *chip) @@ -256,8 +267,15 @@ chip->disable = default_disable; if (!chip->startup) chip->startup = default_startup; + /* + * We use chip->disable, when the user provided its own. When + * we have default_disable set for chip->disable, then we need + * to use default_shutdown, otherwise the irq line is not + * disabled on free_irq(): + */ if (!chip->shutdown) - chip->shutdown = chip->disable; + chip->shutdown = chip->disable != default_disable ? + chip->disable : default_shutdown; if (!chip->name) chip->name = chip->typename; if (!chip->end) @@ -589,3 +607,39 @@ set_irq_chip(irq, chip); __set_irq_handler(irq, handle, 0, name); } + +void __init set_irq_noprobe(unsigned int irq) +{ + struct irq_desc *desc; + unsigned long flags; + + if (irq >= NR_IRQS) { + printk(KERN_ERR "Trying to mark IRQ%d non-probeable\n", irq); + + return; + } + + desc = irq_desc + irq; + + spin_lock_irqsave(&desc->lock, flags); + desc->status |= IRQ_NOPROBE; + spin_unlock_irqrestore(&desc->lock, flags); +} + +void __init set_irq_probe(unsigned int irq) +{ + struct irq_desc *desc; + unsigned long flags; + + if (irq >= NR_IRQS) { + printk(KERN_ERR "Trying to mark IRQ%d probeable\n", irq); + + return; + } + + desc = irq_desc + irq; + + spin_lock_irqsave(&desc->lock, flags); + desc->status &= ~IRQ_NOPROBE; + spin_unlock_irqrestore(&desc->lock, flags); +} --- linux-2.6.24.orig/kernel/power/disk.c +++ linux-2.6.24/kernel/power/disk.c @@ -291,7 +291,7 @@ return error; suspend_console(); - error = device_suspend(PMSG_SUSPEND); + error = device_suspend(PMSG_HIBERNATE); if (error) goto Resume_console; @@ -304,7 +304,7 @@ goto Finish; local_irq_disable(); - error = device_power_down(PMSG_SUSPEND); + error = device_power_down(PMSG_HIBERNATE); if (!error) { hibernation_ops->enter(); /* We should never get here */ --- linux-2.6.24.orig/kernel/power/console.c +++ linux-2.6.24/kernel/power/console.c @@ -16,6 +16,7 @@ int pm_prepare_console(void) { +#ifndef CONFIG_PM_DISABLE_CONSOLE acquire_console_sem(); orig_fgconsole = fg_console; @@ -44,15 +45,18 @@ } orig_kmsg = kmsg_redirect; kmsg_redirect = SUSPEND_CONSOLE; +#endif return 0; } void pm_restore_console(void) { +#ifndef CONFIG_PM_DISABLE_CONSOLE acquire_console_sem(); set_console(orig_fgconsole); release_console_sem(); kmsg_redirect = orig_kmsg; +#endif return; } #endif --- linux-2.6.24.orig/kernel/power/Kconfig +++ linux-2.6.24/kernel/power/Kconfig @@ -97,6 +97,21 @@ powered and thus its contents are preserved, such as the suspend-to-RAM state (i.e. the ACPI S3 state). +config PM_DISABLE_CONSOLE + bool "Disable Power Management messing with the active console" + depends on PM + default n + ---help--- + By defauly, PM will take over the active console (generally, this means + switching to the console when suspending from X). This can at times cause + problems, especially if userspace suspend scripts try to do things with the + console before or after suspending (e.g. calling vbestate). + + To work around this, enable this option so that PM will not handle the + console. + + If unsure, say N. + config HIBERNATION_UP_POSSIBLE bool depends on X86 || PPC64_SWSUSP || PPC32 --- linux-2.6.24.orig/lib/Kconfig.debug +++ linux-2.6.24/lib/Kconfig.debug @@ -517,4 +517,16 @@ help Provide stacktrace filter for fault-injection capabilities +config LATENCYTOP + bool "Latency measuring infrastructure" + select FRAME_POINTER if !MIPS + select KALLSYMS + select KALLSYMS_ALL + select STACKTRACE + depends on SCHEDSTATS + help + Enable this option if you want to use the LatencyTOP tool + to find out which userspace is blocking on what kernel operations. + + source "samples/Kconfig" --- linux-2.6.24.orig/debian/control.stub +++ linux-2.6.24/debian/control.stub @@ -0,0 +1,839 @@ +Source: linux +Section: devel +Priority: optional +Maintainer: Ubuntu Kernel Team +Standards-Version: 3.6.1 +Build-Depends: debhelper (>= 3), module-init-tools, kernel-wedge (>= 2.24ubuntu1), gcc-4.1-hppa64 [hppa], binutils-hppa64 [hppa], device-tree-compiler [powerpc], gcc-4.1 [powerpc ia64], gawk [amd64 i386] +Build-Depends-Indep: xmlto, docbook-utils, gs, transfig, bzip2, sharutils + +Package: linux-kernel-devel +Architecture: all +Section: devel +Priority: optional +Depends: build-essential, git-core, gitk, rsync, curl, openssh-client, debhelper, kernel-package, kernel-wedge +Description: Linux kernel hacking dependencies + This is a dummy package that will install all possible packages + required to hack comfortably on the kernel. + +Package: linux-source-2.6.24 +Architecture: all +Section: devel +Priority: optional +Provides: linux-source, linux-source-2.6 +Depends: binutils, bzip2, coreutils | fileutils (>= 4.0) +Recommends: libc-dev, gcc, make +Suggests: libncurses-dev | ncurses-dev, kernel-package, libqt3-dev +Description: Linux kernel source for version 2.6.24 with Ubuntu patches + This package provides the source code for the Linux kernel version 2.6.24. + . + You may configure the kernel to your setup by typing "make config" and + following instructions, but you could get ncursesX.X-dev and try "make + menuconfig" for a jazzier, and easier to use interface. There are options + to use QT or GNOME based configuration interfaces, but they need + additional packages to be installed. Also, please read the detailed + documentation in the file + /usr/share/doc/linux-source-2.6.24/README.headers.gz. + . + If you wish to use this package to create a custom Linux kernel, then it + is suggested that you investigate the package kernel-package, which has + been designed to ease the task of creating kernel image packages. + . + If you are simply trying to build third-party modules for your kernel, + you do not want this package. Install the appropriate linux-headers + package instead. + +Package: linux-doc-2.6.24 +Architecture: all +Section: doc +Priority: optional +Provides: linux-doc-2.6 +Conflicts: linux-doc-2.6 +Replaces: linux-doc-2.6 +Depends: coreutils | fileutils (>= 4.0) +Description: Linux kernel specific documentation for version 2.6.24 + This package provides the various readme's in the 2.6.24 kernel + Documentation/ subdirectory: these typically contain kernel-specific + installation notes for some drivers for example. See + /usr/share/doc/linux-doc-2.6.24/Documentation/00-INDEX for a list of what + is contained in each file. Please read the Changes file, as it contains + information about the problems, which may result by upgrading your + kernel. + +Package: linux-headers-2.6.24-23 +Architecture: all +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0) +Provides: linux-headers, linux-headers-2.6 +Description: Header files related to Linux kernel version 2.6.24 + This package provides kernel header files for version 2.6.24, for sites + that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details + +Package: linux-libc-dev +Architecture: amd64 i386 powerpc sparc ia64 hppa lpia +Conflicts: libc6-dev (<< 2.3.2.ds1-6), libc6.1-dev (<< 2.3.2.ds1-6), dvb-dev (<< 1.0.1-6), amd64-libs-dev (<= 1.1), linux-kernel-headers +Replaces: libc6-dev (<< 2.3.2.ds1-6), libc6.1-dev (<< 2.3.2.ds1-6), dvb-dev (<< 1.0.1-6), linux-kernel-headers +Provides: linux-kernel-headers +Description: Linux Kernel Headers for development + This package provides headers from the Linux kernel. These headers + are used by the installed headers for GNU glibc and other system + libraries. + +Package: linux-image-2.6.24-23-386 +Architecture: i386 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on i386 + This package contains the Linux kernel image for version 2.6.24 on + i386. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Alternate x86 (486 and better) processors. + . + Geared toward desktop systems. + . + You likely do not want to install this package directly. Instead, install + the linux-386 meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-386 +Architecture: i386 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on i386 + This package provides kernel header files for version 2.6.24 on + i386. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-debug-2.6.24-23-386 +Architecture: i386 +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.24 on i386 + This package provides a kernel debug image for version 2.6.24 on + i386. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. + +Package: linux-image-2.6.24-23-generic +Architecture: i386 amd64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, redhat-cluster-modules, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on x86/x86_64 + This package contains the Linux kernel image for version 2.6.24 on + x86/x86_64. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Generic processors. + . + Geared toward desktop systems. + . + You likely do not want to install this package directly. Instead, install + the linux-generic meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-generic +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on x86/x86_64 + This package provides kernel header files for version 2.6.24 on + x86/x86_64. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-debug-2.6.24-23-generic +Architecture: i386 amd64 +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.24 on x86/x86_64 + This package provides a kernel debug image for version 2.6.24 on + x86/x86_64. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. + +Package: linux-image-2.6.24-23-hppa32 +Architecture: hppa +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: palo +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on 32-bit HP PA-RISC SMP + This package contains the Linux kernel image for version 2.6.24 on + 32-bit HP PA-RISC SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 32-bit HP PA-RISC SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-hppa32 meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-hppa32 +Architecture: hppa +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, gcc-4.1, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on 32-bit HP PA-RISC SMP + This package provides kernel header files for version 2.6.24 on + 32-bit HP PA-RISC SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-hppa64 +Architecture: hppa +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: palo +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on 64-bit HP PA-RISC SMP + This package contains the Linux kernel image for version 2.6.24 on + 64-bit HP PA-RISC SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 64-bit HP PA-RISC SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-hppa64 meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-hppa64 +Architecture: hppa +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, gcc-4.1-hppa64, binutils-hppa64, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on 64-bit HP PA-RISC SMP + This package provides kernel header files for version 2.6.24 on + 64-bit HP PA-RISC SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-itanium +Architecture: ia64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: elilo (>= 3.6-1) +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on Itanium SMP + This package contains the Linux kernel image for version 2.6.24 on + Itanium SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Itanium SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-itanium meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-itanium +Architecture: ia64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, gcc-4.1, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on Itanium SMP + This package provides kernel header files for version 2.6.24 on + Itanium SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-mckinley +Architecture: ia64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: elilo (>= 3.6-1) +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on Itanium II SMP + This package contains the Linux kernel image for version 2.6.24 on + Itanium II SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Itanium II SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-mckinley meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-mckinley +Architecture: ia64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, gcc-4.1, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on Itanium II SMP + This package provides kernel header files for version 2.6.24 on + Itanium II SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-powerpc +Architecture: powerpc +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: yaboot +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on 32-bit PowerPC + This package contains the Linux kernel image for version 2.6.24 on + 32-bit PowerPC. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 32-bit PowerPC processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-powerpc meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-powerpc +Architecture: powerpc +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, gcc-4.1, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on 32-bit PowerPC + This package provides kernel header files for version 2.6.24 on + 32-bit PowerPC. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-powerpc64-smp +Architecture: powerpc +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: yaboot +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on 64-bit PowerPC SMP + This package contains the Linux kernel image for version 2.6.24 on + 64-bit PowerPC SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 64-bit PowerPC SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-powerpc64-smp meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-powerpc64-smp +Architecture: powerpc +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, gcc-4.1, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on 64-bit PowerPC SMP + This package provides kernel header files for version 2.6.24 on + 64-bit PowerPC SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-powerpc-smp +Architecture: powerpc +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: yaboot +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on 32-bit PowerPC SMP + This package contains the Linux kernel image for version 2.6.24 on + 32-bit PowerPC SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 32-bit PowerPC SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-powerpc-smp meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-powerpc-smp +Architecture: powerpc +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, gcc-4.1, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on 32-bit PowerPC SMP + This package provides kernel header files for version 2.6.24 on + 32-bit PowerPC SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-server +Architecture: i386 amd64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules, kvm-api-4, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on x86/x86_64 + This package contains the Linux kernel image for version 2.6.24 on + x86/x86_64. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Server processors. + . + Geared toward server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-server meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-server +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on x86/x86_64 + This package provides kernel header files for version 2.6.24 on + x86/x86_64. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-debug-2.6.24-23-server +Architecture: i386 amd64 +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.24 on x86/x86_64 + This package provides a kernel debug image for version 2.6.24 on + x86/x86_64. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. + +Package: linux-image-2.6.24-23-sparc64 +Architecture: sparc +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: silo +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on 64-bit UltraSPARC + This package contains the Linux kernel image for version 2.6.24 on + 64-bit UltraSPARC. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 64-bit UltraSPARC processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-sparc64 meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-sparc64 +Architecture: sparc +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on 64-bit UltraSPARC + This package provides kernel header files for version 2.6.24 on + 64-bit UltraSPARC. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-sparc64-smp +Architecture: sparc +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: silo +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on 64-bit UltraSPARC SMP + This package contains the Linux kernel image for version 2.6.24 on + 64-bit UltraSPARC SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 64-bit UltraSPARC SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-sparc64-smp meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-sparc64-smp +Architecture: sparc +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on 64-bit UltraSPARC SMP + This package provides kernel header files for version 2.6.24 on + 64-bit UltraSPARC SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-virtual +Architecture: i386 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, redhat-cluster-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on x86 + This package contains the Linux kernel image for version 2.6.24 on + x86. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Virtual processors. + . + Geared toward virtualised hardware. + . + You likely do not want to install this package directly. Instead, install + the linux-virtual meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-virtual +Architecture: i386 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on x86 + This package provides kernel header files for version 2.6.24 on + x86. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-debug-2.6.24-23-virtual +Architecture: i386 +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.24 on x86 + This package provides a kernel debug image for version 2.6.24 on + x86. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. + +Package: linux-image-2.6.24-23-lpia +Architecture: lpia +Section: universe/base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, redhat-cluster-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on Ubuntu Moblie and Embedded LPIA edition + This package contains the Linux kernel image for version 2.6.24 on + Ubuntu Moblie and Embedded LPIA edition. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports UME processors. + . + UME kernel + . + You likely do not want to install this package directly. Instead, install + the linux-lpia meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-lpia +Architecture: lpia +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on Ubuntu Moblie and Embedded LPIA edition + This package provides kernel header files for version 2.6.24 on + Ubuntu Moblie and Embedded LPIA edition. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-rt +Architecture: i386 amd64 +Section: universe/base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, redhat-cluster-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on Ingo Molnar's full real time preemption patch (2.6.24.7-rt21) + This package contains the Linux kernel image for version 2.6.24 on + Ingo Molnar's full real time preemption patch (2.6.24.7-rt21). + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Generic processors. + . + RT kernel + . + You likely do not want to install this package directly. Instead, install + the linux-rt meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-rt +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on Ingo Molnar's full real time preemption patch (2.6.24.7-rt21) + This package provides kernel header files for version 2.6.24 on + Ingo Molnar's full real time preemption patch (2.6.24.7-rt21). + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-lpiacompat +Architecture: lpia +Section: universe/base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, redhat-cluster-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on Ubuntu Moblie and Embedded-x86 compat edition + This package contains the Linux kernel image for version 2.6.24 on + Ubuntu Moblie and Embedded-x86 compat edition. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports UME processors. + . + UME kernel + . + You likely do not want to install this package directly. Instead, install + the linux-lpiacompat meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-lpiacompat +Architecture: lpia +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on Ubuntu Moblie and Embedded-x86 compat edition + This package provides kernel header files for version 2.6.24 on + Ubuntu Moblie and Embedded-x86 compat edition. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-xen +Architecture: i386 amd64 +Section: universe/base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, redhat-cluster-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: grub +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on This kernel can be used for Xen dom0 and domU + This package contains the Linux kernel image for version 2.6.24 on + This kernel can be used for Xen dom0 and domU. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Generic processors. + . + Xen domO/domU + . + You likely do not want to install this package directly. Instead, install + the linux-xen meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-xen +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on This kernel can be used for Xen dom0 and domU + This package provides kernel header files for version 2.6.24 on + This kernel can be used for Xen dom0 and domU. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-openvz +Architecture: i386 amd64 +Section: universe/base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, redhat-cluster-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on OpenVZ Virtualization enabled kernel + This package contains the Linux kernel image for version 2.6.24 on + OpenVZ Virtualization enabled kernel. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Generic processors. + . + OpenVZ kernel + . + You likely do not want to install this package directly. Instead, install + the linux-openvz meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-openvz +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on OpenVZ Virtualization enabled kernel + This package provides kernel header files for version 2.6.24 on + OpenVZ Virtualization enabled kernel. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. --- linux-2.6.24.orig/debian/rules +++ linux-2.6.24/debian/rules @@ -0,0 +1,121 @@ +#!/usr/bin/make -f +# +# debian/rules for Ubuntu linux +# +# Use this however you want, just give credit where credit is due. +# +# Copyright (c) 2007 Ben Collins +# + +# dpkg-buildpackage passes options that are incomptatible +# with the kernel build. +unexport CFLAGS +unexport LDFLAGS + +# This is the debhelper compatability version to use. +export DH_COMPAT=4 +export LC_ALL=C +export SHELL=/bin/bash -e + +# Common variables for all architectures +include debian/rules.d/0-common-vars.mk + +# Pill in some arch specific stuff +include debian/rules.d/$(arch).mk + +# Maintainer targets +include debian/rules.d/1-maintainer.mk + +# Debian Build System targets +binary: binary-indep binary-arch + +build: build-arch build-indep + +clean: debian/control + dh_testdir + dh_testroot + dh_clean + + # d-i stuff + rm -rf modules kernel-versions package-list + rm -rf debian/d-i-$(arch) + + # normal build junk + rm -rf debian/abi/$(release)-$(revision) + rm -rf $(builddir) + rm -f $(stampdir)/stamp-* + rm -rf debian/linux-* + + # This gets rid of the d-i packages in control + cp -f debian/control.stub debian/control + +# Builds the image, arch headers and debug packages +include debian/rules.d/2-binary-arch.mk + +# Rules for building the udebs (debian-installer) +include debian/rules.d/5-udebs.mk + +# Builds the source, doc and linux-headers indep packages +include debian/rules.d/3-binary-indep.mk + +# Various checks to be performed on builds +include debian/rules.d/4-checks.mk + +# Custom binary images (universe/unsupported) +include debian/rules.d/6-binary-custom.mk \ + $(patsubst %,debian/binary-custom.d/%/rules,$(custom_flavours)) + +# Misc stuff +debian/control.stub: debian/d-i/kernel-versions.in \ + debian/scripts/control-create \ + debian/control.stub.in \ + debian/changelog \ + $(wildcard debian/control.d/*) \ + $(patsubst %,debian/binary-custom.d/%/vars,$(all_custom_flavours)) + for i in debian/d-i/kernel-versions.in debian/control.stub.in; do \ + new=`echo $$i | sed 's/\.in$$//'`; \ + cat $$i | sed -e 's/PKGVER/$(release)/g' -e 's/ABINUM/$(abinum)/g' > \ + $$new; \ + done + flavours="$(wildcard debian/control.d/vars.*) $(patsubst %,debian/binary-custom.d/%/vars,$(all_custom_flavours))";\ + for i in $$flavours; do \ + $(SHELL) debian/scripts/control-create $$i | \ + sed -e 's/PKGVER/$(release)/g' -e 's/ABINUM/$(abinum)/g' >>\ + debian/control.stub; \ + done + cp debian/control.stub debian/control + +.PHONY: debian/control +debian/control: debian/control.stub + rm -rf modules kernel-versions package-list + mkdir -p modules/$(arch)/ + cp debian/d-i/modules/* modules/$(arch)/ + cp debian/d-i/package-list debian/d-i/kernel-versions . + touch modules/$(arch)/kernel-image + + # Per flavour module lists + flavour_modules=`ls debian/d-i/modules.$(arch)-* 2>/dev/null` \ + || true; \ + if [ "$$flavour_modules" != "" ]; then \ + for flav in $$flavour_modules; do \ + name=`echo $$flav | sed 's/.*\/modules.$(arch)-//'`; \ + mkdir modules/$(arch)-$$name; \ + (cd debian/d-i/modules/; tar cf - `cat ../../../$$flav`) |\ + (cd modules/$(arch)-$$name/; tar xf -); \ + touch modules/$(arch)-$$name/kernel-image; \ + done; \ + fi + + # Remove unwanted stuff + if [ -r "debian/d-i/exclude-modules.$(arch)" ]; then \ + (cat debian/d-i/exclude-modules.$(arch); \ + ls modules/$(arch)/) | sort | uniq -d | \ + (cd modules/$(arch)/; xargs rm -f); \ + fi + + if [ ! -d modules/$(build_arch) ]; then \ + mkdir -p modules/$(build_arch); \ + cp modules/$(arch)/* modules/$(build_arch); \ + fi + + kernel-wedge gen-control > debian/control --- linux-2.6.24.orig/debian/changelog.historical +++ linux-2.6.24/debian/changelog.historical @@ -0,0 +1,4408 @@ +linux-source-2.6.20 (2.6.20-16.30) UNRELEASED; urgency=low + + CHANGELOG: Do not edit directly. Autogenerated at release. + CHANGELOG: Use the printchanges target to see the curent changes. + CHANGELOG: Use the insertchanges target to create the final log. + + -- Phillip lougher Mon, 11 Jun 2007 19:25:08 +0100 + +linux-source-2.6.20 (2.6.20-16.29) feisty-security; urgency=low + + [Phillip Lougher] + + * Revert "{ata_,}piix: Consolidate PCI IDs. Move ata_piix pata IDs to + piix" + - GIT-SHA d20328e312148f5c47cb38482e967ed9a1b7fdb9 + + [Tim Gardner] + + * Work around Dell E520 BIOS reboot bug. + - GIT-SHA 7d6ddf6fc8d2b5f40faac3c7915df71b4acb2fd4 + - Bug #114854 + + [Upstream Kernel Changes] + + * Fix VMI logic error + * [CRYPTO] geode: Fix in-place operations and set key (CVE-2007-2451) + * random: fix error in entropy extraction (CVE-2007-2453) + * random: fix seeding with zero entropy (CVE-2007-2453) + * [Bluetooth] Fix L2CAP and HCI setsockopt() information leaks (CVE-2007-1353) + + + -- Phillip lougher Thu, 07 Jun 2007 12:51:55 +0100 + +linux-source-2.6.20 (2.6.20-16.28) feisty-security; urgency=low + + [Ben Collins] + + * rtc: Ratelimit "lost interrupts" message. + - GIT-SHA 0102aad3b17d22e67864aa5afd88bc108b881141 + * vbox: Remove this driver. It will be outdated by release. + - GIT-SHA 60c8a6c1fbe7ed5dc28ccdd5a48c624e9ece56f3 + * hppa: Build fixes from jbailey. + - GIT-SHA 4f87aff6afe3479c98f8a64e05c866027e7d473d + * mmc: Set parent for block dev's to host, not class device. + - GIT-SHA 0400a0ceb5afa2afcda76c92d4425c4696e72845 + - Bug #99648 + + [Daniel Chen] + + * sound/pci/: Forward-port intel8x0 quirks from ubuntu-edgy.git + (intel8x0.c) + - GIT-SHA a2ce991fa1b7d601c428564f3741044a492d13a4 + * sound/pci/: Forward-port more intel8x0 quirks from kernel-team@ + (intel8x0.c) + - GIT-SHA 5263bd37eeeedc72447441bdec9fc47e7cca83d9 + * sound/pci/hda/: Revert Toshiba model setting (ALC861_TOSHIBA) for SSID + 1179:ff10 (patch_realtek.c) + - GIT-SHA b6fffb0f499459dfaef0f022f2da1f3fcb4fbdc2 + * sound/pci/hda/: Add missing SSID for ALC861-VD (patch_realtek.c) + - GIT-SHA 0ca1a43cc8e4d484963a7f6e4866602d5fe576db + * sound/pci/ac97/: Fix regression from Edgy - readd jack sense blacklist + entries (ac97_patch.c) + - GIT-SHA 963f93d185fc40ab7853ce75480a5fbcd607e070 + * sound/pci/hda/: Fix regression from Edgy - incorrect model quirk for + ALC861-VD (patch_realtek.c) + - GIT-SHA 382e158458c0771a6bd48cc8a64df6e24a46682e + * sound/pci/hda/: Fix inaudible sound on yet another Toshiba laptop - + incorrect model quirk (patch_realtek.c) + - GIT-SHA fbbec3e6208990a1dbe34766396084d683bc3322 + + [Fabio M. Di Nitto] + + * [OCFS2] Local mounts should skip inode updates + - GIT-SHA 8cbf682c7a9016caf65fb30bb67d1e2de3e924c6 + + [Kyle McMartin] + + * Enable ICH8GM (Crestline) support + - GIT-SHA 5b87e59b3898d33e11f71fcc037e7d1c6480aee0 + * bcm43xx: Update to 2.6.21 + - GIT-SHA 9424583295f2fa0920a611eb0f37ccd8fb2dc453 + * p54pci: Fix error path when eeprom read fails + - GIT-SHA c10305577fa669b114bcb03d6f80bdcbcd46a93a + + [Phillip Lougher] + + * Squashfs: add SetPageError handling + - GIT-SHA ff5082e7b9e1b48d33bbb26fbe9104ee1956688a + * Fix pata_sis crashes preventing booting + - GIT-SHA 1b27e19fa9145a1579cfecccf7d5be7d7e242e46 + - Bug #107774 + * Initialize the Broadcom USB Bluetooth device in Dell laptops. + - GIT-SHA 0f50a719466ae29c18b9b75df3ae64312d6523cf + * Update tifm driver to 0.8d + - GIT-SHA 6bec583645852716f3fee4a7d2534be1acf060d6 + - Bug #53923 + * sound/pci/hda/: Forcibly set the maximum number of codecs (hda_intel.c) + - GIT-SHA d8f18e83ea5ef15ab519f6bf03cccb3bdeb2e469 + - Bug #106843 + * Change CONFIG_NR_CPUS from 32 to 64. + - GIT-SHA 00f6cb2c3cda7dab1d02ceb444f5a34506c7a30d + + [Tim Gardner] + + * Added more USB device IDs + - GIT-SHA 139e45123031d80bebcb8e609d6a079538db0970 + * Prevent i2c_ec module from faulting becasue of uninitialized device + parent. + - GIT-SHA 490e63428ab4b3801bc94f520097fd43a57fbc3f + * Initialize the device with the ACPI structure. + - GIT-SHA 5df920c2fd7da80ea1d47d0c664a747700bf33f1 + * Backported from 2.6.21-rc6 + - GIT-SHA 4d0bb04551b393dfc12552d26dff259034c7620c + * Remove vboxdrv from the module lists. + - GIT-SHA 4aae55dc540f17b7b295047b99f4f68c43d01930 + * Cause SoftMac to emit an association event when setting ESSID. + - GIT-SHA c7a6bbdf4493b2951f02c924bd4a85d01b46c839 + - Bug #https://bugs.launchpad.net/ubuntu/+source/linux-source-2.6.20/+bug/103768 + + [Upstream Kernel Changes] + + * ocfs2_dlm: Missing get/put lockres in dlm_run_purge_lockres + * ocfs2_dlm: Add missing locks in dlm_empty_lockres + * ocfs2_dlm: Fix lockres ref counting bug + * ocfs2_dlm: Check for migrateable lockres in dlm_empty_lockres() + * [PS3] Add HV call to local_irq_restore(). + * i2c: Remove the warning on missing adapter device + * 2.6.21 fix lba48 bug in libata fill_result_tf() + * futex: PI state locking fix + * [APPLETALK]: Fix a remotely triggerable crash (CVE-2007-1357) + * [IPV6]: Fix for ipv6_setsockopt NULL dereference (CVE-2007-1388) + * DCCP: Fix exploitable hole in DCCP socket options (CVE-2007-1730) + * [IPv4] fib: Fix out of bound access of fib_props[] (CVE-2007-2172) + * (Denial of Service security fix from stable kernel 2.6.20.8) + * (Fix to Denial of Service security fix, from stable kernel 2.6.20.10) + * (ipv6 security bug fix from stable kernel 2.6.20.9) + * (Bug fix to ipv6 security fix, from stable kernel 2.6.20.10) + * [SPARC64]: SUN4U PCI-E controller support. + * [VIDEO]: Add Sun XVR-500 framebuffer driver. + * [VIDEO]: Add Sun XVR-2500 framebuffer driver. + * [SPARC64]: Fix recursion in PROM tree building. + * [SPARC64]: Bump PROMINTR_MAX to 32. + * [SPARC64]: Correct FIRE_IOMMU_FLUSHINV register offset. + * [SPARC64]: Add bq4802 TOD chip support, as found on ultra45. + * [SERIAL] SUNHV: Add an ID string. + * [SPARC64]: Be more resiliant with PCI I/O space regs. + * [SPARC64]: Add missing cpus_empty() check in hypervisor xcall handling. + * Input: i8042 - fix AUX IRQ delivery check + * Input: i8042 - another attempt to fix AUX delivery checks + * Input: i8042 - fix AUX port detection with some chips + * [IPV6]: ipv6_fl_socklist is inadvertently shared. (CVE-2007-1592) + + [Wang Zhenyu] + + * intel_agp: fix G965 GTT size detect + - GIT-SHA 8d9fac9fa2123f186f9f7c2b5ba7aaa594de1b58 + + -- Phillip Lougher Tue, 22 May 2007 20:01:42 +0100 + +linux-source-2.6.20 (2.6.20-15.27) feisty; urgency=low + + [Ben Collins] + + * ubuntu: Revert back to amd74xx and disable the troublesome pata_amd + - GIT-SHA 5e93e85491bf4804954643141af47a4692d59a91 + + -- Ben Collins Sat, 14 Apr 2007 17:41:11 -0400 + +linux-source-2.6.20 (2.6.20-15.26) feisty; urgency=low + + [Ben Collins] + + * libata: Rework logic for hpa_resize to work around bad returns from + SET_MAX + - GIT-SHA 5d5f973bfa93079d8dd13a21e2af32306d5a009f + + -- Ben Collins Sat, 14 Apr 2007 15:50:34 -0400 + +linux-source-2.6.20 (2.6.20-15.25) feisty; urgency=low + + [Ben Collins] + + * sata_nv: Revert patch that enabled ADMA for NODATA transfers. + - GIT-SHA 6429d0744ca5ffe007109ef4d70414bebe15966c + * libata: Completely avoid HPA code paths when ignore_hpa=0 + - GIT-SHA 9e3e1aea530dcb2e792f14e365a0d6d95539bfa9 + + -- Ben Collins Fri, 13 Apr 2007 13:39:36 -0400 + +linux-source-2.6.20 (2.6.20-15.24) feisty; urgency=low + + [Ben Collins] + + * libata: Re-add the tracking of n_sectors_boot + - GIT-SHA 1fa3ab07416406841cc1c7064b55fb084bbb1e3f + * i2c_ec: Do not set parent device. Current ACPI is not setup for this. + - GIT-SHA d80fb3540d170f18639c08f64afd133129bed856 + - Bug #96480 + + [Upstream Kernel Changes] + + * 2.6.21 fix lba48 bug in libata fill_result_tf() + + -- Ben Collins Thu, 12 Apr 2007 18:58:24 -0400 + +linux-source-2.6.20 (2.6.20-14.23) feisty; urgency=low + + [Ben Collins] + + * piix: Revery back to using piix (IDE) driver instead of ata_piix + (libata) driver for Intel PATA chipsets. + - GIT-SHA a4b5f29bd0754d49a818a30126c45e3b94ec127c + - Bug #96857 + * piix: Put some newer chipsets back to ata_piix. + - GIT-SHA 18a347500d3c6a2c636ac81556cfa2e1daed70b4 + * libata: Add patch to support recognizing HPA drives. + - GIT-SHA ddc27b2bb3c66026044efc3a4d97f22cd1e9243b + * mmc: Set parent for block dev's to host, not class device. + - GIT-SHA 104cff7bb0413b58091e2e45b6dfda210c1028fe + - Bug #99648 + + -- Ben Collins Thu, 12 Apr 2007 14:01:17 -0400 + +linux-source-2.6.20 (2.6.20-14.22) feisty; urgency=low + + [Ben Collins] + + * powerpc: Make ps3 work in multiplatform kernel + - GIT-SHA 54517f89a70e7cea696d1d21d13b86000c20daf4 + * drivers/ata/: Sync with libata-dev#upstream (ref + 1770cd662ad619e78d73a08a2f12f203656e705b) + - GIT-SHA 6fff74ec14bcaf6ac8bf156787961db83d6c90cd + * debian/rules: Add NOEXTRAS build option to not build things like + lowlatency and crashdump kernels. + - GIT-SHA 76f9f235bbdf048db4f09ef2874ae5766276222a + * libata-acpi: Add _GTM and _STM support to libata + - GIT-SHA 2939a7a99cfac2d0e1b120098c2541514ba48ff4 + * libata-acpi: Cleanup and enable acpi for pata drives by default. + - GIT-SHA 36fe5af2bb79195923a08acc0ebd74a2dd90e0f7 + * pci: Git rid of duplicate quirk exports. + - GIT-SHA a8779f83252855ce1a79ef633be5e8c3c2fe56f9 + * ps3: Merge bits so that ps3 can be compiled into powerpc64-smp + - GIT-SHA 462362a41075c7c803e4b49dbdcccda400a3a8f8 + * ubuntu: Remove remnants of ps3 kernel, now merged with ppc64-smp. + - GIT-SHA 2ba1dc63ca38d8e80c8ad0126dc1eba8c3eb080c + * ps3: Include asm/firmware.h for device-init.c + - GIT-SHA 9e4507538545341dc8ec645249513081ec423970 + * ubuntu: Update sata/pata d-i module lists. + - GIT-SHA 75e3656071e565efe201ac2c287f4743d2e93e0b + * snd_ps3: New driver for ps3 sound, of course. + - GIT-SHA e1a797d335353ad9c16e2cbe080699e41c5828a6 + * libusual: Add my U3 Cruzer as a single LUN device (has driver iso) + - GIT-SHA 2ff96660777c0936ac8064fb2c20b22e4954ef71 + * ps3: Sync to latest ps3-linux-dev git. We now have snd_ps3. + - GIT-SHA 563465bcc598e5f5bce463f78c11a5859814c08c + * gelic_net: Allocate gelic_irq_status from GFP_DMA so it works with + __pa() + - GIT-SHA 3b56675a8df0c4b2a5fd09d663bb880a1024cd44 + * ubuntu/net/ipg: Add MODULE_DEVIVCE_TABLE for autoload of module + - GIT-SHA 025a73f21cf92ae4abe6928bb37ec4176da11eae + - Bug #86388 + * acpi: Make the lack of DSDT.aml in initramfs not sound like an error. + - GIT-SHA 7711ba4a2e77f02793fdceefddc1c9c198f68dce + + [Colin Watson] + + * d-i: Fix fs-core-modules description. + - GIT-SHA 6ab196033b5d41b8d5545a28da6d7c5f672f75ee + * d-i: Restore fat-modules udeb, split out from fs-secondary-modules. + - GIT-SHA 7e436bb85a1483978103b0f236993d7ac1dc20ff + + [Daniel Chen] + + * sound/pci/hda/: Add quirk for Dell Dimension E520 (patch_sigmatel.c) + - GIT-SHA de4755b3b5e905194d9a9d06eb86a9200c28c864 + * sound/pci/hda/: Add missing mic boost mixer controls (patch_analog.c) + - GIT-SHA e882468a6dc91bd9235a548a011c25a43878b70b + * sound/pci/hda/: Add (un)muting for jack sense on Lenovo 3000 N100 + (patch_analog.c) + - GIT-SHA 7c726dbd0d2dd4237d9a4c9a64c41821956d8901 + * sound/pci/hda/: Add missing array terminators resulting in premature + optimisation (patch_conexant.c) + - GIT-SHA 5448559cd8ce389393697b28b6903c876f535c6b + * sound/pci/hda/: Add support for AD1986A Ultra model (patch_analog.c) + - GIT-SHA 0d95cfd2b39aed11eeb72d5fe3889b933bb362e0 + + [Fabio M. Di Nitto] + + * [OCFS2] Wrap access of directory allocations with ip_alloc_sem. + - GIT-SHA ba2f1bf8193c9e0b338f45714f102468c862cc4c + * [OCFS2] Properly lock extent map size changes. + - GIT-SHA a98ce36259ee1f83442f93845b830f6033dc90c8 + * [OCFS2] Local mounts should not truncate the extent map. + - GIT-SHA e87ad18113393107fc7d5a86e6bbd9b32dd44b6c + + [Matthew Garrett] + + * Add _GTM and _STM support to libata + - GIT-SHA 5d320f7915c4124ed56aeb619efbae7ff3beb9d2 + + [Tim Gardner] + + * [SATA ACPI] Fix some thinkos from + 36fe5af2bb79195923a08acc0ebd74a2dd90e0f7 + - GIT-SHA cbf8b6de0c9a84344e16847b03db5adcf0f0c855 + * Catch nonsense keycodes and silently ignore. + - GIT-SHA 560b0ff514b90e4c8bfbddbce3a54c218dc9ff85 + + [Upstream Kernel Changes] + + * Upstream sky2 driver updates + * [PS3] Storage cleanups, defconfig updates. + * [PS3] Fixes for SDK 2.0 toolchain. + * [PS3] Add spufs-avoid-accessing-to-released-inode.diff. + * [PS3] Add spufs-always-release-mapping-lock.diff, + spufs-fix-ctx-lifetimes.diff. + * [PS3] Storage bus dma updates. + * Add NOPFN_REFAULT result from vm_ops->nopfn() + * genirq: do not mask interrupts by default + * add vm_insert_pfn() + + [Zachary Amsden] + + * Urgent fix for VMI in HIGHMEM configurations + - GIT-SHA 72e461e0d638eb608c6ae07f7991e1063c5cbdeb + + -- Ben Collins Sun, 1 Apr 2007 13:03:28 -0400 + +linux-source-2.6.20 (2.6.20-13.21) feisty; urgency=low + + [Ben Collins] + + * debian/config: Enable CONFIG_DEBUG_FS. + - GIT-SHA a02719608695e5d59344600353d4872775a9ae3b + * rtl8187: Rename dir's from 818x to 8187. + - GIT-SHA ef3d971e78ca393bb1bcf3f46895849848010a7e + * rtl818x: Re-add old driver, fixing oops in old code as well. + - GIT-SHA d5d0ac60abafb7438f6736f9033208cac1572c82 + - Bug #78255 + * bluetooth: Update stack to latest code from bluez + - GIT-SHA 138bb4d3d2e65988cefcbd59b180b3788305f071 + - Bug #91194 + * rt2x00-legacy: Re-add rt2570 driver. + - GIT-SHA 43ab28f4b58f129611be5e784cd72ab2b5c46505 + * rt2500usb: Disable module alias when rt2570 is built. + - GIT-SHA ab16ae43815bcf9215965b87d4b05dbcc03e3574 + * mmc: Update to latest git supplied mmc core. + - GIT-SHA 5bf598b427d0ff75bef7186a75194b6b9102e224 + - Bug #93171 + * tifm: Update tifm core. + - GIT-SHA c25cfc3ad3cb8cac3474febfe66cff8ee0bfba18 + * lmpcm_usb: USB Logitech MediaPlay Cordless Mouse driver + - GIT-SHA c4291c4e7b6c2facfd65d3d9460fa667066d1e54 + - Bug #86035 + * drivers/media: Disable CONFIG_VIDEO_HELPER_CHIPS_AUTO to allow all + modules to be built. + - GIT-SHA 994e8c1e58d7b138880190796e6bd0ce3dcbd62a + * unusual_dev: Netac OnlyDisk Mini U2CV2 512MB USB 2.0 Flash Drive + - GIT-SHA ef90ffeabdca584d3539ae00ce746256d818a1a4 + - Bug #94371 + * speedstep-centrino: Include linux-phc built-in tables. + - GIT-SHA fc9f7238d11d5a9ff03ce67fae0b5b5c9fd7f436 + - Bug #63789 + * drivers/char/{agp/drm}: Resync with 2.6.21-rc4. + - GIT-SHA 1eae0b2972e215e9f13b99b7fb64b90db04cc556 + * ps3: Update ps3-storage and ps3fb drivers. + - GIT-SHA f2d4c3f34a613671bbcbc4696ccac6e7737b623a + * ps3: Updates for vuart, ps3av and sys-manager + - GIT-SHA b02d7d3f27d539713d6abba6e23db0b0f758d682 + * ide/generic: Remove errant jmicron entries. + - GIT-SHA d76099fde0ef127fa4f532c72bcd948caca7c2c1 + - Bug #84964 + * xpad: Update to latest version from xbox-linux. + - GIT-SHA 829dee658c6d3d09f049ca430a79997e5ba44838 + - Bug #94560 + * uvcvideo: Update to latest SVN version. + - GIT-SHA 7ca4b455c60b38ad53d03834fe03799ace81166d + - Bug #86754 + * ivtv: Update to 0.10.1 + - GIT-SHA b428794c3de387e2f701a768f98a302d3b4c98ea + - Bug #88680 + * ata_piix/piix: Prefer piix for device 7111 (PIIX4) + - GIT-SHA 9c7b34046bd9de870713e4630b06f95260d37973 + - Bug #94637 + * vboxdrv: Added VirtualBox kernel modules, v1.3.8 + - GIT-SHA 36b8eb8995ff04facae364706f6598fd6dce1cc4 + - Bug #81527 + * ata_piix/piix: Have piix handle device ID 0x24db + - GIT-SHA a083e4e48de3d5399788264259f42db157787603 + - Bug #95105 + + [Daniel T. Chen] + + * sound/pci/hda/: Simplify acer quirk (patch_realtek.c) + - GIT-SHA 1144a6d2628cb11286d8dc44a6f4fa0b740266ef + * sound/pci/hda/: Use proper constraints for HDA spec (hda_intel.c) + - GIT-SHA a51fa971bcf05e18dc9d315c36549126cc5b68ba + * sound/pci/hda/: Fix AZX models (hda_codec.c) + - GIT-SHA 1939127f3614de9f12dc4d42fb9c5b04081fbf0a + * sound/pci/hda/: Fix generic parser (hda_codec.c) + - GIT-SHA d0e1a1280e03111d26c63504451d3bf4378d668c + * sound/pci/hda/: Convert Sigmatel models to enums; differentiate between + Mac Pro revisions (patch_sigmatel.c) + - GIT-SHA e813cfe016a57c0155660f7c247b479bbeb9c8d8 + * sound/pci/hda/: Add _cfg_tbl[] quirk entries (patch_sigmatel.c) + - GIT-SHA 4a56b2a0ccadded72b1575c42db461f18fd2cc75 + * sound/pci/hda/: Fix front/rear mic inputs on AD1986A (patch_analog.c) + - GIT-SHA 50c1252587fc4df1f15248d2ceae8e87225f1283 + * sound/pci/hda/: Probe additional codec slots only if necessary + (hda_intel.c) + - GIT-SHA 81347c779c57515b0375650328cb4054a820a5d9 + + [Fabio M. Di Nitto] + + * Enable CONFIG_DEBUGFS=y + - GIT-SHA 52899638c7ab7e38dad47b884382bdb4e0814ea1 + + [Kyle McMartin] + + * Add Netac OnlyDisk Mini to unusual_devs.h + - GIT-SHA 999e79c3ffa906a970b717821b459724b9c2d939 + - Bug #94371 + + [Phillip Lougher] + + * fix NFS mounting regression from Edgy->Feisty + - GIT-SHA 1ad6cbd54fd2506a39f203cc6b4163d985f94cf0 + - Bug #94814 + + [Tejun Heo] + + * sd: implement stop_on_shutdown + - GIT-SHA 5fafa8d12092c5d722fc02e245b4977fd0765f68 + + [Upstream Kernel Changes] + + * fix process crash caused by randomisation and 64k pages + * HID: zeroing of bytes in output fields is bogus + * libata: don't whine if ->prereset() returns -ENOENT + * sata_sil24: Add Adaptec 1220SA PCI ID + * sata_inic162x: kill double region requests + * libata: kernel-doc fix + * pata_ixp4xx_cf: fix oops on detach + * pata_ixp4xx_cf: fix interrupt + * Execute AML Notify() requests on stack (Ubuntu Bug: 63123) + * Fix buffer overflow and races in capi debug functions + * [SPARC64]: store-init needs trailing membar. + * i2c: Declare more i2c_adapter parent devices + * ieee1394: cycle timer read extension for raw1394 + * ieee1394: fix another deadlock in nodemgr + * ia64: fix noncoherent DMA API so devres builds + + -- Ben Collins Sun, 18 Mar 2007 22:52:00 -0400 + +linux-source-2.6.20 (2.6.20-12.20) feisty; urgency=low + + [Upstream Kernel Changes] + + * pci_iomap_regions() error handling fix + - Fixes bug #93648 + + -- Ben Collins Wed, 21 Mar 2007 11:47:18 -0400 + +linux-source-2.6.20 (2.6.20-12.19) feisty; urgency=low + + [Ben Collins] + + * piix: Fix typo that allowed this module to override ata_piix. + - GIT-SHA 80bc1fd97d95519b2ab8c5007924f9e591838351 + - Bug #84964 + * vdso: Fix incompatibility between vdso and paravirt+vmi + - GIT-SHA 83821a009b3ec3f3d3ebaeda9a4f45900928900c + * drivers/ata/: Sync with upstream for new drivers and acpi fixes. + - GIT-SHA c38186b50b5d8444091a2f974e035abeb783499b + * debian/d-i/: Update sata/pata module listings. + - GIT-SHA e2c160419a8c50e9adc5de4b81e33251a7e952af + * rt2x00: Disable module aliases if legacy drivers are built. + - GIT-SHA a4e3d596f4b304e01ce04e43762ddf3873635a8c + * rt2x00-legacy: Re-add some legacy drivers since mainline isn't working + everywhere yet. + - GIT-SHA 59992a59a531f62aeb82384abc8296779092f1cc + * rt2x00-legacy/rt61: Fix big-endian compilation. + - GIT-SHA 6603c59fa3aee248aaf5ae73015ad155977ddad8 + * lib/iomap: Only build on architectures that need it. + - GIT-SHA fb3d5ca41505e11b8cd2cd85bc8db0571d58a6ae + * rt61: Fixup build on ppc. + - GIT-SHA 8c7eebfaf5c0ea44e7a77165894ebd3861ed3668 + + [Dan Hecht] + + * Feisty VMI paravirt-ops: Fix cpu hotplug on VMI + - GIT-SHA 44bbb009bb465537b9d7660a101641174f67b678 + + [Daniel T. Chen] + + * sound/pci/hda/: LP: #92909: Fix regression in -11.18 for Toshiba + Satellite M115 - S3094 (patch_realtek.c) + - GIT-SHA ff352c874a71fcce9af5f04d19360a0a8a4318b8 + * sound/pci/: LP: #90349: Add SSID for Dell Inspiron 9100 to headphone + quirk table (intel8x0.c) + - GIT-SHA 94ea2cdff6440a5bc8602cc8431380a690520f80 + + [Fabio M. Di Nitto] + + * Make scsi_proc_hostdir_add silent on failure + - GIT-SHA a6ad8ab034e40e188825cede360f69e8101351d3 + + [Upstream Kernel Changes] + + * Synced drivers/ata/ + * ACPI support for IDE devices + * ide-acpi support warning fix + * Disable NMI watchdog by default properly + * devres: device resource management + * sort the devres mess out + * Add pci class code for SATA & AHCI, and replace some magic numbers. + * PCI: allow multiple calls to pcim_pin_device() + * devres: release resources on device_del() + + -- Ben Collins Sat, 17 Mar 2007 11:15:27 -0400 + +linux-source-2.6.20 (2.6.20-11.18) feisty; urgency=low + + [Ben Collins] + + * mac80211/d80211: Switch from d80211 backport to mac80211 from + intellinuxwireless.org + - GIT-SHA 5be1800f366dd9be849c44d1f9a57f938ee04a54 + * adm8211/p54: Convert to use mac80211. + - GIT-SHA 91601e433a7e126260c65ed5ed219691e3ed2b9a + * rt2x00: Fixup Kconfig for mac80211 + - GIT-SHA 07feef3cb5e135d9479d86863ed857b3f89b7deb + * ac97: make patch_ad1986 global for use in other files. + - GIT-SHA f032849c2162da0a2939ebd6451c9bed8b496709 + * wireless: Fix Kconfig for wext-compat + - GIT-SHA fcd5dcb1753f14697319dba5b6ab570def81b9ea + * mac80211: Fixups for correct usage. + - GIT-SHA 22fa222a8a195ea11f3066bd72d426e7ada4b24f + * net/core/wireless.o: Disable in favor of mac80211. + - GIT-SHA 5ea988da86d00b6917d55c4aa6cdc2381e81b113 + * Makefile: Add mac80211 wireless directory to drivers-y. + - GIT-SHA 96aaf9171af0900733952db97b422f5bb0e0cb19 + * adm8211: Update from wireless-dev + - GIT-SHA 3222b8da95637eb5d96b6b092c101dfb70c10e36 + * p54: Update from wireless-dev + - GIT-SHA ee719880109e8d4c53097f7d3e7680e7e6b71087 + * rtl818x/rtl8187: Remove old broken drivers. + - GIT-SHA 7a8d4270ccc39bec2e66d6196ca50d1aa91bfcee + * rtl818x: Add 8180/8187 driver from wireless-dev + - GIT-SHA d3de93c8319a0dfe58e37eb7c27371f2f2d52456 + * eeprom_93cx6: Taken from wireless-dev for rtl818x driver. + - GIT-SHA 2199d23aed53519d2814c6547e47bae72180212f + * rt2x00: Remove legacy and update to mac80211 (wireless-dev) code. + - GIT-SHA 3bc9d8de616716014f0db7de5d36be0587fdea6b + * bxm43xx: Add mac80211 variant of driver (sans module aliases). + - GIT-SHA 883ff4b3fcabad5271995327d9f26512bda33687 + * zd1211rw: Add mac80211 variant of driver (sans module aliases). + - GIT-SHA dde6813b66f1f31c766fcbbdcc20fb43cadd0be4 + * ssb: Update from wireless-dev for bcm43xx usage. + - GIT-SHA 3b86466916f303503d8052b41b720d12fd82d4dd + * kvm: Update to kvm-16. + - GIT-SHA d0388ee0c445d54fef0be4da7f283069c82df80d + * ubuntu/: Fixup some dma-mapping.h includes needed. + - GIT-SHA 3f3f237e8f9c9f986c464abc9ac75d7c4d3ae119 + * d-i: Update nic module listings. + - GIT-SHA f442d4e826548d027373b28562529fa5489105a2 + * prism54_softmac: Remove ancient prism54 code in favor of p54. + - GIT-SHA d924ddb5eb75f16473f7703d17e347dc350d0d4a + * vdso: Fix incompatibility between vdso and paravirt+vmi + - GIT-SHA 77b43e78df1c73c0a8f1333fa9bc440201bf3094 + * bluetooth: SCO flow control patch from bluez website. Fixes BTSCO. + - GIT-SHA a3e22dab227fcdc2778f19c462476bf3c6186938 + * btsco: Update to Revision 1.16 from CVS. + - GIT-SHA edc8305ea5d3b4056369c24c09b12a23b3d0857e + * d-i: Build udebs for ps3. + - GIT-SHA 1255b98db417c2ec0465ed73045b9101c244283c + * quickcam: Add 0.6.6 driver (from qc-usb package). + - GIT-SHA 6cfdbcfc6427769567a0b4bb593751c089f3d852 + * ubuntu/: Rework Makefiles for proper -y/-m recursion. + - GIT-SHA 84440f2f67b8cc89e11aeb5e6ccc4f38fd9f91d4 + * Makefile: Move ubuntu/ to just drivers-y. + - GIT-SHA d8b88338578e9fded8380d94e71d8292ac0eee7d + * ubuntu/: Add ubuntu/net/wireless/ to obj-y for CONFIG_WIRELESS_EXT. + - GIT-SHA 3c4dc7409d831ec9ff68ee7f8624ee6f0714eb34 + * Release 2.6.20-11.18 + - GIT-SHA 94830a5986ed94c5d6402827553bf6b5319a7e32 + * debian/d-i/: Allow per-flavour udeb module listings. + - GIT-SHA 6a2a10a8d622cc80d4a1668ce6fc095c84dceb7e + * ubuntu/: Remove crufty file. + - GIT-SHA 420dd6113f06f136ec745ff0f88776b210c971bf + + [Dan Hecht] + + * Feisty VMI paravirt-ops: fix prototype pragma to match definition + - GIT-SHA 0ebf6936c9e9dc252c7257da8efe471582c36f73 + + [Daniel T. Chen] + + * sound/pci/hda/: (Many) Bug fixes; add Macbook/Pro, Fujitsu, and Lenovo + 3000 C200 support (patch_realtek.c) + - GIT-SHA 21621559de65fb1b336fac148b98637db9b8876e + * sound/pci/: Fix muted speaker on resume from suspend-to-RAM + (intel8x0.c) + - GIT-SHA c73679b8f2fdec4083612671afcf72fe26681b4c + * sound/pci/ac97/: Backport AD1xxx AC'97 fixes (ac97_{codec,patch}.c) + - GIT-SHA b86ead0f620209dcd96c30decc8362ebe2ed5bff + * sound/pci/ac97/: Add MSI L720 laptop to quirk list (ac97_patch.c) + - GIT-SHA 252b8b19279355f1bf4f90b14269a936c3e26322 + * sound/pci/hda/: Add support for Fujitsu EAPD model (patch_conexant.c) + - GIT-SHA 94e796e42ba693e81a0e6497d9477cdbb742ce4c + * sound/pci/hda/: LP #74677: Add models to HDA AD codec (patch_analog.c) + - GIT-SHA 85e78cc0ca76490eec7d956998afe309bc1e4024 + * sound/pci/hda/: Fix codec initialization on ATI HDA chips (hda_intel.c) + - GIT-SHA aa53cf8aff62b05396b1a98e37bbf401e8fb2aa0 + * sound/pci/hda/: Fix speaker output on MacPro (patch_sigmatel.c) + - GIT-SHA 5e06d854c5fe5cdc3692ec067355411725a3ac9e + * include/sound/: Add missing struct member (ac97_codec.h) + - GIT-SHA 658cfb791c276d372433f4ee3b57c8bef99a986d + * sound/pci/: LP: #88080: Fix Oops triggered from interrupt handler + (intel8x0.c) + - GIT-SHA 8376f4bfd0af249c8ab0c9c788184147db07984f + * sound/pci/hda/: Add SSID for HP d5700 to ALC260 quirk table + (patch_realtek.c) + - GIT-SHA f57799abf88ad79fdab977ce40b118d900f8ffc7 + + [David Miller] + + * Fix mach64 with gcc-4.1 and later... + - GIT-SHA 11057e22f19a953916315bbbf2889d6293d31177 + + [Fabio M. Di Nitto] + + * debian/firmware: Update ql2400 file. + - GIT-SHA 40a42fab6f35773ee0dd0a58083897771fd07468 + * Disable CONFIG_IP_ROUTE_MULTIPATH_CACHED for real. + - GIT-SHA 7b7dc1f9197a0d8347517362aad8003882812949 + * Readd gnbd driver + - GIT-SHA de6fffe4180e18f64648d82697d3ca79e180da75 + + [Kyle McMartin] + + * acpi/hotkey: Add loglevel to "Using ... hotkey" printk + - GIT-SHA 398c3db849ca235addc3bc16b8c683f180518661 + + [Upstream Kernel Changes] + + * ocfs2: ocfs2_link() journal credits update + * ocfs2_dlm: fix cluster-wide refcounting of lock resources + * fs/ocfs2/dlm/: make functions static + * ocfs2_dlm: Fixes race between migrate and dirty + * ocfs2_dlm: Make dlmunlock() wait for migration to complete + * ocfs2_dlm: Fix migrate lockres handler queue scanning + * ocfs2_dlm: Flush dlm workqueue before starting to migrate + * ocfs2_dlm: Drop inflight refmap even if no locks found on the lockres + * ocfs2_dlm: Dlm dispatch was stopping too early + * ocfs2_dlm: wake up sleepers on the lockres waitqueue + * ocfs2_dlm: Silence a failed convert + * ocfs2_dlm: Cookies in locks not being printed correctly in error + messages + * ocfs2: Added post handler callable function in o2net message handler + * ocfs2_dlm: Calling post handler function in assert master handler + * ocfs2: Binds listener to the configured ip address + * ocfs2_dlm: Ensure correct ordering of set/clear refmap bit on lockres + * ocfs2_dlm: disallow a domain join if node maps mismatch + * ocfs2_dlm: Silence some messages during join domain + * ocfs2_dlm: Add timeout to dlm join domain + * ocfs2: ocfs2_link() journal credits update + * x86_64: fix 2.6.18 regression - PTRACE_OLDSETOPTIONS should be accepted + * rtc-pcf8563: detect polarity of century bit automatically + * prism54: correct assignment of DOT1XENABLE in WE-19 codepaths + * pata_amd: fix an obvious bug in cable detection + * knfsd: Fix a race in closing NFSd connections. + * Keys: Fix key serial number collision handling + * ide: fix drive side 80c cable check + * bcm43xx: Fix for oops on resume + * bcm43xx: Fix for oops on ampdu status + * AGP: intel-agp bugfix + * Missing critical phys_to_virt in lib/swiotlb.c + * USB: fix concurrent buffer access in the hub driver + * usbaudio - Fix Oops with broken usb descriptors + * usbaudio - Fix Oops with unconventional sample rates + * hda-intel - Don't try to probe invalid codecs + * Fix various bugs with aligned reads in RAID5. + * Fix ATM initcall ordering. + * Fix TCP FIN handling + * Fix allocation failure handling in multicast + * md: Avoid possible BUG_ON in md bitmap handling. + * Fix compile error for e500 core based processors + * ieee1394: video1394: DMA fix + * ieee1394: fix host device registering when nodemgr disabled + * Fix null pointer dereference in appledisplay driver + * USB HID: Fix USB vendor and product IDs endianness for USB HID devices + * Kconfig: FAULT_INJECTION can be selected only if LOCKDEP is enabled. + * MTD: Fatal regression in drivers/mtd/redboot.c in 2.6.20 + * IPV6: HASHTABLES: Use appropriate seed for caluculating ehash index. + * EHCI: turn off remote wakeup during shutdown + * Avoid using nfsd process pools on SMP machines. + * Fix recently introduced problem with shutting down a busy NFS server. + * UHCI: fix port resume problem + * Fix atmarp.h for userspace + * Clear TCP segmentation offload state in ipt_REJECT + * Fix IPX module unload + * Prevent pseudo garbage in SYN's advertized window + * Fix oops in xfrm_audit_log() + * sky2: dont flush good pause frames + * sky2: transmit timeout deadlock + * x86_64: Fix wrong gcc check in bitops.h + * x86: Don't require the vDSO for handling a.out signals + * i386: Fix broken CONFIG_COMPAT_VDSO on i386 + * bcm43xx: fix for 4309 + * md: Fix raid10 recovery problem. + * dvbdev: fix illegal re-usage of fileoperations struct + * V4L: pvrusb2: Fix video corruption on stream start + * V4L: pvrusb2: Handle larger cx2341x firmware images + * DVB: cxusb: fix firmware patch for big endian systems + * DVB: digitv: open nxt6000 i2c_gate for TDED4 tuner handling + * V4L: fix cx25840 firmware loading + * V4L: cx88-blackbird: allow usage of 376836 and 262144 sized firmware + images + * Fix posix-cpu-timer breakage caused by stale p->last_ran value + * swsusp: Fix possible oops in userland interface + * sata_sil: ignore and clear spurious IRQs while executing commands by + polling + * fix umask when noACL kernel meets extN tuned for ACLs + * UML - Fix 2.6.20 hang + * mmc: Power quirk for ENE controllers + * bcm43xx: Fix assertion failures in interrupt handler + * libata: add missing PM callbacks + * libata: add missing CONFIG_PM in LLDs + * POWERPC: Fix performance monitor exception + * HID: fix possible double-free on error path in hid parser + * Fix interrupt probing on E450 sparc64 systems + * Fix xfrm_add_sa_expire() return value + * Fix skb data reallocation handling in IPSEC + * Fix %100 cpu spinning on sparc64 + * Fix TCP MD5 locking. + * Don't add anycast reference to device multiple times + * Fix anycast procfs device leak + * Fix reference counting (memory leak) problem in __nfulnl_send() and + callers related to packet queueing. + * export blk_recount_segments + * forcedeth: disable msix + * tty_io: fix race in master pty close/slave pty close path + * sched: fix SMT scheduler bug + * USB: usbnet driver bugfix + * RPM: fix double free in portmapper code + * NLM: Fix double free in __nlm_async_call + * kexec: Fix CONFIG_SMP=n compilation V2 (ia64) + * Fix MTRR compat ioctl + * ufs: restore back support of openstep + * v9fs_vfs_mkdir(): fix a double free + * enable mouse button 2+3 emulation for x86 macs + * hugetlb: preserve hugetlb pte dirty state + * m32r: build fix for processors without ISA_DSP_LEVEL2 + * kernel/time/clocksource.c needs struct task_struct on m68k + * buffer: memorder fix + * Char: specialix, isr have 2 params + * lockdep: forward declare struct task_struct + * kvm: Fix asm constraint for lldt instruction + * ueagle-atm.c needs sched.h + * fix section mismatch warning in lockdep + * throttle_vm_writeout(): don't loop on GFP_NOFS and GFP_NOIO allocations + * revert "drivers/net/tulip/dmfe: support basic carrier detection" + * video/aty/mach64_ct.c: fix bogus delay loop + * pktcdvd: Correctly set cmd_len field in pkt_generic_packet + * ATA: convert GSI to irq on ia64 + * gfs2: fix locking mistake + * TCP: Fix minisock tcp_create_openreq_child() typo. + * Fix buffer overflow in Omnikey CardMan 4040 driver (CVE-2007-0005) + * x86-64: survive having no irq mapping for a vector + * IPV6: Handle np->opt being NULL in ipv6_getsockopt_sticky() + [CVE-2007-1000] + * Linux 2.6.20.2 + * conntrack: fix {nf, ip}_ct_iterate_cleanup endless loops + * nf_conntrack/nf_nat: fix incorrect config ifdefs + * tcp conntrack: accept SYN|URG as valid + * nfnetlink_log: fix reference leak + * nfnetlink_log: fix use after free + * nfnetlink_log: fix NULL pointer dereference + * nfnetlink_log: fix possible NULL pointer dereference + * ip6_route_me_harder should take into account mark + * nf_conntrack: fix incorrect classification of IPv6 fragments as + ESTABLISHED + * nfnetlink_log: zero-terminate prefix + * nfnetlink_log: fix crash on bridged packet + * Fix bug 7994 sleeping function called from invalid context + * bcm43xx: Fix problem with >1 GB RAM + * Fix compat_getsockopt + * fix for bugzilla #7544 (keyspan USB-to-serial converter) + * Fix callback bug in connector + * Fix sparc64 device register probing + * Fix timewait jiffies + * Fix UDP header pointer after pskb_trim_rcsum() + * Linux 2.6.20.3 + + -- Ben Collins Wed, 14 Mar 2007 13:24:01 -0400 + +linux-source-2.6.20 (2.6.20-10.17) feisty; urgency=low + + [Ben Collins] + + * powerpc: Fix build failure caused by include ordering. + - GIT-SHA ae1f75e4b3e0a5645c5c2e0ace4d98a5c41663bf + * ps3: Update to latest code in linux-ps3.git + - GIT-SHA 87402da9dab94849527c685f09b3aef61b8ccc32 + * i386: Allow VDSO + PARAVIRT + - GIT-SHA a3718cc571410e202382daca05e809fbeb7ffe41 + * acpi: DSDT from initramfs patch + - GIT-SHA 7b650b00d82ec5c80452b2f99de1cfdbae2a465b + * ps3: Use what kexec passed to us. + - GIT-SHA 7711acb4b58f1313830940008ccc03275265c705 + * ps3: Do not call early_init_dt_scan_memory() on PS3 (we use lv1 + routines) + - GIT-SHA daf88d0260215ce90b293c52c65adc819e4a8f65 + * gelic_net: Allocate gelic_irq_status with card struct. + - GIT-SHA a85fc7b805b0b16f4bd97fa707affd71b3a672d9 + * ps3: Disable debug messages. + - GIT-SHA 84fd42468c726cffaafd58df6019e5278c111ef5 + * ps3: Export a few repository symbols (GPL) for storage driver as + module. + - GIT-SHA 26b5fe72a4dfc4fc3293f4020add9b55fde73e67 + * kvm: Update to kvm-15 + - GIT-SHA addefaae3b6bbd33e0ccf804e01a2afc102ee0d5 + * ndiswrapper: Update to v1.38 + - GIT-SHA d45dc1f185baa28a04551acd7d96ad1102633f7a + * ipw3945: Add max timeout_spin for thermal. Avoids softlock up. + - GIT-SHA 5d6caa9edbffa13973a6f9bbbdf47473ac18dc16 + * configs: Enable PM_TRACE on x86_64. + - GIT-SHA 8bb67c60933e524f06133796fb8c60bf0c68fb0e + * tifm_7xx1: include linux/dma-mapping.h (ftbfs on sparc) + - GIT-SHA a44e76a014641330f064062eb86d1e1dce79a57e + * pci: Add empty decleration for pci_yes_msi() on non-msi architectures + - GIT-SHA 96d5fb49720b2ae60406394ca29e96ce0919d83d + + [Dan Hecht] + + * Feisty VMI paravirt-ops: fix vmi timer interrupt handler nested + xtime_lock + - GIT-SHA 3187b0e329245f3667b399dd4a0e8a687f44bce5 + * Feisty VMI paravirt-ops: fix no_timer_check compile fix + - GIT-SHA adec0fc22dcc9039a22f47dfa009d0d76ba37c14 + * Feisty VMI paravirt-ops: unconditionally enable disable_nodelay + - GIT-SHA 1aace0a61ee4e2f5d465f7667445d76ac944538e + + [Daniel T. Chen] + + * sound/pci/{ali5451,ca0106,echoaudio,riptide,rme9652}/: Add missing + sysfs device assignment for ALSA PCI drivers + ({ali5451,ca0106_main,echoaudio,riptide,hdspm}.c) + - GIT-SHA 7324806accd810818a7b66ba17f6ff5923743b2f + * sound/pci/hda/: Add SSID for LG LW40 Express (patch_realtek.c) + - GIT-SHA c3979792b7026ae9f43c5147e9617cf701af054b + * sound/pci/hda/: LP #88452: Fix headphone jack sense regression in + 2.6.20-9.16 on 504[57] (patch_conexant.c) + - GIT-SHA 5bb5522b65050a448245acdb42a63a590c385921 + + [Kyle McMartin] + + * drivers/ata: Enable libata Host Protected Area support + - GIT-SHA a0e61542121a0519bfbe9f6e43980ec96a16156e + * Disable MSI by default + - GIT-SHA dc205519fa6c5e487e9829090145d3eb3e73b496 + * Disable MMCONFIG by default + - GIT-SHA d613cff3d5968d3e93bad197480b90733c71b984 + * Update nozomi driver + - GIT-SHA ece7562eae20233c9ebca8677104f4f99680ab71 + * Add eeprom_bad_csum_allow option to e1000 + - GIT-SHA 4f26a22422aaf987a34b76451383cb243088498c + * Enable TCP_MD5SIG + - GIT-SHA 8afc57f2791aebc0a1180749438c7c84f0e812d0 + * UBUNTU:usb/serial: New device IDs for cp2101 driver + - GIT-SHA cdbb30cb9a1667a84f759b10b1fe714bcedf4084 + * Disable CONFIG_IP_ROUTE_MULTIPATH_CACHED + - GIT-SHA 14dfd17d483d8466faf3605cf931c5f2fc7eac63 + - Bug ##90597 + * Disable CONFIG_ACPI_DEBUG + - GIT-SHA 57516b6c60cdb5b97caed872a638d8efbd8e524e + + [Matthew Garrett] + + * Allow appletouch to bind to Apple touchpads + - GIT-SHA 5bb33520e67b89386880d3a218ecfde550848b5b + * add module_device_table entry for applesmc in order to have it + autoloaded + - GIT-SHA 524e8b89b619f19b70dd38e45fa9a59ff30a82c3 + + [Phillip Lougher] + + * Backport NFS branch oops fix from Unionfs 2.0 + - GIT-SHA feea4eb6e27ac04bbc34a525a6599a79204e81f0 + - Bug #85145 + * Backport unionfs_statfs() from Unionfs 2.0 + - GIT-SHA a47c7c9186612ad5f59bcca95bd5fac5cb01b287 + - Bug #90088 + * i2c-matroxfb: add code to correctly set .class field + - GIT-SHA 82e00f0e073de4849f6cd6ee8b361c28f952ca8d + - Bug #80608 + * i2c-matroxfb: fix typo in patch + - GIT-SHA 85294b26c526ce28c2e513b04293561fe2c8d5f4 + - Bug #80608 + * TI FlashMedia xx12/xx21 driver update to 0.8 release (20070222) + - GIT-SHA a3e42adedcd3c2f3364e6b620e12b14c68c7a149 + - Bug #82680 + + [Upstream Kernel Changes] + + * [PARISC] Delete arch/parisc/mm/kmap.c again + * [PARISC] Show more memory information and memory layout at bootup + * [PARISC] Unbreak discontigmem mem_init() + * [PARISC] Fix ccio_request_resource when CONFIG_IOMMU_CCIO is not + defined + * [PARISC] HPPB bus updates for E-Class systems + * [PARISC] [MUX] Mux driver bug fix + * [PARISC] [MUX] Mux driver updates + * [PARISC] [MUX] Claim resources for the Mux driver + * [PARISC] [MUX] Make the Serial Mux driver work as module + * [PARISC] [MUX] Detect multiple cards in the correct order + * [PARISC] [MUX] Correctly report the number of available ports + * [PARISC] [MUX] Get the hversion directly from the parisc_device + * [PARISC] parisc-agp: Fix integer/pointer warning + * [PARISC] sparse fixes + * [PARISC] more sparse fixes + * [PARISC] Reserve 1GB of space for vmalloc/tmpalias space on parisc64 + * [PARISC] Fix PCI bus numbering in the presence of Cardbus bridges + * [PARISC] avoid compiler warnings when compiling 64bit + * [PARISC] bloody printf fmt string warnings + * [TRIVIAL] [PARISC] Fix module.c printk message, add missing ')' + * [PARISC] lasi_82596: use BUILD_BUG_ON() and constify static array + * [PARISC] Make Lasi Ethernet depend on GSC only + * [PARISC] Remove GCC_VERSION usage as suggested by Adrian Bunk + * [PARISC] pdcpat remove extra brackets + * [PARISC] Remove duplicate PDC_PAT_CELL defines + * WorkStruct: Fix up some PA-RISC work items + * [PARISC] Move spinlock_t out of struct cpu_data + * [PARISC] Fix thinko in cpu_data.lock removal + * parisc: fix module_param iommu permission + * PA-RISC: Fix bogus warnings from modpost + * use __u64 rather than u64 in parisc statfs structs + * [PARISC] Optimize TLB flush on SMP systems + * [PARISC] Clean up the cache and tlb headers + * [PARISC] Only write to memory in test_and_set_bit/test_and_clear_bit if + we're + * [PARISC] "Fix" circular includes + * [PARISC] Add prototypes for flush_user_dcache_range and + flush_user_icache_range + * [PARISC] Remove sched.h from uaccess.h on parisc + * [PARISC] Fix show_stack() when we can't kmalloc + * [PARISC] Generic BUG + * [PARISC] fix build for WARN_ON() when CONFIG_DEBUG_BUGVERBOSE=y + * [PARISC] whitespace cleanups and unify 32/64bit user-access assembler + inlines + * [PARISC] fix fixup declarations for 32bit and use CONFIG_64BIT + * [PARISC] dump stack backtrace on BUG() and add syslog-levels to + printk()s + * [PARISC] add missing syscalls for vmsplice, move_pages, getcpu & + epoll_pwait + * [PARISC] lba_pci format warnings + * [PARISC] Use fstatat64 instead of newfstatat syscall + * [PARISC] use fls_long in irq.c + * [PARISC] a and b in "break a,b" message were swapped + * [PARISC] GENERIC_TIME patchset for parisc + * [PARISC] disable cr16 clocksource when multiple CPUs are online + * [PARISC] Convert soft power switch driver to kthread + * [PARISC] detect recursive kernel crash earlier + * [PARISC] Add TIF_RESTORE_SIGMASK support + * [PARISC] use less assembler statements in syscall path + * [PARISC] display parisc device modalias in sysfs + * [PARISC] move parisc_device_id definition to mod_devicetable.h + * [PARISC] generate modalias for parisc_device_id tables + * [PARISC] rename *_ANY_ID to PA_*_ANY_ID in the exported header + * [PARISC] factor syscall_restart code out of do_signal + * [PARISC] clean up debugging printks in smp.c + * [PARISC] kill ENTRY_SYS_CPUS + * [PARISC] implement standard ENTRY(), END() and ENDPROC() + * [PARISC] Fixes /proc/cpuinfo cache output on B160L + * [PARISC] fix ENTRY() and ENDPROC() for 64bit-parisc + * [PARISC] more ENTRY(), ENDPROC(), END() conversions + * [PARISC] add ASM_EXCEPTIONTABLE_ENTRY() macro + * [PARISC] use CONFIG_64BIT instead of __LP64__ + * [PARISC] convert to use CONFIG_64BIT instead of __LP64__ + * [PARISC] add ENTRY()/ENDPROC() and simplify assembly of HP/UX emulation + code + * [PARISC] do not export get_register/set_register + * [PARISC] fix section mismatch warnings in harmony sound driver + * [PARISC] Reorder syscalls to match unistd.h + * Fix a free-wrong-pointer bug in nfs/acl server (CVE-2007-0772) + * Linux 2.6.20.1 + * [PARISC] Add missing statfs64 and fstatfs64 syscalls + * [PARISC] Use symbolic last syscall in __NR_Linux_syscalls + * add vm_insert_pfn() + * Add NOPFN_REFAULT result from vm_ops->nopfn() + * [SPARC64]: Fix PCI interrupts on E450 et al. + * sata_sil: ignore and clear spurious IRQs while executing commands by + polling + + -- Ben Collins Sun, 11 Mar 2007 06:23:55 -0400 + +linux-source-2.6.20 (2.6.20-9.16) feisty; urgency=low + + == Re-upload for build failures == + + [Ben Collins] + + * d80211/dadwifi: Get rid of this, causes dumb failures + - GIT-SHA fe8556a197d3f3f01e2e71785b3eff55f9a98a0f + * powerpc: ifdef use of spu logo function + - GIT-SHA 8cf5e8f8e79e53b5d13038326a50f94c81bb01e8 + * ssb: Include dma-mapping.h + - GIT-SHA 7fbf0dd183ffbfcd01efebe4bd90172a4346190d + + == 2.6.20-9.15 == + + [Ben Collins] + + * sata_sis: Sync with upstream v0.7 + - GIT-SHA 54db2f91cd5a9115faf2a1142c3788665d4c08de + * d-i: Make storage-core-modules provide loop-modules + - GIT-SHA e9a5522297506bb285ef4c0c803a64fb289abe72 + * pm_trace: Fixup for non-pm architectures (compile failure) + - GIT-SHA 08cfd02cd6fab74af88fda7127d7ab5249a4606c + * ps3: Pull patches from linux-ps3.git HEAD. + - GIT-SHA 05383a8254692b547ae676b59b45d66f19229a27 + * ps3av: Allow native HDMI modes for boot case. + - GIT-SHA 641ab76ed883342c2a19df4c33ac17d795d2f5ca + * bcm43xx-dscape: Remove module_dev_table to avoid autoloading + - GIT-SHA 2082dec4a8ee18cf694a1f26bb136280c1053911 + * bcm43xx: Re-enable stock bcm43xx driver. + - GIT-SHA e5375f74acdad5cd54b7a1c96bd7aff6056941a6 + * bcm43xx-dscape: Actually rename this module to bcm43xx-dscape. + - GIT-SHA 7f8dabc63ea45b2ae0c411073b9044dc0904ea14 + * bcm43xx: Patch for DMA over 1G. + - GIT-SHA 032a9bb14008b8ab88e1e22ee956650de7532c6a + * bcm43xx: Patch to detect radio enable/disable. + - GIT-SHA 95824fb76a8b2ede3156f46c7be19dcf7656e75e + * bcm43xx: Fix bcm4309, patch from upstream -stable. + - GIT-SHA e9b2f2ef91b51796aec064f95f5a816b60498af0 + * namespace: AppArmor patches to export symbols as needed. + - GIT-SHA 9a364aef1f798c16648ef8611eedc675c6c522e8 + * gspcav1: SPCA Driver, for v4l1 + - GIT-SHA f5d420265ac21729cf4ba0d342b370066a2ac7a2 + * ubuntu/: Update kbuild for gspcav1 + - GIT-SHA 814e37d1e7f4ead8a8ca9bf1a238078489ebf0c0 + * iwlwifi: Update to v0.0.8 + - GIT-SHA 968a3b550a7640b4a508e784bb095af8d761d731 + * debian/firmware: Add iwlwifi ucode + - GIT-SHA 76a733559ffdb665a5c5b092c6d7921e9dca38d7 + * ubuntu/ssb: Set better defaults in Kconfig for Ubuntu setups + - GIT-SHA d0c669fe2ebaed94f9837eca9cc3646cca014057 + * bcm43xx-d80211: Disable MODULE_DEVICE_TABLE so it isn't auto-loaded + - GIT-SHA 65c348e7886894076b7610ab3df9162c4d1dfe73 + * fs/exec: Always set max rlim for piped core. + - GIT-SHA 1e0f4a95ab56cadb1e37fb36ee1bc51f7697e062 + - Bug #87065 + * Allow mac mouse emul to be compiled on non-ppc + - GIT-SHA 5ceb16c6c1ebe24463a05328b3b72eea88c21ef8 + - Bug #81421 + * drivers/ide/: Check for pata modules enabled as modules too. + - GIT-SHA 3abf25603e6c855027ea11f9420ae7bddc3f02aa + * i386/pci: Quieten some messages. + - GIT-SHA 8897331220c73b367ad0ab4756f7b0f6cbb51c85 + - Bug #54294 + + [Daniel T. Chen] + + * sound/pci/hda/: Add support for Medion and Toshiba models + (patch_realtek.c) + - GIT-SHA d0c374e410e02bbe608b1eb05ea830326305b25f + * sound/pci/hda/: Add support for more ALC262, ALC883 and ALC660 models + (patch_realtek.c) + - GIT-SHA dab0d409a6253e89769f230190c852f8326f7fcb + * sound/pci/hda/: Add support for Asus models (patch_realtek.c) + - GIT-SHA f281cbd170b929b0b92cabefdfd4ba43616172b0 + * sound/pci/hda/: Add laptop-eapd model for Clevo M540JE, M550JE laptops + (Nvidia MCP51 chipset, ALC883 codec) (patch_realtek.c) + - GIT-SHA b37d077f39d082a5622c70d34be9247691f4cc99 + * sound/pci/hda/: More Conexant HDA fixes (patch_conexant.c) + - GIT-SHA b55060489d99586e5aff8000e74a1f1f195dd20d + * sound/pci/hda/: Add Dell models to STAC_REF and fix probe OOPS + (patch_sigmatel.c) + - GIT-SHA 25107d232a38e525b0a89884315d18eb495c1575 + * sound/pci/ac97/: Fix silent output with Conexant Cx20551 codec + (ac97_codec.c, ac97_patch.c, ac97_patch.h) + - GIT-SHA 1b3afda1c3af46ea96e9c5a3992a7ca83716a6a8 + * sound/pci/hda/: (Re)Add support for Macmini/Macbook/Macbook Pro + (patch_sigmatel.c) + - GIT-SHA 2fadead62fc6222b10799bd8cb134cfb6a79171f + + [Fabio M. Di Nitto] + + * ubuntu/fs/gfs: full update for 2.6.20 as of CVS20070216 + - GIT-SHA a81d2cf71db54eadcae6e213c625287236942eb9 + + [Kyle McMartin] + + * debian/firmware: Add aic94xx firmware + - GIT-SHA 6b0cc3fd1e98f3d1ba4bff6e26af4c94e206257c + * debian/d-i/firmware: Add scsi-firmware + - GIT-SHA 14d79cfe7725796e200c1dd20d92e8d58ba4b9b6 + * debian/: regen control{,.stub} + - GIT-SHA 60e2542a78f55537f6eb5757da0c7b925d3fe9b8 + + [Matthew Garrett] + + * Avoid the hid driver binding the Apple IR controller + - GIT-SHA 482271127ff1e7e3b321867648ea6cb199f6ecf6 + * Add PM_TRACE support for x86_64 + - GIT-SHA c63e3d917a84214a98c81ae497bcd4a72ead62ed + + [Phillip Lougher] + + * r8169: disable TSO by default for RTL8111/8168B chipsets. + - GIT-SHA 0cc30725f64a07cc4084d9e6d1637de405315815 + - Bug #76489 + * r8087: Fix bug in workqueue changes for 2.6.20 + - GIT-SHA 07e3458bdf5ba97519a58e089841ccb185ede7d2 + + [Upstream Kernel Changes] + + * Updated d80211 bcm43xx + * Add ssb support + * Update adm8211 drivers + * Update p54 driver + * Fix config symbol names + * Really fix config symbol names + * Add iwlwifi + * Fix the iwlwifi build + * Make SSB busses children of their parent device + * Add dadwifi (doesn't really work yet, but builds) + + -- Ben Collins Mon, 12 Feb 2007 20:22:14 -0500 + +linux-source-2.6.20 (2.6.20-8.14) feisty; urgency=low + + [Ben Collins] + + * acx: Add wlan_compat bits for ia64 + - GIT-SHA 4f29d1a99f1f8b096aaec9dc7df81cce54aa72b3 + * power: Disable the "Adding/Removing info for" printk's + - GIT-SHA daff39bf329d2522663343d6835f15eb17c0068d + * i82365: Probe before adding platform dev. + - GIT-SHA 06fd3fa13e3b336fcea01c326f3af314e5f37688 + * fs/exec: Fix call_usermodehelper_pipe() to allow waiting for exit + - GIT-SHA bfefaf3d2bd72a193bf5809639180a94ddc032ff + + [Upstream Kernel Changes] + + * sata_promise: TX2plus PATA support + * sata_promise: ATAPI support + * sata_promise: ATAPI cleanup + * sata_promise: issue ATAPI commands as normal packets + * sata_promise: handle ATAPI_NODATA ourselves + + -- Ben Collins Fri, 09 Feb 2007 10:24:58 -0500 + +linux-source-2.6.20 (2.6.20-7.13) feisty; urgency=low + + [Ben Collins - 7.13] + + * adm8211: Include dma-mapping.h for DMA_* constants. + - GIT-SHA d2ef9310ac1482f9230c89161260d74a86b1c9f1 + * p54: Include dma-mapping.h + - GIT-SHA d53668d200221d86b0889706e6560f0579246adc + * ubuntu/: Remove extraneous rt2x00 subdir from d80211 Makefile. + - GIT-SHA 2e9e9411c163478a7ba4aa389fcea2f553045a78 + + [Ben Collins] + + * drivers/core: Add sysfs attr to disable auto binding of drivers/devices + - GIT-SHA 22e8edadfe0141ea0e9f4b3c9626c3f97bf76c93 + * Disable prism2_cs in favor of orinoco/hostap modules. + - GIT-SHA 30cde452a15d9d1f27d20ea95d5fdba319ccd252 + * Update tifm core to latest version. + - GIT-SHA 6e2e96b61fea2d370777af7affe0008a7a7769b4 + * tifm: Update sd driver to latest version. + - GIT-SHA 8b69d97c3415de445ac7f9feff6152f130d001bc + * tifm_memstick: New driver. + - GIT-SHA d4d68aec79a4cb26d49893b0e98212e98549e806 + * netdev header: Add ieee80211 pointer for d80211. + - GIT-SHA 9d5f35c65ae15e6205221dd259a472edcb697812 + * ubuntu/net: Add SSB driver. + - GIT-SHA 4a4e7f2b0d1c71bbf7bb98a3c7981cae1e963d75 + * d80211: Add devicescape 802.11 stack. + - GIT-SHA 4d0fb64df98a9e21644525615df34ab2056eb569 + * p54: d80211 version of prism54 drivers + - GIT-SHA 140c080a78cde3f2a96e55da9ca2b25e44682b3c + * adm8211: d80211 version of this driver. + - GIT-SHA bfb106b04449dc080024eb7dd9e8dd486bcd6d7c + * rt2x00: Use in-tree d80211 now. + - GIT-SHA ffd2b8634285fe51f7a1dbe941a3d3de9682959d + * bcm43xx: d80211 version of this driver. + - GIT-SHA 1c965fad34ead0323464b2fc2f154b769e23d0fa + * ubuntu/wireless: Kbuild mechanisms for d80211 drivers. + - GIT-SHA fa6f353d01467a991d32dfecab5a8d0a97a0ab15 + * ubuntu/net: Add proper obj-* for d80211. + - GIT-SHA 1c197c4b327899fa52334b876f0481e466b5ca33 + * Compile fixes for d80211 drivers. + - GIT-SHA d1fccda7269b068993e9cbfcb59876ca8034ab87 + * rt2x00: Shift to d80211 compatible code. + - GIT-SHA 2a05970a2dc1b4a50ffd1c94d0986d8d1d6c6c3d + * tifm_7xx1: Add defines for new devices. + - GIT-SHA f824ad5dcb0d62f09b78a7930436c513d0128a1d + * ps3fb: Build for PPC_PS3 only + - GIT-SHA f5e173c8b9ff3692f595c417938083b13e64e11a + * powerpc: Export some ps3 symbols for storage module. + - GIT-SHA ec400176132803af41c6aecb3b12db9a31b9c845 + * debian: Correctly copy the ubuntu/include dir to headers pkg. + - GIT-SHA ed07298c5e4d0ddcafed16c448b03113d9759585 + * drivers/video/Kconfig: Fix missing select + - GIT-SHA 6976480384e97a384a9f0e95566d57710389e695 + * ubuntu/wireless: Add and switch to rt61 and rt73 legacy drivers. + - GIT-SHA 04e61f157c9e6f803495f37771ada12ee962a21c + * ubuntu/wireless: rt61 and rt73 should be x86 only. + - GIT-SHA e4adb1e93f9dae772ea6afdcefa036fb0300d1ff + * arch/powerpc: __start_initialization_ps3 should not be called unless + romboot + - GIT-SHA 92d9beacf533c488921d88d1cfc04ecaac73091f + * paravirt: Temporarily remove the _GPL from the paravirt_ops export. + - GIT-SHA dc9ad6a068aee49ff28d684240ef728e4fbd3ccc + * serio: Remove device on shutdown to avoid buggy hw issues. + - GIT-SHA 29f0b9969512eb7b312b0760d7bea7e652e8764e + - Bug #82681 + * zd1211rw: Add support for USR805423 + - GIT-SHA 6a04f78207354e5802e36ed8667d14161a3091f6 + - Bug #82578 + * configs: Provide kvm-modules-APIVER for userspace to dep on. + - GIT-SHA 6ac8dc6d7cccec4d44aa5dfe0c0893cf74110dd6 + - Bug #82258 + * sound/hda_sigmatel: Fix ftbfs in last commit. + - GIT-SHA 7a4d0ac5947972f4ca432c723141310c52d40a4e + * linux_logo: Fix typo from extra_logo changes. + - GIT-SHA 2fcc2e7e6f09eb5a7a7ec4bf318da3c2dc329ec1 + * x86: Remove kdump kernel target since stock kernel can relocate. + - GIT-SHA 3404865f24d45497625128c96a0a0aac09742292 + * ppc: Wrap use of logo with CONFIG_LOGO + - GIT-SHA e047adc25bee4c0c508e2ed4d165a5e317dbf716 + * ppc/ps3: Fix dev_dbg() missing paren. + - GIT-SHA 9a81097a5db61b2c1c53281c6c3a1105b697b2b8 + * fs/exec: Increase size of psuedo rlim for piped core. + - GIT-SHA c92e62051e81a485016b1eb33a25d0d56ec6e3f3 + * fs/exec: Add a CORE_REAL_RLIM env for when we override it. + - GIT-SHA f0fa902c99ae4b462a57239c4828bf2a9b1054f6 + * atl1: Replace PCI vendor macro with constant. + - GIT-SHA c1c238a318c39d3c4f021a3767e9188b5a0cf66b + * megaraid: Add CERC device support patch. + - GIT-SHA 66f63e20e2e9a7fc796f6a9b1af9b3f0019085e3 + * ipw3945: Update to v1.2.0 + - GIT-SHA 1c2e8dfd7e9984658df98ad59e35ce122b47b119 + * Update ipw3945 ucode to 1.14.2. + - GIT-SHA d0f9c02060e586553cfff48776abb7d4e5e8d614 + * debian/config: Enable CONFIG_PM_TRACE to help debug suspend/resume + problems. + - GIT-SHA d52b29c1f900b5089592a20b0e6a0f39aa8c707d + * toshiba_acpi: Add hotkeys support. + - GIT-SHA ce6b8dd74b92e479aad58444b531685500a19aca + - Bug #77026 + + [Dan Hecht] + + * Feisty VMI paravirt-ops: enable vdso even when paravirt enabled + - GIT-SHA 067e03f920818d3b40062be994fd72f6d73b84ee + * Feisty VMI paravirt-ops: export paravirt_ops symbol + - GIT-SHA 4535bc1f5a50a20c2db2784cc655e75672ec92f4 + * Feisty VMI paravirt-ops: use real delay for i8042 + - GIT-SHA 89e6be485bb2f833eadb649daf8cff712fef500b + * Feisty VMI paravirt-ops: fix vmi-timer no-idle-hz idling code + - GIT-SHA d3153a3f8aa3f3c36d9132a58083e1c6bdc079da + * Feisty VMI paravirt-ops: fix profile_pc cpl checks + - GIT-SHA be7fd2bd3b9f85a4121303b8a354a08ba1f05af9 + * Feisty VMI paravirt-ops: Fix sched_clock units in VMI case + - GIT-SHA 16872a27f546105702324c8ebd400893b9a3196f + * Feisty VMI paravirt-ops: fix HIGHPTE when running on vmi hypervisor + - GIT-SHA a5bee01a5fe6c709fadcac4037da76fb77eb4841 + + [Daniel T. Chen] + + * sound/pci/hda/: Add Sigmatel 9205 EAPD support (patch_sigmatel.c) + - GIT-SHA 42a2e17c3caf2e69c54ecf265509c15b086a6dc6 + * sound/pci/hda/: Add digital mic support for STAC HDA (patch_sigmatel.c) + - GIT-SHA 0d584c03b7589c69541ca98854ceca1e76c44818 + * sound/pci/hda/: Add support for more STAC HDA codecs (patch_sigmatel.c) + - GIT-SHA a7346022281e59443ab0408ffe4ac2ae3abe785d + + [Kyle McMartin] + + * nozomi: Added driver + - GIT-SHA b4f2f69278e511e34d2cf248d1d74a4eb1a1e518 + * atl1: Add driver + - GIT-SHA be86d24abdff0cc9ab502e174e3be29cac040991 + * acx: Update driver + - GIT-SHA 11216265914d055c8b46ecb741b882f810e69946 + * Fix Attansic L1 Gigabit Ethernet driver + - GIT-SHA 657112d01c49bc4f4ed3de6ec30aca5801beb302 + + [Upstream Kernel Changes] + + * [libata sata_promise] support PATA ports on SATA controllers + * make sata_promise PATA ports work + * [AGPGART] intel_agp: restore graphics device's pci space early in + resume + * [PS3] Import + ps3-linux-patches-efc1ddc7203ae9a2418e03a9dbbafb260f4fe2a3. + * [PS3] Cleanup fb patches. + * [PS3] Export ps3_get_firmware_version(). + * [ARM] 4084/1: Remove CONFIG_DEBUG_WAITQ + * [ARM] 4085/1: AT91: Header fixes. + * [ARM] 4086/1: AT91: Whitespace cleanup + * [ARM] 4087/1: AT91: CPU reset for SAM9x processors + * [ARM] 4088/1: AT91: Unbalanced IRQ in serial driver suspend/resume + * [ARM] 4089/1: AT91: GPIO wake IRQ cleanup + * [ARM] 4092/1: i.MX/MX1 CPU Frequency scaling latency definition + * [ARM] 4095/1: S3C24XX: Fix GPIO set for Bank A + * [ARM] 4096/1: S3C24XX: change return code form s3c2410_gpio_getcfg() + * [ARM] Fix show_mem() for discontigmem + * [ARM] Update mach-types + * [ARM] 4100/1: iop3xx: fix cpu mask for iop333 + * [ARM] Fix AMBA serial drivers for non-first serial ports + * [ARM] 4102/1: Allow for PHYS_OFFSET on any valid 2MiB address + * [ARM] 4106/1: S3C2410: typo fixes in register definitions + * [PS3] Prepare patches for 2.6.21 submission. + * [ARM] 4112/1: Only ioremap to supersections if DOMAIN_IO is zero + * [ARM] 4111/1: Allow VFP to work with thread migration on SMP + * HID: fix memleaking of collection + * USB HID: fix hid_blacklist clash for 0x08ca/0x0010 + * HID: fix hid-input mapping for Firefly Mini Remote Control + * [PS3] Prepare av and fb patches for 2.6.21 submission. + * [PS3] Prepared patches for 2.6.21 submission. + * ahci: port_no should be used when clearing IRQ in ahci_thaw() + * libata: fix ata_eh_suspend() return value + * ide: update MAINTAINERS entry + * jmicron: fix warning + * atiixp.c: remove unused code + * atiixp.c: sb600 ide only has one channel + * atiixp.c: add cable detection support for ATI IDE + * ide/generic: Jmicron has its own drivers now + * ia64: add pci_get_legacy_ide_irq() + * ide: add missing __init tags to IDE PCI host drivers + * ide: unregister idepnp driver on unload + * via82cxxx/pata_via: correct PCI_DEVICE_ID_VIA_SATA_EIDE ID and add + support for CX700 and 8237S + * [SCSI] Fix scsi_add_device() for async scanning + * [SCSI] qla4xxx: bug fixes + * [SCSI] st: A MTIOCTOP/MTWEOF within the early warning will cause the + file number to be incorrect + * [AGPGART] Prevent (unlikely) memory leak in amd_create_gatt_pages() + * [AGPGART] Remove pointless typedef in ati-agp + * [AGPGART] Remove pointless assignment. + * [AGPGART] Add new IDs to VIA AGP. + * [CPUFREQ] check sysfs_create_link return value + * [CPUFREQ] Remove unneeded errata workaround from p4-clockmod. + * [ARM] 4117/1: S3C2412: Fix writel() usage in selection code + * [PS3] Prepare av and fb patches for 2nd round 2.6.21 submission. + * ALSA: Fix sysfs breakage + * Fix balance_dirty_page() calculations with CONFIG_HIGHMEM + * [PS3] Move system-bus to platform directory. + * sky2: revert IRQ dance on suspend/resume + * [PS3] Fixed ps3_map_sg, enabled CONFIG_USB_STORAGE. + * Fix try_to_free_buffer() locking + * Fix SG_IO timeout jiffy conversion + * Malta: Fix build if CONFIG_MTD is diabled. + * [MIPS] Ocelot G: Fix a few misspellings of CONFIG_GALILEO_GT64240_ETH + * [MIPS] Fix typo of "CONFIG_MT_SMP". + * HID: fix pb_fnmode and move it to generic HID + * pata_sil680: PIO1 taskfile transfers overclocking fix (repost) + * ata_if_xfermask() word 51 fix + * pata_platform: set_mode fix + * libata-scsi: ata_task_ioctl should return ATA registers from sense data + * libata: fix translation for START STOP UNIT + * b44: Fix frequent link changes + * net: ifb error path loop fix + * FS_ENET: OF-related fixup for FEC and SCC MAC's + * 82596 warning fixes + * ehea: Fixed wrong jumbo frames status query + * ehea: Fixed missing tasklet_kill() call + * bonding: ARP monitoring broken on x86_64 + * e100: fix irq leak on suspend/resume + * b44: src_desc->addr is little-endian + * Broadcom 4400 resume small fix + * namespaces: fix exit race by splitting exit + * uml: fix mknod + * use __u8/__u32 in userspace ioctl defines for I2O + * Fix "CONFIG_X86_64_" typo in drivers/kvm/svm.c + * m68k: uaccess.h needs sched.h + * fs/lockd/clntlock.c: add missing newlines to dprintk's + * knfsd: ratelimit some nfsd messages that are triggered by external + events + * use __u8 rather than u8 in userspace SIZE defines in hdreg.h + * fuse: fix bug in control filesystem mount + * ufs: alloc metadata null page fix + * ufs: truncate negative to unsigned fix + * ufs: reallocation fix + * cdev.h: forward declarations + * `make help' in build tree doesn't show headers_* targets + * i386: In assign_irq_vector look at all vectors before giving up + * mm: mremap correct rmap accounting + * missing exports of pm_power_off() on alpha and sparc32 + * mtd/nand/cafe.c missing include of dma-mapping.h + * sym53c500_cs: remove bogus call fo free_dma() + * pata_platform: fallout from set_mode() change + * missing dma_sync_single_range_for{cpu,device} on alpha + * dma-mapping.h stubs fix + * b44: src_desc->addr is little-endian + * fix indentation-related breakage in Kconfig.i386 + * [PS3] More av and fb prepearations for 2nd round 2.6.21 submission. + * [MAINTAINERS]: netfilter@ is subscribers-only + * [NETFILTER]: xt_connbytes: fix division by zero + * [NETFILTER]: SIP conntrack: fix skipping over user info in SIP headers + * [NETFILTER]: SIP conntrack: fix out of bounds memory access + * [IPV6]: Fix up some CONFIG typos + * [IPV6]: fix BUG of ndisc_send_redirect() + * [SCTP]: Force update of the rto when processing HB-ACK + * [PS3] Finish system bus move. + * Don't allow the stack to grow into hugetlb reserved regions + * translate dashes in filenames for headers install + * Remove warning: VFS is out of sync with lock manager + * kprobes: replace magic numbers with enum + * Fix VIA quirks + * jmicron: 40/80pin primary detection + * uml: fix signal frame alignment + * ntfs: kmap_atomic() atomicity fix + * IPMI: fix timeout list handling + * Linux 2.6.20-rc7 + * [NETFILTER]: xt_hashlimit: fix ip6tables dependency + * fix frv headers_check + * mca_nmi_hook() can be called at any point + * ide section fixes + * endianness bug: ntohl() misspelled as >> 24 in fh_verify(). + * fork_idle() should be __cpuinit, not __devinit + * __crc_... is intended to be absolute + * efi_set_rtc_mmss() is not __init + * sanitize sections for sparc32 smp + * radio modems sitting on serial port are not for s390 + * uml-i386: fix build breakage with CONFIG_HIGHMEM + * via quirk update + * pci: remove warning messages + * KVM: fix lockup on 32-bit intel hosts with nx disabled in the bios + * procfs: Fix listing of /proc/NOT_A_TGID/task + * sysrq: showBlockedTasks is sysrq-W + * via82cxxx: fix typo ("cx7000" should be corrected to "cx700") + * Remove avr32@atmel.com from MAINTAINERS + * [SPARC32]: Fix over-optimization by GCC near ip_fast_csum. + * [NET_SCHED]: act_ipt: fix regression in ipt action + * [BNX2]: PHY workaround for 5709 A0. + * e100: fix napi ifdefs removing needed code + * MAINTAINERS: ufs entry + * ahci/pata_jmicron: fix JMicron quirk + * pata_atiixp: propogate cable detection hack from drivers/ide to the new + driver + * pata_via: Correct missing comments + * libata: Fix ata_busy_wait() kernel docs + * libata: Initialize nbytes for internal sg commands + * [SCSI] sd: udev accessing an uninitialized scsi_disk field results in a + crash + * [NETFILTER]: ctnetlink: fix compile failure with NF_CONNTRACK_MARK=n + * [NETFILTER]: nf_conntrack_h323: fix compile error with CONFIG_IPV6=m, + CONFIG_NF_CONNTRACK_H323=y + * [PS3] SPE logo, sys-manager cleanups. + * aio: fix buggy put_ioctx call in aio_complete - v2 + * kexec: Avoid migration of already disabled irqs (ia64) + * net/smc911x: match up spin lock/unlock + * alpha: fix epoll syscall enumerations + * revert blockdev direct io back to 2.6.19 version + * Altix: more ACPI PRT support + * x86-64: define dma noncoherent API functions + * fix rtl8150 + * EFI x86: pass firmware call parameters on the stack + * Linux 2.6.20 + * [GFS2] don't try to lockfs after shutdown + * [DLM] fix resend rcom lock + * [DLM] fix old rcom messages + * [DLM] add version check + * [DLM] fix send_args() lvb copying + * [DLM] fix receive_request() lvb copying + * [DLM] fix lost flags in stub replies + * [DLM] fs/dlm/lowcomms-tcp.c: remove 2 functions + * [GFS2] Fix DIO deadlock + * [GFS2] Fail over to readpage for stuffed files + * [GFS2] Fix change nlink deadlock + * [DLM] Fix schedule() calls + * [DLM] Fix spin lock already unlocked bug + * [GFS2] Fix ordering of page disposal vs. glock_dq + * [GFS2] BZ 217008 fsfuzzer fix. + * [GFS2] Fix gfs2_rename deadlock + * [DLM] change some log_error to log_debug + * [DLM] rename dlm_config_info fields + * [DLM] add config entry to enable log_debug + * [DLM] expose dlm_config_info fields in configfs + * [GFS2] gfs2 knows of directories which it chooses not to display + * [GFS2] make gfs2_change_nlink_i() static + * [DLM] Use workqueues for dlm lowcomms + * [DLM] fix user unlocking + * [DLM] fix master recovery + * [GFS2] Add writepages for "data=writeback" mounts + * [GFS2] Clean up/speed up readdir + * [GFS2] Remove max_atomic_write tunable + * [GFS2] Shrink gfs2_inode memory by half + * [GFS2] Remove the "greedy" function from glock.[ch] + * [GFS2] Remove unused go_callback operation + * [GFS2] Remove local exclusive glock mode + * [DLM] lowcomms tidy + * [GFS2] Tidy up glops calls + * [DLM] fix lowcomms receiving + * [GFS2] Remove queue_empty() function + * [GFS2] Compile fix for glock.c + * [GFS2] use CURRENT_TIME_SEC instead of get_seconds in gfs2 + * [GFS2] Fix typo in glock.c + * [DLM] Make sock_sem into a mutex + * [DLM] saved dlm message can be dropped + * [DLM] can miss clearing resend flag + * [GFS2] Fix recursive locking attempt with NFS + * [GFS2] Fix list corruption in lops.c + * [GFS2] increase default lock limit + * [GFS2] make lock_dlm drop_count tunable in sysfs + * [GFS2/DLM] use sysfs + * [GFS2/DLM] fix GFS2 circular dependency + * [GFS2] more CURRENT_TIME_SEC + * [GFS2] Put back semaphore to avoid umount problem + * [GFS2] Fix unlink deadlocks + * [DLM/GFS2] indent help text + * [DLM] zero new user lvbs + * [DLM] fix softlockup in dlm_recv + * [GFS2] nfsd readdirplus assertion failure + * libata: ACPI and _GTF support + * libata: ACPI _SDD support + * libata: change order of _SDD/_GTF execution (resend #3) + * libata: wrong sizeof for BUFFER + + -- Ben Collins Tue, 30 Jan 2007 10:42:16 -0500 + +linux-source-2.6.20 (2.6.20-6.8) feisty; urgency=low + + [Ben Collins] + + * zd1211rw: Add WL-117 ZyDAS device (also to unusual_devs) + - GIT-SHA f4e590f04c115142f97ae121d1907a4c782f8fe0 + - Bug #78311 + * ubuntu/gfs1: Fixups for build warnings + - GIT-SHA e25792fce5c6d02004e51171387daabf811ae5ae + * ubuntu/mol: Fixes to build again. Fabio owes me a beer. + - GIT-SHA f57afa67e6410d9c3a21d3bf64fb4274c8d83bd2 + * acpi/osl: Dedicated work queue for notify() execution + - GIT-SHA 2365e9585cdc207280bbda4017921aa8b6e5224a + - Bug #75398 + * ubuntu/gfs1: Fix compile failure. + - GIT-SHA aed1705a979b1a4b228598980af5b6095cdb6cb5 + * debian/config: Disable via_pata and re-enable via-ide driver. + - GIT-SHA ec624a5acacae28761f73aa70f61d441fa9931c4 + - Bug #75492 + * fs/exec.c: Implement new style of apport interaction. + - GIT-SHA 1c3aaaa6866c3129e854887cee5180d0881742e1 + * debian/firmware: Update zd1211b_uphr file. + - GIT-SHA d17e13bfd559680e92ddc42b10d0bc0c1f81fd8c + + [Daniel T. Chen] + + * sound/pci/hda/: Add Conexant HDA codec support (hda_patch.h) + - GIT-SHA d3cba8f9d6053991b4979cbef059f9b9c3a49ace + * sound/pci/hda/: Add Conexant HDA codec support (Makefile) + - GIT-SHA c91da21e199515d9ac8daf99a4ffb9771ee249bc + * sound/pci/hda/: Add Conexant HDA codec support (patch_conexant.c) + - GIT-SHA b13229d7257c689bf6f9595b29aa812e918e3439 + + [Upstream Kernel Changes] + + * [JFFS2] kill warning RE debug-only variables + * [MTD NAND] Initial import of CAFÉ NAND driver. + * [MTD] SSFDC must depend on BLOCK + * [MTD NAND] OLPC CAFÉ driver update + * [MTD] MAPS: Add parameter to amd76xrom to override rom window size + * [MTD] CHIPS: Support for SST 49LF040B flash chip + * [MTD] MAPS: Support for BIOS flash chips on Intel ESB2 southbridge + * [JFFS2] Use rb_first() and rb_last() cleanup + * [MTD] JEDEC probe: fix comment typo (devic) + * [MTD] MAPS: esb2rom: use hotplug safe interfaces + * [JFFS2] Fix jffs2_follow_link() typo + * [MTD] NAND: AT91 NAND driver + * [MTD] mtdchar: Fix MEMGETOOBSEL and ECCGETLAYOUT ioctls + * [MTD] MAPS: Remove ITE 8172G and Globespan IVR MTD support + * [MTD] NAND: nandsim page-wise allocation (1/2) + * [MTD] NAND: nandsim page-wise allocation (2/2) + * [MTD] NAND: nandsim coding style fix + * [MTD] core: trivial comments fix + * [MTD] NOR: leave Intel chips in read-array mode on suspend + * [MTD] NAND: nandsim: support subpage write + * [MTD] NAND: Combined oob buffer so it's contiguous with data + * [MTD] NAND: Correct setting of chip->oob_poi OOB buffer + * [MTD] NAND: Add hardware ECC correction support to CAFÉ NAND driver + * [MTD] NAND: CAFÉ NAND driver cleanup, fix ECC on reading empty flash + * [MTD] NAND: Disable ECC checking on CAFÉ since it's broken for now + * [MTD] NAND: Fix nand_default_mark_blockbad() when flash-based BBT + disabled + * [MTD] NAND: Café ECC -- remove spurious BUG_ON() in err_pos() + * [MTD] NAND: Reset Café controller before initialising. + * [MTD] CAFÉ NAND: Add 'slowtiming' parameter, default usedma and + checkecc on + * [MTD] NAND: Add ECC debugging for CAFÉ + * [MTD] NAND: Remove empty block ECC workaround + * [MTD] NAND: Fix timing calculation in CAFÉ debugging message + * [MTD] NAND: Use register #defines throughout CAFÉ driver, not numbers + * [MTD] NAND: Add register debugging spew option to CAFÉ driver + * [MTD] NAND: Fix ECC settings in CAFÉ controller driver. + * MTD: OneNAND: interrupt based wait support + * [MTD] OneNAND: lock support + * [MTD] OneNAND: Single bit error detection + * [MTD] [NAND] rtc_from4.c: use lib/bitrev.c + * [MTD] make drivers/mtd/cmdlinepart.c:mtdpart_setup() static + * [MTD] [NAND] Fix endianess bug in ndfc.c + * [MTD] [MAPS] Support for BIOS flash chips on the nvidia ck804 + southbridge + * [MTD] Allow variable block sizes in mtd_blkdevs + * [MTD] [NAND] remove len/ooblen confusion. + * [MTD] Fix printk format warning in physmap. (resources again) + * [MTD] replace kmalloc+memset with kzalloc + * [MTD] [NAND] Update CAFÉ driver interrupt handler prototype + * [MTD] [NAND] fix ifdef option in nand_ecc.c + * [MTD] Tidy bitrev usage in rtc_from4.c + * [MTD] increase MAX_MTD_DEVICES + * [MTD] fix map probe name for cstm_mips_ixx + * [MTD] add MTD_BLKDEVS Kconfig option + * [MTD] NAND: add subpage write support + * [MTD] add get_mtd_device_nm() function + * [MTD] add get and put methods + * [MTD] return error code from get_mtd_device() + * [MTD] Use EXPORT_SYMBOL_GPL() for exported symbols. + * [MTD] Remove trailing whitespace + * [MTD] bugfix: DataFlash is not bit writable + * [MTD] [NAND] Compile fix in rfc_from4.c + * [MTD] redboot partition combined fis / config problem + * [MTD] NAND: use SmartMedia ECC byte order for ndfc + * [MTD] nandsim: bugfix in page addressing + * [MTD] NAND: Support for 16-bit bus-width on AT91. + * [MTD] Support combined RedBoot FIS directory and configuration area + * [MTD] of_device-based physmap driver + * [MTD] ESB2ROM uses PCI + * [MTD] Fix SSFDC build for variable blocksize. + * [JFFS2] replace kmalloc+memset with kzalloc + * [MTD] Fix ssfdc blksize typo + * [MTD] OneNAND: fix oob handling in recent oob patch + * [MTD] Nuke IVR leftovers + * [JFFS2] add cond_resched() when garbage collecting deletion dirent + * [CIFS] Update CIFS version number + * [JFFS2] Fix error-path leak in summary scan + * ieee80211: WLAN_GET_SEQ_SEQ fix (select correct region) + * ipw2100: Fix dropping fragmented small packet problem + * [SCSI] advansys: wrap PCI table inside ifdef CONFIG_PCI + * [SCSI] qla2xxx: make qla2x00_reg_remote_port() static + * [SCSI] Add missing completion to scsi_complete_async_scans() + * [SCSI] scsi_transport_spi: fix sense buffer size error + * [SCSI] seagate: remove BROKEN tag + * [SCSI] qla2xxx: Don't log trace-control async-events. + * [SCSI] qla2xxx: Correct endianess issue while interrogating MS status. + * [SCSI] qla2xxx: Use proper prep_ms_iocb() function during GFPN_ID. + * [SCSI] qla2xxx: Detect GPSC capabilities within a fabric. + * [SCSI] qla2xxx: Correct IOCB queueing mechanism for ISP54XX HBAs. + * [SCSI] qla2xxx: Correct reset handling logic. + * [SCSI] qla2xxx: Perform a fw-dump when an ISP23xx RISC-paused state is + detected. + * [SCSI] qla2xxx: Use generic isp_ops.fw_dump() function. + * [SCSI] qla2xxx: Update version number to 8.01.07-k4. + * ARM: OMAP: fix MMC workqueue changes + * MMC: at91 mmc linkage updates + * i2c-pnx: Fix interrupt handler, get rid of EARLY config option + * i2c-pnx: Add entry to MAINTAINERS + * i2c: Migration aids for i2c_adapter.dev removal + * ACPI: Altix: ACPI _PRT support + * IB/mthca: Fix off-by-one in FMR handling on memfree + * i2c-mv64xxx: Fix random oops at boot + * i2c/m41t00: Do not forget to write year + * UHCI: make test for ASUS motherboard more specific + * UHCI: support device_may_wakeup + * USB: fix interaction between different interfaces in an "Option" usb + device + * USB: funsoft is borken on sparc + * USB: omap_udc build fixes (sync with linux-omap) + * USB Storage: unusual_devs: add supertop drives + * USB storage: fix ipod ejecting issue + * USB: small update to Documentation/usb/acm.txt + * USB: Fixed bug in endpoint release function. + * sisusb_con warning fixes + * USB: usblp.c - add Kyocera Mita FS 820 to list of "quirky" printers + * USB: asix: Fix AX88772 device PHY selection + * PCI: disable PCI_MULTITHREAD_PROBE + * Driver core: Fix prefix driver links in /sys/module by bus-name + * ACPI: ec: enable printk on cmdline use + * Add AFS_SUPER_MAGIC to magic.h + * Fix implicit declarations in via-pmu + * Fix leds-s3c24xx hardware.h reference + * start_kernel: test if irq's got enabled early, barf, and disable them + again + * kernelparams: detect if and which parameter parsing enabled irq's + * PCI: prevent down_read when pci_devices is empty + * via82cxxx: fix cable detection + * KVM: Fix GFP_KERNEL alloc in atomic section bug + * KVM: Use raw_smp_processor_id() instead of smp_processor_id() where + applicable + * KVM: Recover after an arch module load failure + * KVM: Improve interrupt response + * rtc-at91rm9200 build fix + * Fix BUG at drivers/scsi/scsi_lib.c:1118 caused by "pktsetup dvd + /dev/sr0" + * atiixp: Old drivers/ide layer driver for the ATIIXP hang fix + * adfs: fix filename handling + * swsusp: Do not fail if resume device is not set + * profiling: fix sched profiling typo + * i386: Restore CONFIG_PHYSICAL_START option + * Sanely size hash tables when using large base pages + * i386: fix modpost warning in SMP trampoline code + * i386: fix another modpost warning + * i386: modpost smpboot code warning fix + * ip2 warning fix + * fix memory corruption from misinterpreted bad_inode_ops return values + * fix BUG_ON(!PageSlab) from fallback_alloc + * Update the rtc-rs5c372 driver + * KVM: Prevent stale bits in cr0 and cr4 + * KVM: MMU: Implement simple reverse mapping + * KVM: MMU: Teach the page table walker to track guest page table gfns + * KVM: MMU: Load the pae pdptrs on cr3 change like the processor does + * KVM: MMU: Fold fetch_guest() into init_walker() + * KVM: MU: Special treatment for shadow pae root pages + * KVM: MMU: Use the guest pdptrs instead of mapping cr3 in pae mode + * KVM: MMU: Make the shadow page tables also special-case pae + * KVM: MMU: Make kvm_mmu_alloc_page() return a kvm_mmu_page pointer + * KVM: MMU: Shadow page table caching + * KVM: MMU: Write protect guest pages when a shadow is created for them + * KVM: MMU: Let the walker extract the target page gfn from the pte + * KVM: MMU: Support emulated writes into RAM + * KVM: MMU: Zap shadow page table entries on writes to guest page tables + * KVM: MMU: If emulating an instruction fails, try unprotecting the page + * KVM: MMU: Implement child shadow unlinking + * KVM: MMU: kvm_mmu_put_page() only removes one link to the page + * KVM: MMU: oom handling + * KVM: MMU: Remove invlpg interception + * KVM: MMU: Remove release_pt_page_64() + * KVM: MMU: Handle misaligned accesses to write protected guest page + tables + * KVM: MMU: kvm a little earlier + * KVM: Avoid oom on cr3 switch + * KVM: Add missing 'break' + * KVM: Don't set guest cr3 from vmx_vcpu_setup() + * KVM: MMU: Add missing dirty bit + * KVM: Make loading cr3 more robust + * KVM: Simplify mmu_alloc_roots() + * KVM: Simplify test for interrupt window + * pata_optidma: typo in Kconfig + * hpt37x: Two important bug fixes + * Check for populated zone in __drain_pages + * qconf: fix SIGSEGV on empty menu items + * fix the toshiba_acpi write_lcd return value + * fix OOM killing of swapoff + * fix garbage instead of zeroes in UFS + * shrink_all_memory(): fix lru_pages handling + * connector: some fixes for ia64 unaligned access errors + * [ARM] 4079/1: iop: Update MAINTAINERS + * [ARM] 4070/1: arch/arm/kernel: fix warnings from missing includes + * [ARM] 4082/1: iop3xx: fix iop33x gpio register offset + * [SCSI] scsi_scan: fix report lun problems with CDROM or RBC devices + * [SCSI] iscsi: fix 2.6.19 data digest calculation bug + * [SCSI] iscsi: fix crypto_alloc_hash() error check + * [SCSI] iscsi: newline in printk + * [SCSI] iscsi: simplify IPv6 and IPv4 address printing + * [SCSI] libiscsi: fix senselen calculation + * [SCSI] aacraid: Product List Update + * [SCSI] scsi: lpfc error path fix + * [SCSI] sr: fix error code check in sr_block_ioctl() + * [SCSI] 3ware 8000 serialize reset code + * [SCSI] megaraid_sas: Update module author + * [SCSI] fusion: fibre channel: return DID_ERROR for + MPI_IOCSTATUS_SCSI_IOC_TERMINATED + * [SCSI] fusion: power pc and miscellaneous bug fixs + * [SCSI] fusion: MODULE_VERSION support + * [SCSI] fusion: bump version + * [SCSI] qla1280: set residual correctly + * ixgb: Fix early TSO completion + * ixgb: Maybe stop TX if not enough free descriptors + * [ARM] Fix kernel-mode undefined instruction aborts + * Linux 2.6.20-rc4 + * IB/iser: Return error code when PDUs may not be sent + * qla3xxx: Remove NETIF_F_LLTX from driver features. + * qla3xxx: Add delay to NVRAM register access. + * RDMA/iwcm: iWARP connection timeouts shouldn't be reported as rejects + * RDMA/ucma: Fix struct ucma_event leak when backlog is full + * RDMA/ucma: Don't report events with invalid user context + * IB/mthca: Fix PRM compliance problem in atomic-send completions + * i915: Fix a DRM_ERROR that should be DRM_DEBUG. + * HID: fix mappings for DiNovo Edge Keyboard - Logitech USB BT receiver + * HID: tiny patch to remove a kmalloc cast + * HID: mousepoll parameter makes no sense for generic HID + * [ARM] Fix potential MMCI bug + * [ARM] pass vma for flush_anon_page() + * [ARM] Resolve fuse and direct-IO failures due to missing cache flushes + * [ARM] Provide basic printk_clock() implementation + * [MIPS] Malta: Add missing MTD file. + * [MIPS] csum_partial and copy in parallel + * [MIPS] SMTC build fix + * [MIPS] Fix build errors on SEAD + * [MIPS] pnx8550: Fix write_config_byte() PCI config space accessor + * [MIPS] TX49: Fix use of CDEX build_store_reg() + * [MIPS] PNX8550: Fix system timer support + * [POWERPC] Fix bogus BUG_ON() in in hugetlb_get_unmapped_area() + * [POWERPC] Fix unbalanced uses of of_node_put + * [POWERPC] Avoid calling get_irq_server() with a real, not virtual irq. + * [POWERPC] Fix manual assembly WARN_ON() in enter_rtas(). + * [POWERPC] Update ppc64_defconfig + * [POWERPC] Add legacy iSeries to ppc64_defconfig + * [POWERPC] 52xx: Don't use device_initcall to probe of_platform_bus + * [POWERPC] Fix mpc52xx fdt to use correct device_type for sound devices + * [POWERPC] Don't include powerpc/sysdev/rom.o for arch/ppc builds + * [POWERPC] Fix mpc52xx serial driver to work for arch/ppc again + * [POWERPC] disable PReP and EFIKA during make oldconfig + * [POWERPC] iSeries: fix mf proc initialisation + * [POWERPC] iSeries: fix proc/iSeries initialisation + * [POWERPC] iSeries: fix lpevents initialisation + * [POWERPC] iSeries: fix viopath initialisation + * [POWERPC] iSeries: fix setup initcall + * [POWERPC] Fix corruption in hcall9 + * [POWERPC] Fix bugs in the hypervisor call stats code + * forcedeth: sideband management fix + * s390: qeth driver fixes: VLAN hdr, perf stats + * s390: qeth driver fixes: packet socket + * s390: qeth driver fixes: atomic context fixups + * s390: iucv Kconfig help description changes + * chelsio: error path fix + * pcnet_cs : add new id + * [ALSA] Audio: Add nvidia HD Audio controllers of MCP67 support to + hda_intel.c + * [ALSA] Fix potential NULL pointer dereference in echoaudio midi + * [ALSA] usb-audio: work around wrong frequency in CM6501 descriptors + * [ALSA] hda_intel: ALSA HD Audio patch for Intel ICH9 + * [ALSA] hda-codec - Fix NULL dereference in generic hda code + * [ALSA] _snd_cmipci_uswitch_put doesn't set zero flags + * [ALSA] usb: usbmixer error path fix + * [ALSA] usbaudio - Fix kobject_add() error at reconnection + * [INET]: Fix incorrect "inet_sock->is_icsk" assignment. + * [X25]: Trivial, SOCK_DEBUG's in x25_facilities missing newlines + * [Bluetooth] Add packet size checks for CAPI messages + * [Bluetooth] More checks if DLC is still attached to the TTY + * [Bluetooth] Fix uninitialized return value for RFCOMM sendmsg() + * [Bluetooth] Handle device registration failures + * [Bluetooth] Correct SCO buffer size for another ThinkPad laptop + * [Bluetooth] Correct SCO buffer for Broadcom based HP laptops + * [Bluetooth] Correct SCO buffer for Broadcom based Dell laptops + * NetLabel: correct locking in selinux_netlbl_socket_setsid() + * NetLabel: correct CIPSO tag handling when adding new DOI definitions + * [BNX2]: Don't apply CRC PHY workaround to 5709. + * [BNX2]: Fix 5709 Serdes detection. + * [BNX2]: Fix bug in bnx2_nvram_write(). + * [BNX2]: Update version and reldate. + * [TG3]: Add PHY workaround for 5755M. + * [NETFILTER]: nf_conntrack_netbios_ns: fix uninitialized member in + expectation + * [TCP]: Fix iov_len calculation in tcp_v4_send_ack(). + * [S390] memory detection misses 128k. + * [S390] cio: use barrier() in stsch_reset. + * [S390] Fix cpu hotplug (missing 'online' attribute). + * [S390] Fix vmalloc area size calculation. + * [S390] don't call handle_mm_fault() if in an atomic context. + * [S390] locking problem with __cpcmd. + * [ALSA] version 1.0.14rc1 + * HID: Fix DRIVER_DESC macro + * i2c/pci: fix sis96x smbus quirk once and for all + * IB/ehca: Use proper GFP_ flags for get_zeroed_page() + * IB/mthca: Don't execute QUERY_QP firmware command for QP in RESET state + * [NETFILTER]: nf_conntrack_ipv6: fix crash when handling fragments + * [NETFILTER]: arp_tables: fix userspace compilation + * [NETFILTER]: nf_nat: fix hanging connections when loading the NAT + module + * [NETFILTER]: tcp conntrack: fix IP_CT_TCP_FLAG_CLOSE_INIT value + * [SCTP]: Fix err_hdr assignment in sctp_init_cause. + * [INET]: style updates for the inet_sock->is_icsk assignment fix + * [IPV4] devinet: inetdev_init out label moved after RCU assignment + * [JFFS2] Reschedule in loops + * [JFFS2] use the ref_offset macro + * [MTD] OneNAND: fix onenand_wait bug + * [MTD] OneNAND: add subpage write support + * [MTD] OneNAND: release CPU in cycles + * [MTD] OneNAND: fix onenand_wait bug in read ecc error + * [MTD] OneNAND: Implement read-while-load + * [MTD] OneNAND: return ecc error code only when 2-bit ecc occurs + * [MTD] OneNAND: Handle DDP chip boundary during read-while-load + * MAINTAINERS: maintainer for sata_promise + * fix linux banner format string + * ieee1394: sbp2: fix probing of some DVD-ROM/RWs + * [MIPS] PNX8550: Fix system timer initialization + * [MIPS] Fix N32 SysV IPC routines + * [MIPS] Alchemy: Fix PCI-memory access + * Page allocation hooks for VMI backend + * Paravirt CPU hypercall batching mode + * IOPL handling for paravirt guests + * SMP boot hook for paravirt + * VMI backend for paravirt-ops + * VMI timer patches + * Vmi compile fix + * Vmi native fix + * x86-64: Update defconfig + * i386: Update defconfig + * x86-64: Make noirqdebug_setup function non init to fix modpost warning + * x86-64: Use different constraint for gcc < 4.1 in bitops.h + * i386: cpu hotplug/smpboot misc MODPOST warning fixes + * i386: make apic probe function non-init + * x86-64: modpost add more symbols to whitelist pattern2 + * x86-64: Modpost whitelist reference to more symbols (pattern 3) + * x86-64: pci quirks MODPOST warning fix + * x86-64: - Ignore long SMI interrupts in clock calibration + * x86-64: tighten up printks + * i386: Fix memory hotplug related MODPOST generated warning + * i386: Convert some functions to __init to avoid MODPOST warnings + * x86-64: Fix warnings in ia32_aout.c + * ACPI: rename cstate_entry_s to cstate_entry + * ACPI: delete two spurious ACPI messages + * ACPI: schedule obsolete features for deletion + * ACPI: update MAINTAINERS + * Pull trivial into release branch + * Don't put "linux_banner" in the .init section + * sched: tasks cannot run on cpus onlined after boot + * increment pos before looking for the next cap in __pci_find_next_ht_cap + * Fix sparsemem on Cell + * qconf: (re)fix SIGSEGV on empty menu items + * rtc-sh: correctly report rtc_wkalrm.enabled + * Change cpu_up and co from __devinit to __cpuinit + * Kdump documentation update + * i386: sched_clock using init data tsc_disable fix + * md: pass down BIO_RW_SYNC in raid{1,10} + * KVM: add VM-exit profiling + * NFS: Fix race in nfs_release_page() + * really fix funsoft driver + * Revert bd_mount_mutex back to a semaphore + * intel-rng workarounds + * Fix HWRNG built-in initcalls priority + * fix typo in geode_configre()@cyrix.c + * FD_ZERO build fix + * PCMCIA: fix drivers broken by recent cleanup + * blktrace: only add a bounce trace when we really bounce + * Linux v2.6.20-rc5 + * [JFFS2] debug.h: include for current->pid + * omap: Update MMC response types + * mmc: Correct definition of R6 + * V4L/DVB (5019): Fix the frame->grabstate update in read() entry point. + * V4L/DVB (5020): Fix: disable interrupts while at KM_BOUNCE_READ + * V4L/DVB (5021): Cx88xx: Fix lockup on suspend + * V4L/DVB (5024): Fix quickcam communicator driver for big endian + architectures + * V4L/DVB (5029): Ks0127 status flags + * V4L/DVB (5033): MSI TV@nywhere Plus fixes + * V4L/DVB (5069): Fix bttv and friends on 64bit machines with lots of + memory + * V4L/DVB (5071): Tveeprom: autodetect LG TAPC G701D as tuner type 37 + * V4L/DVB (5023): Fix compilation on ppc32 architecture + * bcm43xx: Fix failure to deliver PCI-E interrupts + * NTFS: 2.1.28 - Fix deadlock reported by Sergey Vlasov due to + ntfs_put_inode(). + * NTFS: Forgot to bump version number in makefile to 2.1.28... + * 8139cp: Don't blindly enable interrupts + * myri10ge: make wc_fifo usage load-time tunable + * myri10ge: check that we can get an irq + * myri10ge: update driver version to 1.2.0 + * Update ucc_geth.c for new workqueue structure + * Fix phy_read/write redefinition errors in ucc_geth_phy.c + * hwmon/w83793: Remove the description of AMDSI and update the voltage + formula + * hwmon: Fix the VRD 11 decoding + * hwmon/w83793: Ignore disabled temperature channels + * hwmon/w83793: Fix the fan input detection + * hwmon/w83793: Hide invalid VID readings + * [MIPS] SMTC: Fix cp0 hazard. + * [MIPS] Delete duplicate call to load_irq_save. + * sis190: failure to set the MAC address from EEPROM + * libata doc: "error : unterminated entity reference exceptions" + * sata_via: add PCI ID 0x5337 + * libata: initialize qc->dma_dir to DMA_NONE + * libata: fix handling of port actions in per-dev action mask + * sata_mv HighPoint 2310 support (88SX7042) + * HID: fix some ARM builds due to HID brokenness - make USB_HID depend on + INPUT + * HID: GEYSER4_ISO needs quirk + * HID: update MAINTAINERS entry for USB-HID + * HID: proper LED-mapping for SpaceNavigator + * HID: compilation fix when DEBUG_DATA is defined + * HID: hid/hid-input.c doesn't need to include linux/usb/input.h + * HID: add missing RX, RZ and RY enum values to hid-debug output + * HID: put usb_interface instead of usb_device into hid->dev to fix + udevinfo breakage + * hid-core.c: Adds GTCO CalComp Interwrite IPanel PIDs to blacklist + * [CIFS] Remove 2 unneeded kzalloc casts + * [CIFS] cifs sprintf fix + * ocfs2: Don't print errors when following symlinks + * ocfs2: Directory c/mtime update fixes + * ocfs2: cleanup ocfs2_iget() errors + * ocfs2: Add backup superblock info to ocfs2_fs.h + * [CIFS] Fix oops when Windows server sent bad domain name null + terminator + * [POWERPC] Remove bogus sanity check in pci -> OF node code + * [POWERPC] Fix cell's mmio nvram to properly parse device tree + * [POWERPC] Fix broken DMA on non-LPAR pSeries + * [POWERPC] Make it blatantly clear; mpc5200 device tree is not yet + stable + * [POWERPC] Fix OF node refcnt underflow in 836x and 832x platform code + * [POWERPC] atomic_dec_if_positive sign extension fix + * usbtouchscreen: make ITM screens report BTN_TOUCH as zero when not + touched + * USB: asix: Detect internal PHY and enable/use accordingly + * USB: rndis_host: fix crash while probing a Nokia S60 mobile + * USB: make usbhid ignore Imation Disc Stakka + * USB: unusual_devs.h for 0x046b:ff40 + * USB: add vendor/device id for Option GT Max 3.6 cards + * USB: disable USB_MULTITHREAD_PROBE + * USB: Fix for typo in ohci-ep93xx.c + * USB: unusual_devs.h entry for nokia 6233 + * PCI: Unhide the SMBus on the Asus P4P800-X + * PCI: rework Documentation/pci.txt + * PCI: fix pci-driver kernel-doc + * [Bluetooth] Missing endian swapping for L2CAP socket list + * [Bluetooth] Restrict well known PSM to privileged users + * IB/srp: Check match_strdup() return + * IB/ehca: Fix improper use of yield() with spinlock held + * IB/ehca: Fix mismatched spin_unlock in irq handler + * vmx: Fix register constraint in launch code + * x86: fix PDA variables to work during boot + * modify 3c589_cs to be SMP safe + * Note that JFFS (v1) is to be deleted, in feature-removal-schedule.txt + * more ftape removal + * PHY: Export phy ethtool helpers + * ehea: Fixed wrong dereferencation + * ehea: Fixing firmware queue config issue + * ehea: Modified initial autoneg state determination + * ehea: New method to determine number of available ports + * ehea: Improved logging of permission issues + * ehea: Added logging off associated errors + * ehea: Fixed possible nullpointer access + * NetXen: Firmware check modifications + * NetXen: Use pci_register_driver() instead of pci_module_init() in + init_module + * [ALSA] Repair snd-usb-usx2y over OHCI + * fix "kvm: add vm exit profiling" + * Revert nmi_known_cpu() check during boot option parsing + * blockdev direct_io: fix signedness bug + * SubmitChecklist update + * paravirt: mark the paravirt_ops export internal + * KVM: make sure there is a vcpu context loaded when destroying the mmu + * KVM: fix race between mmio reads and injected interrupts + * KVM: x86 emulator: fix bit string instructions + * KVM: fix bogus pagefault on writable pages + * rtc-sh: act on rtc_wkalrm.enabled when setting an alarm + * fix blk_direct_IO bio preparation + * tlclk: bug fix + misc fixes + * mbind: restrict nodes to the currently allowed cpuset + * resierfs: avoid tail packing if an inode was ever mmapped + * Kdump documentation update: kexec-tools update + * Kdump documentation update: ia64 portion + * acpi: remove "video device notify" message + * [MIPS] SMTC: Instant IPI replay. + * [MIPS] Vr41xx: Fix after GENERIC_HARDIRQS_NO__DO_IRQ change + * elevator: move clearing of unplug flag earlier + * notifiers: fix blocking_notifier_call_chain() scalability + * funsoft: ktermios fix + * horizon.c: missing __devinit + * s2io bogus memset + * fix prototype of csum_ipv6_magic() (ia64) + * correct sys_shmget allocation check + * s2io bogus memset + * mv643xx_eth: Fix race condition in mv643xx_eth_free_tx_descs + * Clear spurious irq stat information when adding irq handler + * email change for shemminger@osdl.org + * Change Linus' email address too + * V4L/DVB (5123): Buf_qbuf: fix: videobuf_queue->stream corruption and + lockup + * [IPSEC] flow: Fix potential memory leak + * [IPV6] MCAST: Fix joining all-node multicast group on device + initialization. + * [SELINUX]: increment flow cache genid + * [NETFILTER]: ctnetlink: fix leak in ctnetlink_create_conntrack error + path + * [NETFILTER]: fix xt_state compile failure + * [SCTP]: Set correct error cause value for missing parameters + * [SCTP]: Verify some mandatory parameters. + * [SCTP]: Correctly handle unexpected INIT-ACK chunk. + * [SCTP]: Fix SACK sequence during shutdown + * [X.25]: Add missing sock_put in x25_receive_data + * [IrDA]: irda-usb TX path optimization (was Re: IrDA spams logfiles - + since 2.6.19) + * [IrDA]: Removed incorrect IRDA_ASSERT() + * [IPSEC]: Policy list disorder + * [TCP]: skb is unexpectedly freed. + * [IRDA] vlsi_ir.{h,c}: remove kernel 2.4 code + * [NETFILTER]: Fix iptables ABI breakage on (at least) CRIS + * [NET]: Process include/linux/if_{addr,link}.h with unifdef + * [TCP]: rare bad TCP checksum with 2.6.19 + * [IPV6]: Fixed the size of the netlink message notified by + inet6_rt_notify(). + * [IP] TUNNEL: Fix to be built with user application. + * [SCTP]: Fix compiler warning. + * ahci: make ULi M5288 ignore interface fatal error bit + * sata_nv: don't rely on NV_INT_DEV indication with ADMA + * ahci: don't enter slumber on power down + * libata: Fixup n_elem initialization + * libata: Initialize qc->pad_len + * [POWERPC] PS3: Fix uniprocessor kernel build + * [POWERPC] ps3_free_io_irq: Fix inverted error check + * [MIPS] There is no __GNUC_MAJOR__ + * [MIPS] Fix APM build + * [MIPS] SMTC: Fix TLB sizing bug for TLB of 64 >= entries + * [MIPS] SMTC: Fix module build by exporting symbol + * [MIPS] vr41xx: need one more nop with mtc0_tlbw_hazard() + * [MIPS] Fix reported amount of freed memory - it's in kB not bytes + * [MIPS] VPE loader: Initialize lists before they're actually being used + ... + * [MIPS] Fix wrong checksum calculation on 64-bit MIPS + * NFS: Fix Oops in rpc_call_sync() + * NFS: Fix races in nfs_revalidate_mapping() + * [IPV4]: Fix the fib trie iterator to work with a single entry routing + tables + * [AF_PACKET]: Fix BPF handling. + * libata cmd64x: whack into a shape that looks like the documentation + * libata hpt3xn: Hopefully sort out the DPLL logic versus the vendor code + * libata: set_mode, Fix the FIXME + * Linux 2.6.20-rc6 + * [TCP]: Fix sorting of SACK blocks. + * sata_via: don't diddle with ATA_NIEN in ->freeze + * ahci: improve and limit spurious interrupt messages, take#3 + * libata: implement ATA_FLAG_IGN_SIMPLEX and use it in sata_uli + * libata-sff: Don't call bmdma_stop on non DMA capable controllers + * [BNX2]: Fix 2nd port's MAC address. + * [DECNET]: Handle a failure in neigh_parms_alloc (take 2) + * x86_64: fix put_user for 64-bit constant + * [AF_PACKET]: Check device down state before hard header callbacks. + * [TCP]: Restore SKB socket owner setting in tcp_transmit_skb(). + * [NETFILTER]: nf_nat: fix ICMP translation with statically linked + conntrack + * [NETFILTER]: nf_nat_pptp: fix expectation removal + * [NETFILTER]: nf_conntrack_pptp: fix NAT setup of expected GRE + connections + * [AVR32] Export clear_page symbol + * [AVR32] Update ATSTK1000 defconfig: Enable macb by default + * Resurrect 'try_to_free_buffers()' VM hackery + * Write back inode data pages even when the inode itself is locked + * KVM: SVM: Fix SVM idt confusion + * KVM: Emulate IA32_MISC_ENABLE msr + * KVM: MMU: Perform access checks in walk_addr() + * KVM: MMU: Report nx faults to the guest + * KVM: SVM: Propagate cpu shutdown events to userspace + * S3C24XX: fix passing spi chipselect to select routine + * spi: fix error setting the spi mode in pxa2xx_spi.c + * Fix CONFIG_COMPAT_VDSO + * Fix gate_vma.vm_flags + * Add VM_ALWAYSDUMP + * i386 vDSO: use VM_ALWAYSDUMP + * x86_64 ia32 vDSO: use VM_ALWAYSDUMP + * powerpc vDSO: use VM_ALWAYSDUMP + * x86_64 ia32 vDSO: define arch_vma_name + * Fix NULL ->nsproxy dereference in /proc/*/mounts + * SPI: alternative fix for spi_busnum_to_master + * ACPI: fix cpufreq regression + * Gigaset ISDN driver error handling fixes + * knfsd: update email address and status for NFSD in MAINTAINERS + * knfsd: fix setting of ACL server versions + * knfsd: fix an NFSD bug with full sized, non-page-aligned reads + * knfsd: replace some warning ins nfsfh.h with BUG_ON or WARN_ON + * knfsd: Don't mess with the 'mode' when storing a exclusive-create + cookie + * md: update email address and status for MD in MAINTAINERS + * md: make 'repair' actually work for raid1 + * md: make sure the events count in an md array never returns to zero + * md: avoid reading past the end of a bitmap file + * 9p: fix bogus return code checks during initialization + * 9p: fix rename return code + * 9p: update documentation regarding server applications + * 9p: fix segfault caused by race condition in meta-data operations + * 9p: null terminate error strings for debug print + * dm-multipath: fix stall on noflush suspend/resume + * remove __devinit markings from rtc_sysfs_add_device() + * fix various kernel-doc in header files + * knfsd: Fix type mismatch with filldir_t used by nfsd + * md: fix potential memalloc deadlock in md + * MM: Remove invalidate_inode_pages2_range() debug + * Fix UML on non-standard VM split hosts + * md: remove unnecessary printk when raid5 gets an unaligned read. + * core-dumping unreadable binaries via PT_INTERP + * netdev: add a MAINTAINERS entry for via-velocity and update my address + * Fix race in efi variable delete code + * ahci: fix endianness in spurious interrupt message + * sata_via: style clean up, no indirect method call in LLD + * ahci: use 0x80 as wait stat value instead of 0xff + * Fix Maple PATA IRQ assignment. + * ocfs2: fix thinko in ocfs2_backup_super_blkno() + * Boot loader ID for Gujin + * [SPARC64]: Set g4/g5 properly in sun4v dtlb-prot handling. + * [SELINUX]: Fix 2.6.20-rc6 build when no xfrm + * [IPV4]: Fix single-entry /proc/net/fib_trie output. + * [POWERPC] PS3: add not complete comment to kconfig + * [POWERPC] Fix sys_pciconfig_iobase bus matching + + -- Ben Collins Sat, 06 Jan 2007 13:41:11 -0500 + +linux-source-2.6.20 (2.6.20-5.7) feisty; urgency=low + + [Upstream Kernel Changes] + + * [PARTITION]: Add whole_disk attribute. + * [AGPGART] K8M890 support for amd-k8. + * [SPARC64]: Add obppath sysfs attribute for SBUS and PCI devices. + * [AGPGART] Remove unnecessary flushes when inserting and removing pages. + * [CPUFREQ] select consistently + * [CPUFREQ] Bug fix for acpi-cpufreq and cpufreq_stats oops on frequency + change notification + * [CPUFREQ] speedstep-centrino: missing space and bracket + * [AGPGART] fix detection of aperture size versus GTT size on G965 + * [AGPGART] Fix PCI-posting flush typo. + * [CPUFREQ] longhaul: Fix up unreachable code. + * [CPUFREQ] Longhaul - Fix up powersaver assumptions. + * backlight: fix backlight_device_register compile failures + * ACPI: EC: move verbose printk to debug build only + * ACPI: increase ACPI_MAX_REFERENCE_COUNT for larger systems + * ACPI: fix section mis-match build warning + * ACPI: asus_acpi: new MAINTAINER + * [AGPGART] drivers/char/agp/sgi-agp.c: check kmalloc() return value + * [CPUFREQ] Longhaul - Always guess FSB + * [CPUFREQ] Uninitialized use of cmd.val in + arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c:acpi_cpufreq_target() + * [CPUFREQ] longhaul: Kill off warnings introduced by recent changes. + * cdrom: set default timeout to 7 seconds + * ide-cd maintainer + * [SOUND] Sparc CS4231: Fix IRQ return value and initialization. + * [NET]: ifb double-counts packets + * [PKTGEN]: Convert to kthread API. + * [NET] drivers/net/loopback.c: convert to module_init() + * [NETFILTER] xt_hashlimit.c: fix typo + * [XFRM_USER]: avoid pointless void ** casts + * [AF_NETLINK]: module_put cleanup + * [X25]: proper prototype for x25_init_timers() + * [SOUND] Sparc CS4231: Use 64 for period_bytes_min + * [SUNGEM]: PHY updates & pause fixes (#2) + * Fix some ARM builds due to HID brokenness + * HID: fix help texts in Kconfig + * [NETFILTER]: compat offsets size change + * [NETFILTER]: Fix routing of REJECT target generated packets in output + chain + * [NETFILTER]: New connection tracking is not EXPERIMENTAL anymore + * [NETFILTER]: nf_nat: fix MASQUERADE crash on device down + * [NETFILTER]: ebtables: don't compute gap before checking struct type + * [TCP]: Use old definition of before + + -- Ben Collins Fri, 05 Jan 2007 01:27:26 -0500 + +linux-source-2.6.20 (2.6.20-4.6) feisty; urgency=low + + [Ben Collins] + + * acpi/ec: Quiet "evaluating _XX" messages + - GIT-SHA 312a9aed094affc358a8e22b17b209059e68252e + - Bug #77867 + + -- Ben Collins Wed, 03 Jan 2007 16:58:54 -0500 + +linux-source-2.6.20 (2.6.20-4.5) feisty; urgency=low + + [Ben Collins] + + * toshiba_acpi: Add toshset patch + - GIT-SHA 1ffa3a0ddcf076a379a1674725c80fd752e00ed9 + - Bug #73011 + * pm: Config option to disable handling of console during suspend/resume. + - GIT-SHA e301ddf3803af8e6e87048216c63f2adb3e98f10 + - Bug #56591 + * speakup: Update to latest CVS + - GIT-SHA 5f635ed9ba1cbaa1f6f3a0b1b9cba94be3129d2a + * speakup: Include jiffies.h (removed during update) + - GIT-SHA 1bbf403f5d5bb47b707fa4664c815ec42c155279 + + [Upstream Kernel Changes] + + * zd1211rw: Call ieee80211_rx in tasklet + * ieee80211softmac: Fix errors related to the work_struct changes + * ieee80211softmac: Fix mutex_lock at exit of ieee80211_softmac_get_genie + * e1000: The user-supplied itr setting needs the lower 2 bits masked off + * e1000: dynamic itr: take TSO and jumbo into account + * e1000: For sanity, reformat e1000_set_mac_type(), struct + e1000_hw[_stats] + * e1000: omit stats for broken counter in 82543 + * e1000: consolidate managability enabling/disabling + * e1000: Fix Wake-on-Lan with forced gigabit speed + * e1000: disable TSO on the 82544 with slab debugging + * e1000: workaround for the ESB2 NIC RX unit issue + * e1000: fix to set the new max frame size before resetting the adapter + * e1000: fix ethtool reported bus type for older adapters + * e1000: narrow down the scope of the tipg timer tweak + * e1000: Fix PBA allocation calculations + * e1000: Make the copybreak value a module parameter + * e1000: 3 new driver stats for managability testing + * e1000: No-delay link detection at interface up + * netxen: remove private ioctl + * netpoll: drivers must not enable IRQ unconditionally in their NAPI + handler + * r8169: use the broken_parity_status field in pci_dev + * myri10ge: match number of save_state and restore + * myri10ge: move request_irq to myri10ge_open + * myri10ge: make msi configurable at runtime through sysfs + * myri10ge: no need to save MSI and PCIe state in the driver + * myri10ge: handle failures in suspend and resume + * e1000: Do not truncate TSO TCP header with 82544 workaround + * via-velocity uses INET interfaces + * sky2: dual port NAPI problem + * sky2: power management/MSI workaround + * sky2: phy power down needs PCI config write enabled + * ep93xx: some minor cleanups to the ep93xx eth driver + * PHY probe not working properly for ibm_emac (PPC4xx) + * NetXen: Adding new device ids. + * NetXen: driver reload fix for newer firmware. + * NetXen: Using correct CHECKSUM flag. + * NetXen: Multiple adapter fix. + * NetXen: Link status message correction for quad port cards. + * NetXen: work queue fixes. + * NetXen: Fix for PPC machines. + * NetXen: Reducing ring sizes for IOMMU issue. + * forcedeth: modified comment header + * r8169: extraneous Cmd{Tx/Rx}Enb write + * V4L/DVB (4955): Fix autosearch index + * V4L/DVB (4956): [NOVA-T-USB2] Put remote-debugging in the right place + * V4L/DVB (4958): Fix namespace conflict between w9968cf.c on MIPS + * V4L/DVB (4959): Usbvision: possible cleanups + * V4L/DVB (4960): Removal of unused code from usbvision-i2c.c + * V4L/DVB (4964): VIDEO_PALETTE_YUYV and VIDEO_PALETTE_YUV422 are the + same palette + * V4L/DVB (4967): Add missing tuner module option pal=60 for PAL-60 + support. + * V4L/DVB (4968): Add PAL-60 support for cx2584x. + * V4L/DVB (4970): Usbvision memory fixes + * V4L/DVB (4972): Dvb-core: fix bug in CRC-32 checking on 64-bit systems + * V4L/DVB (4973): Dvb-core: fix printk type warning + * V4L/DVB (4979): Fixes compilation when CONFIG_V4L1_COMPAT is not + selected + * V4L/DVB (4980): Fixes bug 7267: PAL/60 is not working + * V4L/DVB (4982): Fix broken audio mode handling for line-in in msp3400. + * V4L/DVB (4983): Force temporal filter to 0 when scaling to prevent + ghosting. + * V4L/DVB (4984): LOG_STATUS should show the real temporal filter value. + * V4L/DVB (4988): Cx2341x audio_properties is an u16, not u8 + * V4L/DVB (4990): Cpia2/cpia2_usb.c: fix error-path leak + * V4L/DVB (4991): Cafe_ccic.c: fix NULL dereference + * V4L/DVB (4992): Fix typo in saa7134-dvb.c + * V4L/DVB (4994): Vivi: fix use after free in list_for_each() + * V4L/DVB (4995): Vivi: fix kthread_run() error check + * V4L/DVB (4996): Msp3400: fix kthread_run error check + * V4L/DVB (4997): Bttv: delete duplicated ioremap() + * V4L/DVB (5014): Allyesconfig build fixes on some non x86 arch + * V4L/DVB (5001): Add two required headers on kernel 2.6.20-rc1 + * V4L/DVB (5012): Usbvision fix: It was using "&&" instead "&" + * V4L/DVB (5010): Cx88: Fix leadtek_eeprom tagging + * [S390] Change max. buffer size for monwriter device. + * [S390] cio: fix stsch_reset. + * ocfs2: don't print error in ocfs2_permission() + * ocfs2: Allow direct I/O read past end of file + * ocfs2: ignore NULL vfsmnt in ocfs2_should_update_atime() + * ocfs2: always unmap in ocfs2_data_convert_worker() + * ocfs2: export heartbeat thread pid via configfs + * VM: Fix nasty and subtle race in shared mmap'ed page writeback + * ieee1394: sbp2: pass REQUEST_SENSE through to the target + * ieee1394: sbp2: fix bogus dma mapping + * [ARM] 4063/1: ep93xx: fix IRQ_EP93XX_GPIO?MUX numbering + * [ARM] 4064/1: make pxa_get_cycles() static + * [ARM] 4065/1: S3C24XX: dma printk fixes + * [ARM] 4066/1: correct a comment about PXA's sched_clock range + * [ARM] 4071/1: S3C24XX: Documentation update + * [ARM] 4073/1: Prevent s3c24xx drivers from including + asm/arch/hardware.h and asm/arch/irqs.h + * [ARM] 4074/1: Flat loader stack alignment + * [ARM] 4077/1: iop13xx: fix __io() macro + * [ARM] 4078/1: Fix ARM copypage cache coherency problems + * Fix IPMI watchdog set_param_str() using kstrdup + * Fix lock inversion aio_kick_handler() + * powerpc iseries link error in allmodconfig + * change WARN_ON back to "BUG: at ..." + * rcu: rcutorture suspend fix + * fix oom killer kills current every time if there is memory-less-node + take2 + * Add .gitignore file for relocs in arch/i386 + * pci/probe: fix macro that confuses kernel-doc + * Char: mxser, fix oops when removing opened + * IB/mthca: Fix FMR breakage caused by kmemdup() conversion + * MAINTAINERS: email addr change for Eric Moore + * make fn_keys work again on power/macbooks + * Char: isicom, eliminate spinlock recursion + * Update to Documentation/tty.txt on line disciplines + * fix mrproper incompleteness + * sched: fix cond_resched_softirq() offset + * Fix compilation of via-pmu-backlight + * module: fix mod_sysfs_setup() return value + * ramfs breaks without CONFIG_BLOCK + * MM: SLOB is broken by recent cleanup of slab.h + * cciss: build with PROC_FS=n + * page_mkclean_one(): fix call to set_pte_at() + * SPI: define null tx_buf to mean "shift out zeroes" + * m25p80 build fixes (with MTD debug) + * SPI/MTD: mtd_dataflash oops prevention + * ARM: OMAP: fix GPMC compiler errors + * ARM: OMAP: fix missing header on apollon board + * Buglet in vmscan.c + * cpuset procfs warning fix + * respect srctree/objtree in Documentation/DocBook/Makefile + * spi_s3c24xx_gpio: use right header + * lockdep: printk warning fix + * PIIX: remove check for broken MW DMA mode 0 + * PIIX/SLC90E66: PIO mode fallback fix + * Update CREDITS and MAINTAINERS entries for Lennert Buytenhek + * KVM: Use boot_cpu_data instead of current_cpu_data + * KVM: Simplify is_long_mode() + * KVM: Initialize kvm_arch_ops on unload + * KVM: Implement a few system configuration msrs + * KVM: Move common msr handling to arch independent code + * KVM: More msr misery + * KVM: Rename some msrs + * KVM: Fix oops on oom + * kvm: fix GFP_KERNEL allocation in atomic section in + kvm_dev_ioctl_create_vcpu() + * sparc32: add offset in pci_map_sg() + * fuse: fix typo + * [SPARC64]: Fix "mem=xxx" handling. + * [SPARC64]: Fix of_iounmap() region release. + * [SPARC64]: Update defconfig. + * [SPARC64]: Handle ISA devices with no 'regs' property. + * [NET]: Add memory barrrier to netif_poll_enable() + * [NET]: Don't export linux/random.h outside __KERNEL__. + * [XFRM]: Algorithm lookup using .compat name + * restore ->pdeath_signal behaviour + * sound: hda: detect ALC883 on MSI K9A Platinum motherboards (MS-7280) + * libata: fix combined mode + * cfq-iosched: merging problem + * selinux: fix selinux_netlbl_inode_permission() locking + * Fix insta-reboot with "i386: Relocatable kernel support" + * [ARM] Fix VFP initialisation issue for SMP systems + * [ARM] 4080/1: Fix for the SSCR0_SlotsPerFrm macro + * [ARM] 4081/1: Add definition for TI Sync Serial Protocol + * x86_64: Fix dump_trace() + + -- Ben Collins Mon, 25 Dec 2006 19:30:22 -0500 + +linux-source-2.6.20 (2.6.20-3.4) feisty; urgency=low + + * Fix FTBFS due to changes in kernel-wedge. + + [Ben Collins] + + * ubuntu/media/usbvideo: Add USB Video Class driver (iSight) + - GIT-SHA a948310ffdeb5d8dddff193aa31da63039d985d5 + * ubuntu/media: Add usbvideo to build. + - GIT-SHA 545ee922c0c492929eaa0a4c675c0f6d3dbc4cfd + * prism2: Fix incorrect conversion of work queue. + - GIT-SHA 44e61605e7d160397082028780da4f749c13db00 + - Bug #76220 + * uvcvideo: Fix usb urb callback prototypes. + - GIT-SHA 4aea9254ec30b7422ca59a617f6a59d951e0769e + * debian/config: Disable speedstep_centrino in favor of acpi_cpufreq. + - GIT-SHA 2a0e7ef37fb8db5953f4c467219552835d7dddd8 + * Fix compile breakage. Patch taken from lkml (will be reverted). + - GIT-SHA 93a714f337c0636b72d605400f41347c4465a344 + * Add ivtv firmware. + - GIT-SHA 9ed1a41d11cffb205f425cc71e7f6c605b284d25 + * sata_svw: Check for error from ata_device_ata() + - GIT-SHA 4b0e1e03cb077b5659d656d8b869c11e2ae47f94 + - Bug #76391 + * pmu-backlight: Fixup for change in backlight_register. + - GIT-SHA c4f21571091b0b7eb798b1e76956b53475bcb5d8 + + [Upstream Kernel Changes] + + * ACPI: Remove unnecessary from/to-void* and to-void casts in + drivers/acpi + * ACPI: avoid gcc warnings in ACPI mutex debug code + * ACPI: uninline ACPI global locking functions + * ACPI: acpi-cpufreq: remove unused data when !CONFIG_SMP + * ACPI: ibm_acpi: Add support for the generic backlight device + * ACPI: asus_acpi: Add support for the generic backlight device + * ACPI: toshiba_acpi: Add support for the generic backlight device + * ACPI: make ec_transaction not extern + * ACPI: optimize pci_rootbridge search + * ACPI: dock: use mutex instead of spinlock + * ACPI: S4: Use "platform" rather than "shutdown" mode by default + * ACPI: Get rid of 'unused variable' warning in + acpi_ev_global_lock_handler() + * ACPI: update comment + * ACPI: button: register with input layer + * ACPI: ibm-acpi: new ibm-acpi maintainer + * ACPI: ibm-acpi: do not use / in driver names + * ACPI: ibm-acpi: trivial Lindent cleanups + * ACPI: ibm-acpi: Use a enum to select the thermal sensor reading + strategy + * ACPI: ibm-acpi: Implement direct-ec-access thermal reading modes for up + to 16 sensors + * ACPI: ibm-acpi: document thermal sensor locations for the A31 + * ACPI: ibm-acpi: prepare to cleanup fan_read and fan_write + * ACPI: ibm-acpi: clean up fan_read + * ACPI: ibm-acpi: break fan_read into separate functions + * ACPI: ibm-acpi: cleanup fan_write + * ACPI: ibm-acpi: document fan control + * ACPI: ibm-acpi: extend fan status functions + * ACPI: ibm-acpi: fix and extend fan enable + * ACPI: ibm-acpi: fix and extend fan control functions + * ACPI: ibm-acpi: store embedded controller firmware version for matching + * ACPI: ibm-acpi: workaround for EC 0x2f initialization bug + * ACPI: ibm-acpi: implement fan watchdog command + * ACPI: ibm-acpi: add support for the ultrabay on the T60,X60 + * ACPI: ibm-acpi: make non-generic bay support optional + * ACPI: ibm-acpi: backlight device cleanup + * ACPI: ibm-acpi: style fixes and cruft removal + * ACPI: ibm-acpi: update version and copyright + * ACPI: dock: Make the dock station driver a platform device driver. + * ACPI: dock: fix build warning + * ACPI: dock: Add a docked sysfs file to the dock driver. + * ACPI: dock: Fix symbol conflict between acpiphp and dock + * ACPI: ec: Allow for write semantics in any command. + * ACPI: ec: Enable EC GPE at beginning of transaction + * ACPI: ec: Increase timeout from 50 to 500 ms to handle old slow + machines. + * ACPI: ec: Read status register from check_status() function + * ACPI: ec: Remove expect_event and all races around it. + * ACPI: ec: Remove calls to clear_gpe() and enable_gpe(), as these are + handled at + * ACPI: ec: Query only single query at a time. + * ACPI: ec: Change semaphore to mutex. + * ACPI: ec: Rename gpe_bit to gpe + * ACPI: ec: Drop udelay() from poll mode. Loop by reading status field + instead. + * ACPI: ec: Acquire Global Lock under EC mutex. + * ACPI: ec: Style changes. + * ACPI: ec: Change #define to enums there possible. + * ACPI: ec: Lindent once again + * drm: fix return value check + * DRM: handle pci_enable_device failure + * i915_vblank_tasklet: Try harder to avoid tearing. + * [CPUFREQ] fixes typo in cpufreq.c + * [CPUFREQ] Trivial cleanup for acpi read/write port in acpi-cpufreq.c + * Generic HID layer - build: USB_HID should select HID + * input/hid: Supporting more keys from the HUT Consumer Page + * Generic HID layer - update MAINTAINERS + * ACPI: dock: add uevent to indicate change in device status + * drm: Unify radeon offset checking. + * [DLM] fix compile warning + * [GFS2] Fix Kconfig + * IB: Fix ib_dma_alloc_coherent() wrapper + * IB/srp: Fix FMR mapping for 32-bit kernels and addresses above 4G + * Fix "delayed_work_pending()" macro expansion + * IB/mthca: Add HCA profile module parameters + * IB/mthca: Use DEFINE_MUTEX() instead of mutex_init() + * Pull ec into test branch + * Pull dock into test branch + * Pull button into test branch + * Pull platform-drivers into test branch + * ACPI: ibm_acpi: respond to workqueue update + * Pull trivial into test branch + * ACPI: fix git automerge failure + * Pull bugfix into test branch + * Pull style into test branch + * ata_piix: IDE mode SATA patch for Intel ICH9 + * ata_piix: use piix_host_stop() in ich_pata_ops + * [libata] use kmap_atomic(KM_IRQ0) in SCSI simulator + * [libata] sata_svw: Disable ATAPI DMA on current boards (errata + workaround) + * libata: don't initialize sg in ata_exec_internal() if DMA_NONE (take + #2) + * ahci: do not mangle saved HOST_CAP while resetting controller + * ata: fix platform_device_register_simple() error check + * initializer entry defined twice in pata_rz1000 + * Fix help text for CONFIG_ATA_PIIX + * pata_via: Cable detect error + * Fix incorrect user space access locking in mincore() + * Make workqueue bit operations work on "atomic_long_t" + * Fix up mm/mincore.c error value cases + * m68k trivial build fixes + * sys_mincore: s/max/min/ + * [ARM] Add more syscalls + * [SPARC64]: Kill no-remapping-needed code in head.S + * [SPARC64]: Minor irq handling cleanups. + * [DocBook]: Fix two typos in generic IRQ docs. + * [SUNKBD]: Fix sunkbd_enable(sunkbd, 0); obvious. + * [SPARC64]: Mirror x86_64's PERCPU_ENOUGH_ROOM definition. + * [SPARC]: Update defconfig. + * [CPUFREQ] set policy->curfreq on initialization + * [ARM] Fix BUG()s in ioremap() code + * [ARM] 4034/1: pxafb: Fix compile errors + * [ARM] 4035/1: fix collie compilation + * [ARM] 4038/1: S3C24XX: Fix copyrights in include/asm-arm/arch-s3c2410 + (core) + * [ARM] 4039/1: S3C24XX: Fix copyrights in include/asm-arm/arch-s3c2410 + (mach) + * [ARM] 4040/1: S3C24XX: Fix copyrights in arch/arm/mach-s3c2410 + * [ARM] 4041/1: S3C24XX: Fix sparse errors from VA addresses + * [ARM] 4042/1: H1940: Fix sparse errors from VA addresses + * [ARM] 4043/1: S3C24XX: fix sparse warnings in + arch/arm/mach-s3c2410/s3c2440-clock.c + * [ARM] 4044/1: S3C24XX: fix sparse warnings in + arch/arm/mach-s3c2410/s3c2442-clock.c + * [ARM] 4045/1: S3C24XX: remove old VA for non-shared areas + * [ARM] 4046/1: S3C24XX: fix sparse errors arch/arm/mach-s3c2410 + * [ARM] 4048/1: S3C24XX: make s3c2410_pm_resume() static + * [ARM] 4049/1: S3C24XX: fix sparse warning due to upf_t in regs-serial.h + * [ARM] 4050/1: S3C24XX: remove old changelogs in arch/arm/mach-s3c2410 + * [ARM] 4051/1: S3C24XX: clean includes in S3C2440 and S3C2442 support + * [CPUFREQ] Advise not to use longhaul on VIA C7. + * [CPUFREQ] longhaul compile fix. + * [ARM] Fix warnings from asm/system.h + * [ARM] 4052/1: S3C24XX: Fix PM in arch/arm/mach-s3c2410/Kconfig + * [ARM] 4054/1: ep93xx: add HWCAP_CRUNCH + * [ARM] 4055/1: iop13xx: fix phys_io/io_pg_offst for iq81340mc/sc + * [ARM] 4056/1: iop13xx: fix resource.end off-by-one in flash setup + * [ARM] 4057/1: ixp23xx: unconditionally enable hardware coherency + * [ARM] 4015/1: s3c2410 cpu ifdefs + * [SPARC]: Make bitops use same spinlocks as atomics. + * more work_struct fixes: tas300x sound drivers + * [TG3]: replace kmalloc+memset with kzalloc + * [AX.25]: Mark all kmalloc users __must_check + * [AX.25]: Fix unchecked ax25_protocol_register uses. + * [AX.25]: Fix unchecked ax25_listen_register uses + * [AX.25]: Fix unchecked nr_add_node uses. + * [AX.25]: Fix unchecked ax25_linkfail_register uses + * [AX.25]: Fix unchecked rose_add_loopback_node uses + * [AX.25]: Fix unchecked rose_add_loopback_neigh uses + * [BNX2]: Fix panic in bnx2_tx_int(). + * [BNX2]: Fix bug in bnx2_nvram_write(). + * [BNX2]: Fix minor loopback problem. + * [NETFILTER] IPV6: Fix dependencies. + * [TG3]: Assign tp->link_config.orig_* values. + * [TG3]: Fix race condition when calling register_netdev(). + * [TG3]: Power down/up 5906 PHY correctly. + * [TG3]: Update version and reldate. + * [CONNECTOR]: Fix compilation breakage introduced recently. + * [TCP]: Fix oops caused by tcp_v4_md5_do_del + * [TCP]: Trivial fix to message in tcp_v4_inbound_md5_hash + * [IPV4]: Fix BUG of ip_rt_send_redirect() + * [CONNECTOR]: Replace delayed work with usual work queue. + * cciss: set default raid level when reading geometry fails + * cciss: fix XFER_READ/XFER_WRITE in do_cciss_request + * drm: savage: compat fix from drm git. + * drm: fixup comment header style + * drm: make kernel context switch same as for drm git tree. + * drm: r128: comment aligment with drm git + * drm: Stop defining pci_pretty_name + * ->nr_sectors and ->hard_nr_sectors are not used for BLOCK_PC requests + * Remove queue merging hooks + * __blk_rq_map_user() doesn't need to grab the queue_lock + * __blk_rq_unmap_user() fails to return error + * Fixup blk_rq_unmap_user() API + * [PARTITION]: Add whole_disk attribute. + * [POWERPC] cell: update cell_defconfig + * [POWERPC] cell: add forward struct declarations to spu.h + * [POWERPC] cell: Enable spider workarounds on all PCI buses + * [POWERPC] cell: Fix spufs with "new style" device-tree + * [POWERPC] spufs: fix assignment of node numbers + * [POWERPC] powerpc: add scanning of ebc bus to of_platform + * [ARM] 4022/1: iop13xx: generic irq fixups + * [ARM] 4059/1: VR1000: fix LED3's platform device number + * [ARM] 4061/1: xsc3: change of maintainer + * [ARM] 4060/1: update several ARM defconfigs + * [ARM] 4062/1: S3C24XX: Anubis and Osiris shuld have CONFIG_PM_SIMTEC + * ACPI: ibm_acpi: allow clean removal + * ACPI: fix single linked list manipulation + * ACPI: prevent processor module from loading on failures + * [POWERPC] Workaround oldworld OF bug with IRQs & P2P bridges + * [POWERPC] iSeries: fix viodasd init + * [POWERPC] iSeries: fix viotape init + * [POWERPC] iSeries: fix iseries_veth init + * [POWERPC] iSeries: fix viocd init + * [POWERPC] iSeries: fix viocons init + * [POWERPC] iSeries: fix CONFIG_VIOPATH dependency + * [POWERPC] Fix build of cell zImage.initrd + * [POWERPC] Probe Efika platform before CHRP. + * [POWERPC] Update MTD OF documentation + * [POWERPC] Fix PCI device channel state initialization + * [POWERPC] Fix register save area alignment for swapcontext syscall + * ACPI: make drivers/acpi/ec.c:ec_ecdt static + * ACPI: fix NULL check in drivers/acpi/osl.c + * ACPI: Kconfig - depend on PM rather than selecting it + * ACPI: Implement acpi_video_get_next_level() + * ACPI: video: Add dev argument for backlight_device_register + * fbdev: update after backlight argument change + * ACPI: Add support for acpi_load_table/acpi_unload_table_id + * Pull platform-drivers into test branch + * Pull ec into test branch + * Pull bugfix into test branch + * merge linus into test branch + * Pull sgi into test branch + * [ALSA] via82xx: add __devinitdata + * [ALSA] sound/usb/usbaudio: Handle return value of usb_register() + * [ALSA] sound: Don't include i2c-dev.h + * [ALSA] ac97_codec (ALC655): add EAPD hack for MSI L725 laptop + * [ALSA] use the ALIGN macro + * [ALSA] use the roundup macro + * [ALSA] ymfpci: fix swap_rear for S/PDIF passthrough + * [ALSA] hda-codec - Fix wrong error checks in patch_{realtek,analog}.c + * [ALSA] hda-codec - Don't return error at initialization of modem codec + * [ALSA] hdsp: precise_ptr control switched off by default + * [ALSA] hda-codec - Fix a typo + * [ALSA] pcm core: fix silence_start calculations + * [ALSA] hda-codec - Add model for HP q965 + * [ALSA] sound/core/control.c: remove dead code + * [ALSA] hda-codec - Fix model for ASUS V1j laptop + * [ALSA] hda-codec - Fix detection of supported sample rates + * [ALSA] hda-codec - Verbose proc output for PCM parameters + * [ALSA] ac97 - Fix potential negative array index + * [ALSA] hda-codec - fix typo in PCI IDs + * [ALSA] Fix races in PCM OSS emulation + * [ALSA] Fix invalid assignment of PCI revision + * [ALSA] Remove IRQF_DISABLED for shared PCI irqs + * [ALSA] snd_hda_intel 3stack mode for ASUS P5P-L2 + * [ALSA] sound: initialize rawmidi substream list + * [ALSA] sound: fix PCM substream list + * [ALSA] snd-ca0106: Add new card variant. + * [ALSA] snd-ca0106: Fix typos. + * [ALSA] ac97_codec - trivial fix for bit update functions + * [ALSA] ac97: Identify CMI9761 chips. + * [ALSA] version 1.0.14rc1 + * cfq-iosched: don't allow sync merges across queues + * block: document io scheduler allow_merge_fn hook + * [libata] pata_cs5530: suspend/resume support tweak + * [libata] pata_via: suspend/resume support fix + * USB: Fix oops in PhidgetServo + * USB: fix transvibrator disconnect race + * USB: airprime: add device id for dell wireless 5500 hsdpa card + * USB: ftdi_sio - MachX product ID added + * USB: removing ifdefed code from gl620a + * usb serial: Eliminate bogus ioctl code + * USB: mutexification of usblp + * Add Baltech Reader ID to CP2101 driver + * USB: Prevent the funsoft serial device from entering raw mode + * USB: fix ohci.h over-use warnings + * USB: rtl8150 new device id + * usb-storage: Ignore the virtual cd-drive of the Huawei E220 USB Modem + * usb-gsm-driver: Added VendorId and ProductId for Huawei E220 USB Modem + * USB: fix Wacom Intuos3 4x6 bugs + * USB AUERSWALD: replace kmalloc+memset with kzalloc + * USB: Nokia E70 is an unusual device + * UHCI: module parameter to ignore overcurrent changes + * USB: gadget driver unbind() is optional; section fixes; misc + * USB: MAINTAINERS update, EHCI and OHCI + * USB: ohci whitespace/comment fixups + * USB: ohci at91 warning fix + * USB: ohci handles hardware faults during root port resets + * USB: OHCI support for PNX8550 + * USB: at91 udc, support at91sam926x addresses + * USB: at91_udc, misc fixes + * USB: u132-hcd/ftdi-elan: add support for Option GT 3G Quad card + * USB: at91_udc: allow drivers that support high speed + * USB: at91_udc: Cleanup variables after failure in + usb_gadget_register_driver() + * USB: at91_udc: Additional checks + * USB: fix to usbfs_snoop logging of user defined control urbs + * PCI: use /sys/bus/pci/drivers//new_id first + * pci: add class codes for Wireless RF controllers + * PCI quirks: remove redundant check + * rpaphp: compiler warning cleanup + * PCI: pcieport-driver: remove invalid warning message + * pci: Introduce pci_find_present + * PCI: Create __pci_bus_find_cap_start() from __pci_bus_find_cap() + * PCI: Add pci_find_ht_capability() for finding Hypertransport + capabilities + * PCI: Use pci_find_ht_capability() in drivers/pci/htirq.c + * PCI: Add #defines for Hypertransport MSI fields + * PCI: Use pci_find_ht_capability() in drivers/pci/quirks.c + * PCI: Only check the HT capability bits in mpic.c + * PCI: Fix multiple problems with VIA hardware + * PCI: Be a bit defensive in quirk_nvidia_ck804() so we don't risk + dereferencing a NULL pdev. + * PCI: don't export device IDs to userspace + * PCI legacy resource fix + * PCI: ATI sb600 sata quirk + * shpchp: remove unnecessary struct php_ctlr + * shpchp: cleanup struct controller + * shpchp: remove shpchprm_get_physical_slot_number + * shpchp: cleanup shpchp.h + * acpiphp: Link-time error for PCI Hotplug + * kref refcnt and false positives + * kobject: kobject_uevent() returns manageable value + * Driver core: proper prototype for drivers/base/init.c:driver_init() + * [libata] Move some PCI IDs from sata_nv to ahci + * libata: clean up variable name usage in xlat related functions + * libata: kill @cdb argument from xlat methods + * libata: take scmd->cmd_len into account when translating SCSI commands + * USB: Nokia E70 is an unusual device + * usb serial: add support for Novatel S720/U720 CDMA/EV-DO modems + * bluetooth: add support for another Kensington dongle + * [libata] sata_svw, sata_vsc: kill iomem warnings + * USB Storage: remove duplicate Nokia entry in unusual_devs.h + * ACPI: replace kmalloc+memset with kzalloc + * __set_irq_handler bogus space + * x86_64: fix boot hang caused by CALGARY_IOMMU_ENABLED_BY_DEFAULT + * x86_64: fix boot time hang in detect_calgary() + * sched: improve efficiency of sched_fork() + * fix leaks on pipe(2) failure exits + * workqueue: fix schedule_on_each_cpu() + * Clean up and make try_to_free_buffers() not race with dirty pages + * VM: Remove "clear_page_dirty()" and "test_clear_page_dirty()" functions + * Fix JFS after clear_page_dirty() removal + * fuse: remove clear_page_dirty() call + * Fix XFS after clear_page_dirty() removal + * elevator: fixup typo in merge logic + * truncate: dirty memory accounting fix + * KVM: add valid_vcpu() helper + * KVM: AMD SVM: handle MSR_STAR in 32-bit mode + * KVM: AMD SVM: Save and restore the floating point unit state + * KVM: Use more traditional error handling in kvm_mmu_init() + * KVM: Do not export unsupported msrs to userspace + * KVM: Force real-mode cs limit to 64K + * KVM: Handle p5 mce msrs + * KVM: API versioning + * CONFIG_VM_EVENT_COUNTER comment decrustify + * Conditionally check expected_preempt_count in __resched_legal() + * Fix for shmem_truncate_range() BUG_ON() + * rtc warning fix + * slab: fix kmem_ptr_validate definition + * fix kernel-doc warnings in 2.6.20-rc1 + * make kernel/printk.c:ignore_loglevel_setup() static + * fs/sysv/: proper prototypes for 2 functions + * Fix swapped parameters in mm/vmscan.c + * Add cscope generated files to .gitignore + * sched: remove __cpuinitdata anotation to cpu_isolated_map + * fix vm_events_fold_cpu() build breakage + * genirq: fix irq flow handler uninstall + * smc911x: fix netpoll compilation faliure + * smc911 workqueue fixes + * fsstack: Remove inode copy + * lock debugging: fix DEBUG_LOCKS_WARN_ON() & debug_locks_silent + * Make JFFS depend on CONFIG_BROKEN + * Add a new section to CodingStyle, promoting include/linux/kernel.h + * fix aoe without scatter-gather [Bug 7662] + * mm: more rmap debugging + * handle SLOB with sparsemen + * compile error of register_memory() + * audit: fix kstrdup() error check + * gss_spkm3: fix error handling in module init + * schedule_timeout(): improve warning message + * microcode: fix mc_cpu_notifier section warning + * MAINTAINERS: fix email for S3C2410 and S3C2440 + * tlclk: delete unnecessary sysfs_remove_group + * gxt4500: Fix colormap and PLL setting, support GXT6000P + * fdtable: Provide free_fdtable() wrapper + * kernel-doc: allow unnamed structs/unions + * kernel-doc: remove Martin from MAINTAINERS + * mips: if_fddi.h: Add a missing inclusion + * memory hotplug: fix compile error for i386 with NUMA config + * ptrace: Fix EFL_OFFSET value according to i386 pda changes + * relay: remove inlining + * increase CARDBUS_MEM_SIZE + * md: fix a few problems with the interface (sysfs and ioctl) to md + * fix s3c24xx gpio driver (include linux/workqueue.h) + * jbd: wait for already submitted t_sync_datalist buffer to complete + * sched: fix bad missed wakeups in the i386, x86_64, ia64, ACPI and APM + idle code + * build compile.h earlier + * Fix reparenting to the same thread group. (take 2) + * serial/uartlite: Only enable port if request_port succeeded + * Fix up page_mkclean_one(): virtual caches, s390 + * NetLabel: perform input validation earlier on CIPSOv4 DOI add ops + * NetLabel: correctly fill in unused CIPSOv4 level and category mappings + * [ATM]: Remove dead ATM_TNETA1570 option. + * [ATM] drivers/atm/fore200e.c: Cleanups. + * [TCP]: Fix ambiguity in the `before' relation. + * [SCTP]: Don't export include/linux/sctp.h to userspace. + * [SCTP]: Fix typo adaption -> adaptation as per the latest API draft. + * [SCTP]: make 2 functions static + * [IPV6]: Dumb typo in generic csum_ipv6_magic() + * [UDP]: Fix reversed logic in udp_get_port(). + * cfq-iosched: tighten allow merge criteria + * Call init_timer() for ISDN PPP CCP reset state timer + * Clean up and export cancel_dirty_page() to modules + * Fix reiserfs after "test_clear_page_dirty()" removal + * suspend: fix suspend on single-CPU systems + * arch/i386/pci/mmconfig.c tlb flush fix + * Fix up CIFS for "test_clear_page_dirty()" removal + * Linux 2.6.20-rc2 + + -- Ben Collins Sat, 16 Dec 2006 01:56:51 -0500 + +linux-source-2.6.20 (2.6.20-2.2) feisty; urgency=low + + [Ben Collins] + + * debian/config: Enable pata_marvell. + - GIT-SHA 8140eb247a50883afe037f57d4afd143cee902a6 + * ivtv: Add new mpeg encoder driver. + - GIT-SHA fc0ee3058f7ae7096235648aa1dbdf114fa3fc58 + * ubuntu/media: Add ivtv to build. + - GIT-SHA 4850a6d86424b28f967e2eab425152ba4f4147e8 + * ubuntu/ivtv: Build fixes for 2.6.20 (INIT_WORK). + - GIT-SHA fa28b2f82bba8c1bb014ab7de500d48b77404abf + * debian/d-i/package-list: Add nic-firmware + - GIT-SHA 42e1278480fe3c33e5c14fb056c34718fac5e713 + - Bug #73896 + * debian/d-i: Split out nfs modules into nfs-modules. + - GIT-SHA 941250b257eb8bbe7ad811fa56c6ec4973ec6545 + - Bug #73910 + * debian/d-i: Add cdrom modules + - GIT-SHA c2670818134e76c571cbc17aa26551d0064305e0 + - Bug #73911 + * include/asm-*/setup.h: Set command line size to 1024 + - GIT-SHA 3812de95f1b4d800081e7f06c5b9bc9c3873003c + - Bug #23716 + * debian/d-i: Add block and message udeb's. + - GIT-SHA 6e997e89249bfd8bbc20bf1f0349fb0bccde2d95 + * ide/piix: ifdef out some pci id's when ata_piix is enabled. + - GIT-SHA d28a0a771e1c30c5b89999e5c51e33471a6f6ed2 + + [Upstream Kernel Changes] + + * [CPUFREQ] Documentation fix + * [CPUFREQ][1/8] acpi-cpufreq: software coordination and handle all CPUs + in the group + * [CPUFREQ][2/8] acpi: reorganize code to make MSR support addition + easier + * [CPUFREQ][3/8] acpi-cpufreq: Pull in MSR based transition support + * [CPUFREQ][4/8] acpi-cpufreq: Mark speedstep-centrino ACPI as deprecated + * [CPUFREQ][5/8] acpi-cpufreq: lindent acpi-cpufreq.c + * [CPUFREQ][6/8] acpi-cpufreq: Eliminate get of current freq on + notification + * [CPUFREQ][7/8] acpi-cpufreq: Fix get of current frequency breakage + * [CPUFREQ][8/8] acpi-cpufreq: Add support for freq feedback from + hardware + * [CPUFREQ] sc520_freq.c: ioremap balanced with iounmap + * [CPUFREQ] Fix speedstep-smi CPU detection to not run on Pentium 4. + * [CPUFREQ] Remove duplicate include from acpi-cpufreq + * [CPUFREQ] acpi-cpufreq: Fix up some CodingStyle nits leftover from the + lindenting. + * [CPUFREQ] handle sysfs errors + * [CPUFREQ] speedstep-centrino: remove dead code + * [CPUFREQ] ifdef more unused on !SMP code. + * [AGPGART] Fix up misprogrammed bridges with incorrect AGPv2 rates. + * [CPUFREQ] Fix coding style issues in cpufreq. + * [CPUFREQ] p4-clockmod: add more CPUs + * [CPUFREQ] speedstep-centrino should ignore upper performance control + bits + * [CPUFREQ] Fix build failure on x86-64 + * JFS: Fix conflicting superblock flags + * [WATCHDOG] rm9k_wdt: fix compilation + * [WATCHDOG] rm9k_wdt: fix interrupt handler arguments + * [WATCHDOG] watchdog miscdevice patch + * ocfs2: local mounts + * ocfs2: update mount option documentation + * ocfs2: Synchronize feature incompat flags in ocfs2_fs.h + * [patch 1/3] OCFS2 - Expose struct o2nm_cluster + * [patch 2/3] OCFS2 Configurable timeouts + * [ARM] 4010/1: AT91SAM9260-EK board: Prepare for MACB Ethernet support + * [ARM] 4011/1: AT91SAM9260: Fix compilation with NAND driver + * [ARM] Handle HWCAP_VFP in VFP support code + * [ARM] Formalise the ARMv6 processor name string + * [ARM] 4004/1: S3C24XX: UDC remove implict addition of VA to regs + * [ARM] Add sys_*at syscalls + * i2c: Fix documentation typos + * i2c: Update the list of driver IDs + * i2c: Delete the broken i2c-ite bus driver + * i2c: New Philips PNX bus driver + * i2c: Add request/release_mem_region to i2c-ibm_iic bus driver + * i2c: Cleanups to the i2c-nforce2 bus driver + * i2c: Add support for nested i2c bus locking + * i2c: New Atmel AT91 bus driver + * i2c: Use put_user instead of copy_to_user where possible + * i2c: Whitespace cleanups + * i2c: Use the __ATTR macro where possible + * i2c: i2c-i801 documentation update + * i2c: fix broken ds1337 initialization + * i2c: New ARM Versatile/Realview bus driver + * i2c: Discard the i2c algo del_bus wrappers + * i2c: Enable PEC on more i2c-i801 devices + * i2c: Fix return value check in i2c-dev + * i2c: Refactor a kfree in i2c-dev + * i2c: Fix OMAP clock prescaler to match the comment + * [patch 3/3] OCFS2 Configurable timeouts - Protocol changes + * [ARM] Clean up KERNEL_RAM_ADDR + * sh: Reworked swap cache entry encoding for SH-X2 MMU. + * sh: Shut up csum_ipv6_magic() warnings. + * sh: push-switch fixups for work_struct API damage. + * sh: Add uImage and S-rec generation support. + * sh: SH-2 defconfig updates. + * sh: register rtc resources for sh775x. + * rtc: rtc-sh: fix for period rtc interrupts. + * sh: landisk board build fixes. + * sh: gcc4 symbol export fixups. + * sh: IPR IRQ updates for SH7619/SH7206. + * sh: Trivial build fixes for SH-2 support. + * sh: Fix Solution Engine 7619 build. + * sh: Split out atomic ops logically. + * serial: sh-sci: Shut up various sci_rxd_in() gcc4 warnings. + * sh: Kill off unused SE7619 I/O ops. + * rtc: rtc-sh: fix rtc for out-by-one for the month. + * rtc: rtc-sh: alarm support. + * sh: BUG() handling through trapa vector. + * sh: Fix get_wchan(). + * sh: Fixup kernel_execve() for syscall cleanups. + * sh: Convert remaining remap_area_pages() users to ioremap_page_range(). + * sh: Fixup dma_cache_sync() callers. + * sh: SH-MobileR SH7722 CPU support. + * sh: Fixup sh_bios() trap handling. + * sh: Hook up SH7722 scif ipr interrupts. + * sh: Fixup .data.page_aligned. + * sh: Fix .empty_zero_page alignment for PAGE_SIZE > 4096. + * sh: Use early_param() for earlyprintk parsing. + * sh: Fixup SH-2 BUG() trap handling. + * remove blk_queue_activity_fn + * fix SG_IO bio leak + * remove unnecessary blk_queue_bounce in SG_IO + * V4L/DVB (4954): Fix: On ia64, i2c adap->inb/adap->outb are wrongly + evaluated + * lockdep: fix seqlock_init() + * net, 8139too.c: fix netpoll deadlock + * netpoll: fix netpoll lockup + * hwmon/f71805f: Store the fan control registers + * hwmon/f71805f: Add manual fan speed control + * hwmon/f71805f: Let the user adjust the PWM base frequency + * hwmon/f71805f: Support DC fan speed control mode + * hwmon/f71805f: Add support for "speed mode" fan speed control + * hwmon/f71805f: Document the fan control features + * hwmon/pc87360: Autodetect the VRM version + * hwmon/hdaps: Move the DMI detection data to .data + * hwmon/hdaps: Update the list of supported devices + * hwmon/it87: Remove the SMBus interface support + * hwmon: New PC87427 hardware monitoring driver + * hwmon/f71805f: Add support for the Fintek F71872F/FG chip + * hwmon/f71805f: Always create all fan inputs + * hwmon/f71805f: Fix the device address decoding + * hwmon: Update Rudolf Marek's e-mail address + * hwmon: New Winbond W83793 hardware monitoring driver + * hwmon/w83793: Add documentation and maintainer + * hwmon: New AMS hardware monitoring driver + * hwmon: Add MAINTAINERS entry for new ams driver + * EXT{2,3,4}_FS: remove outdated part of the help text + * [IA64] Do not call SN_SAL_SET_CPU_NUMBER twice on cpu 0 + * Use consistent casing in help message + * [IA64] CONFIG_KEXEC/CONFIG_CRASH_DUMP permutations + * [IA64] Kexec/Kdump: honour non-zero crashkernel offset. + * [IA64] kexec/kdump: tidy up declaration of relocate_new_kernel_t + * Fix small typo in drivers/serial/icom.c + * Remove duplicate "have to" in comment + * Kconfig: fix spelling error in config KALLSYMS help text + * include/linux/compiler.h: reject gcc 3 < gcc 3.2 + * remove config ordering/dependency between ucb1400-ts and sound + subsystem + * [IA64] s/termios/ktermios/ in simserial.c + * fix typo in net/ipv4/ip_fragment.c + * um: replace kmalloc+memset with kzalloc + * e100: replace kmalloc with kcalloc + * kconfig: Standardize "depends" -> "depends on" in Kconfig files + * configfs.h: Remove dead macro definitions. + * fs: Convert kmalloc() + memset() to kzalloc() in fs/. + * Jon needs a new shift key. + * Fix typo in new debug options. + * Fix inotify maintainers entry + * [IA64] fix arch/ia64/mm/contig.c:235: warning: unused variable `nid' + * [IA64] - Reduce overhead of FP exception logging messages + * [IA64] fix possible XPC deadlock when disconnecting + * IB/fmr: ib_flush_fmr_pool() may wait too long + * IB/ipath: Remove unused "write-only" variables + * IB/iser: Remove unused "write-only" variables + * RDMA/amso1100: Fix memory leak in c2_qp_modify() + * IB/ipath: Fix IRQ for PCI Express HCAs + * RDMA/cma: Remove unneeded qp_type parameter from rdma_cm + * RDMA/cma: Report connect info with connect events + * RDMA/cma: Allow early transition to RTS to handle lost CM messages + * RDMA/cma: Add support for RDMA_PS_UDP + * RDMA/cma: Export rdma cm interface to userspace + * [IA64] Take defensive stance on ia64_pal_get_brand_info() + * [IA64] enable trap code on slot 1 + * [IA64] kprobe clears qp bits for special instructions + * [CPUFREQ] Optimize gx-suspmod revision ID fetching + * [CPUFREQ] speedstep-centrino should ignore upper performance control + bits + * [CPUFREQ] Fix the bug in duplicate freq elimination code in + acpi-cpufreq + * [CPUFREQ] Fix git URL. + * IB: Add DMA mapping functions to allow device drivers to interpose + * IB/ipath: Implement new verbs DMA mapping functions + * IB/core: Use the new verbs DMA mapping functions + * [CPUFREQ] p4-clockmod: fix support for Core + * IPoIB: Use the new verbs DMA mapping functions + * IB/srp: Use new verbs IB DMA mapping functions + * IB/iser: Use the new verbs DMA mapping functions + * [CPUFREQ] Longhaul - fix 200MHz FSB + * [CPUFREQ] Longhaul - Add support for CN400 + * [WATCHDOG] pcwd_usb.c generic HID include file + * IPoIB: Make sure struct ipoib_neigh.queue is always initialized + * [AGPGART] agp-amd64: section mismatches with HOTPLUG=n + * [AGPGART] VIA and SiS AGP chipsets are x86-only + * Propagate down request sync flag + * [PATCH 1/2] cciss: map out more memory for config table + * [PATCH 2/2] cciss: remove calls to pci_disable_device + * Allow as-iosched to be unloaded + * [ARM] Unuse another Linux PTE bit + * [ARM] Clean up ioremap code + * [ARM] 4012/1: Clocksource for pxa + * [ARM] 4013/1: clocksource driver for netx + * [ARM] 4014/1: include drivers/hid/Kconfig + * Fixup cciss error handling + * [ARM] Remove empty fixup function + * arch/i386/kernel/smpboot.c: remove unneeded ifdef + * tty: export get_current_tty + * KVM: Add missing include + * KVM: Put KVM in a new Virtualization menu + * KVM: Clean up AMD SVM debug registers load and unload + * KVM: Replace __x86_64__ with CONFIG_X86_64 + * fix more workqueue build breakage (tps65010) + * another build fix, header rearrangements (OSK) + * uml: fix net_kern workqueue abuse + * isdn/gigaset: fix possible missing wakeup + * i2o_exec_exit and i2o_driver_exit should not be __exit. + * Fix section mismatch in parainstructions + * KVM: Make the GET_SREGS and SET_SREGS ioctls symmetric + * KVM: Move find_vmx_entry() to vmx.c + * KVM: Remove extranous put_cpu() from vcpu_put() + * KVM: MMU: Ignore pcd, pwt, and pat bits on ptes + * KVM: Add MAINTAINERS entry + * vt: fix comments to not refer to kill_proc + * kconfig: new function "bool conf_get_changed(void)" + * kconfig: make sym_change_count static, let it be altered by 2 functions + only + * kconfig: add "void conf_set_changed_callback(void (*fn)(void))", use it + in qconf.cc + * kconfig: set gconf's save-widget's sensitivity according to .config's + changed state + * reorder struct pipe_buf_operations + * slab: fix sleeping in atomic bug + * Fix crossbuilding checkstack + * md: Don't assume that READ==0 and WRITE==1 - use the names explicitly + * KVM: Disallow the kvm-amd module on intel hardware, and vice versa + * KVM: Don't touch the virtual apic vt registers on 32-bit + * KVM: Fix vmx hardware_enable() on macbooks + * w1: Fix for kconfig entry typo + * isicom: fix build with PCI disabled + * mxser_new: fix non-PCI build + * sx: fix non-PCI build + * cciss: map out more memory for config table + * cciss: remove calls to pci_disable_device + * Cleanup slab headers / API to allow easy addition of new slab + allocators + * More slab.h cleanups + * cpuset: rework cpuset_zone_allowed api + * SLAB: use a multiply instead of a divide in obj_to_index() + * PM: Fix freezing of stopped tasks + * PM: Fix SMP races in the freezer + * Xtensa: Add ktermios and minor filename fix + * touch_atime() cleanup + * relative atime + * ocfs2: relative atime support + * optimize o_direct on block devices + * debug: add sysrq_always_enabled boot option + * lockdep: filter off by default + * lockdep: improve verbose messages + * lockdep: improve lockdep_reset() + * lockdep: clean up VERY_VERBOSE define + * lockdep: use chain hash on CONFIG_DEBUG_LOCKDEP too + * lockdep: print irq-trace info on asserts + * lockdep: fix possible races while disabling lock-debugging + * Use activate_mm() in fs/aio.c:use_mm() + * Fix numerous kcalloc() calls, convert to kzalloc() + * tty: remove useless memory barrier + * CONFIG_COMPUTONE should depend on ISA|EISA|PCI + * appldata_mem dependes on vm counters + * uml problems with linux/io.h + * missing includes in hilkbd + * hci endianness annotations + * lockd endianness annotations + * rtc: fx error case + * RTC driver init adjustment + * rtc: remove syslog spam on registration + * rtc framewok: rtc_wkalrm.enabled reporting updates + * tty_io.c balance tty_ldisc_ref() + * n_r3964: Use struct pid to track user space clients + * smbfs: Make conn_pid a struct pid + * ncpfs: Use struct pid to track the userspace watchdog process + * ncpfs: ensure we free wdog_pid on parse_option or fill_inode failure + * update Tigran's email addresses + * one more EXPORT_UNUSED_SYMBOL removal + * remove the broken BLK_DEV_SWIM_IOP driver + * knfsd: nfsd4: remove a dprink from nfsd4_lock + * knfsd: svcrpc: fix gss krb5i memory leak + * knfsd: nfsd4: clarify units of COMPOUND_SLACK_SPACE + * knfsd: nfsd: make exp_rootfh handle exp_parent errors + * knfsd: nfsd: simplify exp_pseudoroot + * knfsd: nfsd4: handling more nfsd_cross_mnt errors in nfsd4 readdir + * knfsd: nfsd: don't drop silently on upcall deferral + * knfsd: svcrpc: remove another silent drop from deferral code + * knfsd: nfsd4: pass saved and current fh together into nfsd4 operations + * knfsd: nfsd4: remove spurious replay_owner check + * knfsd: nfsd4: move replay_owner to cstate + * knfsd: nfsd4: don't inline nfsd4 compound op functions + * knfsd: nfsd4: make verify and nverify wrappers + * knfsd: nfsd4: reorganize compound ops + * knfsd: nfsd4: simplify migration op check + * knfsd: nfsd4: simplify filehandle check + * knfsd: Don't ignore kstrdup failure in rpc caches + * knfsd: Fix up some bit-rot in exp_export + * Optimize calc_load() + * ide: HPT3xxN clocking fixes + * ide: fix HPT37x timing tables + * ide: optimize HPT37x timing tables + * ide: fix HPT3xx hotswap support + * ide: fix the case of multiple HPT3xx chips present + * ide: HPT3xx: fix PCI clock detection + * HPT37x: read f_CNT saved by BIOS from port + * fbdev: remove references to non-existent fbmon_valid_timings() + * sstfb: add sysfs interface + * getting rid of all casts of k[cmz]alloc() calls + * Add support for Korenix 16C950-based PCI cards + * Fix COW D-cache aliasing on fork + * Pass vma argument to copy_user_highpage(). + * MIPS: Fix COW D-cache aliasing on fork + * Optimize D-cache alias handling on fork + * Add missing KORENIX PCI ID's + * [ARM] 4016/1: prefetch macro is wrong wrt gcc's + "delete-null-pointer-checks" + * [ARM] Provide a method to alter the control register + * [ARM] 3992/1: i.MX/MX1 CPU Frequency scaling support + * [IA64] Move sg_dma_{len,address} from pci.h to scatterlist.h + * [ARM] 4017/1: [Jornada7xx] - Updating Jornada720.c + * Driver core: show "initstate" of module + * driver core: delete virtual directory on class_unregister() + * DebugFS : inotify create/mkdir support + * DebugFS : coding style fixes + * DebugFS : file/directory creation error handling + * DebugFS : more file/directory creation error handling + * DebugFS : file/directory removal fix + * Driver core: "platform_driver_probe() can save codespace": save + codespace + * Driver core: Make platform_device_add_data accept a const pointer + * Driver core: deprecate PM_LEGACY, default it to N + * [NETFILTER]: Fix INET=n linking error + * [NETFILTER]: nf_nat: fix NF_NAT dependency + * [NETFILTER]: x_tables: error if ip_conntrack is asked to handle IPv6 + packets + * [NETFILTER]: x_tables: add missing try to load conntrack from + match/targets + * [NETFILTER]: ip_tables: ipt and ipt_compat checks unification + * [NETFILTER]: {ip,ip6,arp}_tables: fix exponential worst-case search for + loops + * [DCCP] ccid3: return value in ccid3_hc_rx_calc_first_li + * [IPV6]: Fix IPV6_UNICAST_HOPS getsockopt(). + * [TCP]: Fix oops caused by __tcp_put_md5sig_pool() + * [SCTP]: Handle address add/delete events in a more efficient way. + * [SCTP]: Enable auto loading of SCTP when creating an ipv6 SCTP socket. + * [SCTP]: Add support for SCTP_CONTEXT socket option. + * [IPV6]: Make fib6_node subtree depend on IPV6_SUBTREES + * Linux v2.6.20-rc1 + * ib_verbs: Use explicit if-else statements to avoid errors with do-while + macros + * [S390] update default configuration + * [S390] hypfs fixes + * [S390] Hipersocket multicast queue: make sure outbound handler is + called + * [S390] zcrypt: module unload fixes. + * [S390] sclp_cpi module license. + * [S390] Fix reboot hang on LPARs + * [S390] Fix reboot hang + * [S390] Save prefix register for dump on panic + * [S390] cio: css_register_subchannel race. + * Remove stack unwinder for now + + -- Ben Collins Wed, 13 Dec 2006 11:29:31 -0500 + +linux-source-2.6.20 (2.6.20-1.1) feisty; urgency=low + + [Ben Collins] + + * debian/: Fix lowlatency config rewrite so PREEMPT gets enabled. + - GIT-SHA 510032237707def6475ec51a206644ebf90da9c9 + * debian/: Add initramfs hook for copying firmware needed in initrd. + - GIT-SHA 2f049facd27d03ca42d0a00bcba3567ea6c43c1c + * x86: Revert patch that allows disabling hyper-threading. + - GIT-SHA a5443e2694749510381b4c54b95f5a3ee2656dcf + * debian/: Revert kernelfirmware changes in favour of initramfs-tools + solution. + - GIT-SHA b4ce570a6dff8b1acfb130e0840ef7bc1ca3194f + * forcedeth: Revert phy patch. + - GIT-SHA 3cd0410cba86a7e97535f5d7dda18a71ec91b772 + * rt2x00: Added drivers from Edgy with build fixes. + - GIT-SHA 3e684dade463576854892501ab33b3f4e6557b6a + * arch/sparc64/prom: Remove local change. + - GIT-SHA e9f507d104bbe9a1bf58671408682c095615c93d + * ndsiwrapper: Added driver + - GIT-SHA d11fd0dd38f5e903108e6205e38dfcf84ea149c6 + * ubuntu/: Compile fixes for header changes in 2.6.20 + - GIT-SHA 9fe44155276658fad4afab56bd80229bb9b903dc + * ubuntu/wireless/rt2x00: Add eeprom module to Makefile. + - GIT-SHA b6406283cc8b87b4f118e532d31f627b4071a086 + * kernel/workqueue: Export current_is_kevent() for libphy. + - GIT-SHA 6f786ce77e68085661a02ee99cfb4b7ca290fb17 + * debian/config: Enable all keyspan fw extensions. + - GIT-SHA 97079628a3cc9921eb5d7149580d2971860980eb + * ubuntu/: Add includes to make up for header changes on x86_64. + - GIT-SHA 1315457d772e24484c9fb5cfae2cf5dcbed6588d + * Remove UP-APIC off-by-default patch. + - GIT-SHA 57daa7b7720d9581f9a2261ef57d70c4160617b9 + * ubuntu/: INIT_WORK changes for ubuntu supplied drivers. + - GIT-SHA 5e330f1f67613ff6d092261c03ba3816a4e9c76d + * debian/config/: Disable legacy rt2x00 drivers, and enable newer ones. + - GIT-SHA 5f3f7f497bf055ee9e8796e08cc14f55e78b7b84 + * ubuntu/ndiswrapper: Allow enabling of OWN_WQ. + - GIT-SHA aef1808d7ce20b989c5da8e8fa983d23d8831447 + * ubuntu/misc/Kconfig: Add NIDSWRAPPER_WQ option. + - GIT-SHA 683ceae36cc76dccf60d0b42b6f7e6dc664338b9 + * ubuntu/fs/asfs: Fix compiler failure with new upstream code. + - GIT-SHA e651660640a32c6701a43ba6ea6b0b88ad3f2f70 + * ubuntu/: kmem_cache and SLAB_{ATOMIC,KERNEL} fixes. + - GIT-SHA 420832806cb9387909466f70739ca6a29281fac2 + * ubuntu/rtl_ieee80211/: Add some compatibility crypto calls. + - GIT-SHA 84d69c35b71f8daff106ff50471ee447adaaf6a9 + * ubuntu/: Fixes for freezer stuff moving to linux/freezer.h + - GIT-SHA f2fc18057022e3b792cddc8326e6116a08bd392b + * libata: Fix legacy mode for things like piix. + - GIT-SHA b604c4235e72743435b81fe20bfd78343edd159f + * ia64: Move sg_dma_* functions from pci.h to scatterlist.h + - GIT-SHA 71f54a36da8d5d098cdd13f86dabe8621834ba45 + * bacom_app: Fix typo introduced in + 15b1c0e822f578306332d4f4c449250db5c5dceb + - GIT-SHA 06c07cb91d6185f691bbd034670308c61bf70dcf + * dmasound: Fix INIT_WORK usage. + - GIT-SHA 9ba10c5168a94a51844b368af0fdcea22aa2ffe2 + * (promise) support PATA ports on SATA controllers + - GIT-SHA 1bcbb7e20a7eab8427ac9b227b3db887d873cbac + * Patch to correct INIT_WORK conversion. + - GIT-SHA d3e411fc1bf19f179b76b1e6e4e13127252e4c64 + * rt2500-legacy: Fixes for INIT_WORK changes. + - GIT-SHA 28b1115c58bda8f1eddffdf855d9034b0c33a7d7 + + [Kyle McMartin] + + * ipw3945: Update to v1.1.3 + - GIT-SHA d5969a44fb688e2a619b3320a571c584a1d6452f + * ubuntu/wireless/: Finish cleaning up INIT_WORK + - GIT-SHA 0f91ed3ff67c95751252172bb48b5fd96980c71f + + -- Ben Collins Tue, 28 Nov 2006 22:53:51 -0500 + +linux-source-2.6.19 (2.6.19-7.10) feisty; urgency=low + + [Ben Collins] + + * amd76x_edac: Disable because of conflict with amd_k7_agp. + - GIT-SHA 6027f7346f0f996c8efca626dec3b327bd7dca9e + - Bug #71522 + * debian/config: Disable aic7xxx_old (scary stuff) + - GIT-SHA a5a7e7b6bd8bb31c9c871aae441d1efd85ef815b + * debian/config: Enable qla2xxx FC driver. + - GIT-SHA afdcea31e92bf7d0de2938848ac21e87fe3ce584 + * debian/firmware: Add qla2xxx firmware. + - GIT-SHA c980a1cfa2bc6623c9732ebae9d63aae9f0d7e27 + * Add a lowlatency kernel target. + - GIT-SHA 1b7aff0509741650a83c7afddc5406ac5278a2c2 + * ubuntu/mactel: Add applesmc driver. + - GIT-SHA c983d32ab69771aadbf7d8f8451f3c28eda8223f + * ubuntu/mactel: Add apple IR driver. + - GIT-SHA 26bb7f92982a1e94c3743e8ebddda8c878979d35 + * debian/bin: Tuck my build scripts in here for public consumption. + - GIT-SHA a77f2b3d8fa59395d3be8e966411e4490a6f8779 + * git-ubuntu-log: Use Text::Wrap to format comments into changelog. + - GIT-SHA 997bab71d64926c335703bbaf5dc4d36bce3b335 + + [Fabio M. Di Nitto] + + * ubuntu/fs/gfs update to 24/11/2006 CVS snapshot + - GIT-SHA c8f1688a4d613c62d6e019aa66b2fd4817209e51 + + [Upstream Kernel Changes] + + * x86-64: Fix C3 timer test + * x86-64: increase PHB1 split transaction timeout + * [ARM] 3933/1: Source drivers/ata/Kconfig + * [ARM] ebsa110: fix warnings generated by asm/arch/io.h + * IB/ipath: Depend on CONFIG_NET + * [XFS] Fix uninitialized br_state and br_startoff in + * [XFS] Stale the correct inode when freeing clusters. + * x86_64: Align data segment to PAGE_SIZE boundary + * Fix CPU_FREQ_GOV_ONDEMAND=y compile error + * [IPV6] ROUTE: Try to use router which is not known unreachable. + * [IPV6] ROUTE: Prefer reachable nexthop only if the caller requests. + * [IPV6] ROUTE: Do not enable router reachability probing in router mode. + * [IPV6] IP6TUNNEL: Delete all tunnel device when unloading module. + * [IPV6] IP6TUNNEL: Add missing nf_reset() on input path. + * [Bluetooth] Attach low-level connections to the Bluetooth bus + * [Bluetooth] Handling pending connect attempts after inquiry + * [Bluetooth] Check if RFCOMM session is still attached to the TTY + * [Bluetooth] Always include MTU in L2CAP config responses + * [Bluetooth] Ignore L2CAP config requests on disconnect + * [IGMP]: Fix IGMPV3_EXP() normalization bit shift value. + * [XFRM]: Sub-policies broke policy events + * [XFRM]: nlmsg length not computed correctly in the presence of + subpolicies + * [BLUETOOTH]: Fix unaligned access in hci_send_to_sock. + * [POWERPC] Revert "[POWERPC] Enable generic rtc hook for the MPC8349 + mITX" + * [POWERPC] Revert "[POWERPC] Add powerpc get/set_rtc_time interface to + new generic rtc class" + * [IRDA]: Lockdep fix. + * [IPV6]: Fix address/interface handling in UDP and DCCP, according to + the scoping architecture. + * [TG3]: Add missing unlock in tg3_open() error path. + * [POWERPC] Fix ucc_geth of_device discovery on mpc832x + * Don't call "note_interrupt()" with irq descriptor lock held + * [AGP] Fix intel 965 AGP memory mapping function + * [ARM] 3942/1: ARM: comment: consistent_sync should not be called + directly + * [ARM] 3941/1: [Jornada7xx] - Addition to MAINTAINERS + * [AGP] Allocate AGP pages with GFP_DMA32 by default + * [MIPS] Hack for SB1 cache issues + * make au1xxx-ide compile again + * Correct bound checking from the value returned from _PPC method. + * Fix i2c-ixp4xx compile (missing brace) + * x86_64: fix bad page state in process 'swapper' + * fix "pcmcia: fix 'rmmod pcmcia' with unbound devices" + * initramfs: handle more than one source dir or file list + * fuse: fix Oops in lookup + * mounstats NULL pointer dereference + * debugfs: add header file + * Documentation/rtc.txt updates (for rtc class) + * rtc framework handles periodic irqs + * rtc class locking bugfixes + * drivers/rtc/rtc-rs5c372.c: fix a NULL dereference + * reiserfs: fmt bugfix + * Fix device_attribute memory leak in device_del + * qconf: fix uninitialsied member + * fix menuconfig colours with TERM=vt100 + * sgiioc4: Disable module unload + * fix copy_process() error check + * tlclk: fix platform_device_register_simple() error check + * Enforce "unsigned long flags;" when spinlocking + * lockdep: spin_lock_irqsave_nested() + * usb: ati remote memleak fix + * uml: make execvp safe for our usage + * [NETFILTER]: H.323 conntrack: fix crash with CONFIG_IP_NF_CT_ACCT + * [UDP]: Make udp_encap_rcv use pskb_may_pull + * [NET]: Fix kfifo_alloc() error check. + * [6PACK]: Masking bug in 6pack driver. + * [NET]: Re-fix of doc-comment in sock.h + * [XFRM] STATE: Fix to respond error to get operation if no matching + entry exists. + * V4L/DVB (4831): Fix tuning on older budget DVBS cards. + * V4L/DVB (4840): Budget: diseqc_method module parameter for cards with + subsystem-id 13c2:1003 + * V4L/DVB (4832): Fix uninitialised variable in dvb_frontend_swzigzag + * V4L/DVB (4849): Add missing spin_unlock to saa6588 decoder driver + * V4L/DVB (4865): Fix: Slot 0 not NULL on disconnecting SN9C10x PC Camera + * V4L/DVB (4885): Improve saa711x check + * Fix incorrent type of flags in + * Fix 'ALIGN()' macro, take 2 + + -- Ben Collins Tue, 21 Nov 2006 08:55:49 -0500 + +linux-source-2.6.19 (2.6.19-6.9) feisty; urgency=low + + [Ben Collins] + + * debian/post-install: Requires built scripts directory. + - GIT-SHA 6f4e4b8f3cf138b57825ed12a0b05ed5bf727216 + + -- Ben Collins Mon, 20 Nov 2006 19:44:27 -0500 + +linux-source-2.6.19 (2.6.19-6.8) feisty; urgency=low + + [Ben Collins] + + * ndsiwrapper: Updates driver to 1.28. + - GIT-SHA a37fed032ec826103a75e51ff1f82c5fea8e9b73 + * debian/*: Update ndiswrapper-modules provides to 1.9 API + - GIT-SHA 4b81c3da5bc7ddf7671f1dd8da2536495e5750ae + * debian/bin/git-hooks/commit-msg: Update to understand merges. + - GIT-SHA 41f189eba8d5645ef0b000007b42f9b26f243297 + * debian/{post,header}-install: Fixup header dirs and symlinks + - GIT-SHA 932cf4988ab7e53d6e71631604aec55c65d4ffa2 + + [Upstream Kernel Changes] + + * [SCSI] aic94xx SCSI timeout fix + * [SCSI] aic94xx SCSI timeout fix: SMP retry fix. + * [SCSI] 3ware 9000 add support for 9650SE + * [SCSI] sg: fix incorrect last scatg length + * [ARM] 3857/2: pnx4008: add devices' registration + * [SCSI] iscsi: always release crypto + * [SCSI] iscsi: add newlines to debug messages + * [SCSI] iscsi_tcp: fix xmittask oops + * [SCSI] iscsi class: update version + * [SCSI] gdth: Fix && typos + * [SCSI] psi240i.c: fix an array overrun + * [ARM] Remove PM_LEGACY=y from selected ARM defconfigs + * hpt37x: Check the enablebits + * pata_artop: fix "& (1 >>" typo + * libata: fix double-completion on error + * x86-64: Fix partial page check to ensure unusable memory is not being marked usable. + * x86-64: Fix PTRACE_[SG]ET_THREAD_AREA regression with ia32 emulation. + * x86-64: shorten the x86_64 boot setup GDT to what the comment says + * x86-64: Handle reserve_bootmem_generic beyond end_pfn + * x86-64: setup saved_max_pfn correctly (kdump) + * x86: Add acpi_user_timer_override option for Asus boards + * x86-64: Fix vgetcpu when CONFIG_HOTPLUG_CPU is disabled + * x86-64: Fix race in exit_idle + * setup_irq(): better mismatch debugging + * fix via586 irq routing for pirq 5 + * revert "PCI: quirk for IBM Dock II cardbus controllers" + * drivers/ide: stray bracket + * autofs4: panic after mount fail + * nvidiafb: fix unreachable code in nv10GetConfig + * usb: MAINTAINERS updates + * hugetlb: prepare_hugepage_range check offset too + * hugetlb: check for brk() entering a hugepage region + * libata: Convert from module_init to subsys_initcall + * cciss: fix iostat + * cpqarray: fix iostat + * Char: isicom, fix close bug + * ALSA: hda-intel - Disable MSI support by default + * Use delayed disable mode of ioapic edge triggered interrupts + * [IA64] bte_unaligned_copy() transfers one extra cache line. + * [POWERPC] Add the thread_siblings files to sysfs + * [POWERPC] Wire up sys_move_pages + * powerpc: windfarm shall request it's sub modules + * Linux 2.6.19-rc6 + * [TG3]: Increase 5906 firmware poll time. + * [NETFILTER]: nfnetlink_log: fix byteorder of NFULA_SEQ_GLOBAL + * [NETFILTER]: Use pskb_trim in {ip,ip6,nfnetlink}_queue + * [NETFILTER]: ip6_tables: fixed conflicted optname for getsockopt + * [NETFILTER]: ip6_tables: use correct nexthdr value in ipv6_find_hdr() + * [TCP]: Fix up sysctl_tcp_mem initialization. + * [TG3]: Disable TSO on 5906 if CLKREQ is enabled. + * [IA64] irqs: use `name' not `typename' + * [IA64] typename -> name conversion + * [IA64] use generic_handle_irq() + * [IA64] a fix towards allmodconfig build + * ipmi: use platform_device_add() instead of platform_device_register() to register device allocated dynamically + * some irq_chip variables point to NULL + * pnx4008: rename driver + * pnx4008:fix NULL dereference in rgbfb + * eCryptfs: dput() lower d_parent on rename + * set default video mode on PowerBook Wallstreet + * IB/ipath - fix driver build for platforms with PCI, but not HT + * parport: fix compilation failure + * hfs_fill_super returns success even if no root inode + * Update udf documentation to reflect current state of read/write support + * dell_rbu: fix error check + * AFS: Amend the AFS configuration options + * Don't give bad kprobes example aka ") < 0))" typo + * fat: add fat_getattr() + * Fix strange size check in __get_vm_area_node() + * eCryptfs: CIFS nlink fixes + * scsi: clear garbage after CDBs on SG_IO + * IPoIB: Clear high octet in QP number + * x86-64: Fix vsyscall.c compilation on UP + * x86_64: fix CONFIG_CC_STACKPROTECTOR build bug + * OHCI: disallow autostop when wakeup is not available + * USB: ftdi_sio: adds vendor/product id for a RFID construction kit + * USB: ftdi driver pid for dmx-interfaces + * USB: Fix UCR-61S2B unusual_dev entry + * USB: OHCI: fix root-hub resume bug + * USB: correct keymapping on Powerbook built-in USB ISO keyboards + * USB Storage: unusual_devs.h entry for Sony Ericsson P990i + * USB: hid-core: Add quirk for new Apple keyboard/trackpad + * usb-storage: Remove duplicated unusual_devs.h entries for Sony Ericsson P990i + * USB: Fixed outdated usb_get_device_descriptor() documentation + * USB: ipaq: Add HTC Modem Support + * USB: auerswald possible memleak fix + * W1: ioremap balanced with iounmap + * debugfs: check return value correctly + * aoe: Add forgotten NULL at end of attribute list in aoeblk.c + * Fix radeon DDC regression + * Fix generic fb_ddc i2c edid probe msg + * lkkbd: Remove my old snail-mail address + * x86_64: stack unwinder crash fix + * i386/x86_64: ACPI cpu_idle_wait() fix + * lockdep: fix static keys in module-allocated percpu areas + * Update my CREDITS entry + * [CRYPTO] api: Remove one too many semicolon + * pcmcia: fix 'rmmod pcmcia' with unbound devices + * i2c-ixp4xx: fix ") != 0))" typo + * scx200_acb: handle PCI errors + * x86_64: fix memory hotplug build with NUMA=n + * ftape: fix printk format warnings + * fix build error for HISAX_NETJET + * m68knommu: fix up for the irq_handler_t changes + * Add "pure_initcall" for static variable initialization + + -- Ben Collins Wed, 15 Nov 2006 13:39:18 -0800 + +linux-source-2.6.19 (2.6.19-6.7) feisty; urgency=low + + [Ben Collins] + + * debian/post-install: Fix typo in asm-ppc header symlinking. + - GIT-SHA 6031489f1288795bface60bf3be309f70046ab58 + + [Upstream Kernel Changes] + + * [CIFS] NFS stress test generates flood of "close with pending write" messages + * [CIFS] Explicitly set stat->blksize + * bcm43xx: Drain TX status before starting IRQs + * bcm43xx: Add error checking in bcm43xx_sprom_write() + * x86-64: clean up io-apic accesses + * x86-64: write IO APIC irq routing entries in correct order + * [CIFS] Fix mount failure when domain not specified + * Regression in 2.6.19-rc microcode driver + * A minor fix for set_mb() in Documentation/memory-barriers.txt + * nfsd4: reindent do_open_lookup() + * nfsd4: fix open-create permissions + * i386: Force data segment to be 4K aligned + * dm: fix find_device race + * dm: suspend: fix error path + * dm: multipath: fix rr_add_path order + * dm: raid1: fix waiting for io on suspend + * drivers/telephony/ixj: fix an array overrun + * Tigran has moved + * md: change ONLINE/OFFLINE events to a single CHANGE event + * md: fix sizing problem with raid5-reshape and CONFIG_LBD=n + * md: do not freeze md threads for suspend + * kretprobe: fix kretprobe-booster to save regs and set status + * ia64: select ACPI_NUMA if ACPI + * sysctl: Undeprecate sys_sysctl + * IPMI: Clean up the waiting message queue properly on unload + * IPMI: retry messages on certain error returns + * ipmi_si_intf.c: fix "&& 0xff" typos + * htirq: refactor so we only have one function that writes to the chip + * htirq: allow buggy drivers of buggy hardware to write the registers + * IB/ipath - program intconfig register using new HT irq hook + * nfsd: fix spurious error return from nfsd_create in async case + * [POWERPC] Make sure initrd and dtb sections get into zImage correctly + * MMC: Poll card status after rescanning cards + * MMC: Do not set unsupported bits in OCR response + * IB/ehca: Assure 4K alignment for firmware control blocks + * [CIFS] Fix minor problem with previous patch + * [IPVS]: Compile fix for annotations in userland. + * [POWERPC] CPM_UART: Fix non-console transmit + * [POWERPC] CPM_UART: Fix non-console initialisation + * [POWERPC] pseries: Force 4k update_flash block and list sizes + * [POWERPC] Fix cell "new style" mapping and add debug + * [POWERPC] cell: set ARCH_SPARSEMEM_DEFAULT in Kconfig + * bonding: lockdep annotation + * com20020 build fix + * drivers cris: return on NULL dev_alloc_skb() + * [IPVS]: More endianness fixed. + * [XFS] 956618: Linux crashes on boot with XFS-DMAPI filesystem when + * [XFS] Keep lockdep happy. + * [XFS] rename uio_read() to xfs_uio_read() + * [XFS] 956664: dm_read_invis() changes i_atime + * [XFS] Clean up i_flags and i_flags_lock handling. + * [XFS] Prevent a deadlock when xfslogd unpins inodes. + * [XFS] Remove KERNEL_VERSION macros from xfs_dmapi.h + * V4L/DVB (4795): Tda826x: use correct max frequency + * V4L/DVB (4802): Cx88: fix remote control on WinFast 2000XP Expert + * V4L/DVB (4804): Fix missing i2c dependency for saa7110 + * V4L/DVB (4814): Remote support for Avermedia 777 + * V4L/DVB (4815): Remote support for Avermedia A16AR + * V4L/DVB (4816): Change tuner type for Avermedia A16AR + * V4L/DVB (4817): Fix uses of "&&" where "&" was intended + * V4L/DVB (4818): Flexcop-usb: fix debug printk + * vmalloc: optimization, cleanup, bugfixes + * pci: don't try to remove sysfs files before they are setup. + * mspec driver build fix + * IPMI: Fix more && typos + * Patch for nvidia divide by zero error for 7600 pci-express card + * Fix missing parens in set_personality() + * .gitignore: add miscellaneous files + * fix Data Acess error in dup_fd + * Fix misrouted interrupts deadlocks + * SCSI core: always store >= 36 bytes of INQUIRY data + * IB/ehca: Use named constant for max mtu + * IB/ehca: Activate scaling code by default + * RDMA/amso1100: Fix unitialized pseudo_netdev accessed in c2_register_device + * RDMA/amso1100: Fix && typo + * IB/mad: Fix race between cancel and receive completion + * Fix bad data direction in SG_IO + * ide-cd: only set rq->errors SCSI style for block pc requests + * [dvb saa7134] Fix missing 'break' for avermedia card case + -- Ben Collins Wed, 15 Nov 2006 13:37:45 -0800 + +linux-source-2.6.19 (2.6.19-5.7) feisty; urgency=low + + [Ben Collins] + + * ubuntu/acerhk: Make this X86_32 only. + - GIT-SHA 58f2ee6dede56d3e412f17561cca861ab155ebfc + + [Upstream Kernel Changes] + + * [ARM] 3917/1: Fix dmabounce symbol exports + * [ARM] 3915/1: S3C2412: Add s3c2410_gpio_getirq() to general gpio.c + * [ARM] 3912/1: Make PXA270 advertise HWCAP_IWMMXT capability + * [ARM] 3918/1: ixp4xx irq-chip rework + * [ARM] 3919/1: Fixed definition of some PXA270 CIF related registers + * [ARM] 3920/1: S3C24XX: Remove smdk2410_defconfig + * [ARM] 3921/1: S3C24XX: remove bast_defconfig + * [ARM] 3922/1: S3C24XX: update s3c2410_defconfig to 2.6.19-rc4 + * [ARM] 3923/1: S3C24XX: update s3c2410_defconfig with new drivers + * [ARM] 3926/1: make timer led handle HZ != 100 + * [ARM] 3927/1: Allow show_mem() to work with holes in memory map. + * Update for the srm_env driver. + * [NET]: kconfig, correct traffic shaper + * [TCP]: Don't use highmem in tcp hash size calculation. + * [PKT_SCHED] sch_htb: Use hlist_del_init(). + * [NETPOLL]: Compute checksum properly in netpoll_send_udp(). + * [NET]: Set truesize in pskb_copy + * [TG3]: Fix array overrun in tg3_read_partno(). + * [DECNET]: Endianess fixes (try #2) + * Linux 2.6.19-rc5 + * [libata] sata_via: fix obvious typo + + -- Ben Collins Tue, 07 Nov 2006 15:18:08 -0800 + +linux-source-2.6.19 (2.6.19-5.6) feisty; urgency=low + + [Ben Collins] + + * debian/bin/git-hooks: Add my hooks for git. + - GIT-SHA 2786fe5a5cd024947d2eec6d9f9014c8a91a4e21 + * acerhk: Acer Travelmate support for special keys. + - GIT-SHA 827225e724afd903b316359effdbb8ae1139cf7b + * rfswitch: Software radio kill switch support. + - GIT-SHA 911f283b4150f73809331a7bcd4812e8d9903a70 + * ubuntu/{av5100,pbe5}: Remove inclusion of linux/config.h + - GIT-SHA 5e6495e09eed2d37c5e19cb827d55b1372f81dbb + * ipg: Added ICPlus 1000A Gigabit Ethernet Driver + - GIT-SHA 9cf35c595ca98658a03932342a4b5d65e36b1226 + * ubuntu/ipg: Fix PCI device ide. + - GIT-SHA 2cc83690105c317ad32ab5340677e894448fe552 + * ipw3945: Update to v1.1.2 + - GIT-SHA 9ad82afb9d97986a46fa849f8e590c070d8a53b5 + * powerpc: Make sure to create arch/powerpc/include/asm symlink + - GIT-SHA 2d655eb92d3a1fa9cdfdd3d5cc01568f0e5d03a7 + + [Upstream Kernel Changes] + + * ieee80211: don't flood log with errors + * hostap_plx: fix CIS verification + * bcm43xx: Fix low-traffic netdev watchdog TX timeouts + * bcm43xx: fix unexpected LED control values in BCM4303 sprom + * V4L/DVB (4752): DVB: Add DVB_FE_CUSTOMISE support for MT2060 + * V4L/DVB (4785): Budget-ci: Change DEBIADDR_IR to a safer default + * V4L/DVB (4786): Pvrusb2: use NULL instead of 0 + * V4L/DVB (4787): Budget-ci: Inversion setting fixed for Technotrend 1500 T + * V4L/DVB (4770): Fix mode switch of Compro Videomate T300 + * V4L/DVB (4784): [saa7146_i2c] short_delay mode fixed for fast machines + * V4L/DVB (4751): Fix DBV_FE_CUSTOMISE for card drivers compiled into kernel + * [IPX]: Trivial parts of endianness annotations + * [IPX]: Annotate and fix IPX checksum + * [IPV6]: Fix ECN bug on big-endian + * [NETFILTER] bug: NFULA_CFG_QTHRESH uses 32bit + * [NETFILTER] bug: nfulnl_msg_config_mode ->copy_range is 32bit + * [NETFILTER] bug: skb->protocol is already net-endian + * [TG3]: Fix 2nd ifup failure on 5752M. + * [PKTGEN]: TCI endianness fixes + * [NET]: __alloc_pages() failures reported due to fragmentation + * [IPV6]: Add ndisc_netdev_notifier unregister. + * [IPV6]: Give sit driver an appropriate module alias. + * [NETLABEL]: Fix build failure. + * [SPARC]: Fix robust futex syscalls and wire up migrate_pages. + * ehea: Nullpointer dereferencation fix + * ehea: Removed redundant define + * ehea: 64K page support fix + * Kconfig: remove redundant NETDEVICES depends + * AVR32: Get rid of board_early_init + * AVR32: Fix thinko in generic_find_next_zero_le_bit() + * Fix the spurious unlock_cpu_hotplug false warnings + * Fix for LKDTM MEM_SWAPOUT crashpoint + * isdn/gigaset: convert warning message + * lockdep: fix delayacct locking bug + * Improve the removed sysctl warnings + * sysctl: allow a zero ctl_name in the middle of a sysctl table + * sysctl: implement CTL_UNNUMBERED + * sunrpc: add missing spin_unlock + * [S390] revert add_active_range() usage patch. + * [S390] IRQs too early enabled. + * AVR32: Wire up sys_epoll_pwait + * AVR32: Add missing return instruction in __raw_writesb + * [GFS2] don't panic needlessly + * [GFS2] Fix incorrect fs sync behaviour. + * [GFS2] Fix OOM error handling + * [DLM] Fix kref_put oops + * [DLM] fix oops in kref_put when removing a lockspace + * [MIPS] Ocelot C: Fix large number of warnings. + * [MIPS] Ocelot C: fix eth registration after conversion to platform_device + * [MIPS] Ocelot C: Fix warning about missmatching format string. + * [MIPS] Ocelot C: Fix mapping of ioport address range. + * [MIPS] Ocelot 3: Fix large number of warnings. + * [MIPS] SB1: On bootup only flush cache on local CPU. + * [MIPS] Ocelot C: Fix MAC address detection after platform_device conversion. + * [MIPS] Ocelot 3: Fix MAC address detection after platform_device conversion. + * [MIPS] EV64120: Fix timer initialization for HZ != 100. + * [MIPS] Make irq number allocator generally available for fixing EV64120. + * [MIPS] EV64120: Fix PCI interrupt allocation. + * [MIPS] Fix EV64120 and Ocelot builds by providing a plat_timer_setup(). + * b44: change comment about irq mask register + * e1000: Fix regression: garbled stats and irq allocation during swsusp + + -- Ben Collins Tue, 7 Nov 2006 14:17:22 -0800 + +linux-source-2.6.19 (2.6.19-5.5) feisty; urgency=low + + [Ben Collins] + + * dev_acpi: Added ACPI Device driver + - GIT-SHA e076c92971e36ea2e629be25462ab40ad20cb704 + * pcc-acpi: Panasonc ACPI Driver + - GIT-SHA 95569514a203153c4c4496c8d9c118b39785022c + * ubuntu/acpi: New driver section + - GIT-SHA e22846d3da0ed6f835bcb60485a9bc93eb9ffc6a + * sony_acpi: Add Sony ACPI Laptop driver + - GIT-SHA e4d2ffe08e0b6930582bd81938fe7d2730a0b953 + * tc1100-wmi: Add IBM TC1100 WMI driver + - GIT-SHA e69c9de0b0a12f0917e2f2266c128dd2752c56f2 + * debian: Enable ABI checking + - GIT-SHA 328078e283ff6eacaf5d1a62720fede1e2a68780 + * ubuntu/acpi: Make ACPI sub menu depend on ACPI + - GIT-SHA f55d355afa1ed54296103ddc1f05afb08e5cfca0 + * debian/rules: Export KPKG_ARCH for post-install script. + - GIT-SHA d1669dc891344b6c155037d81234e0218bfbba90 + * ubuntu: Fix wireless drivers to be compatible with WE >= 21 + - GIT-SHA 2e0a08b1d1451201bcac8dae36cd42fdf07735e1 + + [Upstream Kernel Changes] + + * [IA64] don't double >> PAGE_SHIFT pointer for /dev/kmem access + * jfs: Add splice support + * [CIFS] Fix readdir breakage when blocksize set too small + * [CIFS] Allow null user connections + * [NET] sealevel: uses arp_broken_ops + * [APPLETALK]: Fix potential OOPS in atalk_sendmsg(). + * [XFRM] xfrm_user: Fix unaligned accesses. + * [NET]: Fix segmentation of linear packets + * [DCCP]: fix printk format warnings + * [ETH1394]: Fix unaligned accesses. + * [SCTP]: Always linearise packet on input + * [NET]: fix uaccess handling + * [IPV6]: fix lockup via /proc/net/ip6_flowlabel + * [NETFILTER]: remove masq/NAT from ip6tables Kconfig help + * [NETFILTER]: Missed and reordered checks in {arp,ip,ip6}_tables + * [NETFILTER]: ip_tables: compat error way cleanup + * [NETFILTER]: nf_conntrack: add missing unlock in get_next_corpse() + * [NETFILTER]: ip_tables: compat code module refcounting fix + * [NetLabel]: protect the CIPSOv4 socket option from setsockopt() + * [SCTP]: Correctly set IP id for SCTP traffic + * [SCTP]: Remove temporary associations from backlog and hash. + * [IPV6]: return EINVAL for invalid address with flowlabel lease request + * [SPARC64]: Fix Tomatillo/Schizo IRQ handling. + * [SPARC64]: Add some missing print_symbol() calls. + * sh: Wire up new syscalls. + * video: Fix include in hp680_bl. + * sh: Update r7780rp_defconfig. + * sh: Fix IPR-IRQ's for IRQ-chip change breakage. + * sh: Titan defconfig update. + * IB/iser: Start connection after enabling iSER + * RDMA/cma: rdma_bind_addr() leaks a cma_dev reference count + * IB/ehca: Fix eHCA driver compilation for uniprocessor + * IB/amso1100: Use dma_alloc_coherent() instead of kmalloc/dma_map_single + * IB/amso1100: Fix incorrect pr_debug() + * IB/uverbs: Return sq_draining value in query_qp response + * [IPV6]: fix flowlabel seqfile handling + * find_bd_holder() fix + * uml ubd driver: allow using up to 16 UBD devices + * uml ubd driver: document some struct fields + * uml ubd driver: var renames + * uml ubd driver: give better names to some functions. + * uml ubd driver: change ubd_lock to be a mutex + * uml ubd driver: ubd_io_lock usage fixup + * uml ubd driver: convert do_ubd to a boolean variable + * uml ubd driver: reformat ubd_config + * uml ubd driver: use bitfields where possible + * uml ubd driver: do not store error codes as ->fd + * uml ubd driver: various little changes + * uml: add _text definition to linker scripts + * uml: add INITCALLS + * taskstats: fix sub-threads accounting + * eCryptfs: Clean up crypto initialization + * eCryptfs: Hash code to new crypto API + * eCryptfs: Cipher code to new crypto API + * eCryptfs: Consolidate lower dentry_open's + * eCryptfs: Remove ecryptfs_umount_begin + * eCryptfs: Fix handling of lower d_count + * md: check bio address after mapping through partitions. + * CFQ: request <-> request merging rr_list fixup + * SCSI: ISCSI build failure + * IB/mthca: Fix MAD extended header format for MAD_IFC firmware command + * [MIPS] TX4927: Remove indent error message that somehow ended in the code. + * [MIPS] Add missing file for support of backplane on TX4927 based board + * [MIPS] Sort out missuse of __init for prom_getcmdline() + * [MIPS] Yosemite: fix uninitialized variable in titan_i2c_xfer() + * [MIPS] Fix warning of printk format in mips_srs_init() + * [MIPS] VSMP: Fix initialization ordering bug. + * [MIPS] Flags must be unsigned long. + * [MIPS] VSMP: Synchronize cp0 counters on bootup. + * [MIPS] Fixup migration to GENERIC_TIME + * [IA64] cpu-hotplug: Fixing confliction between CPU hot-add and IPI + * [IA64] MCA recovery: Montecito support + * [IA64] move SAL_CACHE_FLUSH check later in boot + * [IA64] Correct definition of handle_IPI + * ep93xx_eth: fix RX/TXstatus ring full handling + * ep93xx_eth: fix unlikely(x) > y test + * ep93xx_eth: don't report RX errors + * tokenring: fix module_init error handling + * n2: fix confusing error code + * sky2: not experimental + * myri10ge: ServerWorks HT2000 PCI id is already defined in pci_ids.h + * ehea: kzalloc GFP_ATOMIC fix + * net s2io: return on NULL dev_alloc_skb() + * skge, sky2, et all. gplv2 only + * sky2: netpoll on dual port cards + * sata_sis: fix flags handling for the secondary port + * Add 0x7110 piix to ata_piix.c + * libata: unexport ata_dev_revalidate() + * ata_piix: allow 01b MAP for both ICH6M and ICH7M + * [POWERPC] Fix various offb issues + * [POWERPC] Fix rmb() for e500-based machines it + * [POWERPC] Fix oprofile support for e500 in arch/powerpc + * [POWERPC] Use 4kB iommu pages even on 64kB-page systems + * [POWERPC] qe_lib: qe_issue_cmd writes wrong value to CECDR + * [POWERPC] Make current preempt-safe + * [POWERPC] Make high hugepage areas preempt safe + * [POWERPC] Make mmiowb's io_sync preempt safe + * [POWERPC] Disallow kprobes on emulate_step and branch_taken + * [POWERPC] Make alignment exception always check exception table + * ahci: fix status register check in ahci_softreset + * [libata] sata_nv: Add PCI IDs + * i386: clean up io-apic accesses + * [MIPS] 16K & 64K page size fixes + * [MIPS] SMTC: Fix crash if # of TC's > # of VPE's after pt_regs irq cleanup. + * [MIPS] SMTC: Synchronize cp0 counters on bootup. + * [MIPS] Fix warning in mips-boards generic PCI + * i386: write IO APIC irq routing entries in correct order + * powerpc: Eliminate "exceeds stub group size" linker warning + * [TIPC] net/tipc/port.c: fix NULL dereference + * [TCP]: Set default congestion control when no sysctl. + * [IPV6]: File the fingerprints off ah6->spi/esp6->spi + * [SPARC64]: Fix futex_atomic_cmpxchg_inatomic implementation. + * [CIFS] report rename failure when target file is locked by Windows + * [MIPS] Fix merge screwup by patch(1) + * [MIPS] IP27: Allow SMP ;-) Another changeset messed up by patch. + * [MIPS] Fix warning about init_initrd() call if !CONFIG_BLK_DEV_INITRD. + * [MIPS] Ocelot G: Fix : "CURRENTLY_UNUSED" is not defined warning. + * [MIPS] Don't use R10000 llsc workaround version for all llsc-full processors. + * [MIPS] Do not use -msym32 option for modules. + * RDMA/addr: Use client registration to fix module unload race + * [libata] Add support for PATA controllers of MCP67 to pata_amd.c. + * [libata] Add support for AHCI controllers of MCP67. + * pci_ids.h: Add NVIDIA PCI ID + * PCI: Revert "PCI: i386/x86_84: disable PCI resource decode on device disable" + * PCI: Let PCI_MULTITHREAD_PROBE depend on BROKEN + * USB: add another sierra wireless device id + * USB: usb-storage: Unusual_dev update + * hid-core: big-endian fix fix + * USB: new VID/PID-combos for cp2101 + * USB: sierra: Fix id for Sierra Wireless MC8755 in new table + * usbtouchscreen: use endpoint address from endpoint descriptor + * USB: failure in usblp's error path + * USB: usblp: fix system suspend for some systems + * USB: HID: add blacklist AIRcable USB, little beautification + * USB: fix compiler issues with newer gcc versions + * USB: xpad: additional USB id's added + * USB Storage: unusual_devs.h entry for Sony Ericsson P990i + * USB: use MII hooks only if CONFIG_MII is enabled + * eCryptfs: Fix pointer deref + * tidy "md: check bio address after mapping through partitions" + * md: send online/offline uevents when an md array starts/stops + * sys_pselect7 vs compat_sys_pselect7 uaccess error handling + * update some docbook comments + * docbook: merge journal-api into filesystems.tmpl + * Fix ipc entries removal + * mm: un-needed add-store operation wastes a few bytes + * fix UFS superblock alignment issues + * lkdtm: cleanup headers and module_param/MODULE_PARM_DESC + * Cleanup read_pages() + * cifs: ->readpages() fixes + * fuse: ->readpages() cleanup + * gfs2: ->readpages() fixes + * edac_mc: fix error handling + * NFS4: fix for recursive locking problem + * ipmi_si_intf.c sets bad class_mask with PCI_DEVICE_CLASS + * init_reap_node() initialization fix + * Add printk_timed_ratelimit() + * schedule removal of FUTEX_FD + * acpi_noirq section fix + * swsusp: debugging + * spi section fix + * reiserfs: reset errval after initializing bitmap cache + * uml: fix I/O hang + * uml: include tidying + * Create compat_sys_migrate_pages + * powerpc: wire up sys_migrate_pages + * drivers/isdn/hysdn/hysdn_sched.c: sleep after taking spinlock fix + * fix Documentation/accounting/getdelays.c buf size + * IDE: Add the support of nvidia PATA controllers of MCP67 to amd74xx.c + * Fix sys_move_pages when a NULL node list is passed + * Fix user.* xattr permission check for sticky dirs + * splice: fix problem introduced with inode diet + * Revert unintentional "volatile" changes in ipc/msg.c + * Fix unlikely (but possible) race condition on task->user access + * Make sure "user->sigpending" count is in sync + + -- Ben Collins Mon, 6 Nov 2006 07:11:08 -0800 + +linux-source-2.6.19 (2.6.19-4.4) feisty; urgency=low + + [Ben Collins] + + * debian: Fix ppc defconfig, and d-i braindamage + - GIT-SHA 3805cd5ab6796f26fdd2b69d58d72d5bf33f96bb + * debian: Prefix make-kpkg calls with sparc64 on sparc for now. + - GIT-SHA 3b2a6a332c9febffda9cdc26a9a0572ec859e999 + + [Upstream Kernel Changes] + + * CFQ: use irq safe locking in cfq_cic_link() + * CFQ: bad locking in changed_ioprio() + * Fix dmsetup table output change + * ioc4_serial: irq flags fix + * ndiswrapper: don't set the module->taints flags + * isdn/gigaset: avoid cs->dev null pointer dereference + * lockdep: annotate DECLARE_WAIT_QUEUE_HEAD + * cryptocop: double spin_lock_irqsave() + * MTD: fix last kernel-doc warning + * docbook: make a filesystems book + * Fix "Remove the use of _syscallX macros in UML" + * uml: fix compilation options for USER_OBJS + * xacct_add_tsk: fix pure theoretical ->mm use-after-free + * drivers/ide/pci/generic.c: add missing newline to the all-generic-ide message + * sunrpc: fix refcounting problems in rpc servers + * APM: URL of APM 1.2 specs has changed + * fix "sunrpc: fix refcounting problems in rpc servers" + * fix i386 regparm=3 RT signal handlers on x86_64 + * [MIPS] Oprofile: fix on non-VSMP / non-SMTC SMP configurations. + * [MIPS] Au1xx0 code sets incorrect mips_hpt_frequency + * [MIPS] Oprofile: Fix MIPSxx counter number detection. + * [MIPS] SMTC: Make 8 the default number of processors. + * [MIPS] Fix warning about unused definition in c-sb1.c + * [MIPS] Make SB1 cache flushes not to use on_each_cpu + * [MIPS] Wire up getcpu(2) and epoll_wait(2) syscalls. + * [MIPS] Au1000: Fix warning about unused variable. + * [MIPS] Fix return value of TXX9 SPI interrupt handler + * [MIPS] Ocelot G: Fix build error and numerous warnings. + * [MIPS] EMMA 2 / Markeins: Fix build wreckage due to genirq wreckage. + * [MIPS] EMMA 2 / Markeins: Formitting fixes split from actual address fixes. + * [MIPS] EMMA 2 / Markeins: Convert to name struct resource initialization. + * [MIPS] EMMA 2 / Markeins: struct resource takes physical addresses. + * [MIPS] JMR3927: Fixup another victim of the irq pt_regs cleanup. + * [MIPS] MIPS doesn't need compat_sys_getdents. + * fix bd_claim_by_kobject error handling + * clean up add_bd_holder() + * Linux 2.6.19-rc4 + + -- Ben Collins Tue, 31 Oct 2006 10:45:07 -0500 + +linux-source-2.6.19 (2.6.19-3.3) feisty; urgency=low + + [Ben Collins] + + * Revert "ppc: Add defconfig for build" + - GIT-SHA 540057c30de97922c99dcd198e1535c3986abfa0 + * debian: Add defconfig setting for each arch + - GIT-SHA 03248c8d8e00151e085448684eacdafb3acc0833 + * debian/rules: Re-add kernel-wedge workaround to fix sparc FTBFS + - GIT-SHA b0ea4d18b8c8bfdef670980700b2f78948205819 + + -- Ben Collins Tue, 31 Oct 2006 10:02:36 -0500 + +linux-source-2.6.19 (2.6.19-2.2) feisty; urgency=low + + [Ben Collins] + + * btsco: Added new driver + - GIT-SHA 18b128d55a6297da941055abda677cde1c1086ed + * at76: Atmel USB Driver + - GIT-SHA f2460fe216447baa35b7f7a9ca8d440f4922719e + * at76-usb-firmware: Added firmware for Atmel USB + - GIT-SHA b618084d1cf221755848d42bb5b45fe5b97479e1 + * ppc: Add defconfig for build + - GIT-SHA 7eefca4e80cd6016ecec0cf27e1e9dadb05e2e9f + * debian: git-ubuntu-log: Ommit matching revert/commits. + - GIT-SHA 68ed886f702f70e43f4e835d768a38309a4120ca + * debian: Fix KPKG_(ARCH|SUBARCH) to fix sparc64 build failure. + - GIT-SHA 0973b171e2334735687c647673e76f94d21a6d3c + * debian: insert-changes: New script. + - GIT-SHA 492ef6bf5f17554ab82ab170e728e51de7fc1fb1 + + [Upstream Kernel Changes] + + * e1000: FIX: don't poke at manageability registers for incompatible adapters + * e1000: FIX: 82542 doesn't support WoL + * e1000: FIX: fix wrong txdctl threshold bitmasks + * e1000: FIX: Disable Packet Split for non jumbo frames + * e1000: FIX: Don't limit descriptor size to 4kb for PCI-E adapters + * e1000: FIX: move length adjustment due to crc stripping disabled. + * e1000: Increment version to 7.2.9-k4 + * e100: account for closed interface when shutting down + * pcmcia: at91_cf update + * pcmcia: add more IDs to hostap_cs.c + * pcmcia: update alloc_io_space for conflict checking for multifunction PC card + * pcmcia/ds: driver layer error checking + * CONFIG_PM=n slim: drivers/pcmcia/* + * i82092: wire up errors from pci_register_driver() + * pcmcia: au1000_generic fix + * ioremap balanced with iounmap for drivers/pcmcia + * Export soc_common_drv_pcmcia_remove to allow modular PCMCIA. + * PCMCIA: handle sysfs, PCI errors + * PCMCIA: fix __must_check warnings + * [SPARC64]: Fix central/FHC bus handling on Ex000 systems. + * [SPARC64]: Fix memory corruption in pci_4u_free_consistent(). + * [TCP] cubic: scaling error + * [TCP] H-TCP: fix integer overflow + * [BRIDGE]: correct print message typo + * [SPARC]: Fix bus_id[] string overflow. + * [S390] sys_getcpu compat wrapper. + * [S390] Initialize interval value to 0. + * [S390] cio: css_probe_device() must be called enabled. + * [S390] uaccess error handling. + * [S390] Improve AP bus device removal. + * [S390] cio: Make ccw_device_register() static. + * acpiphp: fix latch status + * PCI: fix pci_fixup_video as it blows up on sparc64 + * PCI: x86-64: mmconfig missing printk levels + * PCI: reset pci device state to unknown state for resume + * PCI: Remove quirk_via_abnormal_poweroff + * vmlinux.lds: consolidate initcall sections + * drivers: wait for threaded probes between initcall levels + * silence 'make xmldocs' warning by adding missing description of 'raw' in nand_base.c:1485 + * [ARM] Fix SMP irqflags support + * [ARM] Add realview SMP default configuration + * [ARM] Add __must_check to uaccess functions + * [ARM] 3909/1: Disable UWIND_INFO for ARM (again) + * [ARM] 3899/1: Fix the normalization of the denormal double precision number. + * [ARM] 3900/1: Fix VFP Division by Zero exception handling. + * mm: clean up pagecache allocation + * vmscan: Fix temp_priority race + * Use min of two prio settings in calculating distress for reclaim + * ext4: fix printk format warnings + * jbd: journal_dirty_data re-check for unmapped buffers + * jbd2: journal_dirty_data re-check for unmapped buffers + * fix efi_memory_present_wrapper() + * md: fix bug where spares don't always get rebuilt properly when they become live + * md: simplify checking of available size when resizing an array + * md: fix up maintenance of ->degraded in multipath + * md: fix printk format warnings, seen on powerpc64: + * memory hotplug: __GFP_NOWARN is better for __kmalloc_section_memmap() + * Fix potential OOPs in blkdev_open() + * __vmalloc with GFP_ATOMIC causes 'sleeping from invalid context' + * visws build fix + * Add missing space in module.c for taintskernel + * ioc4: fix printk format warning + * cciss: fix printk format warning + * hugetlb: fix size=4G parsing + * hugetlb: fix prio_tree unit + * hugetlb: fix absurd HugePages_Rsvd + * missing unused dentry in prune_dcache()? + * VFS: Fix an error in unused dentry counting + * Constify compat_get_bitmap argument + * strstrip remove last blank fix + * fill_tgid: fix task_struct leak and possible oops + * bacct_add_tsk: fix unsafe and wrong parent/group_leader dereference + * taskstats_tgid_free: fix usage + * taskstats_tgid_alloc: optimization + * taskstats: kill ->taskstats_lock in favor of ->siglock + * taskstats: don't use tasklist_lock + * fill_tgid: cleanup delays accounting + * move SYS_HYPERVISOR inside the Generic Driver menu + * time_adjust cleared before use + * cpu-hotplug: release `workqueue_mutex' properly on CPU hot-remove + * JMB 368 PATA detection + * workqueue: update kerneldoc + * Calculation fix for memory holes beyong the end of physical memory + * [ARM] Fix i2c-pxa slave mode support + * [ARM] Fix suspend oops caused by PXA2xx PCMCIA driver + * [ARM] Add KBUILD_IMAGE target support + * Fix GFP_HIGHMEM slab panic + * [ARM] 3913/1: n2100: fix IRQ routing for second ethernet port + * ieee1394: ohci1394: revert fail on error in suspend + * taskstats: fix sk_buff leak + * taskstats: fix sk_buff size calculation + * m68k: consolidate initcall sections + * [WATCHDOG] sc1200wdt.c pnp unregister fix. + + + -- Ben Collins Thu, 26 Oct 2006 23:16:13 -0400 + +linux-source-2.6.19 (2.6.19-1.1) feisty; urgency=low + + [Ben Collins] + + * Makefile: Disable compiler stack protection + - GIT-SHA 88e5d8158cceacb7e7b559f5af74f729a17ade71 + * Add git-ubuntu-log parsing script. + - GIT-SHA 5d781e48af9265470bc5de9cfd072b80918e1db8 + * Disable APIC on UP machines by default + - GIT-SHA ce3c49d6164180bcb0e5d6a455f3ae163914af52 + * Quieten compressed boot messages. + - GIT-SHA b31aa3e4c69d1fc4868d39dc63bc2a4baab497b1 + * Add config option to disable hyperthreading by default + - GIT-SHA 161459709590b06c515c7e2657c376e28a98fdc1 + * Default to dongle type 9 on IBM hardware. + - GIT-SHA eb2eaa11c75f1c656a3bef54bef3e8c92e52049d + * Add "TOSHIBA CD-ROM XM-1702BC" to ide-dma blacklist + - GIT-SHA e64e371c8cdba5c0af8d8c8eaef69f07cd3b87b5 + * net/sunhme: Fix Sun Happy Meal ethernet lockups on Ultra 1E + - GIT-SHA add87b82b6ea9b4a9c695d4fb0b5ae1d4ce655cc + * pcmcia: Do not insert pcmcia cards on resume + - GIT-SHA 9334fc580d26a92c81651df4669ce8c19a68b260 + * scsi/BusLogic: Add MODULE_DEVICE_TABLE for autoloading + - GIT-SHA 55f6d5c8bf31270f7289ce9865cb15528327cca8 + * input/mouse/alps: Do not call psmouse_reset() for alps + - GIT-SHA fb3c8d616c602b8876dc50e89ac4987f5ba05bfe + * scsi: Add Matshita DMC-LC33 to devlist + - GIT-SHA b7f273bde8e6e02a6dea490f877ef9ee4f390448 + * scsi: Restore generic SCSI proc_info function + - GIT-SHA 9c1a5525614014486d2ba5ed1181f777c55587f3 + * ide: Make some drivers modular + - GIT-SHA 9ecb5d7cc5db4071f4d9218f8acff96ab5d599f0 + * ide/pnp: Allow ide-pnp to be modular. + - GIT-SHA 924f6bd12dc99b5176940895ec26607f2144b0f1 + * video/vesafb: Modularize + - GIT-SHA f160678572c5cbd97cc96a761d95646fb4c3a50f + * pcmcia: Add missing device releases + - GIT-SHA e3eeb6ee8e14cdcaccf0213446bef4a26ba78bcb + * general: Quieten noisy printk's + - GIT-SHA 13dbeb0d68d892cce0483594fbd795c289ae7c27 + * acpi: Allow loading of DSDT from initrd + - GIT-SHA 5272d84c2ae7ad6dcf98ec83fe2f510a0b8912ee + * ide: Cleaner merge of ide_scan_pcibus() changes (modular) + - GIT-SHA ab460a6bf9bb00b39443190efbc44cf8a9358032 + * video/vesafb: Fixup vesafb modular code to merge with platform driver changes. + - GIT-SHA 08c62e8dea078ca4510f00bbf1e8dce0cef53716 + * ide: Export ide_scan_direction + - GIT-SHA 1b49a08481e74417c114f16c2c6ec0e4e6d282e0 + * ide: Fix Oops in IDE caused by __init for ide_pci_scanbus() + - GIT-SHA d3e3800f6826c7a57872dd22ac93d034d36c91db + * fs: Revert bd_claim change. + - GIT-SHA 8cbff5a651066cd43f6736a45181c0549d91662a + * drivers/video: Fix some video drivers unchecked use of nvram functions + - GIT-SHA e79b253cceeee1f4022b825e3c6acbc9690b81a7 + * tulip: Fix for Uli5261 chipsets. + - GIT-SHA 278130f8818f8ac6550760807815d24dbeee6470 + * net/tulip: Define ULI PCI ID's + - GIT-SHA 68cdca366a7410a1a5c86f1365072edfedbc911c + * ia64: Export some extra symbols so we can build vga16fb + - GIT-SHA 48b37aa458e7e61f396f0bc2e4b8a4bdd039005a + * video: Enable VesaFB for ia64. + - GIT-SHA 9d859229d3ec3bb4325b65e05387f2d6cd12627f + * ide: Revert some of the "modular ide" patch. + - GIT-SHA ccbe68cc3928e6275f4fefed7856c7754d10dd84 + * vga16fb: Set default timings to 640x400 for compatibility. + - GIT-SHA 20556d56d5e13a642d5da77e4fd877f00a63bbdc + * block: Make CDROMEJECT more robust + - GIT-SHA 933956f84fdb520d9cce720fabbb6236efaa188f + * powerpc: Disable prom_printf + - GIT-SHA 52bca28eb10d88db59b8b16fd28f7bd71c859404 + * ide-cd: Disable verbose errors. + - GIT-SHA 72d40db7ba7478afe35e7302d0d61c2bcd41fa53 + * tulip: Fix mdio related lockups. Update from upstream driver. + - GIT-SHA e74fe2962b8fde95756505782a3226a5e30b92c2 + * input: Allow root to inject unknown scan codes. + - GIT-SHA 9dba2e8158382af26d4460242ffe6d45803f43fb + * 3w-9xxx: Add .proc_name member to scsi_host_template + - GIT-SHA a120864ddf97dcaf0a5565ffd2539852e884f411 + * synaptics: Add Toshiba Protege M300 to rate=40 blacklist. + - GIT-SHA d9b4f0e739d81b75fae3f9545d598d865e391e35 + * vga16fb: Do not use 640x480 on certain machines + - GIT-SHA faffc346a48402547964adde5b5c4bf3b37572a8 + * forcedeth: Let the driver work when no PHY is found + - GIT-SHA eb2bbfea12d9f3599ed6019fce78a5bb3b70f9d8 + - Bug #45257 + * tulip: Let dmfe handle davicom on non-sparc. + - GIT-SHA 901dcff694d2c177078a2f9a0e81d765c7db41fb + - Bug #48287 + * speakup: Driver addition + - GIT-SHA 1cf0afb09a96f1c381a9ac42ab56115c957177ab + * kbd: Fix typo in speakup patch + - GIT-SHA 71aeabbdc6e922a454cbb96c93bda44cd6f34613 + * powerpc: Allow config of pSeries panel message + - GIT-SHA 8290fcc662b7a9cb3035222f3c2f0160f5a14fcd + * general: crash helper support for apport + - GIT-SHA d9291b92a80b54e2212348ff82cd6c374351dd05 + * version: Implement version_signature proc file. + - GIT-SHA 87c212ae348ed89e2177af1907fbfff22b758eb4 + * hid-core: Add noget quirk for turbox keyboard. + - GIT-SHA c6ecb350590cbbb62207ecda8acdb36dc503830e + * ipw2100: Add option to disable C3/C4 state transistions. + - GIT-SHA a2a9f735de0c61a7be45ab0c55eea593098de70a + * ubuntu: Create ubuntu driver directory. + - GIT-SHA ce47ddb0f4e34a60599bedc8f0bff996ed252e6f + * hdrinst: Add stub for gfs headers + - GIT-SHA 6fde7f59fd4e921d8255c2fd6ebabc622c88947c + * general: Add MODULE_DEV_TABLE to some drivers for autoloading. + - GIT-SHA bef1c07e02bd1fb0bb2eb020e5c58dd12e56d53f + * i8042: Quiten message about no controlles being found. + - GIT-SHA a438ddf2becf5f6d4a5db68acf0cd9648030d192 + * asfs: Add Amiga Smart File System + - GIT-SHA 63e625a65070eee461f5f4bedd550e39ed8c171e + * kbuild: Add ubuntu/include/ for external driver includes. + - GIT-SHA 6cc08947078031622ef777dc91630b2a25e1cc51 + * fs: Export __d_path symbol for dazuko. + - GIT-SHA f816e1d4eab62bc229991a614f63731f599bf9ae + * speakup: Merges fixes and patches from Edgy. + - GIT-SHA d2c7021c474d7bbaeafd96f890471476514e219d + * ixj: Fix PCI vendor/device ID's for QUICKNET. + - GIT-SHA 7742c3f2837c62c64c08736ca8f6b8931258ba6b + * asfs: Compile fixes. + - GIT-SHA da4e90d5cb6bc656861de64cb200d6de124c39ce + * vt: Fix speakup code to compile. + - GIT-SHA a0ec07a4417656566e19d8415dbc86e91d6f974a + * kbuild: Fix location of ubuntu/include addition to LINUXINCLUDES + - GIT-SHA a30f7b62339415a90a6024ada0e2f10f86a85dbd + * general: Various compile fixes for edgy patch merges. + - GIT-SHA eea36c5c4f202eb95108fd8c1ef9fe5f38c10bcf + * dazuko: Added driver + - GIT-SHA 1283c07c2260047335a58be437dc8ba558011770 + * squashfs: Added v3.1-r2 driver + - GIT-SHA 6acce7627f044b72930dd6cc563aed9559a4b8c4 + * unionfs: Add 20060916 snapshot + - GIT-SHA c375f3b13be8c1f3aba1316b01332f7951d4dda2 + * gfs: Merged from Edgy + - GIT-SHA 29decd8128961ed2a79235240172ec2f646103f4 + * rt2x00: Added drivers from Edgy with build fixes. + - GIT-SHA e8a710260e32cefb7236a8bd3a111387818786c0 + * linux-wlan-ng: Added driver + - GIT-SHA 36d255e73f30f68a23d61048d3f0627bc5241025 + * ndsiwrapper: Added driver + - GIT-SHA f1e27ae3a39b0d389f212df44d6ab5468d04647d + * cloop: Added compressed loop driver + - GIT-SHA 26cb677f9b9205a2ed77a4ee4c554bcdd498eaa4 + * dm-bbr: Added new driver + - GIT-SHA ee36ac9e9c3065f8f594493a3be2e0ae4196e46e + * acx: Add driver from Edgy + - GIT-SHA 959183847e71f99bee6e5682708a672b9c2abd02 + * ipw3945: Add new driver + - GIT-SHA cc542d63e9bc05438570c084e6b701e82aafbda2 + * adm8211: Add new driver + - GIT-SHA 6a9957bd934f4db1dc80a5d7b48638e3373d7c88 + * rtl818x: Add new drivers + - GIT-SHA 9533d6e292539fae27c6062dbf4ba2b663caaa28 + * prism54_softmac: Add new driver + - GIT-SHA 559b895c45424e974caadc3ec249d5cdbcd5ddf4 + * fsam7400: Add new driver + - GIT-SHA 78b8978053c2ee6d0cbd42aec330d6ee2b555212 + * mol: Add Mac-On-Linux driver + - GIT-SHA 51410652caa26b301d6ac968d6fce04c1f21d925 + * ov511: Add ov511 camera driver + - GIT-SHA 63f1564f55645b26f157c418a6e28fb49b23a52b + * zd1211: Install firmware in subdirectory, like the driver expects it. + - GIT-SHA 33564d1acfa96e8cba778e2efb6b0376aad09e12 + * kbuild: Do not add debian/ to clean-dirs. + - GIT-SHA 8e1027b4fefded38704dd473394e2f7238012940 + * debian/: We don't need to run make-kpkg clean in the top level. + - GIT-SHA a8e5dc70095ebd21e21896c82cab8394e5c25a7c + * ubuntu/: Update all drivers for 2.6.19 changes + - GIT-SHA a8dc19f626a200ee837af570ce59a732b3094aa5 + * ubuntu/: More fixes for warnings. ubuntu/ is pretty much warning free + - GIT-SHA 807da64fba9aa414f256ea4d5664a448f9023d78 + * gfs2/dlm: Remove. These modules are in-tree now. + - GIT-SHA bb62e6c94034978605cc148d6c94dd15036eaf4e + * gfs2: Export extra symbols for gfs1 + - GIT-SHA d999702b86414c59d62f9b34450129a9221b523d + * kbuild: Allow header_install to work with O= + - GIT-SHA afa95b842e7b00b21537f2203e4879c2d860a3e9 + * debian/d-i: Update md-modules udeb list. + - GIT-SHA ed24b1fc393feb10061f83bbf152f7718cc94a83 + * debian/: Complete rework of d-i (kernel-wedge) handling + - GIT-SHA 435d7a8fa97f08f1ed39520bf4122434ad7d57ac + * ide: Disable some PCI entries when duplicate ATA driver is enabled. + - GIT-SHA c97951e8a2b085c6ec47fee8f1f933185bde3d75 + * fsam7400: Include linux/io.h for check_signature() + - GIT-SHA fb04e20928624ec398c54131fa7736a2fb6a971e + * sbus: BBC and ENVCTRL both need to be built-in + - GIT-SHA 75bc2c9764754ae2b446ac5613b7a33c2d7a0379 + * prism2: Make modules depend on subsystems. + - GIT-SHA 5d084bc0a60a146d81a910580eeb29a7e92d89d6 + * sparc: Fix some section mismatch warnings from sbus modules. + - GIT-SHA a1e1b46410e1095bad4e401d7bc0591d44137e2a + * kbuild: Remove local change for -fno-stack-protector. + - GIT-SHA 10137f027764e20df233111725a7b148047d92d1 + * sbus/char, synaptics: Revert local Ubuntu changes + - GIT-SHA a3852f015830915eb3fb33b8fea85a5edd7a5838 + * mv643xx: Remove pci dev table. Not needed for this driver. + - GIT-SHA f098f17a693fefb6aa03d4ac317faf4f92c0d05a + * imsttfb: Set USE_NV_MODES to 0 when CONFIG_NVRAM is not set + - GIT-SHA 292f071fb9492af9042e840ca81397108dd0ea83 + * prism2_plx: Disable on ppc for now. + - GIT-SHA db1b9f970535fdc567e08bca05b8bcf6a4e1f07f + * ppc: Do not re-export kd_mksound. + - GIT-SHA 5b7d5bbf5171fcb92d78b0e3fa5437ec6f912838 + * atm/block/wan: Require ISA_DMA_API for some drivers. + - GIT-SHA 40215f7cfb9ec59a90b781c50ffc9424ef16b3ba + * hvcs: select HVC_CONSOLE when enabled. + - GIT-SHA e41dbec0326f0e75e6a80b248b5c26f75899f866 + * ppc: Do not enable ISA_DMA_API on PPC64 + - GIT-SHA 75b0757318306ddd6868d65f2e2da6c806f140f6 + * tmscsim, i2o_config: Depends on ISA_DMA_API + - GIT-SHA f86bd4404911d9107c3bf7e36c894fa5907fac8c + * drivers/atm: Add CPPFLAGS to fore200e-fw endian check. + - GIT-SHA 694db9ff7e16042b3f58bbc01d19ef08609315ce + * bcm43xx: Move dma-mapping.h include to fix compile failure + - GIT-SHA 9cc7a903b72c231510f4cae7e9dee27b0ebc6d2c + + [Chuck Short] + + * atkbd: Disables stupid keyboard warning. + - GIT-SHA aedc2d9246885a41346584b1fe91696611eea756 + + [Fabio M. Di Nitto] + + * drivers/char/vt.c: make promcon driver init a boot option. + - GIT-SHA 41a393f2d8829bceb5c5da136dd12f3dcbe6c94c + + -- Ben Collins Thu, 26 Oct 2006 21:58:29 -0400 --- linux-2.6.24.orig/debian/copyright +++ linux-2.6.24/debian/copyright @@ -0,0 +1,30 @@ +This is the Ubuntu prepackaged version of the Linux kernel. +Linux was written by Linus Torvalds +and others. + +This package was put together by the Ubuntu Kernel Team, from +sources retrieved from upstream linux git. +The sources may be found at most Linux ftp sites, including +ftp://ftp.kernel.org/pub/linux/kernel/ + +This package is currently maintained by the +Ubuntu Kernel Team + +Linux is copyrighted by Linus Torvalds and others. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 dated June, 1991. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. + +On Ubuntu Linux systems, the complete text of the GNU General +Public License v2 can be found in `/usr/share/common-licenses/GPL-2'. --- linux-2.6.24.orig/debian/control.stub.in +++ linux-2.6.24/debian/control.stub.in @@ -0,0 +1,81 @@ +Source: linux +Section: devel +Priority: optional +Maintainer: Ubuntu Kernel Team +Standards-Version: 3.6.1 +Build-Depends: debhelper (>= 3), module-init-tools, kernel-wedge (>= 2.24ubuntu1), gcc-4.1-hppa64 [hppa], binutils-hppa64 [hppa], device-tree-compiler [powerpc], gcc-4.1 [powerpc ia64], gawk [amd64 i386] +Build-Depends-Indep: xmlto, docbook-utils, gs, transfig, bzip2, sharutils + +Package: linux-kernel-devel +Architecture: all +Section: devel +Priority: optional +Depends: build-essential, git-core, gitk, rsync, curl, openssh-client, debhelper, kernel-package, kernel-wedge +Description: Linux kernel hacking dependencies + This is a dummy package that will install all possible packages + required to hack comfortably on the kernel. + +Package: linux-source-PKGVER +Architecture: all +Section: devel +Priority: optional +Provides: linux-source, linux-source-2.6 +Depends: binutils, bzip2, coreutils | fileutils (>= 4.0) +Recommends: libc-dev, gcc, make +Suggests: libncurses-dev | ncurses-dev, kernel-package, libqt3-dev +Description: Linux kernel source for version PKGVER with Ubuntu patches + This package provides the source code for the Linux kernel version PKGVER. + . + You may configure the kernel to your setup by typing "make config" and + following instructions, but you could get ncursesX.X-dev and try "make + menuconfig" for a jazzier, and easier to use interface. There are options + to use QT or GNOME based configuration interfaces, but they need + additional packages to be installed. Also, please read the detailed + documentation in the file + /usr/share/doc/linux-source-PKGVER/README.headers.gz. + . + If you wish to use this package to create a custom Linux kernel, then it + is suggested that you investigate the package kernel-package, which has + been designed to ease the task of creating kernel image packages. + . + If you are simply trying to build third-party modules for your kernel, + you do not want this package. Install the appropriate linux-headers + package instead. + +Package: linux-doc-PKGVER +Architecture: all +Section: doc +Priority: optional +Provides: linux-doc-2.6 +Conflicts: linux-doc-2.6 +Replaces: linux-doc-2.6 +Depends: coreutils | fileutils (>= 4.0) +Description: Linux kernel specific documentation for version PKGVER + This package provides the various readme's in the PKGVER kernel + Documentation/ subdirectory: these typically contain kernel-specific + installation notes for some drivers for example. See + /usr/share/doc/linux-doc-PKGVER/Documentation/00-INDEX for a list of what + is contained in each file. Please read the Changes file, as it contains + information about the problems, which may result by upgrading your + kernel. + +Package: linux-headers-PKGVER-ABINUM +Architecture: all +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0) +Provides: linux-headers, linux-headers-2.6 +Description: Header files related to Linux kernel version PKGVER + This package provides kernel header files for version PKGVER, for sites + that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-PKGVER-ABINUM/debian.README.gz for details + +Package: linux-libc-dev +Architecture: amd64 i386 powerpc sparc ia64 hppa lpia +Conflicts: libc6-dev (<< 2.3.2.ds1-6), libc6.1-dev (<< 2.3.2.ds1-6), dvb-dev (<< 1.0.1-6), amd64-libs-dev (<= 1.1), linux-kernel-headers +Replaces: libc6-dev (<< 2.3.2.ds1-6), libc6.1-dev (<< 2.3.2.ds1-6), dvb-dev (<< 1.0.1-6), linux-kernel-headers +Provides: linux-kernel-headers +Description: Linux Kernel Headers for development + This package provides headers from the Linux kernel. These headers + are used by the installed headers for GNU glibc and other system + libraries. --- linux-2.6.24.orig/debian/control +++ linux-2.6.24/debian/control @@ -0,0 +1,839 @@ +Source: linux +Section: devel +Priority: optional +Maintainer: Ubuntu Kernel Team +Standards-Version: 3.6.1 +Build-Depends: debhelper (>= 3), module-init-tools, kernel-wedge (>= 2.24ubuntu1), gcc-4.1-hppa64 [hppa], binutils-hppa64 [hppa], device-tree-compiler [powerpc], gcc-4.1 [powerpc ia64], gawk [amd64 i386] +Build-Depends-Indep: xmlto, docbook-utils, gs, transfig, bzip2, sharutils + +Package: linux-kernel-devel +Architecture: all +Section: devel +Priority: optional +Depends: build-essential, git-core, gitk, rsync, curl, openssh-client, debhelper, kernel-package, kernel-wedge +Description: Linux kernel hacking dependencies + This is a dummy package that will install all possible packages + required to hack comfortably on the kernel. + +Package: linux-source-2.6.24 +Architecture: all +Section: devel +Priority: optional +Provides: linux-source, linux-source-2.6 +Depends: binutils, bzip2, coreutils | fileutils (>= 4.0) +Recommends: libc-dev, gcc, make +Suggests: libncurses-dev | ncurses-dev, kernel-package, libqt3-dev +Description: Linux kernel source for version 2.6.24 with Ubuntu patches + This package provides the source code for the Linux kernel version 2.6.24. + . + You may configure the kernel to your setup by typing "make config" and + following instructions, but you could get ncursesX.X-dev and try "make + menuconfig" for a jazzier, and easier to use interface. There are options + to use QT or GNOME based configuration interfaces, but they need + additional packages to be installed. Also, please read the detailed + documentation in the file + /usr/share/doc/linux-source-2.6.24/README.headers.gz. + . + If you wish to use this package to create a custom Linux kernel, then it + is suggested that you investigate the package kernel-package, which has + been designed to ease the task of creating kernel image packages. + . + If you are simply trying to build third-party modules for your kernel, + you do not want this package. Install the appropriate linux-headers + package instead. + +Package: linux-doc-2.6.24 +Architecture: all +Section: doc +Priority: optional +Provides: linux-doc-2.6 +Conflicts: linux-doc-2.6 +Replaces: linux-doc-2.6 +Depends: coreutils | fileutils (>= 4.0) +Description: Linux kernel specific documentation for version 2.6.24 + This package provides the various readme's in the 2.6.24 kernel + Documentation/ subdirectory: these typically contain kernel-specific + installation notes for some drivers for example. See + /usr/share/doc/linux-doc-2.6.24/Documentation/00-INDEX for a list of what + is contained in each file. Please read the Changes file, as it contains + information about the problems, which may result by upgrading your + kernel. + +Package: linux-headers-2.6.24-23 +Architecture: all +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0) +Provides: linux-headers, linux-headers-2.6 +Description: Header files related to Linux kernel version 2.6.24 + This package provides kernel header files for version 2.6.24, for sites + that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details + +Package: linux-libc-dev +Architecture: amd64 i386 powerpc sparc ia64 hppa lpia +Conflicts: libc6-dev (<< 2.3.2.ds1-6), libc6.1-dev (<< 2.3.2.ds1-6), dvb-dev (<< 1.0.1-6), amd64-libs-dev (<= 1.1), linux-kernel-headers +Replaces: libc6-dev (<< 2.3.2.ds1-6), libc6.1-dev (<< 2.3.2.ds1-6), dvb-dev (<< 1.0.1-6), linux-kernel-headers +Provides: linux-kernel-headers +Description: Linux Kernel Headers for development + This package provides headers from the Linux kernel. These headers + are used by the installed headers for GNU glibc and other system + libraries. + +Package: linux-image-2.6.24-23-386 +Architecture: i386 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on i386 + This package contains the Linux kernel image for version 2.6.24 on + i386. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Alternate x86 (486 and better) processors. + . + Geared toward desktop systems. + . + You likely do not want to install this package directly. Instead, install + the linux-386 meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-386 +Architecture: i386 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on i386 + This package provides kernel header files for version 2.6.24 on + i386. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-debug-2.6.24-23-386 +Architecture: i386 +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.24 on i386 + This package provides a kernel debug image for version 2.6.24 on + i386. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. + +Package: linux-image-2.6.24-23-generic +Architecture: i386 amd64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, redhat-cluster-modules, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on x86/x86_64 + This package contains the Linux kernel image for version 2.6.24 on + x86/x86_64. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Generic processors. + . + Geared toward desktop systems. + . + You likely do not want to install this package directly. Instead, install + the linux-generic meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-generic +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on x86/x86_64 + This package provides kernel header files for version 2.6.24 on + x86/x86_64. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-debug-2.6.24-23-generic +Architecture: i386 amd64 +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.24 on x86/x86_64 + This package provides a kernel debug image for version 2.6.24 on + x86/x86_64. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. + +Package: linux-image-2.6.24-23-hppa32 +Architecture: hppa +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: palo +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on 32-bit HP PA-RISC SMP + This package contains the Linux kernel image for version 2.6.24 on + 32-bit HP PA-RISC SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 32-bit HP PA-RISC SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-hppa32 meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-hppa32 +Architecture: hppa +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, gcc-4.1, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on 32-bit HP PA-RISC SMP + This package provides kernel header files for version 2.6.24 on + 32-bit HP PA-RISC SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-hppa64 +Architecture: hppa +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: palo +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on 64-bit HP PA-RISC SMP + This package contains the Linux kernel image for version 2.6.24 on + 64-bit HP PA-RISC SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 64-bit HP PA-RISC SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-hppa64 meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-hppa64 +Architecture: hppa +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, gcc-4.1-hppa64, binutils-hppa64, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on 64-bit HP PA-RISC SMP + This package provides kernel header files for version 2.6.24 on + 64-bit HP PA-RISC SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-itanium +Architecture: ia64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: elilo (>= 3.6-1) +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on Itanium SMP + This package contains the Linux kernel image for version 2.6.24 on + Itanium SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Itanium SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-itanium meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-itanium +Architecture: ia64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, gcc-4.1, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on Itanium SMP + This package provides kernel header files for version 2.6.24 on + Itanium SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-mckinley +Architecture: ia64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: elilo (>= 3.6-1) +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on Itanium II SMP + This package contains the Linux kernel image for version 2.6.24 on + Itanium II SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Itanium II SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-mckinley meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-mckinley +Architecture: ia64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, gcc-4.1, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on Itanium II SMP + This package provides kernel header files for version 2.6.24 on + Itanium II SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-powerpc +Architecture: powerpc +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: yaboot +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on 32-bit PowerPC + This package contains the Linux kernel image for version 2.6.24 on + 32-bit PowerPC. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 32-bit PowerPC processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-powerpc meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-powerpc +Architecture: powerpc +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, gcc-4.1, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on 32-bit PowerPC + This package provides kernel header files for version 2.6.24 on + 32-bit PowerPC. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-powerpc64-smp +Architecture: powerpc +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: yaboot +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on 64-bit PowerPC SMP + This package contains the Linux kernel image for version 2.6.24 on + 64-bit PowerPC SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 64-bit PowerPC SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-powerpc64-smp meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-powerpc64-smp +Architecture: powerpc +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, gcc-4.1, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on 64-bit PowerPC SMP + This package provides kernel header files for version 2.6.24 on + 64-bit PowerPC SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-powerpc-smp +Architecture: powerpc +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: yaboot +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on 32-bit PowerPC SMP + This package contains the Linux kernel image for version 2.6.24 on + 32-bit PowerPC SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 32-bit PowerPC SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-powerpc-smp meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-powerpc-smp +Architecture: powerpc +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, gcc-4.1, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on 32-bit PowerPC SMP + This package provides kernel header files for version 2.6.24 on + 32-bit PowerPC SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-server +Architecture: i386 amd64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules, kvm-api-4, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on x86/x86_64 + This package contains the Linux kernel image for version 2.6.24 on + x86/x86_64. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Server processors. + . + Geared toward server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-server meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-server +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on x86/x86_64 + This package provides kernel header files for version 2.6.24 on + x86/x86_64. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-debug-2.6.24-23-server +Architecture: i386 amd64 +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.24 on x86/x86_64 + This package provides a kernel debug image for version 2.6.24 on + x86/x86_64. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. + +Package: linux-image-2.6.24-23-sparc64 +Architecture: sparc +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: silo +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on 64-bit UltraSPARC + This package contains the Linux kernel image for version 2.6.24 on + 64-bit UltraSPARC. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 64-bit UltraSPARC processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-sparc64 meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-sparc64 +Architecture: sparc +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on 64-bit UltraSPARC + This package provides kernel header files for version 2.6.24 on + 64-bit UltraSPARC. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-sparc64-smp +Architecture: sparc +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: silo +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on 64-bit UltraSPARC SMP + This package contains the Linux kernel image for version 2.6.24 on + 64-bit UltraSPARC SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 64-bit UltraSPARC SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-sparc64-smp meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-sparc64-smp +Architecture: sparc +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on 64-bit UltraSPARC SMP + This package provides kernel header files for version 2.6.24 on + 64-bit UltraSPARC SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-virtual +Architecture: i386 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, redhat-cluster-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on x86 + This package contains the Linux kernel image for version 2.6.24 on + x86. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Virtual processors. + . + Geared toward virtualised hardware. + . + You likely do not want to install this package directly. Instead, install + the linux-virtual meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-virtual +Architecture: i386 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on x86 + This package provides kernel header files for version 2.6.24 on + x86. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-debug-2.6.24-23-virtual +Architecture: i386 +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.24 on x86 + This package provides a kernel debug image for version 2.6.24 on + x86. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. + +Package: linux-image-2.6.24-23-lpia +Architecture: lpia +Section: universe/base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, redhat-cluster-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on Ubuntu Moblie and Embedded LPIA edition + This package contains the Linux kernel image for version 2.6.24 on + Ubuntu Moblie and Embedded LPIA edition. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports UME processors. + . + UME kernel + . + You likely do not want to install this package directly. Instead, install + the linux-lpia meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-lpia +Architecture: lpia +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on Ubuntu Moblie and Embedded LPIA edition + This package provides kernel header files for version 2.6.24 on + Ubuntu Moblie and Embedded LPIA edition. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-rt +Architecture: i386 amd64 +Section: universe/base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, redhat-cluster-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on Ingo Molnar's full real time preemption patch (2.6.24.7-rt21) + This package contains the Linux kernel image for version 2.6.24 on + Ingo Molnar's full real time preemption patch (2.6.24.7-rt21). + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Generic processors. + . + RT kernel + . + You likely do not want to install this package directly. Instead, install + the linux-rt meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-rt +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on Ingo Molnar's full real time preemption patch (2.6.24.7-rt21) + This package provides kernel header files for version 2.6.24 on + Ingo Molnar's full real time preemption patch (2.6.24.7-rt21). + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-lpiacompat +Architecture: lpia +Section: universe/base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, redhat-cluster-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on Ubuntu Moblie and Embedded-x86 compat edition + This package contains the Linux kernel image for version 2.6.24 on + Ubuntu Moblie and Embedded-x86 compat edition. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports UME processors. + . + UME kernel + . + You likely do not want to install this package directly. Instead, install + the linux-lpiacompat meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-lpiacompat +Architecture: lpia +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on Ubuntu Moblie and Embedded-x86 compat edition + This package provides kernel header files for version 2.6.24 on + Ubuntu Moblie and Embedded-x86 compat edition. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-xen +Architecture: i386 amd64 +Section: universe/base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, redhat-cluster-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: grub +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on This kernel can be used for Xen dom0 and domU + This package contains the Linux kernel image for version 2.6.24 on + This kernel can be used for Xen dom0 and domU. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Generic processors. + . + Xen domO/domU + . + You likely do not want to install this package directly. Instead, install + the linux-xen meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-xen +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on This kernel can be used for Xen dom0 and domU + This package provides kernel header files for version 2.6.24 on + This kernel can be used for Xen dom0 and domU. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. + +Package: linux-image-2.6.24-23-openvz +Architecture: i386 amd64 +Section: universe/base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, redhat-cluster-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.24 | linux-source-2.6.24 +Description: Linux kernel image for version 2.6.24 on OpenVZ Virtualization enabled kernel + This package contains the Linux kernel image for version 2.6.24 on + OpenVZ Virtualization enabled kernel. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Generic processors. + . + OpenVZ kernel + . + You likely do not want to install this package directly. Instead, install + the linux-openvz meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.24-23-openvz +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.24-23, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.24 on OpenVZ Virtualization enabled kernel + This package provides kernel header files for version 2.6.24 on + OpenVZ Virtualization enabled kernel. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.24-23/debian.README.gz for details. --- linux-2.6.24.orig/debian/changelog +++ linux-2.6.24/debian/changelog @@ -0,0 +1,6569 @@ +linux (2.6.24-23.46) hardy-proposed; urgency=low + + [Alessio Igor Bogani] + + * rt: Updated PREEMPT_RT support to rt21 + - LP: #302138 + + [Amit Kucheria] + + * SAUCE: Update lpia patches from moblin tree + - LP: #291457 + + [Andy Whitcroft] + + * SAUCE: replace gfs2_bitfit with upstream version to prevent oops + - LP: #276641 + + [Colin Ian King] + + * isdn: Do not validate ISDN net device address prior to interface-up + - LP: #237306 + * hwmon: (coretemp) Add Penryn CPU to coretemp + - LP: #235119 + * USB: add support for Motorola ROKR Z6 cellphone in mass storage mode + - LP: #263217 + * md: fix an occasional deadlock in raid5 + - LP: #208551 + + [Stefan Bader] + + * SAUCE: buildenv: Show CVE entries in printchanges + * SAUCE: buildenv: Send git-ubuntu-log informational message to stderr + * Xen: dma: avoid unnecessarily SWIOTLB bounce buffering + - LP: #247148 + * Update openvz patchset to apply to latest stable tree. + - LP: #301634 + * XEN: Fix FTBS with stable updates + - LP: #301634 + + [Steve Conklin] + + * Add HID quirk for dual USB gamepad + - LP: #140608 + + [Tim Gardner] + + * Enable CONFIG_AX25_DAMA_SLAVE=y + - LP: #257684 + * SAUCE: Correctly blacklist Thinkpad r40e in ACPI + - LP: #278794 + * SAUCE: ALPS touchpad for Dell Latitude E6500/E6400 + - LP: #270643 + + [Upstream Kernel Changes] + + * Revert "[Bluetooth] Eliminate checks for impossible conditions in IRQ + handler" + - LP: #217659 + * KVM: VMX: Clear CR4.VMXE in hardware_disable + - LP: #268981 + * iov_iter_advance() fix + - LP: #231746 + * Fix off-by-one error in iov_iter_advance() + - LP: #231746 + * USB: serial: ch341: New VID/PID for CH341 USB-serial + - LP: #272485 + * x86: Fix 32-bit x86 MSI-X allocation leakage + - LP: #273103 + * b43legacy: Fix failure in rate-adjustment mechanism + - LP: #273143 + * x86: Reserve FIRST_DEVICE_VECTOR in used_vectors bitmap. + - LP: #276334 + * openvz: merge missed fixes from vanilla 2.6.24 openvz branch + - LP: #298059 + * openvz: some autofs related fixes + - LP: #298059 + * openvz: fix ve stop deadlock after nfs connect + - LP: #298059 + * openvz: fix netlink and rtnl inside container + - LP: #298059 + * openvz: fix wrong size of ub0_percpu + - LP: #298059 + * openvz: fix OOPS while stopping VE started before binfmt_misc.ko loaded + - LP: #298059 + * x86-64: Fix "bytes left to copy" return value for copy_from_user() + * NET: Fix race in dev_close(). (Bug 9750) + - LP: #301608 + * IPV6: Fix IPsec datagram fragmentation + - LP: #301608 + * IPV6: dst_entry leak in ip4ip6_err. + - LP: #301608 + * IPV4: Remove IP_TOS setting privilege checks. + - LP: #301608 + * IPCONFIG: The kernel gets no IP from some DHCP servers + - LP: #301608 + * IPCOMP: Disable BH on output when using shared tfm + - LP: #301608 + * IRQ_NOPROBE helper functions + - LP: #301608 + * MIPS: Mark all but i8259 interrupts as no-probe. + - LP: #301608 + * ub: fix up the conversion to sg_init_table() + - LP: #301608 + * x86: adjust enable_NMI_through_LVT0() + - LP: #301608 + * SCSI ips: handle scsi_add_host() failure, and other err cleanups + - LP: #301608 + * CRYPTO xcbc: Fix crash with IPsec + - LP: #301608 + * CRYPTO xts: Use proper alignment + - LP: #301608 + * SCSI ips: fix data buffer accessors conversion bug + - LP: #301608 + * SCSI aic94xx: fix REQ_TASK_ABORT and REQ_DEVICE_RESET + - LP: #301608 + * x86: replace LOCK_PREFIX in futex.h + - LP: #301608 + * ARM pxa: fix clock lookup to find specific device clocks + - LP: #301608 + * futex: fix init order + - LP: #301608 + * futex: runtime enable pi and robust functionality + - LP: #301608 + * file capabilities: simplify signal check + - LP: #301608 + * hugetlb: ensure we do not reference a surplus page after handing it to + buddy + - LP: #301608 + * ufs: fix parenthesisation in ufs_set_fs_state() + - LP: #301608 + * spi: pxa2xx_spi clock polarity fix + - LP: #301608 + * NETFILTER: Fix incorrect use of skb_make_writable + - LP: #301608 + * NETFILTER: fix ebtable targets return + - LP: #301608 + * SCSI advansys: fix overrun_buf aligned bug + - LP: #301608 + * pata_hpt*, pata_serverworks: fix UDMA masking + - LP: #301608 + * moduleparam: fix alpha, ia64 and ppc64 compile failures + - LP: #301608 + * PCI x86: always use conf1 to access config space below 256 bytes + - LP: #301608 + * e1000e: Fix CRC stripping in hardware context bug + - LP: #301608 + * atmel_spi: fix clock polarity + - LP: #301608 + * x86: move out tick_nohz_stop_sched_tick() call from the loop + - LP: #301608 + * macb: Fix speed setting + - LP: #301608 + * ioat: fix 'ack' handling, driver must ensure that 'ack' is zero + - LP: #301608 + * VT notifier fix for VT switch + - LP: #301608 + * USB: ftdi_sio: Workaround for broken Matrix Orbital serial port + - LP: #301608 + * USB: ftdi_sio - really enable EM1010PC + - LP: #301608 + * SCSI: fix BUG when sum(scatterlist) > bufflen + - LP: #301608 + * x86: don't use P6_NOPs if compiling with CONFIG_X86_GENERIC + - LP: #301608 + * Fix default compose table initialization + - LP: #301608 + * SCSI: gdth: bugfix for the at-exit problems + - LP: #301608 + * sched: fix race in schedule() + - LP: #301608 + * nfsd: fix oops on access from high-numbered ports + - LP: #301608 + * sched_nr_migrate wrong mode bits + - LP: #301608 + * NETFILTER: xt_time: fix failure to match on Sundays + - LP: #301608 + * NETFILTER: nfnetlink_queue: fix computation of allocated size for + netlink skb + - LP: #301608 + * NETFILTER: nfnetlink_log: fix computation of netlink skb size + - LP: #301608 + * zisofs: fix readpage() outside i_size + - LP: #301608 + * jbd2: correctly unescape journal data blocks + - LP: #301608 + * jbd: correctly unescape journal data blocks + - LP: #301608 + * aio: bad AIO race in aio_complete() leads to process hang + - LP: #301608 + * async_tx: avoid the async xor_zero_sum path when src_cnt > + device->max_xor + - LP: #301608 + * SCSI advansys: Fix bug in AdvLoadMicrocode + - LP: #301608 + * BLUETOOTH: Fix bugs in previous conn add/del workqueue changes. + - LP: #301608 + * relay: fix subbuf_splice_actor() adding too many pages + - LP: #301608 + * slab: NUMA slab allocator migration bugfix + - LP: #301608 + * S390 futex: let futex_atomic_cmpxchg_pt survive early functional tests. + - LP: #301608 + * Linux 2.6.24.4 + - LP: #301608 + * time: prevent the loop in timespec_add_ns() from being optimised away + - LP: #301632 + * kbuild: soften modpost checks when doing cross builds + - LP: #301632 + * mtd: memory corruption in block2mtd.c + - LP: #301632 + * md: remove the 'super' sysfs attribute from devices in an 'md' array + - LP: #301632 + * V4L: ivtv: Add missing sg_init_table() + - LP: #301632 + * UIO: add pgprot_noncached() to UIO mmap code + - LP: #301632 + * USB: new quirk flag to avoid Set-Interface + - LP: #301632 + * NOHZ: reevaluate idle sleep length after add_timer_on() + - LP: #301632 + * slab: fix cache_cache bootstrap in kmem_cache_init() + - LP: #301632 + * xen: fix RMW when unmasking events + - LP: #301632 + * xen: mask out SEP from CPUID + - LP: #301632 + * xen: fix UP setup of shared_info + - LP: #301632 + * PERCPU : __percpu_alloc_mask() can dynamically size percpu_data storage + - LP: #301632 + * alloc_percpu() fails to allocate percpu data + - LP: #301632 + * vfs: fix data leak in nobh_write_end() + - LP: #301632 + * pci: revert SMBus unhide on HP Compaq nx6110 + - LP: #301632 + * vmcoreinfo: add the symbol "phys_base" + - LP: #301632 + * USB: Allow initialization of broken keyspan serial adapters. + - LP: #301632 + * USB: serial: fix regression in Visor/Palm OS module for kernels >= + 2.6.24 + - LP: #301632 + * USB: serial: ti_usb_3410_5052: Correct TUSB3410 endpoint requirements. + - LP: #301632 + * CRYPTO xcbc: Fix crash when ipsec uses xcbc-mac with big data chunk + - LP: #301632 + * mtd: fix broken state in CFI driver caused by FL_SHUTDOWN + - LP: #301632 + * ipmi: change device node ordering to reflect probe order + - LP: #301632 + * AX25 ax25_out: check skb for NULL in ax25_kick() + - LP: #301632 + * NET: include into linux/ethtool.h for __u* typedef + - LP: #301632 + * SUNGEM: Fix NAPI assertion failure. + - LP: #301632 + * INET: inet_frag_evictor() must run with BH disabled + - LP: #301632 + * LLC: Restrict LLC sockets to root + - LP: #301632 + * netpoll: zap_completion_queue: adjust skb->users counter + - LP: #301632 + * PPPOL2TP: Make locking calls softirq-safe + - LP: #301632 + * PPPOL2TP: Fix SMP issues in skb reorder queue handling + - LP: #301632 + * NET: Add preemption point in qdisc_run + - LP: #301632 + * sch_htb: fix "too many events" situation + - LP: #301632 + * SCTP: Fix local_addr deletions during list traversals. + - LP: #301632 + * NET: Fix multicast device ioctl checks + - LP: #301632 + * TCP: Fix shrinking windows with window scaling + - LP: #301632 + * TCP: Let skbs grow over a page on fast peers + - LP: #301632 + * VLAN: Don't copy ALLMULTI/PROMISC flags from underlying device + - LP: #301632 + * SPARC64: Fix atomic backoff limit. + - LP: #301632 + * SPARC64: Fix __get_cpu_var in preemption-enabled area. + - LP: #301632 + * SPARC64: flush_ptrace_access() needs preemption disable. + - LP: #301632 + * libata: assume no device is attached if both IDENTIFYs are aborted + - LP: #301632 + * sis190: read the mac address from the eeprom first + - LP: #301632 + * bluetooth: hci_core: defer hci_unregister_sysfs() + - LP: #301632 + * SPARC64: Fix FPU saving in 64-bit signal handling. + - LP: #301632 + * DVB: tda10086: make the 22kHz tone for DISEQC a config option + - LP: #301632 + * HFS+: fix unlink of links + - LP: #301632 + * plip: replace spin_lock_irq with spin_lock_irqsave in irq context + - LP: #301632 + * signalfd: fix for incorrect SI_QUEUE user data reporting + - LP: #301632 + * POWERPC: Fix build of modular drivers/macintosh/apm_emu.c + - LP: #301632 + * PARISC futex: special case cmpxchg NULL in kernel space + - LP: #301632 + * PARISC pdc_console: fix bizarre panic on boot + - LP: #301632 + * PARISC fix signal trampoline cache flushing + - LP: #301632 + * acpi: bus: check once more for an empty list after locking it + - LP: #301632 + * fbdev: fix /proc/fb oops after module removal + - LP: #301632 + * macb: Call phy_disconnect on removing + - LP: #301632 + * file capabilities: remove cap_task_kill() + - LP: #301632 + * locks: fix possible infinite loop in fcntl(F_SETLKW) over nfs + - LP: #301632 + * Linux 2.6.24.5 + - LP: #301632 + * splice: use mapping_gfp_mask + - LP: #301634 + * fix oops on rmmod capidrv + - LP: #301634 + * USB: gadget: queue usb USB_CDC_GET_ENCAPSULATED_RESPONSE message + - LP: #301634 + * JFFS2: Fix free space leak with in-band cleanmarkers + - LP: #301634 + * Increase the max_burst threshold from 3 to tp->reordering. + - LP: #301634 + * USB: remove broken usb-serial num_endpoints check + - LP: #301634 + * V4L: Fix VIDIOCGAP corruption in ivtv + - LP: #301634 + * Linux 2.6.24.6, 2.6.24.7 + - LP: #301634 + + -- Stefan Bader Mon, 24 Nov 2008 09:44:34 +0100 + +linux (2.6.24-22.45) hardy-security; urgency=low + + [Upstream Kernel Changes] + + * Don't allow splice() to files opened with O_APPEND + - CVE-2008-4554 + * sctp: Fix oops when INIT-ACK indicates that peer doesn't support AUTH + - CVE-2008-4576 + * sctp: Fix kernel panic while process protocol violation parameter + - CVE-2008-4618 + * hfsplus: fix Buffer overflow with a corrupted image + - CVE-2008-4933 + * hfsplus: check read_mapping_page() return value + - CVE-2008-4934 + * net: Fix recursive descent in __scm_destroy(). + - CVE-2008-5029 + * net: unix: fix inflight counting bug in garbage collector + - CVE-2008-5029 + * security: avoid calling a NULL function pointer in + drivers/video/tvaudio.c + - CVE-2008-5033 + * hfs: fix namelength memory corruption + - CVE-2008-5025 + * V4L/DVB (9621): Avoid writing outside shadow.bytes[] array + + -- Stefan Bader Tue, 18 Nov 2008 17:19:02 +0100 + +linux (2.6.24-22.44) hardy-proposed; urgency=low + + [Amit Kucheria] + + * SAUCE: Update lpia patches from moblin tree + - LP: #291457 + + [Colin Ian King] + + * isdn: Do not validate ISDN net device address prior to interface-up + - LP: #237306 + * hwmon: (coretemp) Add Penryn CPU to coretemp + - LP: #235119 + * USB: add support for Motorola ROKR Z6 cellphone in mass storage mode + - LP: #263217 + * md: fix an occasional deadlock in raid5 + - LP: #208551 + * Revert "[Bluetooth] Eliminate checks for impossible conditions in IRQ + handler" + - LP: #217659 + + [Stefan Bader] + + * SAUCE: buildenv: Show CVE entries in printchanges + * SAUCE: buildenv: Send git-ubuntu-log informational message to stderr + + [Tim Gardner] + + * Enable CONFIG_AX25_DAMA_SLAVE=y + - LP: #257684 + * SAUCE: Correctly blacklist Thinkpad r40e in ACPI + - LP: #278794 + * SAUCE: ALPS touchpad for Dell Latitude E6500/E6400 + - LP: #270643 + * KVM: VMX: Clear CR4.VMXE in hardware_disable + - LP: #268981 + * USB: serial: ch341: New VID/PID for CH341 USB-serial + - LP: #272485 + * x86: Fix 32-bit x86 MSI-X allocation leakage + - LP: #273103 + * b43legacy: Fix failure in rate-adjustment mechanism + - LP: #273143 + * x86: Reserve FIRST_DEVICE_VECTOR in used_vectors bitmap. + - LP: #276334 + + -- Stefan Bader Thu, 23 Oct 2008 07:52:39 -0400 + +linux (2.6.24-21.43) hardy-security; urgency=low + + [Stefan Bader] + + * Enable CONFIG_DEBUG_RODATA=y for all architectures. + + [Upstream Kernel Changes] + + * Fix ZERO_PAGE breakage with vmware + - CVE-2008-2372 + * wan: Missing capability checks in sbni_ioctl() + - CVE-2008-3525 + * sctp: add verification checks to SCTP_AUTH_KEY option + - CVE-2008-3526, CVE-2008-4445 + * tmpfs: fix kernel BUG in shmem_delete_inode + - CVE-2008-3534 + * fbdefio: add set_page_dirty handler to deferred IO FB + - CVE-2008-3534 + * iov_iter_advance() fix + - LP: #231746 + * Fix off-by-one error in iov_iter_advance() + - LP: #231746 + - CVE-2008-3535 + * Incorrect length was used in SCTP_*_AUTH_CHUNKS socket option + - CVE-2008-3792 + * sctp: fix potential panics in the SCTP-AUTH API. + - CVE-2008-3792 + * nfsd: fix buffer overrun decoding NFSv4 acl + - CVE-2008-3915 + * sctp: fix random memory dereference with SCTP_HMAC_IDENT option. + - CVE-2008-4113 + * Only allow access to DRM_I915_HWS_ADDR ioctl() for Xserver. + - CVE-2008-383 + + -- Stefan Bader Wed, 01 Oct 2008 16:59:37 -0400 + +linux (2.6.24-21.42) hardy-proposed; urgency=low + + [Stefan Bader] + + * Print bug reference number for upstream changes + + [Tim Gardner] + + * b43 - Add Dell adapter to Bluetooth coexiastence check. + - LP: #257020 + * Enabled CONFIG_NF_CT_NETLINK/CONFIG_NF_CONNTRACK_EVENTS in -virtual + - LP: #257569 + + [Upstream Kernel Changes] + + * eCryptfs: use page_alloc not kmalloc to get a page of memory + - LP: #242448 + * openvz: sync with stable 2.6.18-rhel5 branch + - LP: #258044 + * USB: quirk PLL power down mode + - LP: #257931 + * acpi: unneccessary to scan the PCI bus already scanned + - LP: #258143 + * eCryptfs: make ecryptfs_prepare_write decrypt the page + - LP: #242448 + * gdth: don't call pci_free_consistent under spinlock + - LP: #199934 + * SCSI: gdth: fix to internal commands execution + - LP: #199934 + * r8169: avoid thrashing PCI conf space above RTL_GIGA_MAC_VER_06 + - LP: #141343 + * (CVE-2008-3276) dccp: change L/R must have at least one byte in the + dccpsf_val field + * suspend-vs-iommu: prevent suspend if we could not resume + - LP: #257293 + * x86, gart: add resume handling + - LP: #257293 + + -- Stefan Bader Wed, 22 Aug 2008 12:07:28 -0400 + +linux (2.6.24-21.40) hardy-proposed; urgency=low + + [Tim Gardner] + + * Bump ABI for WiMax 'enum rfkill_type' additions. + + [Upstream Kernel Changes] + + * b43: Add more btcoexist workarounds + - LP: #257020 + + -- Tim Gardner Mon, 11 Aug 2008 13:13:46 -0600 + +linux (2.6.24-20.39) hardy-proposed; urgency=low + + [Amit Kucheria] + + * rfkill: add the WiMAX radio type + - LP: #253347 + * if_arp: add a WiMax pseudo header + - LP: #253347 + + [Stefan Bader] + + * Backport ability to reset the machine using the RESET_REG of ACPI + - LP: #249296 + * SAUCE: Add the ability to whitelist systems to use ACPI reboot + - LP: #249296 + * SAUCE: Add reboot=a preselection quirk + - LP: #249296 + * Backport make USB-PERSIST work after every system sleep + - LP: #254783 + + [Upstream Kernel Changes] + + * V4L/DVB (7068): Add support for WinTV Nova-T-CE driver + - LP: #238164 + * [NETFILTER]: {ip,ip6,nfnetlink}_queue: fix SKB_LINEAR_ASSERT when + mangling packet data + - LP: #236699 + * sky2: 88E8040T pci device id + - LP: #237211 + * md: close a livelock window in handle_parity_checks5 + - LP: #244377 + * Fix typos from signal_32/64.h merge + - LP: #230315 + + -- Stefan Bader Fri, 08 Aug 2008 11:39:18 -0400 + +linux (2.6.24-20.38) hardy-proposed; urgency=low + + [Tim Gardner] + + * SAUCE: Export usbhid_modify_dquirk for LBM module bcm5974 + - LP: #250838 + * Enable TULIP ethernet support in virtual appliance flavour + - LP: #250857 + * VIA AGP VT3364 is not detected + - LP: #251854 + * VIA - Add VIA DRM Chrome9 3D engine + - LP: #251862 + + [Upstream Kernel Changes] + + * net/usb: add support for Apple USB Ethernet Adapter + - LP: #232200 + * acpi: fix "buggy BIOS check" when CPUs are hot removed + - LP: #248509 + * x86: fix paranoia about using BIOS quickboot mechanism. + - LP: #248905 + * flush kacpi_notify_wq before removing notify handler + - LP: #248509 + * fix a deadlock issue when poking "eject" file + - LP: #248509 + * force offline the processor during hot-removal + - LP: #248509 + * create sysfs link from acpi device to sysdev for cpu + - LP: #248509 + * x86: fix bootup crash in native_read_tsc() (aka use XMM2) + - LP: #249135 + * x86: lfence fix - LFENCE is available on XMM2 or higher + Intel CPUs - not XMM or higher... + - LP: #249135 + + -- Tim Gardner Fri, 25 Jul 2008 22:12:46 -0600 + +linux (2.6.24-20.37) hardy-proposed; urgency=low + + [Colin Ian King] + + * scheduling while atomic: archhttp64/7146/0x1000000001 + - LP: #235889 + * Slim USB Apple Keyboard not working correctly when pressing the + "numlock" key + - LP: #201887 + + [Linus Torvalds] + + * Reinstate ZERO_PAGE optimization in 'get_user_pages()' and fix XIP + - LP: #246663 + + [Michael Frey (Senior Manager, MID)] + + * SAUCE: Send HCI_RESET for Broadcomm 2046 + - LP: #241749 + + [Stefan Bader] + + * drivers: fix dma_get_required_mask + - LP: #238118 + * Modify log generation to catch bug numbers when adding with git-am. + * ACPICA: Fix for resource descriptor optimization issues for _CRS/_SRC + - LP: #152187 + * ACPI: Fix acpi_processor_idle and idle= boot parameters interaction + - LP: #241229 + * cpuidle acpi driver: fix oops on AC<->DC + - LP: #241229 + * ACPI: EC: Do the byte access with a fast path + - LP: #191137 + * ACPI: EC: Some hardware requires burst mode to operate properly + - LP: #191137 + + [Tejun Heo] + + * ahci: jmb361 has only one port + - LP: #244363 + + [Tim Gardner] + + * Add native_read_tsc to non __i386__ code. + - LP: #249135 + * Fix x86-64 FTBS after upstream cherry-pick of + 898ad535e2c81e0b02628c1ee5d8400c971500dd + - LP: #249135 + * Use readtsc-barrier in xen + - LP: #249135 (for the previous 7 log entries) + * Enabled CONFIG_NETDEVICES_MULTIQUEUE=y in order to support 802.11n + - LP: #241423 + * SAUCE: e1000 checksum recheck after reset + - LP: #60388 + * Enable CONFIG_CIFS_UPCALL=y to support Kerberos authentication + - LP: #236830 + * Clear host capabilities number of ports after quirking JMB361 + - LP: #244363 + + [Upstream Kernel Changes] + + * x86: tsc prevent time going backwards + - LP: #221351 + * x86: implement support to synchronize RDTSC through MFENCE on AMD CPUs + * x86: Implement support to synchronize RDTSC with LFENCE on Intel CPUs + * x86: move nop declarations into separate include file + * x86: introduce rdtsc_barrier() + * x86: remove get_cycles_sync + * x86: read_tsc sync + * Add barriers to native_read_tsc + - LP: #249135 (for the previous 7 log entries) + * hwmon: (w83781d) Fix I/O resource conflict with PNP + - LP: #242761 + * inotify: fix race + * inotify: remove debug code + - LP: #104837 (previous 2 log entries) + * openvz: sync with stable 2.6.18-rhel5 branch + - LP: #249137 + * UBUNTU SAUCE: Setup PHYs correctly on rtl8101/2(e) hardware + - LP: #240648 + * UBUNTU SAUCE: Update rtl8101/2(e) hardware initialization value + - LP: #240648 + * x86: remove 6 bank limitation in 64 bit MCE reporting code + - LP: #239666 + + -- Tim Gardner Wed, 09 Jul 2008 14:55:14 -0600 + +linux (2.6.24-19.41) hardy-security; urgency=low + + [Upstream Kernel Changes] + + * Fix compiler warning on 64-bit + follow-up for CVE-2008-1673 + * netfilter: nf_nat_snmp_basic: fix a range check in NAT for SNMP + follow-up for CVE-2008-1673 + + -- Stefan.Bader Tue, 19 Aug 2008 15:02:19 -0400 + +linux (2.6.24-19.37) hardy-security; urgency=low + + [Upstream Kernel Changes] + + * (CVE-2008-2812) TTY: fix for tty operations bugs + * (CVE-2008-3272) sound: ensure device number is valid in + snd_seq_oss_synth_make_info + * (CVE-2008-3275) vfs: fix lookup on deleted directory + + -- Ben Collins Tue, 05 Aug 2008 22:28:53 +0000 + +linux (2.6.24-19.36) hardy-security; urgency=low + + * Fixed hppa FTBS by adding ABI files from -19.33. + + -- Tim Gardner Fri, 11 Jul 2008 08:26:29 -0600 + +linux (2.6.24-19.35) hardy-security; urgency=low + + [Upstream Kernel Changes] + + * (CVE-2007-6282) [ESP]: Ensure IV is in linear part of the skb to avoid + BUG() due to OOB access + * (CVE-2008-1673) asn1: additional sanity checking during BER decoding + * (CVE-2008-2136) sit: Add missing kfree_skb() on pskb_may_pull() + failure. + * (CVE-2008-2137) sparc: Fix mmap VA span checking. + * (CVE-2008-2148) vfs: fix permission checking in sys_utimensat + * (CVE-2008-2358) dccp: return -EINVAL on invalid feature length + * (CVE-2008-2750) l2tp: Fix potential memory corruption in + pppol2tp_recvmsg() + * (CVE-2008-1615) x86_64: fix CS corruption on iret + * fuse: fix permission checking + * (CVE-2008-2826) sctp: Make sure N * sizeof(union sctp_addr) does not + overflow. + + -- Tim Gardner Tue, 01 Jul 2008 10:40:28 -0600 + +linux (2.6.24-19.34) hardy-proposed; urgency=low + + [Amit Kucheria] + + * Revert "Update lpia configs to move modules into the kernel" + * LPIA: More conservative culling of LPIA config + + -- Tim Gardner Thu, 05 Jun 2008 09:30:31 -0600 + +linux (2.6.24-19.33) hardy-proposed; urgency=low + + [Alessio Igor Bogani] + + * rt: Updated configuration files + * rt: Disable Dynamic Ticks (CONFIG_NO_HZ) + - LP: #229499 + + [Amit Kucheria] + + * LPIA: USB Client PV release from Intel + * Update lpia configs to move modules into the kernel + + [Colin Ian King] + + * SAUCE: Blacklist IBM 2656 in serio/i8042 + - LP: #21558 + * Fix ipv6 temporary address creation failure + - LP: #210742 + * rndis_host: fix transfer size negotiation + - LP: #192411 + * sata_nv: correct completion handling that fixes system reboots + - LP: #210637 + * drm_sysfs_suspend uses KERN_ERR in printk + - LP: #234239 + + [Mario Limonciello] + + * SAUCE: Work around ACPI corruption upon suspend on some Dell machines. + - LP: #183033 + * SAUCE: Wakeup BT input devices that have been suspended + - LP: #175743 + + [Stefan Bader] + + * cx88: enable radio GPIO correctly + - LP: #209971 + * fix IS_I9XX macro in i915 DRM driver + - LP: #204762 + * x86: fix long standing bug with usb after hibernation with 4GB ram + - LP: #206996 + + [Tim Gardner] + + * rpcb_getport_async in sunrpc can cause oops on Hardy + - LP: #224750 + * kernel: fix x86 DMI checks for PCI quirks + - LP: #225811 + * b43: Workaround invalid bluetooth settings + - LP: #197959 + * ssb: Fix IRQ vectors enable for early cards. + - LP: #197959 + * ssb: Fix TMS low bitmask reject code. + - LP: #197959 + * ssb: Fix all-ones boardflags + - LP: #197959 + * b43legacy: fix hard crash when BCM4303 present. + - LP: #192720 + * b43legacy: Fix bug in firmware loading for 802..11b devices. + - LP: #192720 + * b43legacy: Prevent spamming the logs when LED encoding in SPROM is + faulty. + - LP: #192720 + * block: fix blkdev_issue_flush() not detecting and passing EOPNOTSUPP + back + - LP: #215110 + * V4L/DVB (7132): Add USB ID for a newer variant of Hauppauge WinTV-HVR + 900 + - LP: #195435 + * Add Lenovo Thinkpad X61 DMI Quirk support. + * Enable powerpc-smp64 CONFIG_PASEMI_MAC=m + - LP: #213668 + * OpenVZ kernel: non-POSIX behavior in mmap functions + - LP: #231400 + * SAUCE: fn key doesn't work in hardy with macbook pro fourth generation + (4,1) + - LP: #207127 + * MMC bitmap overflow in 64 bit kernel + - LP: #88992 + * revert: UBUNTU: TSC Clocksource can cause hangs and time jumps + This patch appears to cause suspend to RAM regressions (see LP #226279) + -LP: #221351 + + [Upstream Kernel Changes] + + * openvz: make stat and fstat agree on (st_dev, st_ino) in VE + - LP: #226335 + * V4L/DVB (7066): ASUS My Cinema U3000 Mini DVBT Tuner + - LP: #95277 + * r8169: fix oops in r8169_get_mac_version + - LP: #223656 + * PCI: quirks: set 'En' bit of MSI Mapping for devices onHT-based nvidia + platform + - LP: #181081 + * HID: Implement horizontal wheel handling for A4 Tech X5-005D + - LP: #201964 + * ata-acpi: don't call _GTF for disabled drive + - LP: #202767 + + * openvz: sync 2.6.24-ovz004 => 2.6.24-ovz005 + * openvz: UBC: drop cpuset lock from OOM handling + * openvz: IPv6: get frag's owner VE from inet_frag_queue + * openvz: proc: fix proc_cwd_link + * openvz: VLAN: fix rmmod 8021q with vlan interface setup + * openvz: Remove spurious warnings in kernel/time.c + - LP: #231400, #230432, and #235207 + + -- Tim Gardner Sun, 04 May 2008 20:22:21 -0600 + +linux (2.6.24-18.32) hardy-security; urgency=low + + * CVE-2007-6694: [POWERPC] CHRP: Fix possible NULL pointer dereference + * fix SMP ordering hole in fcntl_setlk() (CVE-2008-1669) + * Fix dnotify/close race (CVE-2008-1375) + * tehuti: check register size (CVE-2008-1675) + * tehuti: move ioctl perm check closer to function start (CVE-2008-1675) + + -- Ben Collins Mon, 19 May 2008 16:50:11 +0000 + +linux (2.6.24-17.31) hardy; urgency=low + + [Alessio Igor Bogani] + + * rt: Fix mutex in the toshiba_acpi driver + * rt: Updated configuration files + + [Ben Collins] + + * build: Fix revert detection in git-ubuntu-log + * SAUCE: Re-add eeprom_bad_csum_allow module-param + - LP: #60388 + + [Stefan Bader] + + * Pulled updates to openvz custom build. Fixes openvz 'refuses to boot' problem. + - LP: #210672 + * sched: retain vruntime, fix delayed key events when CONFIG_FAIR_GROUP_SCHED. + - LP: #218516 + * UBUNTU: SAUCE: Add blacklist support to fix Belkin bluetooth dongle. + - LP: #140511 + + [Tim Gardner] + + * Enable CONFIG_ISCSI_TCP for -virtual + - LP: #218215 + * build: Add fancontrol modules to powerpc64-smp debian installer + * Fix Xen Dom0/DomU bridging + - LP: #218126 + * TSC Clocksource can cause hangs and time jumps + - LP: #221351 + * Kernel should use CONFIG_FAIR_CGROUP_SCHED. Fixes high load issues + with pulseaudio. + - LP: #188226 + + [Upstream Kernel Changes] + + * KVM: MMU: prepopulate guest pages after write-protecting + - LP: #221032 + + -- Tim Gardner Fri, 11 Apr 2008 07:59:10 -0600 + +linux (2.6.24-16.30) hardy; urgency=low + + * Fix amd64/i386 ABI and module check FTBS by creating an ignore + and ignore.modules in the ABI directory. + + -- Tim Gardner Wed, 09 Apr 2008 21:58:25 -0600 + +linux (2.6.24-16.29) hardy; urgency=low + + [Stephan Bader] + + * UBUNTU: SAUCE: mmc: Increase power_up deleay to fix TI readers + + [Alessio Igor Bogani] + + * rt: Updated configuration files + + [Chuck Short] + + * Xen updates for vitrio changes. + + [Tim Gardner] + + * openvz updates for vitrio changes. + + -- Tim Gardner Tue, 08 Apr 2008 21:48:16 -0600 + +linux (2.6.24-16.28) hardy; urgency=low + + [Tim Gardner] + + * Revert "UBUNTU: x86: tsc prevent time going backwards" + + [Kees Cook] + + * AppArmor: implement mmap_min_addr check as done in mainline. + + [Soren Hansen] + + * Bring our virtio code up to date with 2.6.25-rc7 + + [Upstream Kernel Changes] + + * Ubuntu: Revert all our virtio changes + * lguest: Reboot support + * lguest: adapt launcher to per-cpuness + * virtio: Implement skb_partial_csum_set, for setting partial csums on + untrusted packets. + * virtio: simplify config mechanism. + * virtio: explicit enable_cb/disable_cb rather than callback return. + * virtio: configuration change callback + * virtio: Fix vring_init/vring_size to take unsigned long + * virtio: clarify NO_NOTIFY flag usage + * virtio: remove unused id field from struct virtio_blk_outhdr + * virtio: Net header needs hdr_len + * virtio: Tweak virtio_net defines + * virtio: populate network rings in the probe routine, not open + * virtio: reset function + * virtio: handle interrupts after callbacks turned off + * virtio: Use the sg_phys convenience function. + * virtio: Allow virtio to be modular and used by modules + * virtnet: remove double ether_setup + * virtio: flush buffers on open + * virtio: free transmit skbs when notified, not on next xmit. + * virtio_net: parametrize the napi_weight for virtio receive queue. + * virtio_blk: provide getgeo + * virtio_blk: Dont waste major numbers + * virtio_blk: implement naming for vda-vdz,vdaa-vdzz,vdaaa-vdzzz + * virtio: PCI device + * virtio: Use PCI revision field to indicate virtio PCI ABI version + * virtio: balloon driver + * virtio net: fix oops on interface-up + * virtio: add missing #include + * virtio: fix race in enable_cb + * virtio: handle > 2 billion page balloon targets + * virtio_net: Fix oops on early interrupts - introduced by virtio reset + code + * lguest: Do not append space to guests kernel command line + * virtio: Use spin_lock_irqsave/restore for virtio-pci + * virtio: Fix sysfs bits to have proper block symlink + * virtio: Enable netpoll interface for netconsole logging + * virtio_pci: unregister virtio device at device remove + * lguest: Add puppies which where previously missing. + * lguest: lguest.txt documentation fix + * lguest: Don't need comment terminator before disk section. + * virtio_pci iomem annotations + * virtio_net: remove overzealous printk + * virtio: remove overzealous BUG_ON. + + -- Tim Gardner Tue, 08 Apr 2008 11:53:49 -0600 + +linux (2.6.24-15.27) hardy; urgency=low + + [Alan Stern] + + * usb-storage: don't access beyond the end of the sg buffer + - LP: #204922 + + [Mario Limonciello] + + * Enable Reset and SCO workaround on Dell 410 BT adapter + + [Tim Gardner] + + * Enable CONFIG_E1000 in the i386 virtual image. + - LP: #205646 + + [Thomas Gleixner] + + * x86: tsc prevent time going backwards + + [Matthew Garrett] + + * Fix framebuffer fonts on non-x86 platforms + + -- Tim Gardner Fri, 04 Apr 2008 08:14:49 -0600 + +linux (2.6.24-15.26) hardy; urgency=low + + [Colin Ian King] + + * airprime.c supports more devices + - LP: #208250 + + [Kees Cook] + + * AppArmor: get latest batch of upstream fixes into Hardy (svn 1160) + + [Stefan Bader] + + * ACPI: fix boot oops regression in kernel + - LP: #207014 + + [Tim Gardner] + + * Enable CGROUPS for non x86/x86_64 arches, all flavours. + - LP: #188226 + + -- Tim Gardner Thu, 03 Apr 2008 07:00:29 -0600 + +linux (2.6.24-14.25) hardy; urgency=low + + [Mario Limonciello] + + * Resolve sky2 race condition leading to failed suspends + - LP: #210877 + + [Tim Gardner] + + * Copy drivers/media internal header files into header + package for external LUM compilation. This paves the + way for LP #202065. + + -- Tim Gardner Wed, 02 Apr 2008 08:28:32 -0600 + +linux (2.6.24-14.24) hardy; urgency=low + + [Amit Kucheria] + + * LPIA: Update from moblin + * LPIA: Fix reboot problem after S3/S4 + * LPIA: Integrate latest Dabney thermal patches + * LPIA: Change-umd_dbg-debug-level-to-KERN_INFO + * LPIA: Compile modules into kernel to save on boot time + * LPIA: lots of Dabney CONFIG options dissapeared + * LPIA: Purge nonexistent config options + + [Jay Chetty] + + * UBUNTU:USBC:Integrated USBC 2.0.0.32L.0009 + + [Misha Zhilin] + + * USB: ehci: handle large bulk URBs correctly (again) + - LP: #204857 + + [Tim Gardner] + + * frame buffer regression - screen blank except for blinking cursor after + fbcon vtswitch + - LP: #201591 + * Blacklist Bluetooth Dell Wireless 370 for SCO MTU + - LP: #209715 + * Set CONFIG_FAIR_CGROUP_SCHED for server flavours. + - LP: #188226 + * Add DMI IO_DELAY support. + - LP: #200057 + + -- Tim Gardner Mon, 31 Mar 2008 11:19:49 -0600 + +linux (2.6.24-13.23) hardy; urgency=low + + [Alessio Igor Bogani] + + * rt: Updated configuration files + + [Ben Collins] + + * openvz: New custom flavour for OpenVZ + * config: Disable IDE AMD driver in favor of PATA version + - LP: #181561 + * config: Disable IDE VIA driver in favor of PATA version + - LP: #181561 + * drivers/video: Restore gutsy backlight dimming behavior + - LP: #205261 + * build/config: Enable CONFIG_CIFS_WEAK_PW_HASH + - LP: #202445 + + [Colin Ian King] + + * SAUCE: Add support for version 4 of Chelsio NICs in cxgb3 driver + - LP: #201893 + + [Kees Cook] + + * AppArmor: re-add missing "type" field in syslog reports. + - LP: #202888 + * kvm: reset TSS on x86_64 to avoid ioperm bitmap corruption + - LP: #144900 + + [Stefan Bader] + + * USB: EHCI: add separate IAA watchdog timer + - LP: #198619 + * SAUCE: Always use SCO protocol (disable eSCO support) + - LP: #39414 + * PM: Introduce PM_EVENT_HIBERNATE callback state + - LP: #201086 + + [Tim Gardner] + + * Disable DRM suspend/resume on pre-915 Intel chips + - LP: #207496 + * frame buffer regression - screen blank except for blinking cursor after fbcon + vtswitch + - LP: #201591 + + -- Tim Gardner Wed, 19 Mar 2008 10:05:05 -0400 + +linux (2.6.24-12.22) hardy; urgency=low + + [Ben Collins] + + * custom/rt: Disable toshiba_acpi, since it isn't compatible + + -- Ben Collins Wed, 12 Mar 2008 14:38:59 -0400 + +linux (2.6.24-12.21) hardy; urgency=low + + [Ben Collins] + + * build: Fix vesafb module inclusion into initrd subdir + - LP: #129910 + * net/bluetooth: POWERBOOK => APPLE, fix for apple keyboard patch + * custom/xen: Remove asix portion of xen patch, breaks driver + - LP: #199296 + + [Colin Ian King] + + * SAUCE: fix Udma not fully available in Acer 1694 Wlmi + - LP: #187121 + * SAUCE: Update toshiba_acpi.c to version 0.19a + - LP: #77026 + + [Stefan Bader] + + * x86: Clear DF before calling signal handler + * Enable FN key on Apple aluminum bluetooth keyboard + - LP: #162083 + + -- Ben Collins Tue, 11 Mar 2008 13:20:49 -0400 + +linux (2.6.24-12.20) hardy; urgency=low + + [Ben Collins] + + * Enable CONFIG_SOUND at least, so alsa build in lum works + - LP: #200338 + + -- Ben Collins Mon, 10 Mar 2008 08:15:00 -0400 + +linux (2.6.24-12.19) hardy; urgency=low + + * Re-upload of -12.18 to fix build failures + * Fixup binary-custom configs + * Fixup xen patch to cope with kvm changes + + [Amit Kucheria] + + * Move Marvell 8686 and 8688 to LUM + * Poulsbo: Sync patches with moblin/ume-hardy tree + * Break if a patch fails to apply + * SAUCE: implement smarter atime updates support + - LP: #199427 + * Enable USB_PERSIST to allow devices with /root on usb to work with + suspend + * Enable USB_PERSIST across the board + + [Ben Collins] + + * build/config: Really fix ide on smp ppc configs + * build/configs: Enable relatime config option for all flavors + * build/abi: Ignore ide-core module for ppc, moved to built-in + + [Colin Ian King] + + * fix reversed logic for bbuild check leads to -j1 default + - LP: #197040 + * Enable IDE_PMAC for powerpc-smp + - LP: #196686 + * Disable CONFIG_USB_OHCI_HCD_SSB + - LP: #182716 + * SAUCE: fix arcmsr + archttp64 calls dma_free_coherent() with irqs + disabled - dmesg filled with warnings + - LP: #194207 + + [Jorge Boncompte [DTI2]] + + * Fix Messed multicast lists after dev_mc_sync/unsync + - LP: #193468 + + [Stefan Bader] + + * Add support for Apple Aluminium keyboards. + - LP: #162083 + * SAUCE: Restore VT fonts on switch + + [Upstream Kernel Changes] + + * [NET]: Messed multicast lists after dev_mc_sync/unsync + * KVM: x86 emulator: add support for group decoding + * KVM: x86 emulator: group decoding for group 1A + * KVM: x86 emulator: Group decoding for group 3 + * KVM: x86 emulator: Group decoding for groups 4 and 5 + * KVM: x86 emulator: add group 7 decoding + * KVM: constify function pointer tables + * KVM: Only x86 has pio + * KVM: x86 emulator: group decoding for group 1 instructions + * KVM: MMU: Decouple mmio from shadow page tables + * KVM: Limit vcpu mmap size to one page on non-x86 + * KVM: VMX: Enable Virtual Processor Identification (VPID) + * KVM: Use CONFIG_PREEMPT_NOTIFIERS around struct preempt_notifier + * KVM: Disable pagefaults during copy_from_user_inatomic() + * KVM: make EFER_RESERVED_BITS configurable for architecture code + * KVM: align valid EFER bits with the features of the host system + * KVM: allow access to EFER in 32bit KVM + * kvm: i386 fix + * KVM: export information about NPT to generic x86 code + * KVM: MMU: make the __nonpaging_map function generic + * KVM: export the load_pdptrs() function to modules + * KVM: MMU: add TDP support to the KVM MMU + * KVM: x86 emulator: Fix 'jmp abs' + * KVM: x86 emulator: fix group 5 decoding + * KVM: Fix kvm_arch_vcpu_ioctl_set_sregs so that set_cr0 works properly + * KVM: Make the supported cpuid list a host property rather than a vm + property + * KVM: emulate access to MSR_IA32_MCG_CTL + * KVM: remove the usage of the mmap_sem for the protection of the memory + slots. + * KVM: SVM: allocate the MSR permission map per VCPU + * KVM: make MMU_DEBUG compile again + * KVM: paravirtualized clocksource: host part + * KVM: Add missing semicolon + * KVM: x86 emulator: add ad_mask static inline + * KVM: x86 emulator: make register_address, address_mask static inlines + * KVM: x86 emulator: make register_address_increment and JMP_REL static + inlines + * KVM: Add API to retrieve the number of supported vcpus per vm + * KVM: Increase vcpu count to 16 + * KVM: Add API for determining the number of supported memory slots + * KVM: Increase the number of user memory slots per vm + * KVM: Add stat counter for hypercalls + * KVM: x86 emulator: fix sparse warnings in x86_emulate.c + * KVM: sparse fixes for kvm/x86.c + * KVM: Implement dummy values for MSR_PERF_STATUS + * KVM: MMU: ignore zapped root pagetables + * KVM: call write_guest_time as soon as we register the paravirt clock + * KVM: MMU: large page support + * KVM: Prefix control register accessors with kvm_ to avoid namespace + pollution + * KVM: Avoid infinite-frequency local apic timer + * KVM: Route irq 0 to vcpu 0 exclusively + * KVM: SVM: add support for Nested Paging + * KVM: SVM: enable LBR virtualization + * KVM: SVM: make iopm_base static + * KVM: SVM: let init_vmcb() take struct vcpu_svm as parameter + * KVM: VMX: fix typo in VMX header define + * KVM: SVM: fix Windows XP 64 bit installation crash + * KVM: VMX: Fix invalid opcode of VPID + * KVM: VMX: Handle machines without EFER + * KVM: move alloc_apic_access_page() outside of non-preemptable region + * KVM: VMX: unifdef the EFER specific code + * KVM: SVM: move feature detection to hardware setup code + * KVM: Export include/linux/kvm.h only if $ARCH actually supports KVM + * dlm: fix rcom_names message to self + * virtio: Net header needs hdr_len + + -- Tim Gardner Mon, 03 Mar 2008 07:07:16 -0700 + +linux (2.6.24-11.17) hardy; urgency=low + + [Alan Cox] + + * Pull in fixes for pata_it821x. + - LP: #106931 + + [Alessio Igor Bogani] + + * rt: Synchronized with upstream (2.6.24.3-rt3) + * rt: Updated configuration files + + [Amit Kucheria] + + * Add AGP support for Radeon Mobility 9000 chipset + - LP: #178634 + * Bluetooth: SCO flow control to enable bluetooth headsets + + [Ben Collins] + + * binary: Include vesafs in initrd subdir, should fix vga= usage + + [Colin Ian King] + + * AMD SB700 south bridge support patches + - LP: #195354 + * BCM4311 Revision 2 fix + - LP: #184600 + + [Mauro Carvalho Chehab] + + * V4L/DVB (6753): Fix vivi to support non-zero minor node + + [Tim Gardner] + + * Merged 2.6.24.3 + * Add atl1 to d-i bits. + - LP: #159561 + * SAUCE: Add xpad support for RedOctane Guitar Hero + - LP: #196745 + + [Upstream Kernel Changes] + + * DVB: cx23885: add missing subsystem ID for Hauppauge HVR1800 Retail + * slab: fix bootstrap on memoryless node + * vm audit: add VM_DONTEXPAND to mmap for drivers that need it + (CVE-2008-0007) + * USB: keyspan: Fix oops + * usb gadget: fix fsl_usb2_udc potential OOPS + * USB: CP2101 New Device IDs + * USB: add support for 4348:5523 WinChipHead USB->RS 232 adapter + * USB: Sierra - Add support for Aircard 881U + * USB: Adding YC Cable USB Serial device to pl2303 + * USB: sierra driver - add devices + * USB: ftdi_sio - enabling multiple ELV devices, adding EM1010PC + * USB: ftdi-sio: Patch to add vendor/device id for ATK_16IC CCD + * USB: sierra: add support for Onda H600/Zte MF330 datacard to USB Driver + for Sierra Wireless + * USB: remove duplicate entry in Option driver and Pl2303 driver for + Huawei modem + * USB: pl2303: add support for RATOC REX-USB60F + * USB: ftdi driver - add support for optical probe device + * USB: use GFP_NOIO in reset path + * USB: Variant of the Dell Wireless 5520 driver + * USB: storage: Add unusual_dev for HP r707 + * USB: fix usbtest halt check on big endian systems + * USB: handle idVendor of 0x0000 + * USB: Fix usb_serial_driver structure for Kobil cardreader driver. + * forcedeth: mac address mcp77/79 + * lockdep: annotate epoll + * sys_remap_file_pages: fix ->vm_file accounting + * PCI: Fix fakephp deadlock + * ACPI: update ACPI blacklist + * x86: restore correct module name for apm + * sky2: restore multicast addresses after recovery + * sky2: fix for WOL on some devices + * b43: Fix suspend/resume + * b43: Drop packets we are not able to encrypt + * b43: Fix dma-slot resource leakage + * b43legacy: fix PIO crash + * b43legacy: fix suspend/resume + * b43legacy: drop packets we are not able to encrypt + * b43legacy: fix DMA slot resource leakage + * selinux: fix labeling of /proc/net inodes + * b43: Reject new firmware early + * sched: let +nice tasks have smaller impact + * sched: fix high wake up latencies with FAIR_USER_SCHED + * fix writev regression: pan hanging unkillable and un-straceable + * Driver core: Revert "Fix Firmware class name collision" + * drm: the drm really should call pci_set_master.. + * splice: missing user pointer access verification (CVE-2008-0009/10) + * Linux 2.6.24.1 + * splice: fix user pointer access in get_iovec_page_array() + * Linux 2.6.24.2 + * ACPI: video: Rationalise ACPI backlight implementation + * ACPI: video: Ignore ACPI video devices that aren't present in hardware + * SPARC/SPARC64: Fix usage of .section .sched.text in assembler code. + * NETFILTER: nf_conntrack_tcp: conntrack reopening fix + * NFS: Fix a potential file corruption issue when writing + * inotify: fix check for one-shot watches before destroying them + * hugetlb: add locking for overcommit sysctl + * XFS: Fix oops in xfs_file_readdir() + * Fix dl2k constants + * SCSI: sd: handle bad lba in sense information + * TCP: Fix a bug in strategy_allowed_congestion_control + * TC: oops in em_meta + * SELinux: Fix double free in selinux_netlbl_sock_setsid() + * PKT_SCHED: ematch: oops from uninitialized variable (resend) + * NET: Add if_addrlabel.h to sanitized headers. + * IPV4: fib_trie: apply fixes from fib_hash + * IPV4: fib: fix route replacement, fib_info is shared + * IPCOMP: Fix reception of incompressible packets + * IPCOMP: Fetch nexthdr before ipch is destroyed + * INET_DIAG: Fix inet_diag_lock_handler error path. + * INET: Prevent out-of-sync truesize on ip_fragment slow path + * BLUETOOTH: Add conn add/del workqueues to avoid connection fail. + * AUDIT: Increase skb->truesize in audit_expand + * Be more robust about bad arguments in get_user_pages() + * Disable G5 NAP mode during SMU commands on U3 + * hrtimer: fix *rmtp handling in hrtimer_nanosleep() + * hrtimer: fix *rmtp/restarts handling in compat_sys_nanosleep() + * SLUB: Deal with annoying gcc warning on kfree() + * hrtimer: check relative timeouts for overflow + * hrtimer: catch expired CLOCK_REALTIME timers early + * genirq: do not leave interupts enabled on free_irq + * S390: Fix futex_atomic_cmpxchg_std inline assembly. + * USB: fix pm counter leak in usblp + * SCSI: gdth: scan for scsi devices + * PCMCIA: Fix station address detection in smc + * POWERPC: Revert chrp_pci_fixup_vt8231_ata devinit to fix libata on + pegasos + * bonding: fix NULL pointer deref in startup processing + * x86_64: CPA, fix cache attribute inconsistency bug + * Linux 2.6.24.3 + + -- Tim Gardner Mon, 25 Feb 2008 12:28:13 -0700 + +linux (2.6.24-10.16) hardy; urgency=low + + [Alessio Igor Bogani] + + * rt: Synchronized with upstream (2.6.24.2-rt2) + * rt: Updated configuration files + + [Eric Piel] + + * SAUCE: ACPI: Allow custom DSDT tables to be loaded from initramfs + Amit Kucheria consolidated the DSDT patch with another fix that + ifdefs symbols required when BLK_DEV_INITR is disabled. + + [Stefan Bader] + + * Add Optiarc DVD drive to audio quirks list. + - LP: #186664 + * Update drm and i915 drm driver to fix suspend issues. + - LP: #189260 + + [Tim Gardner] + + * Fix FTBS without BLK_DEV_INITRD + - LP: #193507 + * 64 bit CPA cache attribute bug + - LP: #193736 + * Implemented default EDD control + + [Upstream Kernel Changes] + + * bonding: fix NULL pointer deref in startup processing + * dlm: bind connections from known local address when using TCP + * dlm: proper prototypes + * dlm: don't print common non-errors + * dlm: use dlm prefix on alloc and free functions + * dlm: close othercons + * dlm: align midcomms message buffer + * dlm: swap bytes for rcom lock reply + * dlm: use fixed errno values in messages + * dlm: clear ast_type when removing from astqueue + * dlm: recover locks waiting for overlap replies + * dlm: another call to confirm_master in receive_request_reply + * dlm: reject messages from non-members + * dlm: validate messages before processing + * dlm: reject normal unlock when lock is waiting for lookup + * dlm: limit dir lookup loop + * dlm: fix possible use-after-free + * dlm: change error message to debug + * dlm: keep cached master rsbs during recovery + * dlm: Sanity check namelen before copying it + * dlm: clean ups + * dlm: static initialization improvements + * dlm: use proper C for dlm/requestqueue stuff (and fix alignment bug) + * dlm: dlm_process_incoming_buffer() fixes + * dlm: do not byteswap rcom_lock + * dlm: do not byteswap rcom_config + * dlm: use proper type for ->ls_recover_buf + * dlm: missing length check in check_config() + * dlm: validate data in dlm_recover_directory() + * dlm: verify that places expecting rcom_lock have packet long enough + * dlm: receive_rcom_lock_args() overflow check + * dlm: make find_rsb() fail gracefully when namelen is too large + * dlm: fix overflows when copying from ->m_extra to lvb + * dlm: fix dlm_dir_lookup() handling of too long names + * dlm: dlm/user.c input validation fixes + * dlm: proper types for asts and basts + * dlm: eliminate astparam type casting + * dlm: add __init and __exit marks to init and exit functions + * virtio: Use PCI revision field to indicate virtio PCI ABI version + + -- Tim Gardner Tue, 19 Feb 2008 09:57:18 -0700 + +linux (2.6.24-9.15) hardy; urgency=low + + [Alessio Igor Bogani] + + * rt: Fix FTBS + * rt: Updated configuration files + + [Tim Gardner] + + * SAUCE: make /dev/kmem a config option + * SAUCE: x86: introduce /dev/mem restrictions with a config option + * Fixed CGROUP FTBS caused by AppArmor patch. + * Enabled CGROUP and CPUSETS for server flavor. + - LP: #182434 + + [Colin King] + + * Turn on /proc/acpi/alarm for x86_64 (amd64) + - LP: #186297 + + [Upstream Kernel Changes] + + * Ubuntu: LatencyTOP infrastructure patch + + -- Tim Gardner Thu, 14 Feb 2008 13:34:55 -0700 + +linux (2.6.24-8.14) hardy; urgency=low + + [cking] + + * Support Novatel U727 EVDO modem: Add pid and vid to + drivers/usb/serial/airprime.c + - LP: #150996 + * Enable speedstep for sonoma processors. + - LP: #132271 + + [Stefan Bader] + + * SAUCE: Export dm_disk function of device-mapper + + -- Tim Gardner Wed, 13 Feb 2008 21:47:18 -0700 + +linux (2.6.24-8.13) hardy; urgency=low + + [Soren Hansen] + + * Add missing iscsi modules to kernel udebs + + [Stefan Bader] + + * Lower message level for PCI memory and I/O allocation. + + [Tim Gardner] + + * Enabled IP_ADVANCED_ROUTER and IP_MULTIPLE_TABLES in sparc, hppa + - LP: #189560 + * Compile RealTek 8139 using PIO method. + - LP: #90271 + * Add WD WD800ADFS NCQ horkage quirk support. + - LP: #147858 + + [Upstream Kernel Changes] + + * Introduce WEXT scan capabilities + * DVB: cx23885: add missing subsystem ID for Hauppauge HVR1800 Retail + * slab: fix bootstrap on memoryless node + * vm audit: add VM_DONTEXPAND to mmap for drivers that need it + (CVE-2008-0007) + * USB: keyspan: Fix oops + * usb gadget: fix fsl_usb2_udc potential OOPS + * USB: CP2101 New Device IDs + * USB: add support for 4348:5523 WinChipHead USB->RS 232 adapter + * USB: Sierra - Add support for Aircard 881U + * USB: Adding YC Cable USB Serial device to pl2303 + * USB: sierra driver - add devices + * USB: ftdi_sio - enabling multiple ELV devices, adding EM1010PC + * USB: ftdi-sio: Patch to add vendor/device id for ATK_16IC CCD + * USB: sierra: add support for Onda H600/Zte MF330 datacard to USB Driver + for Sierra Wireless + * USB: remove duplicate entry in Option driver and Pl2303 driver for + Huawei modem + * USB: pl2303: add support for RATOC REX-USB60F + * USB: ftdi driver - add support for optical probe device + * USB: use GFP_NOIO in reset path + * USB: Variant of the Dell Wireless 5520 driver + * USB: storage: Add unusual_dev for HP r707 + * USB: fix usbtest halt check on big endian systems + * USB: handle idVendor of 0x0000 + * forcedeth: mac address mcp77/79 + * lockdep: annotate epoll + * sys_remap_file_pages: fix ->vm_file accounting + * PCI: Fix fakephp deadlock + * ACPI: update ACPI blacklist + * x86: restore correct module name for apm + * sky2: restore multicast addresses after recovery + * sky2: fix for WOL on some devices + * b43: Fix suspend/resume + * b43: Drop packets we are not able to encrypt + * b43: Fix dma-slot resource leakage + * b43legacy: fix PIO crash + * b43legacy: fix suspend/resume + * b43legacy: drop packets we are not able to encrypt + * b43legacy: fix DMA slot resource leakage + * selinux: fix labeling of /proc/net inodes + * b43: Reject new firmware early + * sched: let +nice tasks have smaller impact + * sched: fix high wake up latencies with FAIR_USER_SCHED + * fix writev regression: pan hanging unkillable and un-straceable + * Driver core: Revert "Fix Firmware class name collision" + * drm: the drm really should call pci_set_master.. + * splice: missing user pointer access verification (CVE-2008-0009/10) + * Linux 2.6.24.1 + * splice: fix user pointer access in get_iovec_page_array() + * Linux 2.6.24.2 + + -- Tim Gardner Thu, 07 Feb 2008 06:50:13 -0700 + +linux (2.6.24-7.12) hardy; urgency=low + + [Jay Chetty] + + * Added patch to fix legacy USB interrupt issue + * Enabled Poulsbo PATA udma5 support + * Add touchscreen doubleclick workaround + + [Amit Kucheria] + + * Add AGP support for Radeon Mobility 9000 chipset + - LP: #178634 + + [Soren Hansen] + + * Add virtio modules to the relevant udebs + * Add missing "?" for virtio modules in storage-core-modules + + [Stefan Bader] + + * Added vendor id for Dell 5720 broadband modem + + -- Jay Chetty Wed, 06 Feb 2008 14:13:41 -0800 + +linux (2.6.24-7.11) hardy; urgency=low + + [Jay Chetty] + + * poulsbo: Add a 100ms delay for SiB workaround + + [Tim Gardner] + + * -6.10 should have been an ABI bump, but due to incomplete build testing + went undetected. + + -- Tim Gardner Mon, 04 Feb 2008 19:13:52 -0700 + +linux (2.6.24-6.10) hardy; urgency=low + + [Alessio Igor Bogani] + + * rt: Synced with upstream, removed old kvm related patches and updated + configurations files. + + [Chuck Short] + + * SAUCE: Enable Xen + + [Soren Hansen] + + * Update kvm driver to kvm-60. + * Added CONFIG_ARCH_SUPPORTS_KVM=y for lpia, i386, and amd64 + * Add rtl8139 driver to -virtual flavour + + [Stefan Bader] + + * Fix usb_serial_driver structure for Kobil cardreader driver. + - LP: #183109 + * Lower warning level of pci resource allocation messages. + - LP: #159241 + + [Tim Gardner] + + * Enabled CONFIG_BLK_DEV_IDE_PMAC + - LP: #185862 + * Add virtio config options to lpiacompat. + * SAUCE: Export symbols for aufs (in lum). + * Enabled Xen + + [Upstream Kernel Changes] + + * KVM: mmu: add missing dirty page tracking cases + * KVM: Move virtualization deactivation from CPU_DEAD state to + CPU_DOWN_PREPARE + * KVM: Cosmetics + * KVM: vmx: hack set_cr0_no_modeswitch() to actually do modeswitch + * KVM: Use ARRAY_SIZE macro instead of manual calculation. + * KVM: Use page_private()/set_page_private() apis + * KVM: add MSR based hypercall API + * KVM: Add host hypercall support for vmx + * KVM: Add hypercall host support for svm + * KVM: Wire up hypercall handlers to a central arch-independent location + * KVM: svm: init cr0 with the wp bit set + * KVM: SVM: intercept SMI to handle it at host level + * KVM: More 0 -> NULL conversions + * kvm, dirty pages log: adding some calls to mark_page_dirty() + * KVM: Add internal filesystem for generating inodes + * KVM: Create an inode per virtual machine + * KVM: Rename some kvm_dev_ioctl_*() functions to kvm_vm_ioctl_*() + * KVM: Move kvm_vm_ioctl_create_vcpu() around + * KVM: Per-vcpu inodes + * KVM: Bump API version + * .gitignore: ignore emacs backup files (*~) + * kvm: dirty pages log: fix bitmap size/access calculation + * kvm: move do_remove_write_access() up + * kvm: dirty page logging: remove write access permissions when + dirty-page-logging is enabled + * KVM: Add missing calls to mark_page_dirty() + * KVM: Fix dirty page log bitmap size/access calculation + * kvm: move do_remove_write_access() up + * KVM: Remove write access permissions when dirty-page-logging is enabled + * KVM: Fix bogus failure in kvm.ko module initialization + * KVM: Move kvmfs magic number to + * KVM: Unset kvm_arch_ops if arch module loading failed + * KVM: Fix guest register corruption on paravirt hypercall + * KVM: Use the generic skip_emulated_instruction() in hypercall code + * KVM: Use own minor number + * KVM: Fix guest sysenter on vmx + * KVM: Export + * KVM: Fix bogus sign extension in mmu mapping audit + * KVM: MMU: Fix guest writes to nonpae pde + * KVM: MMU: Fix host memory corruption on i386 with >= 4GB ram + * KVM: trivial whitespace fixes + * KVM: always reload segment selectors + * KVM: Remove extraneous guest entry on mmio read + * added KVM_GET_MEM_MAP ioctl to get the memory bitmap for a memory slot + * KVM: Prevent system selectors leaking into guest on real->protected + mode transition on vmx + * KVM: Use a shared page for kernel/user communication when runing a vcpu + * KVM: Do not communicate to userspace through cpu registers during PIO + * KVM: Initialize PIO I/O count + * KVM: Handle cpuid in the kernel instead of punting to userspace + * KVM: Remove the 'emulated' field from the userspace interface + * KVM: Remove minor wart from KVM_CREATE_VCPU ioctl + * KVM: Renumber ioctls + * KVM: Add method to check for backwards-compatible API extensions + * KVM: Allow userspace to process hypercalls which have no kernel handler + * KVM: Fold kvm_run::exit_type into kvm_run::exit_reason + * KVM: Add a special exit reason when exiting due to an interrupt + * KVM: Initialize the apic_base msr on svm too + * KVM: Add guest mode signal mask + * KVM: Allow kernel to select size of mmap() buffer + * KVM: Future-proof argument-less ioctls + * KVM: Avoid guest virtual addresses in string pio userspace interface + * KVM: MMU: Remove unnecessary check for pdptr access + * KVM: MMU: Remove global pte tracking + * KVM: Workaround vmx inability to virtualize the reset state + * KVM: Remove set_cr0_no_modeswitch() arch op + * KVM: Modify guest segments after potentially switching modes + * KVM: Hack real-mode segments on vmx from KVM_SET_SREGS + * KVM: Don't allow the guest to turn off the cpu cache + * KVM: Remove unused and write-only variables + * KVM: Handle writes to MCG_STATUS msr + * KVM: MMU: Fix hugepage pdes mapping same physical address with + different access + * KVM: SVM: Ensure timestamp counter monotonicity + * KVM: Remove unused function + * KVM: Remove debug message + * KVM: x86 emulator: fix bit string operations operand size + * KVM: SVM: enable LBRV virtualization if available + * Add mmu cache clear function + * KVM: Simply gfn_to_page() + * KVM: Add physical memory aliasing feature + * KVM: Add fpu get/set operations + * KVM: Use kernel-standard types + * KVM: Fix overflow bug in overflow detection code + * KVM: Fix memory leak on pio completion + * KVM: Handle partial pae pdptr + * KVM: Fix string pio when count == 0 + * KVM: Use slab caches to allocate mmu data structures + * KVM: Retry sleeping allocation if atomic allocation fails + * KVM: Fix pio completion + * KVM: SVM: Report hardware exit reason to userspace instead of dmesg + * KVM: Handle guest page faults when emulating mmio + * KVM: VMX: Reduce unnecessary saving of host msrs + * KVM: Fix off-by-one when writing to a nonpae guest pde + * KVM: VMX: Don't switch 64-bit msrs for 32-bit guests + * KVM: Fold drivers/kvm/kvm_vmx.h into drivers/kvm/vmx.c + * KVM: VMX: Only save/restore MSR_K6_STAR if necessary + * KVM: Per-vcpu statistics + * KVM: Silence compile warning on i386 + * KVM: Allow passing 64-bit values to the emulated read/write API + * KVM: Lazy FPU support for SVM + * KVM: Fix msr-avoidance regression on Core processors + * KVM: Don't complain about cpu erratum AA15 + * KVM: Document MSR_K6_STAR's special place in the msr index array + * KVM: MMU: Avoid heavy ASSERT at non debug mode. + * KVM: Initialize cr0 to indicate an fpu is present + * KVM: We want asserts on debug builds, not release + * KVM: Avoid unused function warning due to assertion removal + * KVM: VMX: Avoid unnecessary vcpu_load()/vcpu_put() cycles + * KVM: Move need_resched() check to common code + * KVM: VMX: Properly shadow the CR0 register in the vcpu struct + * KVM: VMX: Add lazy FPU support for VT + * KVM: fix an if() condition + * KVM: SVM: Only save/restore MSRs when needed + * KVM: Remove trailing whitespace + * KVM: Remove extraneous guest entry on mmio read + * KVM: Don't require explicit indication of completion of mmio or pio + * KVM: Remove unused 'instruction_length' + * KVM: VMX: Enable io bitmaps to avoid IO port 0x80 VMEXITs + * KVM: SVM: Allow direct guest access to PC debug port + * KVM: Fix RMW mmio handling + * KVM: Assume that writes smaller than 4 bytes are to non-pagetable pages + * KVM: Avoid saving and restoring some host CPU state on lightweight + vmexit + * KVM: Unindent some code + * KVM: Reduce misfirings of the fork detector + * KVM: Be more careful restoring fs on lightweight vmexit + * KVM: Unify kvm_mmu_pre_write() and kvm_mmu_post_write() + * KVM: MMU: Respect nonpae pagetable quadrant when zapping ptes + * KVM: Update shadow pte on write to guest pte + * KVM: Increase mmu shadow cache to 1024 pages + * KVM: Fix potential guest state leak into host + * KVM: Prevent guest fpu state from leaking into the host + * KVM: Move some more msr mangling into vmx_save_host_state() + * KVM: Rationalize exception bitmap usage + * KVM: Consolidate guest fpu activation and deactivation + * KVM: Ensure host cr0.ts is saved + * KVM: Set cr0.mp for guests + * KVM: Implement IA32_EBL_CR_POWERON msr + * KVM: MMU: Simplify kvm_mmu_free_page() a tiny bit + * KVM: MMU: Store shadow page tables as kernel virtual addresses, not + physical + * KVM: VMX: Only reload guest msrs if they are already loaded + * KVM: Avoid corrupting tr in real mode + * KVM: Fix vmx I/O bitmap initialization on highmem systems + * KVM: Remove merge artifact + * KVM: VMX: Use local labels in inline assembly + * KVM: VMX: Handle #SS faults from real mode + * KVM: VMX: Avoid saving and restoring msrs on lightweight vmexit + * KVM: VMX: Compile-fix for 32-bit hosts + * KVM: VMX: Cleanup redundant code in MSR set + * KVM: VMX: Fix a typo which mixes X86_64 and CONFIG_X86_64 + * KVM: VMX: Avoid saving and restoring msr_efer on lightweight vmexit + * KVM: VMX: Remove warnings on i386 + * Use menuconfig objects II - KVM/Virt + * KVM: x86 emulator: implement wbinvd + * KVM: Fix includes + * KVM: Use symbolic constants instead of magic numbers + * KVM: MMU: Use slab caches for shadow pages and their headers + * KVM: MMU: Simplify fetch() a little bit + * KVM: MMU: Move set_pte_common() to pte width dependent code + * KVM: MMU: Pass the guest pde to set_pte_common + * KVM: MMU: Fold fix_read_pf() into set_pte_common() + * KVM: MMU: Fold fix_write_pf() into set_pte_common() + * KVM: Move shadow pte modifications from set_pte/set_pde to + set_pde_common() + * KVM: Make shadow pte updates atomic + * KVM: MMU: Make setting shadow ptes atomic on i386 + * KVM: MMU: Remove cr0.wp tricks + * KVM: MMU: Simpify accessed/dirty/present/nx bit handling + * KVM: MMU: Don't cache guest access bits in the shadow page table + * KVM: MMU: Remove unused large page marker + * KVM: VMX: Fix asm constraint + * KVM: Lazy guest cr3 switching + * KVM: Replace C code with call to ARRAY_SIZE() macro. + * KVM: Remove unnecessary initialization and checks in mark_page_dirty() + * KVM: Fix vcpu freeing for guest smp + * KVM: Fix adding an smp virtual machine to the vm list + * KVM: Enable guest smp + * KVM: Move duplicate halt handling code into kvm_main.c + * KVM: Emulate hlt on real mode for Intel + * KVM: Keep an upper bound of initialized vcpus + * KVM: Flush remote tlbs when reducing shadow pte permissions + * KVM: SVM: Replace memset(, 0, PAGESIZE) with clear_page() + * KVM: VMX: Replace memset(, 0, PAGESIZE) with clear_page() + * KVM: Require a cpu which can set 64-bit values atomically + * KVM: Initialize the BSP bit in the APIC_BASE msr correctly + * KVM: VMX: Ensure vcpu time stamp counter is monotonous + * KVM: Bring local tree in line with origin + * KVM: Implement emulation of "pop reg" instruction (opcode 0x58-0x5f) + * KVM: Implement emulation of instruction "ret" (opcode 0xc3) + * KVM: Adds support for in-kernel mmio handlers + * KVM: VMX: Fix interrupt checking on lightweight exit + * KVM: Add support for in-kernel pio handlers + * KVM: Fix x86 emulator writeback + * KVM: Avoid useless memory write when possible + * KVM: VMX: Reinitialize the real-mode tss when entering real mode + * KVM: MMU: Fix Wrong tlb flush order + * KVM: VMX: Remove unnecessary code in vmx_tlb_flush() + * KVM: SVM: Reliably detect if SVM was disabled by BIOS + * KVM: Remove kvmfs in favor of the anonymous inodes source + * KVM: Clean up #includes + * KVM: Fix svm availability check miscompile on i386 + * HOTPLUG: Add CPU_DYING notifier + * HOTPLUG: Adapt cpuset hotplug callback to CPU_DYING + * HOTPLUG: Adapt thermal throttle to CPU_DYING + * SMP: Implement on_cpu() + * KVM: Keep track of which cpus have virtualization enabled + * KVM: Tune hotplug/suspend IPIs + * KVM: Use CPU_DYING for disabling virtualization + * KVM: MMU: Store nx bit for large page shadows + * KVM: Fix *nopage() in kvm_main.c + * KVM: SMP: Add vcpu_id field in struct vcpu + * KVM - add hypercall nr to kvm_run + * KVM:: Future-proof the exit information union ABI + * KVM: In-kernel string pio write support + * KVM: Fix memory slot management functions for guest smp + * KVM: x86 emulator: implement rdmsr and wrmsr + * KVM: Trivial: /dev/kvm interface is no longer experimental. + * KVM: Trivial: Remove unused struct cpu_user_regs declaration + * KVM: Trivial: Make decode_register() static + * KVM: Trivial: Comment spelling may escape grep + * KVM: Trivial: Avoid hardware_disable predeclaration + * KVM: Trivial: Use standard CR0 flags macros from asm/cpu-features.h + * Use standard CR3 flags, tighten checking + * Use standard CR4 flags, tighten checking + * KVM: Trivial: Use standard BITMAP macros, open-code userspace-exposed + header + * KVM: Set exit_reason to KVM_EXIT_MMIO where run->mmio is initialized. + * KVM: Use standard CR8 flags, and fix TPR definition + * KVM: MMU: Fix oopses with SLUB + * KVM: x86 emulator: fix cmov for writeback changes + * KVM: MMU: Fix cleaning up the shadow page allocation cache + * KVM: Require CONFIG_ANON_INODES + * KVM: x86 emulator: fix faulty check for two-byte opcode + * KVM: Correctly handle writes crossing a page boundary + * KVM: Fix unlikely kvm_create vs decache_vcpus_on_cpu race + * KVM: Hoist kvm_mmu_reload() out of the critical section + * KVM: Fix removal of nx capability from guest cpuid + * KVM: Move gfn_to_page out of kmap/unmap pairs + * KVM: disable writeback for 0x0f 0x01 instructions. + * KVM: VMX: Import some constants of vmcs from IA32 SDM + * KVM: Remove dead code in the cmpxchg instruction emulation + * KVM: load_pdptrs() cleanups + * KVM: Remove arch specific components from the general code + * KVM: Dynamically allocate vcpus + * KVM: VMX: Improve the method of writing vmcs control + * KVM: Use the scheduler preemption notifiers to make kvm preemptible + * KVM: Convert vm lock to a mutex + * KVM: fx_init() needs preemption disabled while it plays with the FPU + state + * KVM: VMX: pass vcpu_vmx internally + * KVM: Remove three magic numbers + * KVM: SVM: de-containization + * KVM: SVM: internal function name cleanup + * KVM: x86 emulator: disable writeback for debug register instructions + * KVM: Change the emulator_{read,write,cmpxchg}_* functions to take a + vcpu + * KVM: Remove kvm_{read,write}_guest() + * KVM: Use kmem cache for allocating vcpus + * KVM: Use alignment properties of vcpu to simplify FPU ops + * KVM: kvm_vm_ioctl_get_dirty_log restore "nothing dirty" optimization + * KVM: VMX: Add cpu consistency check + * KVM: Don't assign vcpu->cr3 if it's invalid: check first, set last + * KVM: Cleanup mark_page_dirty + * KVM: SVM: Make set_msr_interception more reliable + * KVM: Remove redundant alloc_vmcs_cpu declaration + * KVM: Fix defined but not used warning in drivers/kvm/vmx.c + * KVM: Remove stat_set from debugfs + * KVM: Remove unneeded kvm_dev_open and kvm_dev_release functions. + * KVM: Add and use pr_unimpl for standard formatting of unimplemented + features + * KVM: Use kmem_cache_free for kmem_cache_zalloc'ed objects + * KVM: VMX: Remove a duplicated ia32e mode vm entry control + * KVM: Remove useless assignment + * KVM: Cleanup string I/O instruction emulation + * KVM: Clean up kvm_setup_pio() + * KVM: VMX: Don't require cr8 load/store exit capability when running on + 32-bit + * KVM: Close minor race in signal handling + * KVM: Communicate cr8 changes to userspace + * KVM: x86 emulator: implement 'and $imm, %{al|ax|eax}' + * KVM: x86 emulator: implement 'jmp rel' instruction (opcode 0xe9) + * KVM: x86 emulator: Implement 'jmp rel short' instruction (opcode 0xeb) + * KVM: x86 emulator: implement 'push reg' (opcodes 0x50-0x57) + * KVM: VMX: allow rmode_tss_base() to work with >2G of guest memory + * KVM: Avoid calling smp_call_function_single() with interrupts disabled + * KVM: MMU: Fix rare oops on guest context switch + * KVM: Support more memory slots + * KVM: X86 emulator: fix 'push reg' writeback + * KVM: VMX: Split segments reload in vmx_load_host_state() + * KVM: Add support for in-kernel PIC emulation + * KVM: Define and use cr8 access functions + * KVM: Emulate local APIC in kernel + * KVM: In-kernel I/O APIC model + * KVM: Emulate hlt in the kernel + * KVM: Protect in-kernel pio using kvm->lock + * KVM: Add get/set irqchip ioctls for in-kernel PIC live migration + support + * KVM: Bypass irq_pending get/set when using in kernel irqchip + * KVM: in-kernel IOAPIC save and restore support + * KVM: in-kernel LAPIC save and restore support + * KVM: pending irq save/restore + * KVM: VMX: Use shadow TPR/cr8 for 64-bits guests + * KVM: Keep track of missed timer irq injections + * KVM: Migrate lapic hrtimer when vcpu moves to another cpu + * KVM: disable tpr/cr8 sync when in-kernel APIC is used + * KVM: VMX: Fix tpr threshold updating + * KVM: deliver PIC interrupt only to vcpu0 + * KVM: round robin for APIC lowest priority delivery mode + * KVM: enable in-kernel APIC INIT/SIPI handling + * KVM: Set the ET flag in CR0 after initializing FX + * KVM: Remove the unused invlpg member of struct kvm_arch_ops. + * KVM: Clean up unloved invlpg emulation + * KVM: Keep control regs in sync + * KVM: Hoist SVM's get_cs_db_l_bits into core code. + * KVM: Simplify memory allocation + * KVM: Rename kvm_arch_ops to kvm_x86_ops + * KVM: Fix lapic 64-bit division on 32-bit hosts + * KVM: fix apic timer migration when inactive + * KVM: MMU: Don't do GFP_NOWAIT allocations + * KVM: Remove smp_processor_id() in kvm_vcpu_kick() + * KVM: VMX: Move vm entry failure handling to the exit handler + * KVM: Move main vcpu loop into subarch independent code + * KVM: Fix link error to "genapic" + * KVM: VMX: Fix exit qualification width on i386 + * KVM: x86 emulator: push imm8 + * KVM: x86 emulator: call near + * KVM: x86 emulator: pushf + * KVM: Improve emulation failure reporting + * KVM: VMX: Prevent setting CPU_BASED_TPR_SHADOW on i386 host + * KVM: x86 emulator: sort opcodes into ascending order + * KVM: x86 emulator: imlpement jump conditional relative + * KVM: X86 emulator: jump conditional short + * KVM: x86 emulator: lea + * KVM: x86 emulator: jmp abs + * KVM: x86 emulator: fix src, dst value initialization + * KVM: x86 emulator: popf + * KVM: Skip pio instruction when it is emulated, not executed + * KVM: fix PIC interrupt delivery on different APIC conditions + * KVM: Fix kvm_vcpu_ioctl_get_sregs() warning on i386 + * KVM: Remove errant printk() in kvm_vcpu_ioctl_get_sregs() + * KVM: Fix virtualization menu help text + * KVM: x86 emulator: Add vmmcall/vmcall to x86_emulate (v3) + * KVM: Refactor hypercall infrastructure (v3) + * KVM: x86 emulator: remove unused functions + * KVM: x86 emulator: move all x86_emulate_memop() to a structure + * KVM: x86 emulator: move all decoding process to function + x86_decode_insn() + * KVM: emulate_instruction() calls now x86_decode_insn() and + x86_emulate_insn() + * KVM: Call x86_decode_insn() only when needed + * KVM: Fix ioapic level-triggered interrupt redelivery + * KVM: Fix #UD exception delivery + * KVM: VMX: Further reduce efer reloads + * KVM: VMX: Fix build on i386 due to EFER_LMA not defined + * KVM: Fix ioapic.c compilation failure due to missing include + * KVM: x86 emulator: fix merge screwup due to emulator split + * KVM: x85 emulator: Correct inconcistency in between cr2 and ctxt->cr2. + * KVM: Avoid redelivery of edge-triggered irq if it is already in service + * KVM: Implement ioapic irq polarity bit + * KVM: x86 emulator: fix repne/repnz decoding + * KVM: Fix host oops due to guest changing efer + * KVM: Fix ioapic edge-triggered interrupts + * KVM: MMU: Set shadow pte atomically in mmu_pte_write_zap_pte() + * KVM: Allow not-present guest page faults to bypass kvm + * KVM: MMU: Make flooding detection work when guest page faults are + bypassed + * KVM: MMU: Ignore reserved bits in cr3 in non-pae mode + * KVM: x86 emulator: split some decoding into functions for readability + * KVM: x86 emulator: remove _eflags and use directly ctxt->eflags. + * KVM: x86 emulator: Remove no_wb, use dst.type = OP_NONE instead + * KVM: x86_emulator: no writeback for bt + * KVM: apic round robin cleanup + * KVM: Purify x86_decode_insn() error case management + * KVM: x86 emulator: Any legacy prefix after a REX prefix nullifies its + effect + * i386: Expose IOAPIC register definitions even if CONFIG_X86_IO_APIC is + not set + * KVM: x86 emulator: On a pop instruction, don't restore ECX and EIP on + error + * KVM: x86 emulator: remove unused variable + * KVM: VMX: Don't clear the vmcs if the vcpu is not loaded on any + processor + * KVM: VMX: Simplify vcpu_clear() + * KVM: Remove the usage of paeg->private field by rmap + * KVM: x86 emulator: Correct management of REP prefix + * KVM: Add general accessors to read and write guest memory + * KVM: Allow dynamic allocation of the mmu shadow cache size + * KVM: Check I/O APIC indirect index before writing + * KVM: Add kvm_free_lapic() to pair with kvm_create_lapic() + * KVM: Hoist kvm_create_lapic() into kvm_vcpu_init() + * KVM: Remove gratuitous casts from lapic.c + * KVM: CodingStyle cleanup + * KVM: VMX: Handle NMIs before enabling interrupts and preemption + * KVM: Support assigning userspace memory to the guest + * KVM: Export PIC reset for kernel device reset + * KVM: Split IOAPIC reset function and export for kernel RESET + * KVM: VMX: Reset mmu context when entering real mode + * KVM: Replace enum by #define + * KVM: Move x86 msr handling to new files x86.[ch] + * KVM: MMU: Clean up MMU functions to take struct kvm when appropriate + * KVM: MMU: More struct kvm_vcpu -> struct kvm cleanups + * KVM: Move guest pte dirty bit management to the guest pagetable walker + * KVM: MMU: Fix nx access bit for huge pages + * KVM: MMU: Disable write access on clean large pages + * KVM: MMU: Instatiate real-mode shadows as user writable shadows + * KVM: MMU: Move dirty bit updates to a separate function + * KVM: MMU: When updating the dirty bit, inform the mmu about it + * KVM: Portability: split kvm_vcpu_ioctl + * KVM: Restore missing #include + * KVM: Add some \n in ioapic_debug() + * KVM: x86 emulator: implement 'movnti mem, reg' + * KVM: MMU: Call update_dirty_bit() without disabling preemption + * KVM: Move apic timer interrupt backlog processing to common code + * KVM: Move interrupt injection out of interrupt disabled section + * KVM: Rename KVM_TLB_FLUSH to KVM_REQ_TLB_FLUSH + * KVM: VMX: Force vm86 mode if setting flags during real mode + * KVM: MMU: Simplify page table walker + * KVM: Actually move the interrupt injection code out of the critical + section + * KVM: x86 emulator: cmc, clc, cli, sti + * KVM: x86 emulator: use a defined flag definition + * KVM: x86 emulator: fix access registers for instructions with ModR/M + byte and Mod = 3 + * KVM: MMU: Add rmap_next(), a helper for walking kvm rmaps + * KVM: MMU: Keep a reverse mapping of non-writable translations + * KVM: MMU: Make gfn_to_page() always safe + * KVM: Partial swapping of guest memory + * KVM: VMX: Initialize vcpu with preemption enabled + * KVM: Use virtual cpu accounting if available for guest times. + * KVM: Move kvm_guest_exit() after local_irq_enable() + * KVM: MMU: Fix dirty bit pte gpa calculation + * KVM: Allocate userspace memory for older userspace + * KVM: Portability: Split kvm_vcpu into arch dependent and independent + parts (part 1) + * KVM: Fix local apic timer divide by zero + * KVM: Move vmx_vcpu_reset() out of vmx_vcpu_setup() + * KVM: Add a might_sleep() annotation to gfn_to_page() + * KVM: VMX: vmx_vcpu_setup(): remove unused variable. + * KVM: Per-architecture hypercall definitions + * KVM: Use new smp_call_function_mask() in kvm_flush_remote_tlbs() + * KVM: Unmap kernel-allocated memory on slot destruction + * KVM: Export memory slot allocation mechanism + * KVM: Add kernel-internal memory slots + * KVM: Add ioctl to tss address from userspace, + * KVM: x86 emulator: fix 'push imm8' emulation + * KVM: VMX: Let gcc to choose which registers to save (x86_64) + * KVM: VMX: Let gcc to choose which registers to save (i386) + * KVM: SVM: Let gcc to choose which registers to save (x86_64) + * KVM: SVM: Let gcc to choose which registers to save (i386) + * KVM: x86 emulator: invd instruction + * KVM: SVM: Intercept the 'invd' and 'wbinvd' instructions + * KVM: x86 emulator: don't depend on cr2 for mov abs emulation + * KVM: Move page fault processing to common code + * KVM: MMU: Topup the mmu memory preallocation caches before emulating an + insn + * KVM: Portability: Split kvm_vm_ioctl v3 + * KVM: Portability: Move memory segmentation to x86.c + * KVM: Portability: move get/set_apic_base to x86.c + * KVM: Portability: Move control register helper functions to x86.c + * KVM: VMX: Enable memory mapped TPR shadow (FlexPriority) + * KVM: Fix gfn_to_page() acquiring mmap_sem twice + * KVM: Portability: Move kvm_get/set_msr[_common] to x86.c + * KVM: Portability: Move x86 emulation and mmio device hook to x86.c + * KVM: Portability: Move pio emulation functions to x86.c + * KVM: x86 emulator: Extract the common code of SrcReg and DstReg + * KVM: x86 emulator: centralize decoding of one-byte register access + insns + * KVM: Simplify decode_register_operand() calling convention + * KVM: Make mark_page_dirty() work for aliased pages too. + * KVM: x86 emulator: Hoist modrm and abs decoding into separate functions + * KVM: Portability: Make exported debugfs data architecture-specific + * KVM: Portability: Move x86 instruction emulation code to x86.c + * KVM: Portability: Move x86 FPU handling to x86.c + * KVM: Portability: Move x86 vcpu ioctl handlers to x86.c + * KVM: x86 emulator: Move one-byte insns with reg operand into one-byte + section + * KVM: VMX: Fix repeated allocation of apic access page on smp + * KVM: SVM: Fix SMP with kernel apic + * KVM: Add make_page_dirty() to kvm_clear_guest_page() + * KVM: SVM: Defer nmi processing until switch to host state is complete + * KVM: VMX: Avoid reloading host efer on cpus that don't have it + * KVM: VMX: Use vmx to inject real interrupts + * KVM: Go back to atomically injecting interrupts + * KVM: VMX: Comment VMX primary/secondary exec ctl definitions + * KVM: VMX: wbinvd exiting + * KVM: x86 emulator: fix JMP_REL + * KVM: x86 emulator: fix the saving of of the eip value + * KVM: x86 emulator: remove 8 bytes operands emulator for call near + instruction + * KVM: Simplify CPU_TASKS_FROZEN cpu notifier handling + * KVM: add kvm_is_error_hva() + * KVM: introduce gfn_to_hva() + * KVM: Change kvm_{read,write}_guest() to use copy_{from,to}_user() + * KVM: Portability: Move some includes to x86.c + * KVM: Portability: Move kvm_x86_ops to x86.c + * KVM: Portability: Add vcpu and hardware management arch hooks + * KVM: Portability: Combine kvm_init and kvm_init_x86 + * KVM: Portability: Move x86 specific code from kvm_init() to kvm_arch() + * KVM: x86 emulator: modify 'lods', and 'stos' not to depend on CR2 + * KVM: Portability: move KVM_CHECK_EXTENSION + * KVM: VMX: Consolidate register usage in vmx_vcpu_run() + * KVM: Portability: Make kvm_vcpu_ioctl_translate arch dependent + * KVM: x86 emulator: Rename 'cr2' to 'memop' + * KVM: Remove ptr comparisons to 0 + * KVM: Remove __init attributes for kvm_init_debug and kvm_init_msr_list + * KVM: Portability: Add two hooks to handle kvm_create and destroy vm + * KVM: Replace 'light_exits' stat with 'host_state_reload' + * KVM: Add fpu_reload counter + * KVM: Add instruction emulation statistics + * KVM: Extend stats support for VM stats + * KVM: MMU: Add some mmu statistics + * KVM: x86 emulator: Use emulator_write_emulated and not + emulator_write_std + * KVM: Make unloading of FPU state when putting vcpu arch-independent + * KVM: SVM: Disable Lazy FPU optimization + * KVM: Portability: Move kvm_vcpu_ioctl_get_dirty_log to arch-specific + file + * KVM: Portability: MMU initialization and teardown split + * KVM: Portability: Move some macro definitions from kvm.h to x86.h + * KVM: Portability: Move struct kvm_x86_ops definition to x86.h + * KVM: Portability: Move vcpu regs enumeration definition to x86.h + * KVM: Move some static inline functions out from kvm.h into x86.h + * KVM: Portability: Move some function declarations to x86.h + * KVM: VMX: Force seg.base == (seg.sel << 4) in real mode + * KVM: MMU: Change guest pte access to kvm_{read,write}_guest() + * kvm: simplify kvm_clear_guest_page() + * KVM: Add missing #include + * KVM: MMU: Remove unused variable + * KVM: Remove unused "rmap_overflow" variable + * KVM: Correct consistent typo: "destory" -> "destroy" + * KVM: Move misplaced comment + * KVM: Portability: Move kvm_memory_alias to asm/kvm.h + * KVM: Portability: Move x86 pic strutctures + * KVM: Portability: Move kvm_regs to + * KVM: Portability: Move structure lapic_state to + * KVM: Portability: Move kvm_segment & kvm_dtable structure to + + * KVM: Portability: Move kvm_sregs and msr structures to + * KVM: Portability: Move cpuid structures to + * KVM: Export include/asm-x86/kvm.h + * KVM: MMU: Fix potential memory leak with smp real-mode + * KVM: MMU: Selectively set PageDirty when releasing guest memory + * KVM: x86 emulator: retire ->write_std() + * KVM: x86 emulator: prefetch up to 15 bytes of the instruction executed + * KVM: SVM: Fix FPU leak and re-enable lazy FPU switching + * KVM: Recalculate mmu pages needed for every memory region change + * KVM: Portability: Split kvm_set_memory_region() to have an arch + callout + * KVM: Split vcpu creation to avoid vcpu_load() before preemption setup + * KVM: MMU: Implement guest page fault bypass for nonpae + * KVM: Add statistic for remote tlb flushes + * KVM: MMU: Avoid unnecessary remote tlb flushes when guest updates a pte + * KVM: Add parentheses to silence gcc + * KVM: Don't bother the mmu if cr3 load doesn't change cr3 + * KVM: MMU: Code cleanup + * KVM: MMU: Introduce and use gpte_to_gfn() + * KVM: MMU: Move pse36 handling to the guest walker + * KVM: MMU: Remove extra gaddr parameter from set_pte_common() + * KVM: MMU: Remove set_pde() + * KVM: MMU: Adjust page_header_update_slot() to accept a gfn instead of a + gpa + * KVM: MMU: Introduce gfn_to_gpa() + * KVM: MMU: Simplify nonpaging_map() + * KVM: MMU: Remove gva_to_hpa() + * KVM: Remove gpa_to_hpa() + * KVM: MMU: Rename variable of type 'struct kvm_mmu_page *' + * KVM: MMU: Rename 'release_page' + * KVM: Disallow fork() and similar games when using a VM + * KVM: Enhance guest cpuid management + * KVM: Replace private 'struct segment descriptor' by x86's desc_struct + * KVM: Remove segment_descriptor, part 2 + * KVM: Fix compile error on i386 + * KVM: VMX: Read & store IDT_VECTORING_INFO_FIELD + * KVM: Fix faults during injection of real-mode interrupts + * KVM: x86 emulator: Fix instruction fetch cache hit check + * KVM: VMX: Remove the secondary execute control dependency on irqchip + * KVM: Portability: Move unalias_gfn to arch dependent file + * KVM: x86 emulator: Make a distinction between repeat prefixes F3 and F2 + * KVM: x86 emulator: address size and operand size overrides are sticky + * KVM: Remove desc.h include in kvm_main.c + * KVM: Revert segment_descriptor.h removal + * KVM: Remove misleading check for mmio during event injection + * KVM: MMU: mark pages that were inserted to the shadow pages table as + accessed + * KVM: x86 emulator: rename REP_REPE_PREFIX + * KVM: x86 emulator: cmps instruction + * KVM: Add ifdef in irqchip struct for x86 only structures + * KVM: Fix cpuid2 killing 32-bit guests on non-NX machines + * KVM: x86 emulator: Move rep processing before instruction execution + * KVM: x86 emulator: unify two switches + * KVM: x86 emulator: unify four switch statements into two + * KVM: Don't bypass the mmu if in pae and pdptrs changed + * KVM: Portability: Move KVM_INTERRUPT vcpu ioctl to x86.c + * KVM: Correct kvm_init() error paths not freeing bad_pge. + * KVM: Export include/linux/kvm.h only if $ARCH actually supports KVM + * KVM: SVM: Remove KVM specific defines for MSR_EFER + * KVM: Replace kvm_lapic with kvm_vcpu in ioapic/lapic interface + * KVM: Replace dest_Lowest_Prio and dest_Fixed with self-defined macros + * KVM: Extend ioapic code to support iosapic + * KVM: Portability: Move address types to their own header file + * KVM: Portability: Move IO device definitions to its own header file + * KVM: Portability: Stop including x86-specific headers in kvm_main.c + * KVM: Portability: Create kvm_arch_vcpu_runnable() function + * KVM: Convert KVM from ->nopage() to ->fault() + * KVM: MMU: Remove unused prev_shadow_ent variable from fetch() + * KVM: Generalize exception injection mechanism + * KVM: Replace page fault injection by the generalized exception queue + * KVM: Replace #GP injection by the generalized exception queue + * KVM: Use generalized exception queue for injecting #UD + * KVM: x86 emulator: fix eflags preparation for emulation + * KVM: VMX: Avoid exit when setting cr8 if the local apic is in the + kernel + * KVM: SVM: Emulate read/write access to cr8 + * KVM: x86 emulator: Fix stack instructions on 64-bit mode + * KVM: SVM: Trap access to the cr8 register + * KVM: VMX: Fix cr8 exit optimization + * KVM: MMU: Use cmpxchg for pte updates on walk_addr() + * KVM: MMU: Simplify calculation of pte access + * KVM: MMU: Set nx bit correctly on shadow ptes + * KVM: MMU: Move pte access calculation into a helper function + * KVM: MMU: Fix inherited permissions for emulated guest pte updates + * KVM: MMU: No need to pick up nx bit from guest pte + * KVM: MMU: Pass pte dirty flag to set_pte() instead of calculating it + on-site + * KVM: MMU: Remove walker argument to set_pte() + * KVM: MMU: Move set_pte() into guest paging mode independent code + * KVM: MMU: Adjust mmu_set_spte() debug code for gpte removal + * KVM: MMU: Use mmu_set_spte() for real-mode shadows + * KVM: SVM: Exit to userspace if write to cr8 and not using in-kernel + apic + * KVM: SVM: support writing 0 to K8 performance counter control registers + * KVM: MMU: Fix kunmap_atomic() call in cmpxchg_gpte() + * KVM: MMU: Fix SMP shadow instantiation race + * KVM: LAPIC: minor debugging compile fix + * KVM: MMU: emulated cmpxchg8b should be atomic on i386 + * KVM: Fix bad kunmap_atomic() paramerter inm cmpxchg emulation + * KVM: Make cmpxchg emulation compile on i386 + * KVM: Another cmpxchg i386 compile fix + * KVM: Another cmpxchg emulation compile fix + * KVM: Another cmpxchg emulation compile fix + * KVM: Portability: Move kvm{pic,ioapic} accesors to x86 specific code + * KVM: Portability: Introduce kvm_vcpu_arch + * KVM: Portability: Split mmu-related static inline functions to mmu.h + * KVM: Portability: Move kvm_vcpu definition back to kvm.h + * KVM: Portability: Expand the KVM_VCPU_COMM in kvm_vcpu structure. + * KVM: Portability: Move kvm_vcpu_stat to x86.h + * KVM: Portability: Move memslot aliases to new struct kvm_arch + * KVM: Portability: Move mmu-related fields to kvm_arch + * KVM: Portability: move vpic and vioapic to kvm_arch + * KVM: Portability: Move round_robin_prev_vcpu and tss_addr to kvm_arch + * KVM: Portability: Move kvm_vm_stat to x86.h + * KVM: VMX: Add printk_ratelimit in vmx_intr_assist + * KVM: Move arch dependent files to new directory arch/x86/kvm/ + * KVM: Move drivers/kvm/* to virt/kvm/ + * KVM: Fix compile error in asm/kvm_host.h + * KVM: Move irqchip declarations into new ioapic.h and lapic.h + * KVM: Move ioapic code to common directory. + * KVM: Move kvm_vcpu_kick() to x86.c + * KVM: Expose ioapic to ia64 save/restore APIs + * KVM: MMU: Coalesce remote tlb flushes + * KVM: MMU: Add cache miss statistic + * KVM: Print data for unimplemented wrmsr + * KVM: Ensure pages are copied on write + * KVM: MMU: Fix cmpxchg8b emulation on i386 (again) + * KVM: x86 emulator: Add vmmcall/vmcall to x86_emulate (v3) + * KVM: Refactor hypercall infrastructure (v3) + * KVM: x86 emulator: remove unused functions + * KVM: x86 emulator: move all x86_emulate_memop() to a structure + * KVM: x86 emulator: move all decoding process to function + x86_decode_insn() + * KVM: emulate_instruction() calls now x86_decode_insn() and + x86_emulate_insn() + * KVM: Call x86_decode_insn() only when needed + * KVM: VMX: Further reduce efer reloads + * KVM: Allow not-present guest page faults to bypass kvm + * KVM: MMU: Make flooding detection work when guest page faults are + bypassed + * KVM: MMU: Ignore reserved bits in cr3 in non-pae mode + * KVM: x86 emulator: split some decoding into functions for readability + * KVM: x86 emulator: remove _eflags and use directly ctxt->eflags. + * KVM: x86 emulator: Remove no_wb, use dst.type = OP_NONE instead + * KVM: x86_emulator: no writeback for bt + * KVM: Purify x86_decode_insn() error case management + * KVM: x86 emulator: Any legacy prefix after a REX prefix nullifies its + effect + * KVM: VMX: Don't clear the vmcs if the vcpu is not loaded on any + processor + * KVM: VMX: Simplify vcpu_clear() + * KVM: Remove the usage of page->private field by rmap + * KVM: Add general accessors to read and write guest memory + * KVM: Allow dynamic allocation of the mmu shadow cache size + * KVM: Add kvm_free_lapic() to pair with kvm_create_lapic() + * KVM: Hoist kvm_create_lapic() into kvm_vcpu_init() + * KVM: Remove gratuitous casts from lapic.c + * KVM: CodingStyle cleanup + * KVM: Support assigning userspace memory to the guest + * KVM: Move x86 msr handling to new files x86.[ch] + * KVM: MMU: Clean up MMU functions to take struct kvm when appropriate + * KVM: MMU: More struct kvm_vcpu -> struct kvm cleanups + * KVM: Move guest pte dirty bit management to the guest pagetable walker + * KVM: MMU: Fix nx access bit for huge pages + * KVM: MMU: Disable write access on clean large pages + * KVM: MMU: Instantiate real-mode shadows as user writable shadows + * KVM: MMU: Move dirty bit updates to a separate function + * KVM: MMU: When updating the dirty bit, inform the mmu about it + * KVM: Portability: split kvm_vcpu_ioctl + * KVM: apic round robin cleanup + * KVM: Add some \n in ioapic_debug() + * KVM: Move apic timer interrupt backlog processing to common code + * KVM: Rename KVM_TLB_FLUSH to KVM_REQ_TLB_FLUSH + * KVM: x86 emulator: Implement emulation of instruction: inc & dec + * KVM: MMU: Simplify page table walker + * KVM: x86 emulator: cmc, clc, cli, sti + * KVM: MMU: Add rmap_next(), a helper for walking kvm rmaps + * KVM: MMU: Keep a reverse mapping of non-writable translations + * KVM: MMU: Make gfn_to_page() always safe + * KVM: MMU: Partial swapping of guest memory + * KVM: Use virtual cpu accounting if available for guest times. + * KVM: Allocate userspace memory for older userspace + * KVM: Portability: Split kvm_vcpu into arch dependent and independent + parts (part 1) + * KVM: Move vmx_vcpu_reset() out of vmx_vcpu_setup() + * KVM: Add a might_sleep() annotation to gfn_to_page() + * KVM: Export PIC reset for kernel device reset + * KVM: Split IOAPIC reset function and export for kernel RESET + * KVM: Per-architecture hypercall definitions + * KVM: Unmap kernel-allocated memory on slot destruction + * KVM: Export memory slot allocation mechanism + * KVM: Add kernel-internal memory slots + * KVM: Add ioctl to tss address from userspace, + * KVM: VMX: Let gcc to choose which registers to save (x86_64) + * KVM: VMX: Let gcc to choose which registers to save (i386) + * KVM: SVM: Let gcc to choose which registers to save (x86_64) + * KVM: SVM: Let gcc to choose which registers to save (i386) + * KVM: x86 emulator: don't depend on cr2 for mov abs emulation + * KVM: Move page fault processing to common code + * KVM: MMU: Topup the mmu memory preallocation caches before emulating an + insn + * KVM: Portability: Split kvm_vm_ioctl v3 + * KVM: Portability: Move memory segmentation to x86.c + * KVM: Portability: move get/set_apic_base to x86.c + * KVM: Portability: Move control register helper functions to x86.c + * KVM: VMX: Enable memory mapped TPR shadow (FlexPriority) + * KVM: Fix gfn_to_page() acquiring mmap_sem twice + * KVM: Portability: Move kvm_get/set_msr[_common] to x86.c + * KVM: Portability: Move x86 emulation and mmio device hook to x86.c + * KVM: Portability: Move pio emulation functions to x86.c + * KVM: x86 emulator: Extract the common code of SrcReg and DstReg + * KVM: x86 emulator: centralize decoding of one-byte register access + insns + * KVM: Simplify decode_register_operand() calling convention + * KVM: Make mark_page_dirty() work for aliased pages too. + * KVM: x86 emulator: Hoist modrm and abs decoding into separate functions + * KVM: Portability: Make exported debugfs data architecture-specific + * KVM: Portability: Move x86 instruction emulation code to x86.c + * KVM: Portability: Move x86 FPU handling to x86.c + * KVM: Portability: Move x86 vcpu ioctl handlers to x86.c + * KVM: Add make_page_dirty() to kvm_clear_guest_page() + * KVM: VMX: Use vmx to inject real-mode interrupts + * KVM: VMX: Read & store IDT_VECTORING_INFO_FIELD + * KVM: Fix faults during injection of real-mode interrupts + * KVM: VMX: Comment VMX primary/secondary exec ctl definitions + * KVM: VMX: wbinvd exiting + * KVM: x86 emulator: remove 8 bytes operands emulator for call near + instruction + * KVM: Simplify CPU_TASKS_FROZEN cpu notifier handling + * KVM: add kvm_is_error_hva() + * KVM: introduce gfn_to_hva() + * KVM: Change kvm_{read,write}_guest() to use copy_{from,to}_user() + * KVM: Portability: Move some includes to x86.c + * KVM: Portability: Move kvm_x86_ops to x86.c + * KVM: Portability: Add vcpu and hardware management arch hooks + * KVM: Portability: Combine kvm_init and kvm_init_x86 + * KVM: Portability: Move x86 specific code from kvm_init() to kvm_arch() + * KVM: x86 emulator: modify 'lods', and 'stos' not to depend on CR2 + * KVM: Portability: move KVM_CHECK_EXTENSION + * KVM: VMX: Consolidate register usage in vmx_vcpu_run() + * KVM: Portability: Make kvm_vcpu_ioctl_translate arch dependent + * KVM: Remove ptr comparisons to 0 + * KVM: Remove __init attributes for kvm_init_debug and kvm_init_msr_list + * KVM: Portability: Add two hooks to handle kvm_create and destroy vm + * KVM: Replace 'light_exits' stat with 'host_state_reload' + * KVM: Add fpu_reload counter + * KVM: Add instruction emulation statistics + * KVM: Extend stats support for VM stats + * KVM: MMU: Add some mmu statistics + * KVM: Make unloading of FPU state when putting vcpu arch-independent + * KVM: Portability: Move kvm_vcpu_ioctl_get_dirty_log to arch-specific + file + * KVM: Portability: MMU initialization and teardown split + * KVM: Portability: Move some macro definitions from kvm.h to x86.h + * KVM: Portability: Move struct kvm_x86_ops definition to x86.h + * KVM: Portability: Move vcpu regs enumeration definition to x86.h + * KVM: Move some static inline functions out from kvm.h into x86.h + * KVM: Portability: Move some function declarations to x86.h + * KVM: VMX: Force seg.base == (seg.sel << 4) in real mode + * KVM: MMU: Change guest pte access to kvm_{read,write}_guest() + * KVM: Simplify kvm_clear_guest_page() + * KVM: Add missing #include + * KVM: MMU: Remove unused variable + * KVM: Remove unused "rmap_overflow" variable + * KVM: Correct consistent typo: "destory" -> "destroy" + * KVM: Move misplaced comment + * KVM: Portability: Move kvm_memory_alias to asm/kvm.h + * KVM: Portability: Move x86 pic strutctures + * KVM: Portability: Move kvm_regs to + * KVM: Portability: Move structure lapic_state to + * KVM: Portability: Move kvm_segment & kvm_dtable structure to + + * KVM: Portability: Move kvm_sregs and msr structures to + * KVM: Portability: Move cpuid structures to + * KVM: Export include/asm-x86/kvm.h + * KVM: MMU: Fix potential memory leak with smp real-mode + * KVM: MMU: Selectively set PageDirty when releasing guest memory + * KVM: x86 emulator: retire ->write_std() + * KVM: x86 emulator: prefetch up to 15 bytes of the instruction executed + * KVM: Recalculate mmu pages needed for every memory region change + * KVM: Portability: Split kvm_set_memory_region() to have an arch + callout + * KVM: Split vcpu creation to avoid vcpu_load() before preemption setup + * KVM: MMU: Implement guest page fault bypass for nonpae + * KVM: Add statistic for remote tlb flushes + * KVM: MMU: Avoid unnecessary remote tlb flushes when guest updates a pte + * KVM: Don't bother the mmu if cr3 load doesn't change cr3 + * KVM: MMU: Code cleanup + * KVM: MMU: Introduce and use gpte_to_gfn() + * KVM: MMU: Move pse36 handling to the guest walker + * KVM: MMU: Remove extra gaddr parameter from set_pte_common() + * KVM: MMU: Remove set_pde() + * KVM: MMU: Adjust page_header_update_slot() to accept a gfn instead of a + gpa + * KVM: MMU: Introduce gfn_to_gpa() + * KVM: MMU: Simplify nonpaging_map() + * KVM: MMU: Remove gva_to_hpa() + * KVM: Remove gpa_to_hpa() + * KVM: MMU: Rename variables of type 'struct kvm_mmu_page *' + * KVM: MMU: Rename 'release_page' + * KVM: Disallow fork() and similar games when using a VM + * KVM: Enhance guest cpuid management + * KVM: VMX: Remove the secondary execute control dependency on irqchip + * KVM: Portability: Move unalias_gfn to arch dependent file + * KVM: x86 emulator: Make a distinction between repeat prefixes F3 and F2 + * KVM: x86 emulator: address size and operand size overrides are sticky + * KVM: Remove misleading check for mmio during event injection + * KVM: MMU: mark pages that were inserted to the shadow pages table as + accessed + * KVM: x86 emulator: rename REP_REPE_PREFIX + * KVM: x86 emulator: Rename 'cr2' to 'memop' + * KVM: x86 emulator: cmps instruction + * KVM: Add ifdef in irqchip struct for x86 only structures + * KVM: Fix cpuid2 killing 32-bit guests on non-NX machines + * KVM: x86 emulator: Move rep processing before instruction execution + * KVM: x86 emulator: unify two switches + * KVM: x86 emulator: unify four switch statements into two + * KVM: Portability: Move KVM_INTERRUPT vcpu ioctl to x86.c + * KVM: Correct kvm_init() error paths not freeing bad_pge. + * KVM: Export include/linux/kvm.h only if $ARCH actually supports KVM + * KVM: SVM: Remove KVM specific defines for MSR_EFER + * KVM: Replace kvm_lapic with kvm_vcpu in ioapic/lapic interface + * KVM: Replace dest_Lowest_Prio and dest_Fixed with self-defined macros + * KVM: Extend ioapic code to support iosapic + * KVM: Portability: Move address types to their own header file + * KVM: Portability: Move IO device definitions to its own header file + * KVM: Portability: Stop including x86-specific headers in kvm_main.c + * KVM: Portability: Create kvm_arch_vcpu_runnable() function + * KVM: Convert KVM from ->nopage() to ->fault() + * KVM: MMU: Remove unused prev_shadow_ent variable from fetch() + * KVM: Generalize exception injection mechanism + * KVM: Replace page fault injection by the generalized exception queue + * KVM: Replace #GP injection by the generalized exception queue + * KVM: Use generalized exception queue for injecting #UD + * KVM: x86 emulator: fix eflags preparation for emulation + * KVM: VMX: Avoid exit when setting cr8 if the local apic is in the + kernel + * KVM: SVM: Emulate read/write access to cr8 + * KVM: x86 emulator: Fix stack instructions on 64-bit mode + * KVM: SVM: Trap access to the cr8 register + * KVM: VMX: Fix cr8 exit optimization + * KVM: MMU: Use cmpxchg for pte updates on walk_addr() + * KVM: MMU: Simplify calculation of pte access + * KVM: MMU: Set nx bit correctly on shadow ptes + * KVM: MMU: Move pte access calculation into a helper function + * KVM: MMU: Fix inherited permissions for emulated guest pte updates + * KVM: MMU: No need to pick up nx bit from guest pte + * KVM: MMU: Pass pte dirty flag to set_pte() instead of calculating it + on-site + * KVM: MMU: Remove walker argument to set_pte() + * KVM: MMU: Move set_pte() into guest paging mode independent code + * KVM: MMU: Adjust mmu_set_spte() debug code for gpte removal + * KVM: MMU: Use mmu_set_spte() for real-mode shadows + * KVM: SVM: Exit to userspace if write to cr8 and not using in-kernel + apic + * KVM: MMU: Fix SMP shadow instantiation race + * KVM: LAPIC: minor debugging compile fix + * KVM: SVM: support writing 0 to K8 performance counter control registers + * KVM: MMU: emulated cmpxchg8b should be atomic on i386 + * KVM: Portability: Move kvm{pic,ioapic} accesors to x86 specific code + * KVM: Portability: Introduce kvm_vcpu_arch + * KVM: Portability: Split mmu-related static inline functions to mmu.h + * KVM: Portability: Move kvm_vcpu definition back to kvm.h + * KVM: Portability: Expand the KVM_VCPU_COMM in kvm_vcpu structure. + * KVM: Portability: Move kvm_vcpu_stat to x86.h + * KVM: Portability: Move memslot aliases to new struct kvm_arch + * KVM: Portability: Move mmu-related fields to kvm_arch + * KVM: Portability: move vpic and vioapic to kvm_arch + * KVM: Portability: Move round_robin_prev_vcpu and tss_addr to kvm_arch + * KVM: Portability: Move kvm_vm_stat to x86.h + * KVM: VMX: Add printk_ratelimit in vmx_intr_assist + * KVM: Move arch dependent files to new directory arch/x86/kvm/ + * KVM: Move drivers/kvm/* to virt/kvm/ + * KVM: Move irqchip declarations into new ioapic.h and lapic.h + * KVM: Move ioapic code to common directory. + * KVM: Move kvm_vcpu_kick() to x86.c + * KVM: Expose ioapic to ia64 save/restore APIs + * KVM: MMU: Coalesce remote tlb flushes + * KVM: MMU: Add cache miss statistic + * KVM: Print data for unimplemented wrmsr + * KVM: Ensure pages are copied on write + * KVM: local APIC TPR access reporting facility + * KVM: Accelerated apic support + * KVM: Disable vapic support on Intel machines with FlexPriority + * KVM: MMU: Concurrent guest walkers + * KVM: Add kvm_read_guest_atomic() + * KVM: MMU: Avoid calling gfn_to_page() in mmu_set_spte() + * KVM: MMU: Switch to mmu spinlock + * KVM: MMU: Move kvm_free_some_pages() into critical section + * KVM: MMU: Broaden scope of mmap_sem to include actual mapping + * KVM: MMU: Fix recursive locking of mmap_sem() + * KVM: Fix unbalanced mmap_sem operations in cmpxchg8b emulation + * KVM: Mark vapic page as dirty for save/restore/migrate + * KVM: x86 emulator: Only allow VMCALL/VMMCALL trapped by #UD + * KVM: MMU: Update shadow ptes on partial guest pte writes + * KVM: MMU: Simplify hash table indexing + * KVM: Portability: Move kvm_fpu to asm-x86/kvm.h + * KVM: MMU: Fix dirty page setting for pages removed from rmap + * KVM: Initialize the mmu caches only after verifying cpu support + * KVM: Fix unbounded preemption latency + * KVM: Put kvm_para.h include outside __KERNEL__ + * KVM: Move apic timer migration away from critical section + * KVM: SVM: Fix lazy FPU switching + * KVM: MMU: Fix gpa truncation when reading a pte + * [GFS2] Handle multiple glock demote requests + * [GFS2] Clean up internal read function + * [GFS2] Use ->page_mkwrite() for mmap() + * [GFS2] Remove useless i_cache from inodes + * [GFS2] Remove unused field in struct gfs2_inode + * [GFS2] Add gfs2_is_writeback() + * [GFS2] Introduce gfs2_set_aops() + * [GFS2] Split gfs2_writepage into three cases + * [GFS2] Add writepages for GFS2 jdata + * [GFS2] Don't hold page lock when starting transaction + * [GFS2] Use correct include file in ops_address.c + * [GFS2] Remove unused variables + * [GFS2] Remove "reclaim limit" + * [GFS2] Add sync_page to metadata address space operations + * [GFS2] Reorder writeback for glock sync + * [GFS2] Remove flags no longer required + * [GFS2] Given device ID rather than s_id in "id" sysfs file + * [GFS2] check kthread_should_stop when waiting + * [GFS2] Don't add glocks to the journal + * [GFS2] Use atomic_t for journal free blocks counter + * [GFS2] Move gfs2_logd into log.c + * [GFS2] Don't periodically update the jindex + * [GFS2] Check for installation of mount helpers for DLM mounts + * [GFS2] tidy up error message + * [GFS2] Fix runtime issue with UP kernels + * [GFS2] remove unnecessary permission checks + * [GFS2] Fix build warnings + * [GFS2] Remove unrequired code + * [GFS2] Remove lock methods for lock_nolock protocol + * [GFS2] patch to check for recursive lock requests in gfs2_rename code + path + * [GFS2] Remove unused variable + * [GFS2] use pid for plock owner for nfs clients + * [GFS2] Remove function gfs2_get_block + * [GFS2] Journal extent mapping + * [GFS2] Get rid of useless "found" variable in quota.c + * [GFS2] Run through full bitmaps quicker in gfs2_bitfit + * [GFS2] Reorganize function gfs2_glmutex_lock + * [GFS2] Only fetch the dinode once in block_map + * [GFS2] Function meta_read optimization + * [GFS2] Incremental patch to fix compiler warning + * [GFS2] Eliminate the no longer needed sd_statfs_mutex + * [GFS2] Minor correction + * [GFS2] Fix log block mapper + * [GFS2] Remove unused variable + * [GFS2] Allow page migration for writeback and ordered pages + * [GFS2] Initialize extent_list earlier + * [GFS2] Fix problems relating to execution of files on GFS2 + * [GFS2] Fix assert in log code + * [GFS2] Reduce inode size by moving i_alloc out of line + * [GFS2] Remove unneeded i_spin + * [GFS2] gfs2_alloc_required performance + * [GFS2] Fix write alloc required shortcut calculation + * [GFS2] Fix typo + * [GFS2] Fix page_mkwrite truncation race path + * [GFS2] Lockup on error + * [GFS2] Allow journal recovery on read-only mount + + -- Tim Gardner Sun, 27 Jan 2008 20:37:18 -0700 + +linux (2.6.24-5.9) hardy; urgency=low + + [Amit Kucheria] + + * Fix LPIA FTBFS due to virtio Ignore: yes + + [Upstream Kernel Changes] + + * ACPI: processor: Fix null pointer dereference in throttling + * [SPARC64]: Fix of section mismatch warnings. + * [SPARC64]: Fix section error in sparcspkr + * [SPARC]: Constify function pointer tables. + * [BLUETOOTH]: Move children of connection device to NULL before + connection down. + * [TULIP] DMFE: Fix SROM parsing regression. + * [IPV4]: Add missing skb->truesize increment in ip_append_page(). + * iwlwifi: fix possible read attempt on ucode that is not available + * [NETNS]: Re-export init_net via EXPORT_SYMBOL. + * [INET]: Fix truesize setting in ip_append_data + * sis190: add cmos ram access code for the SiS19x/968 chipset pair + * sis190: remove duplicate INIT_WORK + * sis190: mdio operation failure is not correctly detected + * sis190: scheduling while atomic error + * Update ctime and mtime for memory-mapped files + * [SCSI] initio: fix module hangs on loading + * xen: disable vcpu_info placement for now + * agp/intel: add support for E7221 chipset + * drm/i915: add support for E7221 chipset + * DMI: move dmi_available declaration to linux/dmi.h + * DMI: create dmi_get_slot() + * ACPI: create acpi_dmi_dump() + * ACPI: on OSI(Linux), print needed DMI rather than requesting dmidecode + output + * ACPI: Delete Intel Customer Reference Board (CRB) from OSI(Linux) DMI + list + * ACPI: make _OSI(Linux) console messages smarter + * ACPI: Add ThinkPad R61, ThinkPad T61 to OSI(Linux) white-list + * ACPI: DMI blacklist to reduce console warnings on OSI(Linux) systems. + * ACPI: EC: fix dmesg spam regression + * ACPI: EC: add leading zeros to debug messages + * Pull bugzilla-9747 into release branch + * Pull bugzilla-8459 into release branch + * Pull bugzilla-9798 into release branch + * Pull dmi-2.6.24 into release branch + * [SPARC64]: Partially revert "Constify function pointer tables." + * lockdep: fix kernel crash on module unload + * sysctl: kill binary sysctl KERN_PPC_L2CR + * fix hugepages leak due to pagetable page sharing + * spi: omap2_mcspi PIO RX fix + * Linux 2.6.24 + + -- Tim Gardner Fri, 25 Jan 2008 01:44:27 -0700 + +linux (2.6.24-5.8) hardy; urgency=low + + [Alessio Igor Bogani] + + * rt: Update to 2.6.24-rc8-rt1 + * rt: Update configuration files + + [Amit Kucheria] + + * Asix: fix breakage caused in 2.6.24-rc7 + * Add CONFIG_CPUSETS to server-related flavours + - LP: #182434 + + [Chuck Short] + + * SAUCE: ata: blacklist FUJITSU MHW2160BH PL + - LP: #175834 + + [Kees Cook] + + * AppArmor: updated patch series to upstream SVN 1079. + + [Soren Hansen] + + * Updated configs to enable virtio stuff Ignore: yes + + [Stefan Bader] + + * Enabled CONFIG_BSD_PROCESS_ACCT=y for sparc. + - LP: #176587 + * Enable CONFIG_AUDITSYSCALL=y. + - LP: #140784 + * Added CONFIG_AUDIT_SYSCALL=y to custom lpia(compat) + * Enabled CONFIG_HUGETLBFS=y for i386/server amd64/server and ia64. + * Lower priority of pnpacpi resource messages to warning level. + - LP: #159241 + * Fix the messed up message level of pnpacpi parser. + + [Tim Gardner] + + * Start new release, bump ABI to -5 + * Disabled iwlwifi preperatory to moving it to l-u-m. + * Enabled CONFIG_USB_SERIAL_KEYSPAN + * Disabled CONFIG_CGROUPS. + * Virtio config settings for -rt. + * Re-enable IWLWIFI in the kernel. + * Fixed -rt saa7134-core.c FTBS + + [Upstream Kernel Changes] + + * Input: Handle EV_PWR type of input caps in input_set_capability. + * Input: jornada680_kbd - fix default keymap + * increase PNP_MAX_PORT to 40 from 24 + * sched: fix gcc warnings + * leds: Fix leds_list_lock locking issues + * leds: Fix locomo LED driver oops + * x86: fix asm-x86/byteorder.h for userspace export + * x86: fix asm-x86/msr.h for user-space export + * ACPI: EC: Enable boot EC before bus_scan + * ACPI: Make sysfs interface in ACPI power optional. + * fix lguest rmmod "bad pgd" + * slub: provide /proc/slabinfo + * [POWERPC] Fix build failure on Cell when CONFIG_SPU_FS=y + * slub: register slabinfo to procfs + * [SCSI] scsi_sysfs: restore prep_fn when ULD is removed + * Unify /proc/slabinfo configuration + * scsi: revert "[SCSI] Get rid of scsi_cmnd->done" + * restrict reading from /proc//maps to those who share ->mm or can + ptrace pid + * Fix kernel/ptrace.c compile problem (missing "may_attach()") + * hwmon: (w83627ehf) Be more careful when changing VID input level + * NFS: Fix a possible Oops in fs/nfs/super.c + * NFSv4: Fix circular locking dependency in nfs4_kill_renewd + * NFS: add newline to kernel warning message in auth_gss code + * NFSv4: nfs4_open_confirm must not set the open_owner as confirmed on + error + * NFSv4: Fix open_to_lock_owner sequenceid allocation... + * gameport: don't export functions that are static inline + * Input: spitzkbd - fix suspend key handling + * Input: pass EV_PWR events to event handlers + * [ARM] 4735/1: Unbreak pxa25x suspend/resume + * IB/srp: Fix list corruption/oops on module reload + * Console is utf-8 by default + * [IA64] Update Altix BTE error return status patch + * [IA64] Update Altix nofault code + * [X25]: Add missing x25_neigh_put + * [XFRM]: Do not define km_migrate() if !CONFIG_XFRM_MIGRATE + * [CASSINI]: Fix endianness bug. + * [CASSINI]: Revert 'dont touch page_count'. + * [CASSINI]: Program parent Intel31154 bridge when necessary. + * [CASSINI]: Set skb->truesize properly on receive packets. + * [CASSINI]: Fix two obvious NAPI bugs. + * [CASSINI]: Bump driver version and release date. + * [INET]: Fix netdev renaming and inet address labels + * [CONNECTOR]: Return proper error code in cn_call_callback() + * [ISDN] i4l: 'NO CARRIER' message lost after ldisc flush + * [ISDN]: i4l: Fix DLE handling for i4l-audio + * fix: using joysticks in 32 bit applications on 64 bit systems + * [ARM] 4691/1: add missing i2c_board_info struct for at91rm9200 + * hda_intel suspend latency: shorten codec read + * CPU hotplug: fix cpu_is_offline() on !CONFIG_HOTPLUG_CPU + * Linux 2.6.24-rc7 + * sh: Fix argument page dcache flushing regression. + * V4L/DVB (6944a): Fix Regression VIDIOCGMBUF ioctl hangs on bttv driver + * V4L/DVB (6916): ivtv: udelay has to be changed *after* the eeprom was + read, not before + * [MIPS] Move inclusing of kernel/time/Kconfig menu to appropriate place + * [MIPS] Alchemy: Fix use of __init code bug exposed by modpost warning + * [MIPS] Fix IP32 breakage + * [MIPS] Assume R4000/R4400 newer than 3.0 don't have the mfc0 count bug + * [MIPS] Fix CONFIG_BOOT_RAW. + * ACPI: Reintroduce run time configurable max_cstate for !CPU_IDLE case + * core dump: real_parent ppid + * acct: real_parent ppid + * IB/mlx4: Fix value of pkey_index in QP1 completions + * IB/srp: Release transport before removing host + * x86: fix do_fork_idle section mismatch + * spi_bitbang: always grab lock with irqs blocked + * fat: optimize fat_count_free_clusters() + * KEYS: fix macro + * md: fix data corruption when a degraded raid5 array is reshaped + * xip: fix get_zeroed_page with __GFP_HIGHMEM + * eCryptfs: fix dentry handling on create error, unlink, and inode + destroy + * vmcoreinfo: add the array length of "free_list" for filtering free + pages + * dmi-id: fix for __you_cannot_kmalloc_that_much failure + * snd_mixer_oss_build_input(): fix for __you_cannot_kmalloc_that_much + failure with gcc-3.2 + * Fix crash with FLAT_MEMORY and ARCH_PFN_OFFSET != 0 + * hfs: handle more on-disk corruptions without oopsing + * pl2303: Fix mode switching regression + * futex: Prevent stale futex owner when interrupted/timeout + * [NIU]: Fix slowpath interrupt handling. + * [NIU]: Missing ->last_rx update. + * [NIU]: Fix potentially stuck TCP socket send queues. + * [NIU]: Update driver version and release date. + * [IPV4] raw: Strengthen check on validity of iph->ihl + * [IPV4] ipconfig: Fix regression in ip command line processing + * [NET]: Fix netx-eth.c compilation. + * [METH]: Fix MAC address handling. + * [TULIP]: NAPI full quantum bug. + * [ATM]: [nicstar] delay irq setup until card is configured + * [SCTP]: Fix the name of the authentication event. + * [SCTP]: Correctly handle AUTH parameters in unexpected INIT + * [SCTP]: Add back the code that accounted for FORWARD_TSN parameter in + INIT. + * [IRDA]: irda_create() nuke user triggable printk + * b43: Fix rxheader channel parsing + * [NET]: Do not grab device reference when scheduling a NAPI poll. + * [NET]: Add NAPI_STATE_DISABLE. + * [NET]: Do not check netif_running() and carrier state in ->poll() + * ssb: Fix probing of PCI cores if PCI and PCIE core is available + * mac80211: return an error when SIWRATE doesn't match any rate + * [NETXEN]: Fix ->poll() done logic. + * [NET]: Fix drivers to handle napi_disable() disabling interrupts. + * [NET]: Stop polling when napi_disable() is pending. + * [NET]: Make ->poll() breakout consistent in Intel ethernet drivers. + * [NET] Intel ethernet drivers: update MAINTAINERS + * [NET]: kaweth was forgotten in msec switchover of usb_start_wait_urb + * [IPV4] ROUTE: ip_rt_dump() is unecessary slow + * [NET]: Clone the sk_buff 'iif' field in __skb_clone() + * [LRO] Fix lro_mgr->features checks + * [NET]: mcs7830 passes msecs instead of jiffies to usb_control_msg + * [FORCEDETH]: Fix reversing the MAC address on suspend. + * [XFRM]: xfrm_algo_clone() allocates too much memory + * [SOCK]: Adds a rcu_dereference() in sk_filter + * [CONNECTOR]: Don't touch queue dev after decrement of ref count. + * [IPV6]: IPV6_MULTICAST_IF setting is ignored on link-local connect() + * [ATM]: Check IP header validity in mpc_send_packet + * show_task: real_parent + * [SCSI] qla1280: fix 32 bit segment code + * [NIU]: Support for Marvell PHY + * [NEIGH]: Fix race between neigh_parms_release and neightbl_fill_parms + * [IPV4] ROUTE: fix rcu_dereference() uses in /proc/net/rt_cache + * [AX25]: Kill user triggable printks. + * [ARM] pxa: silence warnings from cpu_is_xxx() macros + * [POWERPC] efika: add phy-handle property for fec_mpc52xx + * [ARM] vfp: fix fuitod/fsitod instructions + * [CRYPTO] padlock: Fix alignment fault in aes_crypt_copy + * rt2x00: Allow rt61 to catch up after a missing tx report + * rt2x00: Corectly initialize rt2500usb MAC + * rt2x00: Put 802.11 data on 4 byte boundary + * NFSv4: Give the lock stateid its own sequence queue + * sata_qstor: use hardreset instead of softreset + * libata-sff: PCI IRQ handling fix + * pata_pdc202xx_old: Further fixups + * pata_ixp4xx_cf: fix compilation introduced by ata_port_desc() + conversion + * libata-pmp: 4726 hates SRST + * libata-pmp: propagate timeout to host link + * libata: don't normalize UNKNOWN to NONE after reset + * Update kernel parameter document for libata DMA mode setting knobs. + * sata_sil24: prevent hba lockup when pass-through ATA commands are used + * ide: workaround suspend bug for ACPI IDE + * ide: fix cable detection for SATA bridges + * trm290: do hook dma_host_{on,off} methods (take 2) + * libata and starting/stopping ATAPI floppy devices + * ACPI : Not register gsi for PCI IDE controller in legacy mode + * ACPICA: fix acpi_serialize hang regression + * sh: Force __access_ok() to obey address space limit. + * [AX25] af_ax25: Possible circular locking. + * ACPI: apply quirk_ich6_lpc_acpi to more ICH8 and ICH9 + * [POWERPC] Fix CPU hotplug when using the SLB shadow buffer + * [BLUETOOTH]: rfcomm tty BUG_ON() code fix + * [BLUETOOTH]: Always send explicit hci_ll wake-up acks. + * [DECNET] ROUTE: fix rcu_dereference() uses in /proc/net/decnet_cache + * [VLAN]: nested VLAN: fix lockdep's recursive locking warning + * [MACVLAN]: Prevent nesting macvlan devices + * [NETFILTER]: ip6t_eui64: Fixes calculation of Universal/Local bit + * [NETFILTER]: xt_helper: Do not bypass RCU + * [XFS] fix unaligned access in readdir + * Don't blatt first element of prv in sg_chain() + * loop: fix bad bio_alloc() nr_iovec request + * block: fix blktrace timestamps + * blktrace: kill the unneeded initcall + * V4L/DVB (6999): ivtv: stick to udelay=10 after all + * V4L/DVB (7001): av7110: fix section mismatch + * [MIPS] Wrong CONFIG option prevents setup of DMA zone. + * [MIPS] pnx8xxx: move to clocksource + * [MIPS] Malta: Fix software reset on big endian + * [MIPS] Lasat: Fix built in separate object directory. + * [MIPS] Replace 40c7869b693b18412491fdcff64682215b739f9e kludge + * Pull bugzilla-5637 into release branch + * Pull bugzilla-8171 into release branch + * Pull bugzilla-8973 into release branch + * PM: ACPI and APM must not be enabled at the same time + * Pull bugzilla-9194 into release branch + * Pull bugzilla-9494 into release branch + * Pull bugzilla-9535 into release branch + * Pull bugzilla-9627 into release branch + * Pull bugzilla-9683 into release branch + * IDE: terminate ACPI DMI list + * cache invalidation error for buffered write + * ps3fb: prevent use after free of fb_info + * ps3fb: fix deadlock on kexec() + * [NETFILTER]: bridge: fix double POST_ROUTING invocation + * xircom_cb endianness fixes + * de4x5 fixes + * endianness noise in tulip_core + * netxen: update MAINTAINERS + * netxen: update driver version + * netxen: stop second phy correctly + * netxen: optimize tx handling + * netxen: fix byte-swapping in tx and rx + * 3c509: PnP resource management fix + * Fixed a small typo in the loopback driver + * ip1000: menu location change + * r8169: fix missing loop variable increment + * [usb netdev] asix: fix regression + * fs_enet: check for phydev existence in the ethtool handlers + * Use access mode instead of open flags to determine needed permissions + * sky2: large memory workaround. + * sky2: remove check for PCI wakeup setting from BIOS + * spidernet MAINTAINERship update + * pnpacpi: print resource shortage message only once + * Pull bugzilla-9535 into release branch + * [SPARC]: Make gettimeofday() monotonic again. + * [SPARC64]: Fix build with SPARSEMEM_VMEMMAP disabled. + * remove task_ppid_nr_ns + * knfsd: Allow NFSv2/3 WRITE calls to succeed when krb5i etc is used. + * Input: improve Kconfig help entries for HP Jornada devices + * [TOKENRING]: rif_timer not initialized properly + * modules: de-mutex more symbol lookup paths in the module code + * w1: decrement slave counter only in ->release() callback + * Kick CPUS that might be sleeping in cpus_idle_wait + * TPM: fix suspend and resume failure + * MAINTAINERS: email update and add missing entry + * quicklists: Only consider memory that can be used with GFP_KERNEL + * macintosh: fix fabrication of caplock key events + * scsi/qla2xxx/qla_os.c section fix + * cciss: section mismatch + * advansys: fix section mismatch warning + * hugetlbfs: fix quota leak + * s3c2410fb: fix incorrect argument type in resume function + * CRIS: define __ARCH_WANT_SYS_RT_SIGSUSPEND in unistd.h for CRIS + * CRIS v10: correct do_signal to fix oops and clean up signal handling in + general + * CRIS v10: kernel/time.c needs to include linux/vmstat.h to compile + * uvesafb: fix section mismatch warnings + * CRIS v10: driver for ds1302 needs to include cris-specific i2c.h + * OSS msnd: fix array overflows + * i2c-omap: Fix NULL pointer dereferencing + * i2c: Spelling fixes + * i2c: Driver IDs are optional + * i2c-sibyte: Fix an error path + * fix the "remove task_ppid_nr_ns" commit + * [MIPS] Kconfig fixes for BCM47XX platform + * [MIPS] Cobalt: Fix ethernet interrupts for RaQ1 + * [MIPS] Cobalt: Qube1 has no serial port so don't use it + * [MIPS] Cacheops.h: Fix typo. + * ata_piix: ignore ATA_DMA_ERR on vmware ich4 + * sata_sil24: fix stupid typo + * sata_sil24: freeze on non-dev errors reported via CERR + * libata: relocate sdev->manage_start_stop configuration + * [POWERPC] Fix boot failure on POWER6 + * x86: fix boot crash on HIGHMEM4G && SPARSEMEM + * x86: asm-x86/msr.h: pull in linux/types.h + * x86: fix RTC_AIE with CONFIG_HPET_EMULATE_RTC + * Fix ARM profiling/instrumentation configuration + * Fix Blackfin HARDWARE_PM support + * libata fixes for sparse-found problems + * [libata] pata_bf54x: checkpatch fixes + * [libata] core checkpatch fix + * libata: correct handling of TSS DVD + * [IA64] Fix unaligned handler for floating point instructions with base + update + * Linux 2.6.24-rc8 + * lockdep: fix internal double unlock during self-test + * lockdep: fix workqueue creation API lockdep interaction + * lockdep: more hardirq annotations for notify_die() + * hostap: section mismatch warning + * wireless/libertas support for 88w8385 sdio older revision + * ipw2200: fix typo in kerneldoc + * b43: fix use-after-free rfkill bug + * rt2x00: Fix ieee80211 payload alignment + * sysfs: make sysfs_lookup() return ERR_PTR(-ENOENT) on failed lookup + * sysfs: fix bugs in sysfs_rename/move_dir() + * Use access mode instead of open flags to determine needed permissions + (CVE-2008-0001) + * IB/ipath: Fix receiving UD messages with immediate data + * [NET]: Fix TX timeout regression in Intel drivers. + * [NIU]: Fix 1G PHY link state handling. + * [SPARC64]: Fix hypervisor TLB operation error reporting. + * Input: mousedev - handle mice that use absolute coordinates + * Input: usbtouchscreen - fix buffer overflow, make more egalax work + * Input: psmouse - fix potential memory leak in psmouse_connect() + * Input: psmouse - fix input_dev leak in lifebook driver + * Input: ALPS - fix sync loss on Acer Aspire 5720ZG + * ipg: balance locking in irq handler + * ipg: plug Tx completion leak + * ipg: fix queue stop condition in the xmit handler + * ipg: fix Tx completion irq request + * cpufreq: Initialise default governor before use + * hfs: fix coverity-found null deref + * pnpacpi: print resource shortage message only once (more) + * CRIS v10: vmlinux.lds.S: ix kernel oops on boot and use common defines + * mm: fix section mismatch warning in page_alloc.c + * jbd: do not try lock_acquire after handle made invalid + * alpha: fix conversion from denormal float to double + * #ifdef very expensive debug check in page fault path + * Fix unbalanced helper_lock in kernel/kmod.c + * fix wrong sized spinlock flags argument + * bonding: fix locking in sysfs primary/active selection + * bonding: fix ASSERT_RTNL that produces spurious warnings + * bonding: fix locking during alb failover and slave removal + * bonding: release slaves when master removed via sysfs + * bonding: Fix up parameter parsing + * bonding: fix lock ordering for rtnl and bonding_rwsem + * bonding: Don't hold lock when calling rtnl_unlock + * Documentation: add a guideline for hard_start_xmit method + * atl1: fix frame length bug + * S2io: Fixed synchronization between scheduling of napi with card reset + and close + * dscc4 endian fixes + * wan/lmc bitfields fixes + * sbni endian fixes + * 3c574, 3c515 bitfields abuse + * dl2k: BMCR_t fixes + * dl2k: ANAR, ANLPAR fixes + * dl2k: BMSR fixes + * dl2k: MSCR, MSSR, ESR, PHY_SCR fixes + * dl2k: the rest + * Replace cpmac fix + * [WATCHDOG] Revert "Stop looking for device as soon as one is found" + * [WATCHDOG] clarify watchdog operation in documentation + * x86: add support for the latest Intel processors to Oprofile + * Selecting LGUEST should turn on Guest support, as in 2.6.23. + * ARM: OMAP1: Keymap fix for f-sample and p2-sample + * ARM: OMAP1: Fix compile for board-nokia770 + * pata_pdc202xx_old: Fix crashes with ATAPI + * arch: Ignore arch/i386 and arch/x86_64 + * Remove bogus duplicate CONFIG_LGUEST_GUEST entry. + * [ARM] pxa: don't rely on r2 being preserved over a function call + * [ARM] 4748/1: dca: source drivers/dca/Kconfig in arch/arm/Kconfig to + fix warning + * rfkill: call rfkill_led_trigger_unregister() on error + * [IPV6]: Mischecked tw match in __inet6_check_established. + * [IPV4] fib_hash: fix duplicated route issue + * [IPV4] fib_trie: fix duplicated route issue + * [NET]: Fix interrupt semaphore corruption in Intel drivers. + * [IPV4] FIB_HASH : Avoid unecessary loop in fn_hash_dump_zone() + * [IPV6] ROUTE: Make sending algorithm more friendly with RFC 4861. + * [NETFILTER]: bridge-netfilter: fix net_device refcnt leaks + * [NEIGH]: Revert 'Fix race between neigh_parms_release and + neightbl_fill_parms' + * [IrDA]: af_irda memory leak fixes + * [ATM] atm/idt77105.c: Fix section mismatch. + * [ATM] atm/suni.c: Fix section mismatch. + * [AF_KEY]: Fix skb leak on pfkey_send_migrate() error + * [NET]: rtnl_link: fix use-after-free + * [IPV6]: ICMP6_MIB_OUTMSGS increment duplicated + * [IPV6]: RFC 2011 compatibility broken + * [ICMP]: ICMP_MIB_OUTMSGS increment duplicated + * selinux: fix memory leak in netlabel code + * [MIPS] SMTC: Fix build error. + * [MIPS] Malta: Fix reading the PCI clock frequency on big-endian + * tc35815: Use irq number for tc35815-mac platform device id + * keyspan: fix oops + * hrtimer: fix section mismatch + * timer: fix section mismatch + * CRIS: add missed local_irq_restore call + * s3c2410_fb: fix line length calculation + * Fix filesystem capability support + * sched: group scheduler, set uid share fix + * hwmon: (it87) request only Environment Controller ports + * W1: w1_therm.c ds18b20 decode freezing temperatures correctly + * W1: w1_therm.c is flagging 0C etc as invalid + * rcu: fix section mismatch + * Fix file references in documentation and Kconfig + * x86: GEODE fix a race condition in the MFGPT timer tick + * virtnet: remove double ether_setup + * virtio:simplify-config-mechanism + * virtio: An entropy device, as suggested by hpa. + * virtio: Export vring functions for modules to use + * virtio: Put the virtio under the virtualization menu + * virtio:pci-device + * Fix vring_init/vring_size to take unsigned long + * virtio:vring-kick-when-empty + * virtio:explicit-callback-disable + * virtio:net-flush-queue-on-init + * virtio:net-fix-xmit-skb-free-real + * Parametrize the napi_weight for virtio receive queue. + * Handle module unload Add the device release function. + * Update all status fields on driver unload + * Make virtio modules GPL + * Make virtio_pci license be GPL2+ + * Use Qumranet donated PCI vendor/device IDs + * virtio:more-interrupt-suppression + * Reboot Implemented + * lguest:reboot-fix + * introduce vcpu struct + * adapt lguest launcher to per-cpuness + * initialize vcpu + * per-cpu run guest + * make write() operation smp aware + * make hypercalls use the vcpu struct + * per-vcpu lguest timers + * per-vcpu interrupt processing. + * map_switcher_in_guest() per-vcpu + * make emulate_insn receive a vcpu struct. + * make registers per-vcpu + * replace lguest_arch with lg_cpu_arch. + * per-vcpu lguest task management + * makes special fields be per-vcpu + * make pending notifications per-vcpu + * per-vcpu lguest pgdir management + + -- Tim Gardner Thu, 17 Jan 2008 14:45:01 -0700 + +linux (2.6.24-4.7) hardy; urgency=low + + [Amit Kucheria] + + * Poulsbo: Add SD8686 and 8688 WLAN drivers + * Poulsbo: Mass update of patches to be identical to those on moblin + * SAUCE: make fc transport removal of target configurable OriginalAuthor: + Michael Reed sgi.com> OriginalLocation: + http://thread.gmane.org/gmane.linux.scsi/25318 Bug: 163075 + + [Fabio M. Di Nitto] + + * Fix handling of gcc-4.1 for powerpc and ia64 + + [Tim Gardner] + + * Re-engineered architecture specific linux-headers compiler version + dependencies. + * Doh! Changed header-depends to header_depends. + + -- Tim Gardner Fri, 11 Jan 2008 07:10:46 -0700 + +linux (2.6.24-4.6) hardy; urgency=low + + [Alessio Igor Bogani] + + * Fix -rt build FTBS. + + [Amit Kucheria] + + * LPIACOMPAT: Update thermal patches to be inline with lpia flavour + * Poulsbo: Add USB Controller patch and corresponding config change + + [Fabio M. Di Nitto] + + * Enable aoe and nbd modules on hppa Ignore: yes + * Fix ia64 build by using gcc-4.1 + + [Tim Gardner] + + * Enable JFFS2 LZO compression. + - LP: #178343 + * Remove IS_G33 special handling. + - LP: #174367 + * Enabled CONFIG_SECURITY_CAPABILITIES and + CONFIG_SECURITY_FILE_CAPABILITIES + - LP: #95089 + * Enabled CONFIG_TASKSTATS and CONFIG_TASK_IO_ACCOUNTING + * Turned CONFIG_SECURITY_FILE_CAPABILITIES back off. + * Enabled CONFIG_B43LEGACY=m + * Enabled CONFIG_SCSI_QLOGIC_1280=m + * Enabled CONFIG_FUSION=y for virtual + * USB bluetooth device 0x0e5e:0x6622 floods errors to syslog + - LP: #152689 + * Removed lpia from d-i. + * Added ia64 modules. + * Added hppa32/64 modules. + + [Upstream Kernel Changes] + + * DMI autoload dcdbas on all Dell systems. + * sched: fix gcc warnings + * leds: Fix leds_list_lock locking issues + * leds: Fix locomo LED driver oops + * x86: fix asm-x86/byteorder.h for userspace export + * x86: fix asm-x86/msr.h for user-space export + * fix lguest rmmod "bad pgd" + * slub: provide /proc/slabinfo + * [POWERPC] Fix build failure on Cell when CONFIG_SPU_FS=y + * slub: register slabinfo to procfs + * [SCSI] scsi_sysfs: restore prep_fn when ULD is removed + * Unify /proc/slabinfo configuration + * scsi: revert "[SCSI] Get rid of scsi_cmnd->done" + * restrict reading from /proc//maps to those who share ->mm or can + ptrace pid + * Fix kernel/ptrace.c compile problem (missing "may_attach()") + * hwmon: (w83627ehf) Be more careful when changing VID input level + * NFS: Fix a possible Oops in fs/nfs/super.c + * NFSv4: Fix circular locking dependency in nfs4_kill_renewd + * NFS: add newline to kernel warning message in auth_gss code + * NFSv4: nfs4_open_confirm must not set the open_owner as confirmed on + error + * NFSv4: Fix open_to_lock_owner sequenceid allocation... + * IB/srp: Fix list corruption/oops on module reload + * Console is utf-8 by default + * [IA64] Update Altix BTE error return status patch + * [IA64] Update Altix nofault code + * [X25]: Add missing x25_neigh_put + * [XFRM]: Do not define km_migrate() if !CONFIG_XFRM_MIGRATE + * [CASSINI]: Fix endianness bug. + * [CASSINI]: Revert 'dont touch page_count'. + * [CASSINI]: Program parent Intel31154 bridge when necessary. + * [CASSINI]: Set skb->truesize properly on receive packets. + * [CASSINI]: Fix two obvious NAPI bugs. + * [CASSINI]: Bump driver version and release date. + * [INET]: Fix netdev renaming and inet address labels + * [CONNECTOR]: Return proper error code in cn_call_callback() + * [ISDN] i4l: 'NO CARRIER' message lost after ldisc flush + * [ISDN]: i4l: Fix DLE handling for i4l-audio + * fix: using joysticks in 32 bit applications on 64 bit systems + * hda_intel suspend latency: shorten codec read + * CPU hotplug: fix cpu_is_offline() on !CONFIG_HOTPLUG_CPU + * Linux 2.6.24-rc7 + * PIE executable randomization (upstream cherry pick by kees) + + -- Tim Gardner Fri, 04 Jan 2008 07:15:47 -0700 + +linux (2.6.24-3.5) hardy; urgency=low + + [Alessio Igor Bogani] + + * rt: Fix rt preempt patchset version + * Updated README file for binary custom flavours + * Fix -rt build FTBS. + * rt: Update configuration files + + [Tim Gardner] + + * SAUCE: Add extra headers to linux-libc-dev + + [Upstream Kernel Changes] + + * [WATCHDOG] at32ap700x_wdt: add support for boot status and add fix for + silicon errata + * [WATCHDOG] Stop looking for device as soon as one is found + * [WATCHDOG] bfin_wdt, remove SPIN_LOCK_UNLOCKED + * [WATCHDOG] Sbus: cpwatchdog, remove SPIN_LOCK_UNLOCKED + * [WATCHDOG] IT8212F watchdog driver + * ACPI: acpiphp: Remove dmesg spam on device remove + * [WATCHDOG] ipmi: add the standard watchdog timeout ioctls + * [WATCHDOG] add Nano 7240 driver + * ACPI: battery: fix ACPI battery technology reporting + * [ARM] 4667/1: CM-X270 fixes + * [ARM] 4690/1: PXA: fix CKEN corruption in PXA27x AC97 cold reset code + * [IPV6] XFRM: Fix auditing rt6i_flags; use RTF_xxx flags instead of + RTCF_xxx. + * [IPV4]: Swap the ifa allocation with the"ipv4_devconf_setall" call + * [IPv4] ESP: Discard dummy packets introduced in rfc4303 + * [IPv6] ESP: Discard dummy packets introduced in rfc4303 + * [UM]: Fix use of skb after netif_rx + * [XTENSA]: Fix use of skb after netif_rx + * [S390]: Fix use of skb after netif_rx + * [BNX2]: Add PHY_DIS_EARLY_DAC workaround. + * [BNX2]: Fix RX packet rot. + * [BNX2]: Update version to 1.6.9. + * [NET]: Fix wrong comments for unregister_net* + * [VLAN]: Fix potential race in vlan_cleanup_module vs + vlan_ioctl_handler. + * [IPSEC]: Fix potential dst leak in xfrm_lookup + * V4L/DVB (6485): ivtv: fix compile warning + * V4L/DVB (6540): em28xx: fix failing autodetection after the reboot + * V4L/DVB (6542): Fix S-video mode on tvp5150 + * V4L/DVB (6579): Fix bug #8824: Correct support for Diseqc on tda10086 + * V4L/DVB (6581): Fix: avoids negative vma usage count + * V4L/DVB (6601): V4L: videobuf-core locking fixes and comments + * V4L/DVB (6602): V4L: Convert videobuf drivers to videobuf_stop + * V4L/DVB (6615): V4L: Fix VIDIOCGMBUF locking in saa7146 + * V4L/DVB (6629): zl10353: fix default adc_clock and TRL nominal rate + calculation + * V4L/DVB (6666): saa7134-alsa: fix period handling + * V4L/DVB (6684): Complement va_start() with va_end() + style fixes + * V4L/DVB (6686): saa7134: fix composite over s-video input on the Tevion + MD 9717 + * V4L/DVB (6690): saa7134: fix ignored interrupts + * V4L/DVB (6751): V4L: Memory leak! Fix count in videobuf-vmalloc mmap + * V4L/DVB (6746): saa7134-dvb: fix tuning for WinTV HVR-1110 + * V4L/DVB (6750): Fix in-kernel compilation for cxusb + * V4L/DVB (6733): DVB: Compile 3000MC-specific DIB code only for + CONFIG_DVB_DIB3000MC + * V4L/DVB (6794): Fix compilation when dib3000mc is compiled as a module + * NFS: Fix NFS mountpoint crossing... + * V4L/DVB (6796): ivtv/ section fix + * V4L/DVB (6797): bt8xx/ section fixes + * NFSv2/v3: Fix a memory leak when using -onolock + * V4L/DVB (6609): Re-adds lock safe videobuf_read_start + * i2c: Delete an outdated piece of documentation + * i2c-gpio: Initialize adapter class + * i2c: Add missing spaces in split log messages + * i2c/isp1301_omap: Build fix + * [SERIAL] sparc: Infrastructure to fix section mismatch bugs. + * NFS: Fix an Oops in NFS unmount + * sdhci: describe quirks + * sdhci: don't warn about sdhci 2.0 controllers + * sdhci: use PIO when DMA can't satisfy the request + * sdhci: support JMicron JMB38x chips + * mmc: remove unused 'mode' from the mmc_host structure + * IB/ehca: Return correct number of SGEs for SRQ + * IB/ehca: Serialize HCA-related hCalls if necessary + * ide-scsi: add ide_scsi_hex_dump() helper + * ide: add missing checks for control register existence + * ide: deprecate CONFIG_BLK_DEV_OFFBOARD + * ide: fix ide_scan_pcibus() error message + * ide: coding style fixes for drivers/ide/setup-pci.c + * ide: add /sys/bus/ide/devices/*/{model,firmware,serial} sysfs entries + * ide: DMA reporting and validity checking fixes (take 3) + * ide-cd: remove dead post_transform_command() + * pdc202xx_new: fix Promise TX4 support + * hpt366: fix HPT37x PIO mode timings (take 2) + * ide: remove dead code from __ide_dma_test_irq() + * ide: remove stale changelog from ide-disk.c + * ide: remove stale changelog from ide-probe.c + * ide: fix ->io_32bit race in set_io_32bit() + * MAINTAINERS: update the NFS CLIENT entry + * V4L/DVB (6803): buf-core.c locking fixes + * [SPARC64]: Fix two kernel linear mapping setup bugs. + * IB/ehca: Fix lock flag variable location, bump version number + * kbuild: re-enable Makefile generation in a new O=... directory + * V4L/DVB (6798): saa7134: enable LNA in analog mode for Hauppauge WinTV + HVR-1110 + * V4L/DVB (6814): Makefile: always enter video/ + * V4L/DVB (6819): i2c: fix drivers/media/video/bt866.c + * V4L/DVB (6820): s5h1409: QAM SNR related fixes + * ACPI: video_device_list corruption + * ACPI: fix modpost warnings + * ACPI: thinkpad-acpi: fix lenovo keymap for brightness + * Pull thinkpad-2.6.24 into release branch + * Pull battery-2.6.24 into release branch + * [POWERPC] Fix typo #ifdef -> #ifndef + * [POWERPC] Kill non-existent symbols from ksyms and commproc.h + * [POWRPC] CPM2: Eliminate section mismatch warning in cpm2_reset(). + * [POWERPC] 82xx: mpc8272ads, pq2fads: Update defconfig with + CONFIG_FS_ENET_MDIO_FCC + * [POWERPC] iSeries: don't printk with HV spinlock held + * [POWERPC] Fix rounding bug in emulation for double float operating + * [POWERPC] Make PS3_SYS_MANAGER default y, not m + * [MIPS] time: Set up Cobalt's mips_hpt_frequency + * [MIPS] Alchemy: fix PCI resource conflict + * [MIPS] Alchemy: fix off by two error in __fixup_bigphys_addr() + * [MIPS] Atlas, Malta: Don't free firmware memory on free_initmem. + * [MIPS] PCI: Make pcibios_fixup_device_resources ignore legacy + resources. + * [MIPS] time: Delete weak definition of plat_time_init() due to gcc bug. + * [MIPS] Ensure that ST0_FR is never set on a 32 bit kernel + * [SPARC32]: Silence sparc32 warnings on missing syscalls. + * Pull hotplug into release branch + * ACPI: SBS: Reset alarm bit + * ACPI: SBS: Ignore alarms coming from unknown devices + * ACPI: SBS: Return rate in mW if capacity in mWh + * Pull bugzilla-9362 into release branch + * sky2: RX lockup fix + * sundance fixes + * starfire VLAN fix + * e100: free IRQ to remove warningwhenrebooting + * hamachi endianness fixes + * drivers/net/sis190.c section fix + * drivers/net/s2io.c section fixes + * ucc_geth: minor whitespace fix + * net: smc911x: shut up compiler warnings + * Net: ibm_newemac, remove SPIN_LOCK_UNLOCKED + * ixgb: make sure jumbos stay enabled after reset + * [NETFILTER]: ctnetlink: set expected bit for related conntracks + * [NETFILTER]: ip_tables: fix compat copy race + * [XFRM]: Display the audited SPI value in host byte order. + * [NETFILTER]: xt_hashlimit should use time_after_eq() + * [TIPC]: Fix semaphore handling. + * [SYNCPPP]: Endianness and 64bit fixes. + * [NETFILTER]: bridge: fix missing link layer headers on outgoing routed + packets + * [ATM]: Fix compiler warning noise with FORE200E driver + * [IPV4]: Updates to nfsroot documentation + * [BRIDGE]: Assign random address. + * [IPV6]: Fix the return value of ipv6_getsockopt + * [IPV4]: Make tcp_input_metrics() get minimum RTO via tcp_rto_min() + * [AX25]: Locking dependencies fix in ax25_disconnect(). + * [SCTP]: Flush fragment queue when exiting partial delivery. + * [IRDA]: Race between open and disconnect in irda-usb. + * [IRDA]: mcs7780 needs to free allocated rx buffer. + * [IRDA]: irlmp_unregister_link() needs to free lsaps. + * [IRDA]: stir4200 fixes. + * [IRDA]: irda parameters warning fixes. + * [S390] pud_present/pmd_present bug. + * [ARM] 4710/1: Fix coprocessor 14 usage for debug messages via ICEDCC + * [ARM] 4694/1: IXP4xx: Update clockevent support for shutdown and resume + * kobject: fix the documentation of how kobject_set_name works + * tipar: remove obsolete module + * HOWTO: Change man-page maintainer address for Japanese HOWTO + * Add Documentation for FAIR_USER_SCHED sysfs files + * HOWTO: change addresses of maintainer and lxr url for Korean HOWTO + * add stable_api_nonsense.txt in korean + * HOWTO: update misspelling and word incorrected + * PCI: Restore PCI expansion ROM P2P prefetch window creation + * USB: sierra: fix product id + * usb-storage: Fix devices that cannot handle 32k transfers + * USB: cp2101: new device id + * USB: option: Bind to the correct interface of the Huawei E220 + * usb.h: fix kernel-doc warning + * USB: fix locking loop by avoiding flush_scheduled_work + * USB: use IRQF_DISABLED for HCD interrupt handlers + * USB: at91_udc: correct hanging while disconnecting usb cable + * usb: Remove broken optimisation in OHCI IRQ handler + * USB: revert portions of "UNUSUAL_DEV: Sync up some reported devices + from Ubuntu" + * ocfs2: fix exit-while-locked bug in ocfs2_queue_orphans() + * ocfs2: Don't panic when truncating an empty extent + * ocfs2: Allow for debugging of transaction extends + * ocfs2: Re-journal buffers after transaction extend + * pcnet_cs: add new id + * ucc_geth: really fix section mismatch + * sis190 endianness + * libertas: add Dan Williams as maintainer + * zd1211rw: Fix alignment problems + * wireless/ipw2200.c: add __dev{init,exit} annotations + * ieee80211_rate: missed unlock + * iwlwifi3945/4965: fix rate control algo reference leak + * libertas: select WIRELESS_EXT + * bcm43xx_debugfs sscanf fix + * b43: Fix rfkill radio LED + * iwlwifi: fix rf_kill state inconsistent during suspend and resume + * sata_sil: fix spurious IRQ handling + * libata: clear link->eh_info.serror from ata_std_postreset() + * libata: add ST3160023AS / 3.42 to NCQ blacklist + * sata_mv: improve warnings about Highpoint RocketRAID 23xx cards + * libata-acpi: adjust constness in ata_acpi_gtm/stm() parameters + * libata: update ata_*_printk() macros such that level can be a variable + * libata: add more opcodes to ata.h + * libata: ata_dev_disable() should be called from EH context + * libata-acpi: add new hooks ata_acpi_dissociate() and + ata_acpi_on_disable() + * libata-acpi: implement and use ata_acpi_init_gtm() + * libata-acpi: implement dev->gtf_cache and evaluate _GTF right after + _STM during resume + * libata-acpi: improve ACPI disabling + * libata-acpi: improve _GTF execution error handling and reporting + * libata-acpi: implement _GTF command filtering + * libata: update atapi_eh_request_sense() such that lbam/lbah contains + buffer size + * libata: fix ATAPI draining + * fix headers_install + * revert "Hibernation: Use temporary page tables for kernel text mapping + on x86_64" + * uml: stop gdb from deleting breakpoints when running UML + * alpha: strncpy/strncat fixes + * rtc-at32ap700x: fix irq init oops + * parport: "dev->timeslice" is an unsigned long, not an int + * ecryptfs: initialize new auth_tokens before teardown + * Fix lguest documentation + * sparsemem: make SPARSEMEM_VMEMMAP selectable + * fs/Kconfig: grammar fix + * ext3, ext4: avoid divide by zero + * alpha: build fixes + * cpufreq: fix missing unlocks in cpufreq_add_dev error paths. + * mm/sparse.c: check the return value of sparse_index_alloc() + * mm/sparse.c: improve the error handling for sparse_add_one_section() + * pktcdvd: add kobject_put when kobject register fails + * drivers/macintosh/via-pmu.c: Added a missing iounmap + * drivers/cpufreq/cpufreq_stats.c section fix + * apm_event{,info}_t are userspace types + * mm: fix page allocation for larger I/O segments + * ecryptfs: set s_blocksize from lower fs in sb + * I/OAT: fixups from code comments + * I/OAT: fix null device in call to dev_err() + * fix bloat-o-meter for ppc64 + * ecryptfs: fix fsx data corruption problems + * Documentation: update hugetlb information + * Fix compilation warning in dquot.c + * SLUB: remove useless masking of GFP_ZERO + * quicklist: Set tlb->need_flush if pages are remaining in quicklist 0 + * sysctl: fix ax25 checks + * [XFS] Don't wait for pending I/Os when purging blocks beyond eof. + * [XFS] Put the correct offset in dirent d_off + * block: use jiffies conversion functions in scsi_ioctl.c + * as-iosched: fix incorrect comments + * as-iosched: fix write batch start point + * block: let elv_register() return void + * Cleanup umem driver: fix most checkpatch warnings, conform to kernel + * sched: fix crash on ia64, introduce task_current() + * sched: mark rwsem functions as __sched for wchan/profiling + * sched: sysctl, proc_dointvec_minmax() expects int values for + * sched: touch softlockup watchdog after idling + * sched: do not hurt SCHED_BATCH on wakeup + * oprofile: op_model_athlon.c support for AMD family 10h barcelona + performance counters + * clockevents: fix reprogramming decision in oneshot broadcast + * genirq: add unlocked version of set_irq_handler() + * timer: kernel/timer.c section fixes + * x86: jprobe bugfix + * x86: kprobes bugfix + * x86: also define AT_VECTOR_SIZE_ARCH + * genirq: revert lazy irq disable for simple irqs + * x86: fix "Kernel panic - not syncing: IO-APIC + timer doesn't work!" + * [SCSI] sym53c8xx: fix free_irq() regression + * [SCSI] dpt_i2o: driver is only 32 bit so don't set 64 bit DMA mask + * [SCSI] sym53c8xx: fix "irq X: nobody cared" regression + * [SCSI] initio: fix conflict when loading driver + * [SCSI] st: fix kernel BUG at include/linux/scatterlist.h:59! + * [SCSI] initio: bugfix for accessors patch + * IA64: Slim down __clear_bit_unlock + * [IA64] signal: remove redundant code in setup_sigcontext() + * [IA64] ia32 nopage + * [IA64] Avoid unnecessary TLB flushes when allocating memory + * [IA64] Two trivial spelling fixes + * [IA64] print kernel release in OOPS to make kerneloops.org happy + * [IA64] set_thread_area fails in IA32 chroot + * [IA64] Remove compiler warinings about uninitialized variable in + irq_ia64.c + * [IA64] Remove assembler warnings on head.S + * [IA64] Fix Altix BTE error return status + * [IA64] Guard elfcorehdr_addr with #if CONFIG_PROC_FS + * [IA64] make flush_tlb_kernel_range() an inline function + * [IA64] Adjust CMCI mask on CPU hotplug + * Do dirty page accounting when removing a page from the page cache + * x86 apic_32.c section fix + * x86 smpboot_32.c section fixes + * x86_32: select_idle_routine() must be __cpuinit + * x86_32: disable_pse must be __cpuinitdata + * x86: fix show cpuinfo cpu number always zero + * ps3fb: Update for firmware 2.10 + * ps3fb: Fix ps3fb free_irq() dev_id + * pata_hpt37x: Fix HPT374 detection + * mac80211: Drop out of associated state if link is lost + * mac80211: fix header ops + * NET: mac80211: fix inappropriate memory freeing + * [TG3]: Endianness annotations. + * [TG3]: Endianness bugfix. + * rtl8187: Add USB ID for Sitecom WL-168 v1 001 + * p54: add Kconfig description + * iwlwifi: fix possible priv->mutex deadlock during suspend + * ipw2200: prevent alloc of unspecified size on stack + * [IPV4] ARP: Remove not used code + * [IPSEC]: Avoid undefined shift operation when testing algorithm ID + * [XFRM]: Audit function arguments misordered + * [IPV4] ip_gre: set mac_header correctly in receive path + * [NET]: Correct two mistaken skb_reset_mac_header() conversions. + * [SPARC64]: Fix OOPS in dma_sync_*_for_device() + * sched: rt: account the cpu time during the tick + * debug: add end-of-oops marker + * mm: fix exit_mmap BUG() on a.out binary exit + * dm: table detect io beyond device + * dm mpath: hp requires scsi + * dm crypt: fix write endio + * dm: trigger change uevent on rename + * dm: merge max_hw_sector + * dm crypt: use bio_add_page + * [SPARC64]: Spelling fixes + * [SPARC32]: Spelling fixes + * [NET] include/net/: Spelling fixes + * [DCCP]: Spelling fixes + * [IRDA]: Spelling fixes + * [IPV6]: Spelling fixes + * [NET] net/core/: Spelling fixes + * [PKT_SCHED]: Spelling fixes + * [NETLABEL]: Spelling fixes + * [SCTP]: Spelling fixes + * [NETFILTER]: Spelling fixes + * [NETFILTER] ipv4: Spelling fixes + * [ATM]: Spelling fixes + * [NET]: Fix function put_cmsg() which may cause usr application memory + overflow + * x86: fix die() to not be preemptible + * x86: intel_cacheinfo.c: cpu cache info entry for Intel Tolapai + * [XFS] Fix mknod regression + * [XFS] Initialise current offset in xfs_file_readdir correctly + * Linux 2.6.24-rc6 + * [IPV4]: OOPS with NETLINK_FIB_LOOKUP netlink socket + * SLUB: Improve hackbench speed + * typhoon: endianness bug in tx/rx byte counters + * typhoon: missing le32_to_cpu() in get_drvinfo + * typhoon: set_settings broken on big-endian + * typhoon: missed rx overruns on big-endian + * typhoon: memory corruptor on big-endian if TSO is enabled + * typhoon: trivial endianness annotations + * cycx: annotations and fixes (.24 fodder?) + * asix fixes + * yellowfin: annotations and fixes (.24 fodder?) + * dl2k endianness fixes (.24 fodder?) + * r8169 endianness + * rrunner: use offsetof() instead of homegrown insanity + * 3c574 and 3c589 endianness fixes (.24?) + * fec_mpc52xx: write in C... + * 3c359 endianness annotations and fixes + * MACB: clear transmit buffers properly on transmit underrun + * UIO: Add a MAINTAINERS entry for Userspace I/O + * Modules: fix memory leak of module names + * USB: Unbreak fsl_usb2_udc + * USB: VID/PID update for sierra + * USB: New device ID for the CP2101 driver + * quicklists: do not release off node pages early + * ecryptfs: fix string overflow on long cipher names + * Fix computation of SKB size for quota messages + * Don't send quota messages repeatedly when hardlimit reached + * ecryptfs: fix unlocking in error paths + * ecryptfs: redo dget,mntget on dentry_open failure + * MAINTAINERS: mailing list archives are web links + * ps3: vuart: fix error path locking + * lib: proportion: fix underflow in prop_norm_percpu() + * pcmcia: remove pxa2xx_lubbock build warning + * kconfig: obey KCONFIG_ALLCONFIG choices with randconfig. + * tty: fix logic change introduced by wait_event_interruptible_timeout() + * uml: user of helper_wait() got missed when it got extra arguments + * V4L/DVB (6871): Kconfig: VIDEO_CX23885 must select DVB_LGDT330X + * V4L/DVB (6876): ivtv: mspx4xx needs a longer i2c udelay + * drivers/ide/: Spelling fixes + * ide-cd: fix SAMSUNG CD-ROM SCR-3231 quirk + * ide-cd: fix ACER/AOpen 24X CDROM speed reporting on big-endian machines + * ide-cd: use ide_cd_release() in ide_cd_probe() + * ide-cd: fix error messages in cdrom_{read,write}_check_ireason() + * ide-cd: add missing 'ireason' masking to cdrom_write_intr() + * ide-cd: fix error messages in cdrom_write_intr() + * ide-cd: add error message for DMA error to cdrom_read_intr() + * ide-cd: fix error message in cdrom_pc_intr() + * ide-cd: fix 'ireason' reporting in cdrom_pc_intr() + * MAINTAINERS: update ide-cd entry + * [SPARC64]: Implement pci_resource_to_user() + * mac80211: round station cleanup timer + * mac80211: warn when receiving frames with unaligned data + * [NETFILTER]: nf_conntrack_ipv4: fix module parameter compatibility + * [TUNTAP]: Fix wrong debug message. + * [NET] tc_nat: header install + * [VETH]: move veth.h to include/linux + * [IPV4]: Fix ip command line processing. + * Revert quicklist need->flush fix + * [CRYPTO] padlock: Fix spurious ECB page fault + * [POWERPC] Oprofile: Remove dependency on spufs module + * [POWERPC] PS3: Fix printing of os-area magic numbers + * [PCI] Do not enable CRS Software Visibility by default + * [IPV4] Fix ip=dhcp regression + * [SERIAL]: Fix section mismatches in Sun serial console drivers. + * [TCP]: use non-delayed ACK for congestion control RTT + * [BLUETOOTH]: put_device before device_del fix + + -- Tim Gardner Sat, 22 Dec 2007 15:16:11 -0700 + +linux (2.6.24-2.4) hardy; urgency=low + + [Alessio Igor Bogani] + + * rt: First import for Hardy + + [Amit Kucheria] + + * LPIA: Fix FTBFS for hda + * LPIA: Trim configs including disabling stock DRM + + [Tim Gardner] + + * SAUCE: Increase CONFIG_IDE_MAX_HWIFS to 8 (from 4) + - LP: #157909 + Then reverted since it causes an ABI bump. Will pick it up + again when next the ABI changes. + * Expose apm for applications. + + -- Tim Gardner Wed, 19 Dec 2007 13:17:31 -0700 + +linux (2.6.24-2.3) hardy; urgency=low + + [Amit Kucheria] + + * LPIA: Add thermal framework from Intel + * LPIA: Poulsbo-specific patches + * LPIA: Add thermal framework from Intel + + [Tim Gardner] + + * SAUCE: hdaps module does not load on Thinkpad T61P + - LP: #133636 + + [Upstream Kernel Changes] + + * Rebased against 2.6.24-rc5 + + -- Tim Gardner Wed, 12 Dec 2007 13:58:52 -0700 + +linux (2.6.24-1.2) hardy; urgency=low + + [Ben Collins] + + * cell: Remove cell custom flavour, merged upstream + * apparmor: Added module from SVN repo + * ubuntu: Update configs to enable apparmor + * ubuntu/configs: Disable vga type framebuffers on hppa32. Fixes FTBFS + + [Tim Gardner] + + * Add support for PPA builds. + + [Upstream Kernel Changes] + + * [SPARC64] Export symbols for sunvnet and sunvdc to be built modular + + -- Ben Collins Fri, 07 Dec 2007 15:18:32 -0500 + +linux (2.6.24-1.1) hardy; urgency=low + + [Ben Collins] + + * ubuntu: Disable custom binary flavours for now + * ubuntu: Remove cruft in headers-postinst + * ubuntu: Set skipabi/skipmodule to true if prev_revions == 0.0 + * ubuntu: Do not fail on missing module lists when skipmodule is set + * ubuntu: capability.ko is built-in now, no need to place in initrd. + * ubuntu: Change to "linux" instead of "linux-source-2.6.x" + * d-i: cdrom-modules disappeared, and sha256/aes modules renamed. + * ubuntu-build: Add asm_link= to arch rules, and use them + * config: Re-enable snd-hda-intel + + -- Ben Collins Wed, 28 Nov 2007 12:58:37 -0500 + +linux-source-2.6.22 (2.6.22-14.46) gutsy; urgency=low + + [Upstream Kernel Changes] + + * [SPARC64]: Fix bugs in SYSV IPC handling in 64-bit processes. + + -- Kyle McMartin Sun, 14 Oct 2007 20:30:09 +0000 + +linux-source-2.6.22 (2.6.22-14.45) gutsy; urgency=low + + [Upstream Kernel Changes] + + * [SPARC64]: Fix register usage in xor_raid_4(). + + -- Kyle McMartin Sun, 14 Oct 2007 12:34:44 -0400 + +linux-source-2.6.22 (2.6.22-14.44) gutsy; urgency=low + + [Kyle McMartin] + + * Revert "sparc wants ehci built in" + + [Upstream Kernel Changes] + + * Revert "[PATCH]: Gutsy OHCI hang workaround for Huron" + * [USB]: Serialize EHCI CF initialization. + + -- Kyle McMartin Sun, 14 Oct 2007 16:25:51 +0000 + +linux-source-2.6.22 (2.6.22-14.43) gutsy; urgency=low + + [Kyle McMartin] + + * sparc wants ehci built in + + -- Kyle McMartin Tue, 09 Oct 2007 20:07:58 +0000 + +linux-source-2.6.22 (2.6.22-14.42) gutsy; urgency=low + + [Kyle McMartin] + + * fix up module-check to bail early if asked to ignore modules + * disable kernel DRM on lpia (we provide one in lum) + - LP: #145168 + * add ignore for ia64 abi too + + [Upstream Kernel Changes] + + * [NIU]: Use netif_msg_*(). + * [NIU]: Use pr_info(). + * [NIU]: Remove redundant BUILD_BUG_ON() in __niu_wait_bits_clear(). + * [NIU]: Remove BUG_ON() NULL pointer checks. + * [NIU]: Use dev_err(). + * [NIU]: Fix x86_64 build failure. + * [NIU]: Use linux/io.h instead of asm/io.h + * [NIU]: Fix some checkpatch caught coding style issues. + * [NIU]: Fix shadowed local variables. + * [NIU]: Fix locking errors in link_status_10g(). + * [NIU]: Document a few magic constants using comments. + * [NIU]: MII phy handling fixes. + * [NIU]: Make sure link_up status is set to something in + link_status_{1,10}g(). + * [PATCH]: Gutsy OHCI hang workaround for Huron + + -- Kyle McMartin Tue, 09 Oct 2007 17:25:06 +0000 + +linux-source-2.6.22 (2.6.22-14.41) gutsy; urgency=low + + [Ben Collins] + + * ubuntu/d-i: Add niu to nic-modules + + [Kyle McMartin] + + * vesafb is not for ia64 + * remove CONFIG_NIU from places it shouldn't be + * fix orinoco_cs oops + - LP: #149997 + + [Upstream Kernel Changes] + + * [SPARC64]: Allow userspace to get at the machine description. + * [SPARC64]: Niagara-2 optimized copies. + * [SPARC64]: Do not touch %tick_cmpr on sun4v cpus. + * [SPARC64]: SMP trampoline needs to avoid %tick_cmpr on sun4v too. + * [SPARC64]: Create a HWCAP_SPARC_N2 and report it to userspace on + Niagara-2. + * [MATH-EMU]: Fix underflow exception reporting. + * [SPARC64]: Need to clobber global reg vars in switch_to(). + * [MATH]: Fix typo in FP_TRAPPING_EXCEPTIONS default setting. + * [SUNVDC]: Use slice 0xff on VD_DISK_TYPE_DISK. + * [SPARC64]: Fix type and constant sizes wrt. sun4u IMAP/ICLR handling. + * [SPARC64]: Enable MSI on sun4u Fire PCI-E controllers. + * [SPARC64]: Fix several bugs in MSI handling. + * [SPARC64]: Fix booting on V100 systems. + * [SPARC64]: Fix lockdep, particularly on SMP. + * [SPARC64]: Warn user if cpu is ignored. + * [SUNSAB]: Fix several bugs. + * [SUNSAB]: Fix broken SYSRQ. + * [SPARC64]: Fix missing load-twin usage in Niagara-1 memcpy. + * [SPARC64]: Don't use in/local regs for ldx/stx data in N1 memcpy. + * [SPARC64]: Fix domain-services port probing. + * [SPARC64]: VIO device addition log message level is too high. + * [SPARC64]: check fork_idle() error + * [SPARC64]: Fix 'niu' complex IRQ probing. + * [NIU]: Add Sun Neptune ethernet driver. + + -- Kyle McMartin Tue, 09 Oct 2007 00:38:16 +0000 + +linux-source-2.6.22 (2.6.22-13.40) gutsy; urgency=low + + [Amit Kucheria] + + * Enable CONFIG_VM86 for LPIA + - LP: #146311 + * Update configuration files + * Disable MSI by default + * Add mmconf documentation + * Update configuration files + + [Bartlomiej Zolnierkiewicz] + + * ide-disk: workaround for buggy HPA support on ST340823A (take 3) + - LP: #26119 + + [Ben Collins] + + * ubuntu/cell: Fixup ps3 related modules for d-i, enable RTAS console + * ubuntu/cell: Enable CELLEB and related modules (pata_scc) + * ubuntu/cell: Move ps3rom to storage-core. Also use spidernet, not + spider_net. + * ubuntu/cell: Set PS3_MANAGER=y + * ubuntu: Set NR_CPUS=256 for sparc64-smp + + [Chuck Short] + + * [USB] USB] Support for MediaTek MT6227 in cdc-acm. + - LP: #134123 + * [XEN] Fix xen vif create with more than 14 guests. + - LP: #14486 + + [Jorge Juan Chico] + + * ide: ST320413A has the same problem as ST340823A + - LP: #26119 + + [Kyle McMartin] + + * fix -rt build + * fix ia32entry-xen.S for CVE-2007-4573 + * fix build when CONFIG_PCI_MSI is not set + + [Matthew Garrett] + + * hostap: send events on data interface as well as master interface + - LP: #57146 + * A malformed _GTF object should not prevent ATA device recovery + - LP: #139079 + * hostap: send events on data interface as well as master interface + - LP: #57146 + * A malformed _GTF object should not prevent ATA device recovery + - LP: #139079 + * Don't lose appletouch button release events + * Fix build with appletouch change + * Disable Thinkpad backlight support on machines with ACPI video + - LP: #148055 + * Don't attempt to register a callback if there is no CMOS object + - LP: #145857 + * Update ACPI bay hotswap code to support locking + - LP: #148219 + * Update ACPI bay hotswap code to support locking + - LP: #148219 + * Don't attempt to register a callback if there is no CMOS object + - LP: #145857 + * Disable Thinkpad backlight support on machines with ACPI video + - LP: #148055 + + [Steffen Klassert] + + * 3c59x: fix duplex configuration + - LP: #94186 + + [Thomas Gleixner] + + * clockevents: remove the suspend/resume workaround^Wthinko + + [Tim Gardner] + + * orinoco_cs.ko missing + - LP: #125832 + * Marvell Technology ethernet card not recognized and not operational + - LP: #135316 + * Marvell Technology ethernet card not recognized and not operational + - LP: #135316 + * acpi_scan_rsdp() breaks some PCs by not honouring ACPI specification + - LP: #144336 + * VIA southbridge Intel id missing + - LP: #128289 + * Add T-Sinus 111card to hostap_cs driver to be able to upload firmware + - LP: #132466 + * RTL8111 PCI Express Gigabit driver r8169 big files produce slow file + transfer + - LP: #114171 + * Guest OS does not recognize a lun with non zero target id on Vmware ESX + Server + - LP: #140761 + * Modualrize vesafb + - LP: #139505 + * Nikon cameras need support in unusual_devs.h + - LP: #134477 + * agp for i830m broken in gutsy + - LP: #139767 + * hdaps: Added support for Thinkpad T61 + - LP: #147383 + * xen: Update config for i386 + - LP: #139047 + * xen: resync for amd64 + - LP: #139047 + * ide-disk: workaround for buggy HPA support on ST340823A (take 4) + - LP: #26119 + + [Upstream Kernel Changes] + + * Convert snd-page-alloc proc file to use seq_file (CVE-2007-4571) + * Linux 2.6.22.8 + * ACPI: disable lower idle C-states across suspend/resume + * V4L: ivtv: fix VIDIOC_S_FBUF: new OSD values were never set + * DVB: get_dvb_firmware: update script for new location of sp8870 + firmware + * DVB: get_dvb_firmware: update script for new location of tda10046 + firmware + * DVB: b2c2-flexcop: fix Airstar HD5000 tuning regression + * setpgid(child) fails if the child was forked by sub-thread + * sigqueue_free: fix the race with collect_signal() + * kconfig: oldconfig shall not set symbols if it does not need to + * MTD: Makefile fix for mtdsuper + * USB: fix linked list insertion bugfix for usb core + * ACPI: Validate XSDT, use RSDT if XSDT fails + * POWERPC: Flush registers to proper task context + * 3w-9xxx: Fix dma mask setting + * MTD: Initialise s_flags in get_sb_mtd_aux() + * JFFS2: fix write deadlock regression + * V4L: cx88: Avoid a NULL pointer dereference during mpeg_open() + * hwmon: End of I/O region off-by-one + * Fix debug regression in video/pwc + * splice: fix direct splice error handling + * rpc: fix garbage in printk in svc_tcp_accept() + * disable sys_timerfd() + * afs: mntput called before dput + * Fix DAC960 driver on machines which don't support 64-bit DMA + * Fix "Fix DAC960 driver on machines which don't support 64-bit DMA" + * firewire: fw-ohci: ignore failure of pci_set_power_state (fix suspend + regression) + * futex_compat: fix list traversal bugs + * Leases can be hidden by flocks + * ext34: ensure do_split leaves enough free space in both blocks + * nfs: fix oops re sysctls and V4 support + * dir_index: error out instead of BUG on corrupt dx dirs + * ieee1394: ohci1394: fix initialization if built non-modular + * Correctly close old nfsd/lockd sockets. + * Fix race with shared tag queue maps + * crypto: blkcipher_get_spot() handling of buffer at end of page + * fix realtek phy id in forcedeth + * Fix decnet device address listing. + * Fix device address listing for ipv4. + * Fix inet_diag OOPS. + * Fix IPV6 append OOPS. + * Fix IPSEC AH4 options handling + * Fix ipv6 double-sock-release with MSG_CONFIRM + * Fix IPV6 DAD handling + * Fix ipv6 source address handling. + * Fix oops in vlan and bridging code + * Fix tc_ematch kbuild + * Handle snd_una in tcp_cwnd_down() + * Fix TCP DSACK cwnd handling + * Fix datagram recvmsg NULL iov handling regression. + * Fix pktgen src_mac handling. + * Fix sparc64 v100 platform booting. + * bcm43xx: Fix cancellation of work queue crashes + * Linux 2.6.22.9 + * usb: serial/pl2303: support for BenQ Siemens Mobile Phone EF81 + * pata_it821x: fix lost interrupt with atapi devices + * i915: make vbl interrupts work properly on i965g/gm hw. + + -- Kyle McMartin Thu, 04 Oct 2007 13:57:53 +0000 + +linux-source-2.6.22 (2.6.22-12.39) gutsy; urgency=low + + [Ben Collins] + + * ubuntu: Re-order deps so that binary-custom is done before + binary-udebs. Fixes ppc build + + [Upstream Kernel Changes] + + * x86_64: Zero extend all registers after ptrace in 32bit entry path. + * Linux 2.6.22.7 + + -- Ben Collins Sun, 23 Sep 2007 11:05:32 -0400 + +linux-source-2.6.22 (2.6.22-12.38) gutsy; urgency=low + + [Kyle McMartin] + + * add -12 abi files + * update getabis for new flavours + + -- Kyle McMartin Fri, 21 Sep 2007 13:35:49 -0400 + +linux-source-2.6.22 (2.6.22-12.37) gutsy; urgency=low + + [Kyle McMartin] + + * enable d-i for cell flavour + * ignore ABI check on all hppa flavours + + -- Kyle McMartin Fri, 21 Sep 2007 11:28:34 -0400 + +linux-source-2.6.22 (2.6.22-12.36) gutsy; urgency=low + + [Ben Collins] + + * ABI bump due to LED support being enabled. + + [Kyle McMartin] + + * fix memory leak in psparse.c + - Bug introduced in previous commit to acpi + + [Upstream Kernel Changes] + + * Ubuntu: Allocate acpi_devices structure rather than leaving it on the + stack. + * ipw2100: Fix `iwpriv set_power` error + * Fix ipw2200 set wrong power parameter causing firmware error + * [SCSI] Fix async scanning double-add problems + - LP: #110997 + + -- Ben Collins Thu, 20 Sep 2007 11:34:52 -0400 + +linux-source-2.6.22 (2.6.22-11.34) gutsy; urgency=low + + [Alan Stern] + + * USB: disable autosuspend by default for non-hubs + - LP: #85488 + + [Ben Collins] + + * ubuntu: Enable LEDS_TRIGGERS and related options + - Needed for iwlwifi + * ubuntu: Add real ABI files for virtual flavour + * ubuntu: Re-enable missing CONFIG_SERPENT for hppa64 + - Noticed by Lamont + * ubuntu: Add linux-headers postinst to handle hooks + - LP: #125816 + * ubuntu: Add support for /etc/kernel/headers_postinst.d/ to + headers-postinst + - LP: #120049 + * cell: Add binary-custom flavour "cell" to support ps3 + + [Mattia Dongili] + + * sony-laptop: restore the last user requested brightness level on + resume. + - LP: #117331 + + [Tejun Heo] + + * ata_piix: fix suspend/resume for some TOSHIBA laptops + - LP: #139045 + * PCI: export __pci_reenable_device() + - needed for ata_piix change + + [Tim Gardner] + + * Enable Sierra Wireless MC8775 0x6813 + - LP: #131167 + + [Zhang Rui] + + * ACPI: work around duplicate name "VID" problem on T61 + - Noted by mjg59 + + -- Ben Collins Sun, 16 Sep 2007 22:31:47 -0400 + +linux-source-2.6.22 (2.6.22-11.33) gutsy; urgency=low + + [Alessio Igor Bogani] + + * rt: Update to rt9 + * rt: Update configuration files + + [Ben Collins] + + * ubuntu: Enable A100 driver + - LP: #138632 + * libata: Default to hpa being overridden + + [Chuck Short] + + * [HDAPS] Add support for Thinkpad R61. + * [LIBATA] Add more hard drives to blacklist. + * [USB] Added support for Sprint Pantech PX-500. + * [XEN] No really enable amd64. + * [XEN] Fix amd64 yet again. + + [Matthew Garrett] + + * alter default behaviour of ACPI video module + * Add infrastructure for notification on ACPI method execution + * Get thinkpad_acpi to send notifications on CMOS updates + * Add support to libata-acpi for acpi-based bay hotplug + + [Phillip Lougher] + + * Add kernel flavour optimised for virtualised environments + * Change abi-check script to check for $flavour.ignore in previous abi + * Disable abi and module check for virtual flavour + + [Richard Hughes] + + * Refresh laptop lid status on resume + + [Upstream Kernel Changes] + + * [pata_marvell]: Add more identifiers + + -- Ben Collins Sun, 16 Sep 2007 22:13:08 -0400 + +linux-source-2.6.22 (2.6.22-11.32) gutsy; urgency=low + + [Amit Kucheria] + + * Build system: Allow custom builds to comprise multiple patches + * Move UME to a Custom build and add first setup of thermal framework + + [Ben Collins] + + * ubuntu: Enable CONFIG_BLK_DEV_IO_TRACE + * bcm203x: Fix firmware loading + - LP: #85247 + * ubuntu: mtd changes caused module renaming. Ignore + * rt: Do not patch top level Makefile for SUBLEVEL. Will always end up + breaking + + [Chuck Short] + + * [USB] Unusual Device support for Gold MP3 Player Energy + - LP: #125250 + * [SIERRA] Adds support for Onda H600 ZTE MF330 + - LP: #129433 + * [HDAPS] Add Thinkpad T61P to whitelist. + - LP: #133636 + * [USB] Add support for Toshiba (Novatel Wireless) HSDPA for M400. + - LP: #133650 + + [Kyle McMartin] + + * apparmor 10.3 hooks + * unionfs 2.1 hooks + * nuke UNION_FS stuff from fs/{Kconfig,Makefile} + + [Tim Gardner] + + * Paravirt-ops I/O hypercalls + * Fix lazy vmalloc bug for Gutsy + * bluetooth headset patch + - LP: #130870 + * Add the PCI ID of this ICH4 in list of laptops that use short cables. + * v2.6.22.5 merge + * Update Xen config options. + - LP: #132726 + * Remove mtd modules from ABI + * Support parallel= in DEB_BUILD_OPTIONS + - LP: #136426 + + [Upstream Kernel Changes] + + * hwmon: fix w83781d temp sensor type setting + * hwmon: (smsc47m1) restore missing name attribute + * sky2: restore workarounds for lost interrupts + * sky2: carrier management + * sky2: check for more work before leaving NAPI + * sky2: check drop truncated packets + * revert "x86, serial: convert legacy COM ports to platform devices" + * ACPICA: Fixed possible corruption of global GPE list + * ACPICA: Clear reserved fields for incoming ACPI 1.0 FADTs + * AVR32: Fix atomic_add_unless() and atomic_sub_unless() + * r8169: avoid needless NAPI poll scheduling + * forcedeth: fix random hang in forcedeth driver when using netconsole + * libata: add ATI SB700 device IDs to AHCI driver + * Hibernation: do not try to mark invalid PFNs as nosave + * i386: allow debuggers to access the vsyscall page with compat vDSO + * x86_64: Check for .cfi_rel_offset in CFI probe + * x86_64: Change PMDS invocation to single macro + * i386: Handle P6s without performance counters in nmi watchdog + * i386: Fix double fault handler + * JFFS2 locking regression fix. + * [Input]: appletouch - improve powersaving for Geyser3 devices + * [Input]: add driver for Fujitsu serial touchscreens + * [sdhci]: add support to ENE-CB714 + * v2.6.22.5 + * [MTD] Makefile fix for mtdsuper + * ocfs2: Fix bad source start calculation during kernel writes + * NET: Share correct feature code between bridging and bonding + * sky2: don't clear phy power bits + * uml: fix previous request size limit fix + * i386: fix lazy mode vmalloc synchronization for paravirt + * signalfd: fix interaction with posix-timers + * signalfd: make it group-wide, fix posix-timers scheduling + * DCCP: Fix DCCP GFP_KERNEL allocation in atomic context + * IPV6: Fix kernel panic while send SCTP data with IP fragments + * IPv6: Invalid semicolon after if statement + * Fix soft-fp underflow handling. + * Netfilter: Missing Kbuild entry for netfilter + * SNAP: Fix SNAP protocol header accesses. + * NET: Fix missing rcu unlock in __sock_create() + * SPARC64: Fix sparc64 task stack traces. + * SPARC64: Fix sparc64 PCI config accesses on sun4u + * TCP: Do not autobind ports for TCP sockets + * TCP: Fix TCP rate-halving on bidirectional flows. + * TCP: Fix TCP handling of SACK in bidirectional flows. + * PPP: Fix PPP buffer sizing. + * PCI: lets kill the 'PCI hidden behind bridge' message + * PCI: disable MSI on RS690 + * PCI: disable MSI on RD580 + * PCI: disable MSI on RX790 + * USB: allow retry on descriptor fetch errors + * USB: fix DoS in pwc USB video driver + * usb: add PRODUCT, TYPE to usb-interface events + * Linux 2.6.22.6 + * V4L/DVB (6042): b2c2-flexcop: fix Airstar HD5000 tuning regression + * V4L/DVB (5967): ivtv: fix VIDIOC_S_FBUF:new OSD values where never set + * Re-add _GTM and _STM support + + -- Ben Collins Fri, 31 Aug 2007 16:26:56 -0400 + +linux-source-2.6.22 (2.6.22-10.30) gutsy; urgency=low + + * URGENT upload to fix FTBFS with xen-{i386,amd64} configs, + lpia d-i ftbfs, xen ftbfs. + * URGENT fix module-check to actually ignore things + * URGENT ignore ume modules + + [Alek Du] + + * Add Intel Poulsbo chipset Libata support + + [Amit Kucheria] + + * Update configuration files + * Enable stylus on Lenovo X60/X61 thinkpads + + [Ben Collins] + + * ubuntu: Disable snd-hda-intel, in favor of lum updated version + + [Kyle McMartin] + + * apparmor 10.3 hooks + * add lpia d-i udeb generation + * fix bits of rt/diff for -rt8 + * fix rt/diff for 2.6.22.3 changes + * fix up rt/diff for stable 2.6.22.4 + + [LaMont Jones] + + * Update configuration files + + [Phillip Lougher] + + * WriteSupportForNTFS: make fuse module available to d-i + + [Tim Gardner] + + * Gutsy Tribe 3 CD don't load on Dell Inspiron 1501 + - LP: #121111 + * Update configuration files + * Update configuration files + * Update configuration files + + [Upstream Kernel Changes] + + * [SPARC64]: Fix handling of multiple vdc-port nodes. + * [SPARC64]: Tweak assertions in sun4v_build_virq(). + * [SPARC64]: Fix log message type in vio_create_one(). + * [SPARC64]: Fix two year old bug in early bootup asm. + * [SPARC64]: Improve VIO device naming further. + * [SPARC64]: Handle multiple domain-services-port nodes properly. + * [SPARC64]: Add proper multicast support to VNET driver. + * [SPARC64]: Do not flood log with failed DS messages. + * [SPARC64]: Use KERN_ERR in IRQ manipulation error printks. + * [SPARC64]: Fix virq decomposition. + * [SPARC]: Fix serial console device detection. + * [SPARC64]: fix section mismatch warning in pci_sunv4 + * [SPARC64]: fix section mismatch warning in mdesc.c + * [SPARC64] viohs: extern on function definition + * [SPARC64]: Fix sun4u PCI config space accesses on sun4u. + * [SPARC64]: Fix show_stack() when stack argument is NULL. + * [SUNLANCE]: Fix sparc32 crashes by using of_*() interfaces. + * [SPARC]: Centralize find_in_proplist() instead of duplicating N times. + * [SPARC64]: Fix hard-coding of cpu type output in /proc/cpuinfo on + sun4v. + * [SPARC64]: Do not assume sun4v chips have load-twin/store-init support. + * [SPARC64]: Fix memory leak when cpu hotplugging. + * USB: cdc-acm: fix sysfs attribute registration bug + * TCP FRTO retransmit bug fix + * Fix TC deadlock. + * Fix IPCOMP crashes. + * Fix console write locking in sparc drivers. + * Add a PCI ID for santa rosa's PATA controller. + * Missing header include in ipt_iprange.h + * SCTP scope_id handling fix + * Fix rfkill IRQ flags. + * gen estimator timer unload race + * gen estimator deadlock fix + * Fix error queue socket lookup in ipv6 + * Fix ipv6 link down handling. + * Netpoll leak + * Sparc64 bootup assembler bug + * Fix ipv6 tunnel endianness bug. + * Fix sparc32 memset() + * Fix sparc32 udelay() rounding errors. + * Fix TCP IPV6 MD5 bug. + * KVM: SVM: Reliably detect if SVM was disabled by BIOS + * USB: fix warning caused by autosuspend counter going negative + * usb-serial: Fix edgeport regression on non-EPiC devices + * Fix reported task file values in sense data + * aacraid: fix security hole + * firewire: fw-sbp2: set correct maximum payload (fixes CardBus adapters) + * make timerfd return a u64 and fix the __put_user + * V4L: Add check for valid control ID to v4l2_ctrl_next + * V4L: ivtv: fix broken VBI output support + * V4L: ivtv: fix DMA timeout when capturing VBI + another stream + * V4L: ivtv: Add locking to ensure stream setup is atomic + * V4L: wm8775/wm8739: Fix memory leak when unloading module + * Input: lifebook - fix an oops on Panasonic CF-18 + * splice: fix double page unlock + * drm/i915: Fix i965 secured batchbuffer usage (CVE-2007-3851) + * Fix leak on /proc/lockdep_stats + * CPU online file permission + * Fix user struct leakage with locked IPC shem segment + * md: handle writes to broken raid10 arrays gracefully + * md: raid10: fix use-after-free of bio + * pcmcia: give socket time to power down + * Fix leaks on /proc/{*/sched, sched_debug, timer_list, timer_stats} + * futex: pass nr_wake2 to futex_wake_op + * "ext4_ext_put_in_cache" uses __u32 to receive physical block number + * Include serial_reg.h with userspace headers + * dm io: fix panic on large request + * i386: HPET, check if the counter works + * fw-ohci: fix "scheduling while atomic" + * firewire: fix memory leak of fw_request instances + * softmac: Fix ESSID problem + * eCryptfs: ecryptfs_setattr() bugfix + * nfsd: fix possible read-ahead cache and export table corruption + * readahead: MIN_RA_PAGES/MAX_RA_PAGES macros + * fs: 9p/conv.c error path fix + * forcedeth bug fix: cicada phy + * forcedeth bug fix: vitesse phy + * forcedeth bug fix: realtek phy + * acpi-cpufreq: Proper ReadModifyWrite of PERF_CTL MSR + * jbd commit: fix transaction dropping + * jbd2 commit: fix transaction dropping + * hugetlb: fix race in alloc_fresh_huge_page() + * do not limit locked memory when RLIMIT_MEMLOCK is RLIM_INFINITY + * uml: limit request size on COWed devices + * sony-laptop: fix bug in event handling + * destroy_workqueue() can livelock + * drivers/video/macmodes.c:mac_find_mode() mustn't be __devinit + * cfq-iosched: fix async queue behaviour + * libata: add FUJITSU MHV2080BH to NCQ blacklist + * ieee1394: revert "sbp2: enforce 32bit DMA mapping" + * nfsd: fix possible oops on re-insertion of rpcsec_gss modules + * dm raid1: fix status + * dm io: fix another panic on large request + * dm snapshot: permit invalid activation + * dm: disable barriers + * cr_backlight_probe() allocates too little storage for struct cr_panel + * ACPI: dock: fix opps after dock driver fails to initialize + * Hangup TTY before releasing rfcomm_dev + * Keep rfcomm_dev on the list until it is freed + * nf_conntrack: don't track locally generated special ICMP error + * IPV6: /proc/net/anycast6 unbalanced inet6_dev refcnt + * sysfs: release mutex when kmalloc() failed in sysfs_open_file(). + * Netfilter: Fix logging regression + * USB: fix for ftdi_sio quirk handling + * sx: switch subven and subid values + * UML: exports for hostfs + * Linux 2.6.22.2 + * fix oops in __audit_signal_info() + * random: fix bound check ordering (CVE-2007-3105) + * softmac: Fix deadlock of wx_set_essid with assoc work + * ata_piix: update map 10b for ich8m + * PPC: Revert "[POWERPC] Don't complain if size-cells == 0 in + prom_parse()" + * PPC: Revert "[POWERPC] Add 'mdio' to bus scan id list for platforms + with QE UEC" + * powerpc: Fix size check for hugetlbfs + * direct-io: fix error-path crashes + * stifb: detect cards in double buffer mode more reliably + * pata_atiixp: add SB700 PCI ID + * CPUFREQ: ondemand: fix tickless accounting and software coordination + bug + * CPUFREQ: ondemand: add a check to avoid negative load calculation + * Linux 2.6.22.3 + * intel_agp: really fix 945/965GME + * Reset current->pdeath_signal on SUID binary execution (CVE-2007-3848) + * MSS(mmc/sd/sdio) driver patch + + -- Kyle McMartin Thu, 16 Aug 2007 12:17:27 -0400 + +linux-source-2.6.22 (2.6.22-9.25) gutsy; urgency=low + + [Kyle McMartin] + + * ubuntu: Fix FTBFS -- forgot to bump debian/abi + + -- Kyle McMartin Thu, 02 Aug 2007 22:13:28 +0000 + +linux-source-2.6.22 (2.6.22-9.24) gutsy; urgency=low + + [Colin Watson] + + * provide Provides for fs-*-modules udebs + + [Matthias Klose] + + * test $dilist before using it + + [Lamont Jones] + + * hppa: Update abi files + + -- Kyle McMartin Thu, 02 Aug 2007 18:26:34 +0000 + +linux-source-2.6.22 (2.6.22-9.23) gutsy; urgency=low + + [Ben Collins] + + * ubuntu: Add missing newline to module-check script + * ubuntu: Add lpia to linux-libc-dev. Should finally build now. + + -- Ben Collins Thu, 02 Aug 2007 13:10:23 -0400 + +linux-source-2.6.22 (2.6.22-9.22) gutsy; urgency=low + + [Ben Collins] + + * ubuntu: Use DEB_HOST_ARCH, not DEB_HOST_ARCH_CPU + + -- Ben Collins Thu, 02 Aug 2007 08:44:09 -0400 + +linux-source-2.6.22 (2.6.22-9.21) gutsy; urgency=low + + [Ben Collins] + + * lpia: Add build stuff for lpia architecture + + [LaMont Jones] + + * abi files for hppa + * UBUNTU-HPPA: configs that seem to work + * hppa: abi files for 9.20 + + -- Ben Collins Wed, 01 Aug 2007 11:12:59 -0400 + +linux-source-2.6.22 (2.6.22-9.20) gutsy; urgency=low + + [Ben Collins] + + * tulip: Fix for Uli5261 chipsets. + * tulip: Define ULI PCI ID's + * tulip: Let dmfe handle davicom on non-sparc + * input: Allow root to inject unknown scan codes. + * irda: Default to dongle type 9 on IBM hardware + * input/mouse/alps: Do not call psmouse_reset() for alps + * pcmcia: Do not insert pcmcia cards on resume + * ide-cd: Disable verbose errors. + * block: Make CDROMEJECT more robust + * pm: Config option to disable handling of console during suspend/resume. + * version: Implement version_signature proc file. + * update toshiba_acpi to 0.19a-dev + * xpad: Update to latest version from xbox-linux. + * ubuntu: Enable setting of CONFIG_VERSION_SIGNATURE at build time + * toshiba_acpi: Don't use init_MUTEX_LOCKED + + [Chuck Short] + + * [USB]: add ASUS LCM to the blacklist + * [NET]: Add mcp73 to forcedeth. + * [USB]: Added support for Sanwa PC5000 multimeter usb cable (KB-USB2). + * [ATA] Add support for Sb700 AHCI nor-raid5 and raid5 + + [Fabio M. Di Nitto] + + * drivers/char/vt.c: make promcon driver init a boot option. + + [Kyle McMartin] + + * Disable MMCONFIG by default + + [Phillip Lougher] + + * fix NFS mounting regression from Edgy->Feisty + * r8169: disable TSO by default for RTL8111/8168B chipsets. + + [Tim Gardner] + + * Catch nonsense keycodes and silently ignore + * Cause SoftMac to emit an association event when setting ESSID. + + -- Ben Collins Mon, 30 Jul 2007 12:01:43 -0400 + +linux-source-2.6.22 (2.6.22-9.19) gutsy; urgency=low + + [Amit Kucheria] + + * Fix for FTBFS bug 123178 + * Fix for FTBFS bug 123178 + * Add devices to USB quirks to prevent USB autosuspend + * More devices added to USB quirks + - LP: #85488 + * Support for ENE CB-712/4 SD card reader + * Reorder quirk list based on Vendor/Product ID + + [Ben Collins] + + * ubuntu: Enable HOTPLUG_CPU in sparc64-smp config. + * ubuntu: Add xen to amd64 custom builds + * ubuntu: Update real-time kernel to -rt4 + * rt: Patch from Alessio Igor Bogani for RT-8 + + [Chuck Short] + + * IDE: add MHV2080BH to NCQ blacklist + * XEN: update to 2.6.22 final and amd64 support. + * NET: Add more pci-ids to zd1211rw + * IDE: add new PCI ID + * USB: fix oops in ftdi_sio + + [Eric Piel] + + * ACPI: Allow custom DSDT tables to be loaded from initramfs + + [Ryan Lortie] + + * Macbook calibration loop fix + - LP: #54621 + + [Upstream Kernel Changes] + + * NETFILTER: {ip, nf}_conntrack_sctp: fix remotely triggerable NULL ptr + dereference (CVE-2007-2876) + * Linux 2.6.22.1 + * [SPARC64]: Use KERN_ERR in sun4v IRQ printk()'s. + * [SPARC64]: Add LDOM virtual channel driver and VIO device layer. + * [SPARC64]: Add Sun LDOM virtual network driver. + * [SPARC64]: Add Sun LDOM virtual disk driver. + * [SPARC64]: Create proper obppath sysfs files for VIO bus devices. + * [SPARC64] LDC: Do limited polled retry on setting RX queue head. + * [SUNVNET]: Validate RX descriptor size field. + * [SPARC64]: Add missing symbol exports for LDOM infrastructure. + * [SPARC64]: Temporary workaround for LDC INO double-delivery. + * [SPARC64]: Create 'devspec' nodes for vio devices. + * [SPARC64]: vdev->type can be NULL, handle this in devspec_show(). + * [SPARC64]: Assorted LDC bug cures. + * [SPARC64]: Add domain-services nodes to VIO device tree. + * [SPARC64]: Export powerd facilities for external entities. + * [SPARC64]: Initial domain-services driver. + * [SPARC64]: Use more mearningful names for IRQ registry. + * [SPARC64]: Abstract out mdesc accesses for better MD update handling. + * [SPARC64]: Fix MD property lifetime bugs. + * [SPARC64]: Fix setting of variables in LDOM guest. + * [SPARC64]: Initial LDOM cpu hotplug support. + * [SPARC64]: Unconditionally register vio_bus_type. + * [SPARC64]: Fix build regressions added by dr-cpu changes. + * [SPARC64]: mdesc.c needs linux/mm.h + * [SPARC64]: SMP build fixes. + * [SPARC64]: More sensible udelay implementation. + * [SPARC64]: Process dr-cpu events in a kthread instead of workqueue. + * [SPARC64]: Add ->set_affinity IRQ handlers. + * [SPARC64]: Fix leak when DR added cpu does not bootup. + * [SPARC64]: Clear cpu_{core,sibling}_map[] in + smp_fill_in_sib_core_maps() + * [SPARC64]: Give more accurate errors in dr_cpu_configure(). + * [SERIAL]: Fix console write locking in sparc drivers. + * [TIMER]: Fix clockevent notifications on 64-bit. + * [SPARC64]: dr-cpu unconfigure support. + * [SPARC64]: Fix UP build. + * [SPARC64]: SMP build fix. + * [SPARC64]: Fix race between MD update and dr-cpu add. + * [SERIAL] SUNHV: Fix jerky console on LDOM guests. + * [SPARC64]: Kill explicit %gl register reference. + * [SPARC64]: Add basic infrastructure for MD add/remove notification. + * [SPARC64]: Simplify VDC device probing. + * [SPARC64]: Simplify VNET probing. + * [SPARC64]: Massively simplify VIO device layer and support hot + add/remove. + * [SPARC64]: Handle LDC resets properly in domain-services driver. + * [SPARC64]: Handle reset events in vio_link_state_change(). + * [SPARC64]: Fix reset handling in VNET driver. + * [SPARC64]: Set vio->desc_buf to NULL after freeing. + * [SPARC64]: Fix MODULE_DEVICE_TABLE() specification in VDC and VNET. + * [SPARC64]: Fix device type matching in VIO's devspec_show(). + * Add empty + * Add dummy isa_(bus|virt)_to_(virt|bus) inlines + * Clean up sti_flush + * Do not allow STI_CONSOLE to be modular + * Use compat_sys_getdents + + -- Ben Collins Sat, 28 Jul 2007 12:30:53 -0400 + +linux-source-2.6.22 (2.6.22-8.18) gutsy; urgency=low + + [Ben Collins] + + * ubuntu: *sigh* update xen config to fix FTBFS + + -- Ben Collins Thu, 12 Jul 2007 14:23:20 +0100 + +linux-source-2.6.22 (2.6.22-8.17) gutsy; urgency=low + + [Ben Collins] + + * ubuntu: Actually enable the -xen build. + + -- Ben Collins Thu, 12 Jul 2007 09:51:01 +0100 + +linux-source-2.6.22 (2.6.22-8.16) gutsy; urgency=low + + * Removed CONFIG_BLINK from all configs and added to modules.ignore + * This fixes a build failure for 8.15 + + [Alexey Starikovskiy] + + * Fix ACPI battery detection on Asus + + [Amit Kucheria] + + * Export symbols required to build GFS1 in LUM + * Update configuration files + * 2.6.22-7.14 ABI + * Remove old ABI + * Update d-i modules to support Sparc LDOM + * Introducing the UME kernel flavour + + [Jacob Pan] + + * Poulsbo SMBus Controller + * Intel Poulsbo SCH IDE Controller + * Intel Poulsbo HD audio controller + + [Phillip Lougher] + + * xen: Update custom binary flavour (Xen 3.1 for 2.6.22-rc5) + * xen: Update xen/config.i386 to enable PAE + + [Upstream Kernel Changes] + + * [SCSI] fusion: fix for BZ 8426 - massive slowdown on SCSI CD/DVD drive + * [XFS] Update the MAINTAINERS file entry for XFS. + * IB/mlx4: Fix handling of wq->tail for send completions + * IB/mlx4: Fix warning in rounding up queue sizes + * [SCSI] ESP: Don't forget to clear ESP_FLAG_RESETTING. + * firewire: fix hang after card ejection + * ieee1394: fix to ether1394_tx in ether1394.c + * [ARM] Add support for pause_on_oops and display preempt/smp options + * sh: Fix restartable syscall arg5 clobbering. + * ACPI: gracefully print null trip-point device + * ACPICA: fix error path in new external package objects as method + arguments + * sh: oops_enter()/oops_exit() in die(). + * [ARM] Update show_regs/oops register format + * IB/mlx4: Handle new FW requirement for send request prefetching + * IB/mlx4: Get rid of max_inline_data calculation + * IB/mlx4: Handle buffer wraparound in __mlx4_ib_cq_clean() + * IB/mlx4: Handle FW command interface rev 3 + * Fix signalfd interaction with thread-private signals + * sched: fix SysRq-N (normalize RT tasks) + * Fix possible runqueue lock starvation in wait_task_inactive() + * sh: Handle -ERESTART_RESTARTBLOCK for restartable syscalls. + * sh64: Handle -ERESTART_RESTARTBLOCK for restartable syscalls. + * [POWERPC] Fix snd-powermac refcounting bugs + * [XFS] s/memclear_highpage_flush/zero_user_page/ + * [XFS] Update the MAINTAINERS file entry for XFS - change git repo name. + * [XFRM]: Fix MTU calculation for non-ESP SAs + * [IPVS]: Fix state variable on failure to start ipvs threads + * [AF_RXRPC]: Return the number of bytes buffered in rxrpc_send_data() + * [S390] Missing blank when appending cio_ignore kernel parameter + * [S390] Fix zfcpdump header + * [S390] Fix yet another two section mismatches. + * [S390] Print list of modules on die(). + * [S390] Add oops_enter()/oops_exit() calls to die(). + * [S390] Move psw_set_key. + * [POWERPC] rheap - eliminates internal fragments caused by alignment + * [POWERPC] PowerPC: Prevent data exception in kernel space (32-bit) + * [POWERPC] Fix powermac late initcall to only run on powermac + * [MIPS] Don't drag a platform specific header into generic arch code. + * x86_64: Fix readahead/sync_file_range/fadvise64 compat calls + * x86_64: Fix eventd/timerfd syscalls + * x86: Disable DAC on VIA bridges + * x86_64: Quieten Atari keyboard warnings in Kconfig + * x86: Only make Macintosh drivers default on Macs + * x86: Disable KPROBES with DEBUG_RODATA for now + * x86: change_page_attr bandaids + * x86_64: fix link warning between for .text and .init.text + * Fix up CREDIT entry ordering + * firewire: Only set client->iso_context if allocation was successful. + * spidernet: null out skb pointer after its been used. + * spidernet: Cure RX ram full bug + * spidernet: Don't terminate the RX ring + * spidernet: silence the ramfull messages + * spidernet: turn off descriptor chain end interrupt. + * spidernet: checksum and ethtool + * bonding: Fix use after free in unregister path + * bonding: Fix 802.3ad no carrier on "no partner found" instance + * s390: print correct level for HiperSockets devices + * s390: qeth driver does not recover + * s390: avoid inconsistent lock state in qeth + * s390: qeth: wrong packet length in qdio header + * s390: Use ccw_device_get_id() in qeth/claw drivers + * s390: don't call iucv_path_connect from tasklet context + * s390: netiucv spinlock initializer cleanup + * s390: netiucv inlining cleanup + * forcedeth: use unicast receive mode for WoL + * natsemi irq flags + * cxgb3 - fix skb->dev dereference + * cxgb3 - fix netpoll hanlder + * cxgb3 - Fix direct XAUI support + * cxgb3 - Stop mac RX when changing MTU + * cxgb3 - MAC watchdog update + * PATA: Add the MCP73/77 support to PATA driver + * pata_it821x: (partially) fix DMA in RAID mode + * libata: more NONCQ devices + * kerneldoc fix in libata + * ahci: fix PORTS_IMPL override + * fix module_param mistake in it821x + * Blackfin arch: update ANOMALY handling + * Blackfin arch: update printk to use KERN_EMERG and reformat crash + output + * Blackfin arch: add missing braces around array bfin serial init + * Blackfin arch: match kernel startup messaage with new linker script + * Blackfin arch: move cond_syscall() behind __KERNEL__ like all other + architectures + * Blackfin arch: Add definition of dma_mapping_error + * Blackfin arch: add proper const volatile to addr argument to the read + functions + * [AGPGART] intel_agp: don't load if no IGD and AGP port + * IB/umem: Fix possible hang on process exit + * IPoIB/cm: Initialize RX before moving QP to RTR + * IPoIB/cm: Fix interoperability when MTU doesn't match + * IPoIB/cm: Remove dead definition of struct ipoib_cm_id + * IB/mlx4: Correct max_srq_wr returned from mlx4_ib_query_device() + * [PARISC] stop lcd driver from stripping initial whitespace + * [PARISC] Handle wrapping in expand_upwards() + * [PARISC] Fix unwinder on 64-bit kernels + * [PARISC] unwinder improvements + * page_mapping must avoid slub pages + * posix-timers: Prevent softirq starvation by small intervals and SIG_IGN + * Allow DEBUG_RODATA and KPROBES to co-exist + * [NETFILTER]: nf_conntrack_sip: add missing message types containing RTP + info + * [NETFILTER]: nfctnetlink: Don't allow to change helper + * [IPV6] NDISC: Fix thinko to control Router Preference support. + * [IPV4]: include sysctl.h from inetdevice.h + * i386: Make CMPXCHG64 only dependent on PAE + * x86_64: Fix only make Macintosh drivers default on Macs + * x86_64: Ignore compat mode SYSCALL when IA32_EMULATION is not defined + * [AVR32] Fix bug in invalidate_dcache_region() + * [AVR32] NGW100, Remove relics of the old USART mapping scheme + * [AVR32] Initialize dma_mask and dma_coherent_mask + * [AVR32] Update defconfigs + * ACPI: fix 2.6.20 SMP boot regression + * [SKBUFF]: Fix incorrect config #ifdef around skb_copy_secmark + * [TIPC]: Fix infinite loop in netlink handler + * [PPP]: Revert 606f585e363527da9feaed79465132c0c661fd9e + * [PPP]: Fix osize too small errors when decoding mppe. + * [TCP] tcp_read_sock: Allow recv_actor() return return negative error + value. + * [NET]: Re-enable irqs before pushing pending DMA requests + * [NET]: Make skb_seq_read unmap the last fragment + * hwmon/coretemp: fix a broken error path + * fix refcounting of nsproxy object when unshared + * console UTF-8 fixes (fix) + * SM501: suspend support + * SM501: initialise SDRAM clock before bus clocks + * SM501: Fix sm501_init_reg() mask/set order + * SM501: Clock updates and checks + * SM501: Add Documentation/SM501.txt + * SM501: Check SM501 ID register on initialisation + * SLUB: fix behavior if the text output of list_locations overflows + PAGE_SIZE + * sched: fix next_interval determination in idle_balance() + * update checkpatch.pl to version 0.05 + * alpha: fix alignment problem in csum_ipv6_magic() + * Char: stallion, fix oops during init with ISA cards + * uml: use generic BUG + * uml: add asm/paravirt.h + * "volatile considered harmful" + * document nlink function + * slab allocators: MAX_ORDER one off fix + * update checkpatch.pl to version 0.06 + * x86_64: fix misplaced `continue' in mce.c + * ext2: disallow setting xip on remount + * audit: fix oops removing watch if audit disabled + * ext3: lost brelse in ext3_read_inode() + * ext4: lost brelse in ext4_read_inode() + * ACPI: preserve the ebx value in acpi_copy_wakeup_routine + * FUTEX: Restore the dropped ERSCH fix + * Linus 2.6.22-rc6 + * [ARM] 4452/1: Force the literal pool dump before reloc_end + * [ARM] 4449/1: more entries in arch/arm/boot/.gitignore + * fix nmi_watchdog=2 bootup hang + * [POWERPC] Update g5_defconfig + * [POWERPC] Update defconfigs + * [POWERPC] Fix VDSO gettimeofday() when called with NULL struct timeval + * [POWERPC] Fix subtle FP state corruption bug in signal return on SMP + * USB: g_file_storage: call allow_signal() + * USB: ti serial driver sleeps with spinlock held + * USB: memory leak in iowarrior.c + * USB: usblcd doesn't limit memory consumption during write + * USB: fix race leading to use after free in io_edgeport + * USB: add new device id to option driver + * USB: ftdio_sio: New IPlus device ID + * [MIPS] __ucmpdi2 arguments are unsigned long long. + * [MIPS] add io_map_base to pci_controller on Cobalt + * [MIPS] remove "support for" from system type entry + * [MIPS] Alchemy: Fix wrong cast + * [MIPS] Fix pb1500 reg B access + * [MIPS] AP/SP requires shadow registers, auto enable support. + * [MIPS] 20K: Handle WAIT related bugs according to errata information + * [MIPS] use compat_siginfo in rt_sigframe_n32 + * [MIPS] Remove a duplicated local variable in test_and_clear_bit() + * [MIPS] EMMA2RH: Disable GEN_RTC, it can't possibly work. + * [MIPS] SMTC and non-SMTC kernel and modules are incompatible + * [MIPS] Count timer interrupts correctly. + * x86_64: set the irq_chip name for lapic + * x86_64 irq: use mask/unmask and proper locking in fixup_irqs() + * [SPARC64]: Add irqs to mdesc_node. + * [SPARC64]: Fix VIRQ enabling. + * [SPARC64]: Need to set state to IDLE during sun4v IRQ enable. + * [SPARC64]: Add LDOM virtual channel driver and VIO device layer. + * [SPARC64]: Add Sun LDOM virtual network driver. + * [SPARC64]: Add Sun LDOM virtual disk driver. + * [SPARC64]: Create proper obppath sysfs files for VIO bus devices. + * [SPARC64] LDC: Do limited polled retry on setting RX queue head. + * [GFS2] Fix gfs2_block_truncate_page err return + * [DLM] Telnet to port 21064 can stop all lockspaces + * [GFS2] inode size inconsistency + * [GFS2] remounting w/o acl option leaves acls enabled + * [GFS2] System won't suspend with GFS2 file system mounted + * [GFS2] git-gfs2-nmw-build-fix + * [GFS2] Obtaining no_formal_ino from directory entry + * [GFS2] Remove i_mode passing from NFS File Handle + * [SUNVNET]: Validate RX descriptor size field. + * [SPARC64]: Add missing symbol exports for LDOM infrastructure. + * [SPARC64]: Temporary workaround for LDC INO double-delivery. + * [SPARC64]: Create 'devspec' nodes for vio devices. + * [SPARC64]: vdev->type can be NULL, handle this in devspec_show(). + + -- Amit Kucheria Mon, 09 Jul 2007 12:55:56 +0300 + +linux-source-2.6.22 (2.6.22-7.14) gutsy; urgency=low + + [Ben Collins] + + * build/vars: Provide ivtv-modules + * Bump ABI + * ubuntu/config: Enable Intermediate Functional Block device + * coredump: Fix typo in patch merge + * ubuntu/scripts: Make sure to symlink *.lds for ia64 builds + * ubuntu/config: Enable NO_HZ for server and sparc64 targets. + * ubuntu/config: Remove bigiron target, see if anyone complains + * ubuntu: Ok, really remove bigiron + * ubuntu/control-scripts: Fo sho, remove the debconf stuff from controls + scripts + * AppArmor: Enable exports and changes for AppArmor usage + * ubuntu: Add feisty changelog for historical purposes. + + [Colin Watson] + + * Move isofs to storage-core-modules udeb from fs-core-modules. + + [Upstream Kernel Changes] + + * [MTD] [MAPS] don't force uclinux mtd map to be root dev + * [MTD] generalise the handling of MTD-specific superblocks + * [SCSI] zfcp: avoid clutter in erp_dbf + * [SCSI] zfcp: IO stall after deleting and path checker changes after + reenabling zfcp devices + * [SCSI] ipr: Proper return codes for eh_dev_reset for SATA devices + * [SCSI] stex: fix id mapping issue + * [SCSI] stex: extend hard reset wait time + * [SCSI] stex: fix reset recovery for console device + * [SCSI] stex: minor cleanup and version update + * [SCSI] MegaRAID: Update MAINTAINERS email-id + * [SCSI] tgt: fix a rdma indirect transfer error bug + * [SCSI] NCR53C9x: correct spelling mistake in deprecation notice + * [SCSI] aacraid: Correct sa platform support. (Was: [Bug 8469] Bad EIP + value on pentium3 SMP kernel-2.6.21.1) + * [SCSI] aacraid: fix panic on short Inquiry + * [WATCHDOG] ks8695_wdt.c - new KS8695 watchdog driver + * [JFFS2] Fix BUG() caused by failing to discard xattrs on deleted files. + * [JFFS2] Fix potential memory leak of dead xattrs on unmount. + * [SCSI] sd: fix refcounting regression in suspend/resume routines + * [SCSI] aacraid: apply commit config for reset_devices flag + * [SCSI] aic7xxx: fix aicasm build failure with gcc-3.4.6 + * [SCSI] aic94xx: asd_clear_nexus should fail if the cleared task does + not complete + * [SCSI] fusion: Fix |/|| confusion + * parisc: make command_line[] static + * parisc: sync compat getdents + * [PARISC] Move #undef to end of syscall table + * [PARISC] Wire up kexec_load syscall + * parisc: convert /proc/gsc/pcxl_dma to seq_file + * [PARISC] Let PA-8900 processors boot + * [PARISC] Disable LWS debugging + * [PARISC] spelling fixes: arch/parisc/ + * sh: section mismatch fixes for system timer. + * [PARISC] ROUND_UP macro cleanup in arch/parisc + * [PARISC] ROUNDUP macro cleanup in drivers/parisc + * [PPC] Fix COMMON symbol warnings + * [PPC] Remove duplicate export of __div64_32. + * [POWERPC] 52xx: unbreak lite5200 dts (_pic vs. -pic) + * [POWERPC] QE: fix Kconfig 'select' warning with UCC_FAST + * [POWERPC] Fix Section mismatch warnings + * [POWERPC] Fix modpost warning + * [PPC] Fix modpost warning + * [CIFS] Fix oops on failed cifs mount (in kthread_stop) + * [POWERPC] Fix Kconfig warning + * [CIFS] typo in previous patch + * [SCSI] megaraid_sas: intercept cmd timeout and throttle io + * [WATCHDOG] clean-up watchdog documentation + * drm: Spinlock initializer cleanup + * drm/radeon: add more IGP chipset pci ids + * drm: make sure the drawable code doesn't call malloc(0). + * [PARISC] kobject is embedded in subsys, not kset + * [PARISC] Build fixes for power.c + * [ARM] 4401/1: S3C2443: Add definitions for port GPIOJ + * [ARM] 4402/1: S3C2443: Add physical address of HSMMC controller + * [ARM] 4403/1: Make the PXA-I2C driver work with lockdep validator + * [ARM] 4404/1: Trivial IXP42x Kconfig cleanup + * [ARM] 4405/1: NSLU2, DSM-G600 frequency fixup code + * [ARM] 4406/1: Trivial NSLU2 / NAS-100D header & setup code cleanup + * [ARM] remove unused header file: arch/arm/mach-s3c2410/bast.h + * [PARISC] fix lasi_82596 build + * [PARISC] fix section mismatch in parport_gsc + * [PARISC] fix section mismatch in parisc STI video drivers + * [PARISC] fix section mismatch in ccio-dma + * [PARISC] fix section mismatches in arch/parisc/kernel + * [PARISC] fix section mismatch in parisc eisa driver + * [PARISC] fix section mismatch in superio serial drivers + * [PARISC] Wire up utimensat/signalfd/timerfd/eventfd syscalls + * hwmon/ds1621: Fix swapped temperature limits + * hwmon/coretemp: Add more safety checks + * hwmon/w83627hf: Be quiet when no chip is found + * hwmon-vid: Don't spam the logs when VRM version is missing + * hwmon/applesmc: Simplify dependencies + * hwmon/applesmc: Handle name file creation error and deletion + * ieee1394: sbp2: include workqueue.h + * ieee1394: eth1394: remove bogus netif_wake_queue + * ieee1394: eth1394: handle tlabel exhaustion + * ieee1394: eth1394: bring back a parent device + * ieee1394: raw1394: Fix async send + * firewire: Add missing byteswapping for receive DMA programs. + * firewire: prefix modules with firewire- instead of fw- + * firewire: fix return code + * [libata] Add drive to NCQ blacklist + * [ARM] enable arbitary speed tty ioctls and split input/output speed + * Input: db9 - do not ignore dev2 module parameter + * Input: logips2pp - fix typo in Kconfig + * [XFS] Write at EOF may not update filesize correctly. + * [SCSI] pluto: Use wait_for_completion_timeout. + * [SPARC64]: Kill unused DIE_PAGE_FAULT enum value. + * [SPARC64]: Don't be picky about virtual-dma values on sun4v. + * [SPARC32]: Removes mismatch section warnigs in sparc time.c file + * [SERIAL] sunzilog: section mismatch fix + * [SPARC64]: PCI device scan is way too verbose by default. + * [SCSI] jazz_esp: Converted to use esp_core. + * [SCSI] ESP: Kill SCSI_ESP_CORE and link directly just like jazz_esp + * [SPARC64]: Fix typo in sun4v_hvapi_register error handling. + * [SPARC64]: Report proper system soft state to the hypervisor. + * [SPARC64]: Negotiate hypervisor API for PCI services. + * [SPARC64]: Use machine description and OBP properly for cpu probing. + * [SPARC64]: Eliminate NR_CPUS limitations. + * [SPARC64]: arch/sparc64/time.c doesn't compile on Ultra 1 (no PCI) + * [SPARC]: Linux always started with 9600 8N1 + * [SPARC64]: Fix _PAGE_EXEC_4U check in sun4u I-TLB miss handler. + * [SPARC]: Emulate cmpxchg like parisc + * [SPARC]: Mark as emulating cmpxchg, add appropriate depends for DRM. + * [SPARC64]: Fix two bugs wrt. kernel 4MB TSB. + * [SPARC64]: Fill holes in hypervisor APIs and fix KTSB registry. + * mac80211: fail back to use associate from reassociate + * mac80211: fix memory leak when defrag fragments + * mac80211: always set carrier status on open + * mac80211: avoid null ptr deref in ieee80211_ibss_add_sta + * prism54: fix monitor mode oops + * ieee80211: fix incomplete error message + * softmac: alloc_ieee80211() NULL check + * hostap: Allocate enough tailroom for TKIP + * sparc64: fix alignment bug in linker definition script + * USB: replace flush_workqueue with cancel_sync_work + * ACPICA: allow Load(OEMx) tables + * ACPI: thermal: Replace pointer with name in trip_points + * ACPI: extend "acpi_osi=" boot option + * IB/mthca: Fix handling of send CQE with error for QPs connected to SRQ + * IPoIB/cm: Fix performance regression on Mellanox + * IB/cm: Fix stale connection detection + * IB/mlx4: Fix last allocated object tracking in bitmap allocator + * NOHZ: prevent multiplication overflow - stop timer for huge timeouts + * random: fix error in entropy extraction + * random: fix seeding with zero entropy + * ACPI: Make _OSI(Linux) a special case + * ACPI: add __init to acpi_initialize_subsystem() + * [PARISC] fix "ENTRY" macro redefinition + * [PARISC] fix section mismatch in smp.c + * [PARISC] remove remnants of parisc-specific softirq code + * [PARISC] fix trivial spelling nit in asm/linkage.h + * [PARISC] fix null ptr deref in unwind.c + * [PARISC] fix "reduce size of task_struct on 64-bit machines" fallout + * [PARISC] be more defensive in process.c::get_wchan + * [ARM] use __used attribute + * [ARM] Fix stacktrace FP range checking + * [ARM] oprofile: avoid lockdep warnings on mpcore oprofile init + * [ARM] 4411/1: KS8695: Another serial driver fix + * [ARM] 4412/1: S3C2412: reset errata fix + * [ARM] 4414/1: S3C2443: sparse fix for clock.c + * [ARM] 4415/1: AML5900: fix sparse warnings from map_io + * [ARM] 4416/1: NWFPE: fix undeclared symbols + * [ARM] 4410/1: Remove extern declarations in coyote/ixdpg425-pci.c + * [ARM] 4394/1: ARMv7: Add the TLB range operations + * [ARM] 4417/1: Serial: Fix AMBA drivers locking + * sky2: dont set bogus bit in PHY register + * sky2: checksum offload plus vlan bug + * sky2: program proper register for fiber PHY + * defxx: Fix the handling of ioremap() failures + * e1000: restore netif_poll_enable call but make sure IRQs are off + * sky2: enable IRQ on duplex renegotiation + * ehea: Fixed multi queue RX bug + * [SCSI] fix CONFIG_SCSI_WAIT_SCAN=m + * [SCSI] qla2xxx: fix timeout in qla2x00_down_timeout + * [ARM] Fix some section mismatch warnings + * alpha: cleanup in bitops.h + * alpha: support new syscalls + * fix possible null ptr deref in kallsyms_lookup + * NFS: Fix a refcount leakage in O_DIRECT + * a bug in ramfs_nommu_resize function, passing old size to vmtruncate + * sh: Fix pcrel too far for in_nmi label. + * sh: Trivial fix for dma-api compile failure. + * sh: Fix vsyscall build failure. + * sh: trivial build cleanups. + * sh: support older gcc's + * [ALSA] HDA: Add support for Gateway NX860 + * [ALSA] HDA: Add more systems to Sigmatel codec + * [ALSA] HDA: Fix headphone mute issue on non-eapd Conexant systems + * [ALSA] hda-codec - Add support for ASUS A8J modem + * [ALSA] ali5451 - Fix possible NULL dereference + * [ALSA] hda-intel: fix ASUS M2V detection + * [ALSA] Fix ASoC s3c24xx-pcm spinlock bug + * [ALSA] hda-codec - Add quirk for MSI S420 + * [ALSA] hda-codec - Add quirk for Supermicro PDSBA to alc883_cfg_tbl[] + * [ALSA] hda-codec - Add support for MSI K9N Ultra + * [ALSA] hda-codec - Fix pin configs for Gateway MX6453 + * [ALSA] hda-codec - Fix input with STAC92xx + * [ALSA] hda-codec - Fix STAC922x capture boost level + * [CRYPTO] cryptd: Fix problem with cryptd and the freezer + * [CASSINI]: Fix printk message typo. + * [XFRM]: Allow XFRM_ACQ_EXPIRES to be tunable via sysctl. + * [XFRM]: xfrm_larval_drop sysctl should be __read_mostly. + * [IPSEC]: Fix IPv6 AH calculation in outbound + * [IPV6] ROUTE: No longer handle ::/0 specially. + * [NET]: parse ip:port strings correctly in in4_pton + * [IPSEC]: Fix panic when using inter address familiy IPsec on loopback. + * [IPV4]: Kill references to bogus non-existent CONFIG_IP_NOSIOCRT + * [AF_PACKET]: Kill bogus CONFIG_PACKET_MULTICAST + * [IPV6]: Fix build warning. + * [AF_PACKET]: Kill CONFIG_PACKET_SOCKET. + * [SOCK]: Shrink struct sock by 8 bytes on 64-bit. + * [TCP]: Consolidate checking for tcp orphan count being too big. + * [NET] napi: Call __netif_rx_complete in netif_rx_complete + * [IPV6] ADDRCONF: Fix conflicts in DEVCONF_xxx constant. + * [TCP] tcp_probe: a trivial fix for mismatched number of printl + arguments. + * [TCP] tcp_probe: use GCC printf attribute + * [BRIDGE]: Reduce frequency of forwarding cleanup timer in bridge. + * [BRIDGE]: Round off STP perodic timers. + * [IPSEC]: Add xfrm_sysctl.txt. + * [SPARC64]: Add missing NCS and SVC hypervisor interfaces. + * [SPARC32]: Build fix. + * [SPARC]: Missing #include in drivers/sbus/char/flash.c + * [ALSA] version 1.0.14 + * neofb: Fix pseudo_palette array overrun in neofb_setcolreg + * smpboot: fix cachesize comparison in smp_tune_scheduling() + * at91: fix enable/disable_irq_wake symmetry in pcmcia driver + * SLUB: More documentation + * pci-quirks: fix MSI disabling on RS400-200 and RS480 + * ntfs_init_locked_inode(): fix array indexing + * m68k: runtime patching infrastructure + * SLUB: Fix NUMA / SYSFS bootstrap issue + * afs: needs sched.h + * m68k: discontinuous memory support + * [S390] Add exception handler for diagnose 224 + * [S390] dasd_eer: use mutex instead of semaphore + * [S390] arch/s390/kernel/debug.c: use mutex instead of semaphore + * [S390] raw3270: use mutex instead of semaphore + * [S390] Fix section annotations. + * [S390] cio: Use device_schedule_callback() for removing disconnected + devices. + * [S390] cio: deregister ccw device when pgid disband failed + * ACPI: thinkpad-acpi: do not use named sysfs groups + * ieee1394: fix calculation of sysfs attribute "address" + * ieee1394: sbp2: offer SAM-conforming target port ID in sysfs + * firewire: fw-sbp2: implement sysfs ieee1394_id + * firewire: add to MAINTAINERS + * firewire: Implement suspend/resume PCI driver hooks. + * firewire: Change struct fw_cdev_iso_packet to not use bitfields. + * firewire: Install firewire-constants.h and firewire-cdev.h for + userspace. + * EXT4: Fix whitespace + * Remove unnecessary exported symbols. + * ext4: Extent overlap bugfix + * When ext4_ext_insert_extent() fails to insert new blocks + * Define/reserve new ext4 superblock fields + * msi: fix ARM compile + * PCI: disable MSI by default on systems with Serverworks HT1000 chips + * PCI: Fix pci_find_present + * PCI: i386: fixup for Siemens Nixdorf AG FSC Multiprocessor Interrupt + Controllers + * PCI: quirk disable MSI on via vt3351 + * [XTENSA] fix bit operations in bitops.h + * [XTENSA] Spelling fixes in arch/xtensa + * [XTENSA] fix sources using deprecated assembler directive + * [XTENSA] Remove multi-exported symbols from xtensa_ksyms.c + * [XTENSA] Use generic 64-bit division + * [XTENSA] clean-up header files + * [XTENSA] Move common sections into bss sections + * [XTENSA] Remove non-rt signal handling + * Xtensa: use asm-generic/fcntl.h + * [JFFS2] Fix buffer length calculations in jffs2_get_inode_nodes() + * Fix vmi.c compilation + * x86_64: allocate sparsemem memmap above 4G + * Add select PHYLIB to the UCC_GETH Kconfig option + * Fix possible UDF data corruption + * m68k: parenthesis balance + * msi: fix the ordering of msix irqs + * msi: mask the msix vector before we unmap it + * potential parse error in ifdef + * parse errors in ifdefs + * pci_ids: update patch for Intel ICH9M + * x86: fix oprofile double free + * Work around Dell E520 BIOS reboot bug + * fix compat futex code for private futexes + * skeletonfb: fix of xxxfb_setup ifdef + * vt8623fb: arkfb: null pointer dereference fix + * cfag12864bfb: Use sys_ instead of cfb_ framebuffer accessors + * fbdev: Move declaration of fb_class to + * misc/tifm_7xx1: replace deprecated irq flag + * add a trivial patch style checker + * Documentation: How to use GDB to decode OOPSes + * RTC: use fallback IRQ if PNP tables don't provide one + * memory hotplug: fix unnecessary calling of init_currenty_empty_zone() + * tty: fix leakage of -ERESTARTSYS to userland + * ISDN4Linux: fix maturity label + * Fix broken CLIR in isdn driver + * prism54: MAINTAINERS update + * atmel_spi dma address bugfix + * h8300 trival patches + * ALPHA: support graphics on non-zero PCI domains + * ALPHA: correct low-level I/O routines for sable-lynx + * ALPHA: misc fixes + * Better documentation for ERESTARTSYS + * serial_core.h: include + * SPI: Freescale iMX SPI controller driver fixes + * SLUB: fix locking for hotplug callbacks + * pm3fb: switching between X and fb fix + * microcode: fix section mismatch warning + * isdn: fix section mismatch warnings + * acpi: fix section mismatch warning in asus + toshiba + * kvm: fix section mismatch warning in kvm-intel.o + * net/hp100: fix section mismatch warning + * timer statistics: fix race + * timer stats: speedups + * [SCSI] aacraid: fix shutdown handler to also disable interrupts. + * [MTD] Fix error checking after get_mtd_device() in get_sb_mtd functions + * [JFFS2] Fix obsoletion of metadata nodes in jffs2_add_tn_to_tree() + * ACPI: Section mismatch ... acpi_map_pxm_to_node + * ACPICA: Support for external package objects as method arguments + * Pull now into release branch + * Pull osi-now into release branch + * [POWERPC] Update documentation for of_find_node_by_type() + * [POWERPC] Fix ppc32 single-stepping out of syscalls + * [POWERPC] Fix compiler/assembler flags for Ebony platform boot files + * [POWERPC] Fix possible access to free pages + * [POWERPC] ps3/interrupt.c uses get_hard_smp_processor_id + * [POWERPC] pasemi idle uses hard_smp_processor_id + * [POWERPC] Create a zImage for legacy iSeries + * [POWERPC] Don't use HOSTCFLAGS in BOOTCFLAGS + * [POWERPC] Fix compile warning in pseries xics code + * [POWERPC] Fix return from pte_alloc_one() in out-of-memory case + * [POWERPC] Compare irq numbers with NO_IRQ not IRQ_NONE + * [POWERPC] Don't allow PMAC_APM_EMU for 64-bit + * [POWERPC] Fix compile breakage for IBM/AMCC 4xx arch/ppc platforms + * [POWERPC] Fix zImage.coff generation for 32-bit pmac + * [ARM] 4392/2: Do not corrupt the SP register in compressed/head.S + * [ARM] 4418/1: AT91: Number of programmable clocks differs + * [ARM] 4419/1: AT91: SAM9 USB clocks check for suspending + * [ARM] 4422/1: Fix default value handling in gpio_direction_output (PXA) + * [ARM] Solve buggy smp_processor_id() usage + * qla3xxx: device doesnt do hardware checksumming. + * VLAN: kill_vid is only useful for VLAN filtering devices + * sky2: Fix VLAN unregistration + * 8139cp: fix VLAN unregistration + * atl1: eliminate unneeded kill_vid code + * network drivers: eliminate unneeded kill_vid code + * e1000: disable polling before registering netdevice + * smc91x: sh solution engine fixes. + * Update tulip maintainer email address + * NetXen: Removal of extra free_irq call + * myri10ge: report link up/down in standard ethtool way + * NET: add MAINTAINERS entry for ucc_geth driver + * [ARM] 4421/1: AT91: Value of _KEY fields. + * [PARISC] Fix bug when syscall nr is __NR_Linux_syscalls + * [AF_UNIX]: Make socket locking much less confusing. + * [TG3]: Fix link problem on Dell's onboard 5906. + * [AF_UNIX]: Fix datagram connect race causing an OOPS. + * [TCP]: Use default 32768-61000 outgoing port range in all cases. + * [ATM]: Fix warning. + * [NET]: Make net watchdog timers 1 sec jiffy aligned. + * [NET]: Fix comparisons of unsigned < 0. + * [TCP]: Fix GSO ignorance of pkts_acked arg (cong.cntrl modules) + * [NET] gso: Fix GSO feature mask in sk_setup_caps + * [IPV4]: Fix "ipOutNoRoutes" counter error for TCP and UDP + * [ICMP]: Fix icmp_errors_use_inbound_ifaddr sysctl + * [VIDEO]: XVR500 and XVR2500 require FB=y + * [ATA]: Don't allow to enable this for SPARC64 without PCI. + * sh: Fix in_nmi symbol build error. + * sh: microdev: Fix compile warnings. + * sh: Fix SH4-202 clock fwk set_rate() mismatch. + * sh: voyagergx: Fix build warnings. + * sh: ioremap() through PMB needs asm/mmu.h. + * sh: Fix se73180 platform device registration. + * Input: ucb1x00 - do not access input_dev->private directly + * Input: reduce raciness when input handlers disconnect + * [PARISC] Fix kernel panic in check_ivt + * [SCSI] atari_NCR5380: update_timeout removal + * [SCSI] JAZZ ESP and SUN ESP need SPI_ATTRS + * [CIFS] fix mempool destroy done in wrong order in cifs error path + * SPI dynamic busid generation bugfix + * mtrr atomicity fix + * vanishing ioctl handler debugging + * libata: always use polling SETXFER + * Linux 2.6.22-rc4 + * [SPARC64]: Move topology init code into new file, sysfs.c + * [SPARC64]: Export basic cpu properties via sysfs. + * [SPARC64]: Fix service channel hypervisor function names. + * [SPARC64]: Provide mmu statistics via sysfs. + * [SPARC64]: Proper multi-core scheduling support. + * [SPARC64]: Make core and sibling groups equal on UltraSPARC-IV. + * [SPARC64]: Fix {mc,smt}_capable(). + * [SPARC64]: Fill in gaps in non-PCI dma_*() NOP implementation. + * [ATA]: Back out bogus (SPARC64 && !PCI) Kconfig depends. + * [VIDEO]: Fix section mismatch warning in promcon. + * [CIFS] whitespace cleanup + * [ARM] Fix 4417/1: Serial: Fix AMBA drivers locking + * [VIDEO] ffb: The pseudo_palette is only 16 elements long + * [ARM] pxa: fix pxa27x keyboard driver + * [VIDEO] sunxvr2500fb: Fix pseudo_palette array size + * [VIDEO] sunxvr500fb: Fix pseudo_palette array size + * [CIFS] whitespace cleanup part 2 + * [CIFS] Missing flag on negprot needed for some servers to force packet + signing + * [MIPS] Atlas, Malta, SEAD: Remove scroll from interrupt handler. + * [MIPS] Remove duplicate fpu enable hazard code. + * [MIPS] EMMA2RH: remove dead KGDB code + * [MIPS] RM300: Fix MMIO problems by marking the PCI INT ACK region busy + * [MIPS] Fix VGA corruption on RM300C + * [MIPS] Drop __ARCH_WANT_SYS_FADVISE64 + * [MIPS] Make dma_map_sg handle sg elements which are longer than one + page + * [MIPS] Fix some system calls with long long arguments + * [MIPS] Remove prototype for deleted function qemu_handle_int + * [MIPS] Fix some minor typoes in arch/mips/Kconfig. + * [MIPS] Fix warning by moving do_default_vi into CONFIG_CPU_MIPSR2_SRS + * [AGPGART] intel_agp: cleanup intel private data + * [AGPGART] intel_agp: use table for device probe + * [AGPGART] intel_agp: add support for 965GME/GLE + * [AGPGART] intel_agp: add support for 945GME + * [AGPGART] intel_agp: Add support for G33, Q33 and Q35 chipsets + * ocfs2: Fix masklog breakage + * ocfs2: Fix invalid assertion during write on 64k pages + * [POWERPC] pasemi: Fix iommu + 64K PAGE_SIZE bug + * [POWERPC] spufs: Refuse to load the module when not running on cell + * [POWERPC] spufs: Hook up spufs_release_mem + * [POWERPC] spufs: Fix gang destroy leaks + * [POWERPC] spufs: Free mm if spufs_fill_dir() failed + * [POWERPC] spufs: Synchronize pte invalidation vs ps close + * [POWERPC] spufs scheduler: Fix wakeup races + * [POWERPC] Fix pci_setup_phb_io_dynamic for pci_iomap + * [POWERPC] cbe_cpufreq: Limit frequency via cpufreq notifier chain + * [POWERPC] scc_sio: Fix link failure + * [POWERPC] Fix typo in booting-without-of-txt section numbering + * [POWERPC] spufs: Don't yield nosched context + * [POWERPC] Add table of contents to booting-without-of.txt + * [POWERPC] spufs: Fix error handling in spufs_fill_dir() + * mmc-atmel: remove linux/mmc/protocol.h dependencies + * au1xmmc: Replace C code with call to ARRAY_SIZE() macro. + * mmc: fix broken if clause + * mmc: don't call switch on old cards + * [POWERPC] Fix building of COFF zImages + * checkpatch.pl: should be executable + * Restrict clearing TIF_SIGPENDING + * mlx4_core: Fix CQ context layout + * mlx4_core: Initialize ctx_list and ctx_lock earlier + * mlx4_core: Free catastrophic error MSI-X interrupt with correct dev_id + * IB/mthca, mlx4_core: Fix typo in comment + * [BNX2]: Fix netdev watchdog on 5708. + * [BNX2]: Add missing wait in bnx2_init_5709_context(). + * [BNX2]: Enable DMA on 5709. + * [BNX2]: Fix occasional counter corruption on 5708. + * [BNX2]: Update version and reldate. + * [TCP]: Honour sk_bound_dev_if in tcp_v4_send_ack + * [IPV4]: Only panic if inetdev_init fails for loopback + * [IPV4]: Convert IPv4 devconf to an array + * [IPV4]: Add default config support after inetdev_init + * [IPV4]: Restore old behaviour of default config values + * [RFKILL]: Make rfkill->name const + * [TCP]: Use LIMIT_NETDEBUG in tcp_retransmit_timer(). + * [TCP] tcp_probe: Attach printf attribute properly to printl(). + * [NETLINK]: Mark netlink policies const + * [RTNETLINK]: ifindex 0 does not exist + * [NETFILTER]: nf_conntrack: fix helper module unload races + * [NETFILTER]: ip_tables: fix compat related crash + * [NETFILTER]: nf_conntrack_amanda: fix textsearch_prepare() error check + * [AF_UNIX]: Fix stream recvmsg() race. + * [UDP]: Revert 2-pass hashing changes. + * [NET]: Avoid duplicate netlink notification when changing link state + * [NET_SCHED]: Fix filter double free + * xfrm: Add security check before flushing SAD/SPD + * [SPARC64]: Fix 2 bugs in PCI Sabre bus scanning. + * [SPARC64]: Fix SBUS IRQ regression caused by PCI-E driver. + * frv: build fix + * enable interrupts in user path of page fault. + * RAMFS NOMMU: missed POSIX UID/GID inode attribute checking + * [SPARC64]: Include instead of . + * [SPARC64]: Handle PCI bridges without 'ranges' property. + * mlx4_core: Check firmware command interface revision + * mlx4_core: Don't set MTT address in dMPT entries with PA set + * IB/mlx4: Fix zeroing of rnr_retry value in ib_modify_qp() + * RDMA/cma: Fix initialization of next_port + * IB/mlx4: Make sure RQ allocation is always valid + * splice: move inode size check into generic_file_splice_read() + * splice: remove do_splice_direct() symbol export + * pipe: move pipe_inode_info structure decleration up before it's used + * splice: move balance_dirty_pages_ratelimited() outside of splice actor + * splice: __generic_file_splice_read: fix i_size_read() length checks + * splice: __generic_file_splice_read: fix read/truncate race + * V4L/DVB (5702): Fix Kconfig items to avoid linkedition errors + * V4L/DVB (5700): Saa7111: fix picture settings cache bug + * V4L/DVB (5699): Cinergyt2: fix file release handler + * V4L/DVB (5675): Move big PIO accesses from the interrupt handler to a + workhandler + * V4L/DVB (5716): Tda10086,tda826x: fix tuning, STR/SNR values + * V4L/DVB (5720): Usbvision: fix urb allocation and submits + * V4L/DVB (5730): Remove unused V4L2_CAP_VIDEO_OUTPUT_POS + * V4L/DVB (5732): Add ivtv CROPCAP support and fix ivtv S_CROP for video + output. + * V4L/DVB (5736): Add V4L2_FBUF_CAP/FLAG_LOCAL/GLOBAL_INV_ALPHA + * V4L/DVB (5673): Fix audio stuttering for saa711x/ivtv when in radio + mode. + * V4L/DVB (5761): Fix broken b2c2 dependency on non x86 architectures + * V4L/DVB (5751): Ivtv: fix ia64 printk format warnings. + * serverworks: remove crappy code + * serverworks: fix CSB6 tuning logic + * it821x: RAID mode fixes + * ide: HPA detect from resume + * ide: generic IDE PCI driver, add another device exception + * hpt366: disallow Ultra133 for HPT374 + * Add the PATA controller device ID to pci_ids.h for MCP73/MCP77. + * ide: Add the MCP73/77 support to PATA driver + * [CIFS] CIFS should honour umask + * update Documentation/driver-model/platform.txt + * Driver core: keep PHYSDEV for old struct class_device + * Driver core: kill unused code + * kobject: use the proper printk level for kobject error + * firmware: remove orphaned Email + * [IPV4]: Do not remove idev when addresses are cleared + * [NetLabel]: consolidate the struct socket/sock handling to just struct + sock + * [CIPSO]: Fix several unaligned kernel accesses in the CIPSO engine. + * USB: set default y for CONFIG_USB_DEVICE_CLASS + * usblp: Don't let suspend to kill ->used + * USB: usb gadgets avoid le{16,32}_to_cpup() + * USB: UNUSUAL_DEV: Sync up some reported devices from Ubuntu + * USB: cxacru: add Documentation file + * USB: cxacru: create sysfs attributes in atm_start instead of bind + * USB: cxacru: ignore error trying to start ADSL in atm_start + * USB: Fix up bogus bInterval values in endpoint descriptors + * OHCI: Fix machine check in ohci_hub_status_data + * update checkpatch.pl to version 0.03 + * m68knommu: fix ColdFire timer off by 1 + * nommu: report correct errno in message + * loop: preallocate eight loop devices + * document Acked-by: + * update feature-removal-schedule.txt to include deprecated functions + * mount -t tmpfs -o mpol=: check nodes online + * slab: fix alien cache handling + * potential parse error in ifdef part 3 + * SLUB: return ZERO_SIZE_PTR for kmalloc(0) + * uml: fix kernel stack size on x86_64 + * Documentation/atomic_ops.txt typo fix + * Move three functions that are only needed for CONFIG_MEMORY_HOTPLUG + * Char: stallion, don't fail with less than max panels + * Char: stallion, alloc tty before pci devices init + * Char: stallion, proper fail return values + * uml: get declaration of simple_strtoul + * isdn/diva: fix section mismatch + * sata_promise: use TF interface for polling NODATA commands + * rt-mutex: fix stale return value + * rt-mutex: fix chain walk early wakeup bug + * pi-futex: fix exit races and locking problems + * fix sysrq-m oops + * x86_64: oops_begin() fix + * reiserfs: mailing list has moved + * checkpatch: produce fewer lines of output + * MAINTAINERS: corrections + * hexdump: more output formatting + * update checkpatch.pl to version 0.04 + * Protect from multiple inclusion + * [IrDA]: Fix Rx/Tx path race. + * [IrDA]: f-timer reloading when sending rejected frames. + * ibmveth: Fix h_free_logical_lan error on pool resize + * ibmveth: Automatically enable larger rx buffer pools for larger mtu + * typo in via-velocity.c + * NetXen: Fix ping issue after reboot on Blades with 3.4.19 firmware + * NetXen: Fix compile failure seen on PPC architecture + * ehea: Fixed possible kernel panic on VLAN packet recv + * phylib: add RGMII-ID mode to the Marvell m88e1111 PHY to fix broken + ucc_geth + * net: fix typo in drivers/net/usb/Kconfig + * remove unused variable in pata_isapnp + * libata: disable NCQ for HITACHI HTS541680J9SA00/SB21C7EP + * libata: fix probe time irq printouts + * libata: print device model and firmware revision for ATAPI devices + * libata: fix hw_sata_spd_limit initialization + * ahci: Add MCP73/MCP77 support to AHCI driver + * libata-core/sff: Fix multiple assumptions about DMA + * libata: Correct abuse of language + * libata passthru: update protocol numbers + * libata passthru: support PIO multi commands + * libata passthru: map UDMA protocols + * libata passthru: always enforce correct DEV bit + * libata passthru: update cached device paramters + * i915: add new pciids for 945GME, 965GME/GLE + * drm/i915: Add support for the G33, Q33, and Q35 chipsets. + * drm: fix radeon setparam on 32/64 bit systems. + * [ARM] VFP: fix section mismatch error + * libata: force PIO on IOMEGA ZIP 250 ATAPI + * libata: limit post SRST nsect/lbal wait to ~100ms + * Blackfin arch: remove defconfig file + * Blackfin arch: DMA code minor naming convention fix + * Blackfin arch: spelling fixes + * Blackfin arch: fix bug ad1836 fails to build properly for BF533-EZKIT + * Blackfin arch: all symbols were offset by 4k, since we didn't have the + __text label. + * Blackfin arch: mark our memory init functions with __init so they get + freed after init + * Blackfin arch: implement a basic /proc/sram file for L1 allocation + visibility + * Blackfin arch: fixup Blackfin MAINTIANERS team member list + * Blackfin arch: scrub old console defines + * Blackfin arch: update defconfigs + * Blackfin arch: unify differences between our diff head.S files -- no + functional changes + * Blackfin arch: move more of our startup code to .init so it can be + freed once we are up and running + * Blackfin arch: add proper ENDPROC() + * Blackfin arch: try to split up functions like this into smaller units + according to LKML review + * Blackfin arch: fix spelling typo in output + * Blackfin arch: As Mike pointed out range goes form m..MAX_BLACKFIN_GPIO + -1 + * Blackfin arch: add missing gpio.h header to fix compiling in some pm + configurations + * Blackfin arch: add support for Alon Bar-Lev's dynamic kernel + command-line + * Blackfin arch: fix bug can not wakeup from sleep via push buttons + * Blackfin arch: make sure we initialize our L1 Data B section properly + based on the linked kernel + * Blackfin arch: redo our linker script a bit + * Blackfin arch: move HI/LO macros into blackfin.h and punt the rest of + macros.h as it includes VDSP macros we never use + * Blackfin serial driver: hook up our UARTs STP bit with userspaces + CMSPAR + * Blackfin serial driver: ignore framing and parity errors + * Blackfin serial driver: actually implement the break_ctl() function + * Blackfin serial driver: decouple PARODD and CMSPAR checking from PARENB + * Blackfin RTC drivers: update MAINTAINERS information + * Blackfin SPI driver: tweak spi cleanup function to match newer kernel + changes + * [ARM] 4442/1: OSIRIS: Fix CPLD register definitions + * [ARM] 4443/1: OSIRIS: Add watchdog device to machine devices + * [ARM] 4444/2: OSIRIS: CPLD suspend fix + * [ARM] 4445/1: ANUBIS: Fix CPLD registers + * Blackfin SPI driver: fix bug SPI DMA incomplete transmission + * Blackfin SMC91X ethernet supporting driver: SMC91C111 LEDs are note + drived in the kernel like in uboot + * [MIPS] Fix KMODE for the R3000 + * [MIPS] SMTC: Don't set and restore irqregs ptr from self_ipi. + * [MIPS] Always install the DSP exception handler. + * [MIPS] Atlas: Fix build. + * [MIPS] Wire up utimensat, signalfd, timerfd, eventfd + * [MIPS] SMTC: Fix warning. + * [MIPS] SMTC: Don't continue in set_vi_srs_handler on detected bad + arguments. + * [MIPS] SMTC: The MT ASE requires to initialize c0_pagemask and + c0_wired. + * [MIPS] SMTC: Fix build error caused by nonsense code. + * [MIPS] Fix modpost warnings by making start_secondary __cpuinit + * [MIPS] Fix IP27 build + * [MIPS] Fix smp barriers in test_and_{change,clear,set}_bit + * libertas: scan two channels per scan command + * libertas: rename wlan_association_worker + * libertas: a debug output was missing a newline + * libertas: fix removal of all debugfs files + * libertas: remove deprecated pm_register and associated code + * libertas: remove __FILE__ from debug output + * libertas: remove unused/superfluous definitions of DEV_NAME_LEN + * libertas: move vendor & product id's into if_usb.c + * libertas: make libertas_wlan_data_rates static + * libertas: fix scanning from associate path + * libertas: exclude non-used code when PROC_DEBUG is not set + * libertas: make debug configurable + * libertas: tune debug code + * libertas: single out mesh code + * libertas: change debug output of libertas_interrupt() + * libertas: get rid of libertas_sbi_get_priv() + * libertas: fix SSID output + * libertas: changed some occurences of kmalloc() + memset(&a,0,sz) to + kzalloc() + * libertas: move reset_device() code main.c to if_usb.c + * libertas: split wlan_add_card() + * libertas: fixed transmission flow control on the mesh interface + * libertas: fix error handling of card initialization + * libertas: added transmission failures to mesh statistics + * libertas: wakeup both mesh and normal wakeup when getting out of scan + * libertas: indirect all hardware access via hw_XXXX functions + * libertas: move contents of fw.h to decl.h + * libertas: split module into two (libertas.ko and usb8xxx.ko) + * libertas: fix RESET logic at unload time + * libertas: let DRV_NAME be overridable + * libertas: remove unused variables in wlan_dev_t + * libertas: fixed incorrect assigment of fcs errors to frag errors + * libertas: add URB debug info + * libertas: fixed kernel oops on module/card removal + * libertas: call SET_NETDEV_DEV from common code + * libertas: replace 'macaddress' with 'bssid' + * libertas: correctly unregister mesh netdev on error + * libertas: don't tear down netdev in libertas_activate_card + * libertas: version bump (321p0) and cmds update for new fw (5.220.10.p0) + * libertas: updated mesh commands for 5.220.9.p11 + * libertas: make scan result handling more flexible + * libertas: fix 'keep previous scan' behavior + * libertas: cleanup of fwt_list_route processing + * libertas: fix oops on rmmod + * libertas: move channel changing into association framework + * libertas: make association paths consistent + * libertas: use MAC_FMT and MAC_ARG where appropriate + * libertas: use compare_ether_addr() rather than memcmp() where + appropriate + * libertas: fix debug enter/leave prints for + libertas_execute_next_command + * libertas: correctly balance locking in libertas_process_rx_command + * libertas: correct error report paths for wlan_fwt_list_ioctl + * libertas: fix deadlock SIOCGIWSCAN handler + * libertas: fix default adhoc channel + * libertas: honor specific channel requests during association + * libertas: send SIOCGIWSCAN event after partial scans too + * libertas: debug print spacing fixes in assoc.c + * libertas: add more verbose debugging to libertas_cmd_80211_authenticate + * libertas: Make WPA work through supplicant handshake + * libertas: updated readme file + * libertas: make mac address configuration work with mesh interface too + * libertas: split wext for eth and msh + * libertas: support for mesh autostart on firmware 5.220.11 + * libertas: fix character set in README + * libertas: sparse fixes + * libertas: first pass at fixing up endianness issues + * libertas: More endianness fixes. + * libertas: more endianness fixes, in tx.c this time + * libertas: don't byte-swap firmware version number. It's a byte array. + * libertas: fix big-endian associate command. + * libertas: tweak association debug output + * libertas: remove structure WLAN_802_11_SSID and libertas_escape_essid + * libertas: remove WPA_SUPPLICANT structure + * libertas: reduce SSID and BSSID mixed-case abuse + * kbuild: fix sh64 section mismatch problems + * cfg80211: fix signed macaddress in sysfs + * mac80211: fix debugfs tx power reduction output + * mac80211: Don't stop tx queue on master device while scanning. + * Input: usbtouchscreen - fix fallout caused by move from drivers/usb + * Input: i8042 - add ASUS P65UP5 to the noloop list + * Input: i8042 - add ULI EV4873 to noloop list + * [PARISC] remove global_ack_eiem + * libertas: pull current channel from firmware on mesh autostart + * libertas: deauthenticate from AP in channel switch + * libertas: actually send mesh frames to mesh netdev + * libertas: convert libertas_mpp into anycast_mask + * [PPP_MPPE]: Fix "osize too small" check. + * NetXen: Fix link status messages + * myri10ge: limit the number of recoveries + * myri10ge: report when the link partner is running in Myrinet mode + * myri10ge: update driver version + * sysfs: store sysfs inode nrs in s_ino to avoid readdir oopses + * sysfs: fix condition check in sysfs_drop_dentry() + * sysfs: fix race condition around sd->s_dentry, take#2 + * [TCP]: Fix left_out setting during FRTO + * Input: move input-polldev to drivers/input + * [SPARC64]: Wire up cookie based sun4v interrupt registry. + * [SPARC64]: Fix IO/MEM space sizing for PCI. + * [SPARC64]: Really fix parport. + * [SPARC64]: Fix args to sun4v_ldc_revoke(). + * [TCP]: Set initial_ssthresh default to zero in Cubic and BIC. + * mmc-omap: fix sd response type 6 vs. 1 + * mmc: get back read-only switch function + * [SCTP]: Correctly set daddr for IPv6 sockets during peeloff + * [SCTP]: Allow unspecified port in sctp_bindx() + * [SCTP] Fix leak in sctp_getsockopt_local_addrs when copy_to_user fails + * [SCTP] Update pmtu handling to be similar to tcp + * [SCTP] Flag a pmtu change request + * [SCTP] Don't disable PMTU discovery when mtu is small + * [POWERPC] Fix per-cpu allocation on oldworld SMP powermacs + * [POWERPC] Fix console output getting dropped on platforms without + udbg_putc + * [AVR32] ratelimit segfault reporting rate + * [AVR32] gpio_*_cansleep() fix + * [AVR32] STK1000: Set SPI_MODE_3 in the ltv350qv board info + * [AVR32] Define ARCH_KMALLOC_MINALIGN to L1_CACHE_BYTES + * [MIPS] Malta: Fix for SOCitSC based Maltas + * [MIPS] Separate performance counter interrupts + * [MIPS] Fix builds where MSC01E_xxx is undefined. + * [TCP]: Add missing break to TCP option parsing code + * [IPV6] addrconf: Fix IPv6 on tuntap tunnels + * [AGPGART] intel_agp: fix device probe + * KVM: Prevent guest fpu state from leaking into the host + * splice: adjust balance_dirty_pages_ratelimited() call + * splice: fix leak of pages on short splice to pipe + * splice: only check do_wakeup in splice_to_pipe() for a real pipe + * [TCP]: Congestion control API RTT sampling fix + * [TCP]: Fix logic breakage due to DSACK separation + * [RXRPC] net/rxrpc/ar-connection.c: fix NULL dereference + * block: always requeue !fs requests at the front + * mm: Fix memory/cpu hotplug section mismatch and oops. + * Resume from RAM on HPC nx6325 broken + * ide-scsi: fix OOPS in idescsi_expiry() + * fix radeon setparam on 32/64 systems, harder. + * tty: restore locked ioctl file op + * i386: fix NMI watchdog not reserving its MSRs + * i386: use the right wrapper to disable the NMI watchdog + * SLUB slab validation: Alloc while interrupts are disabled must use + GFP_ATOMIC + * Restore shmid as inode# to fix /proc/pid/maps ABI breakage + * i386 mm: use pte_update() in ptep_test_and_clear_dirty() + * cpuset: zero malloc - fix for old cpusets + * toshiba_acpi: fix section mismatch in allyesconfig + * swsusp: Fix userland interface + * perfctr-watchdog: fix interchanged parameters to + release_{evntsel,perfctr}_nmi + * fuse: ->fs_flags fixlet + * md: fix two raid10 bugs + * md: fix bug in error handling during raid1 repair + * spi doc updates + * uml: remove PAGE_SIZE from libc code + * uml: kill x86_64 STACK_TOP_MAX + * random: fix output buffer folding + * Rework ptep_set_access_flags and fix sun4c + * SLUB: minimum alignment fixes + * udf: fix possible leakage of blocks + * hugetlb: fix get_policy for stacked shared memory files + * shm: fix the filename of hugetlb sysv shared memory + * Linux 2.6.22-rc5 + * [GFS2] flush the glock completely in inode_go_sync + * [DLM] fix a couple of races + * [GFS2] kernel changes to support new gfs2_grow command + * [GFS2] Kernel changes to support new gfs2_grow command (part 2) + * [GFS2] use zero_user_page + * [GFS2] Addendum patch 2 for gfs2_grow + * [GFS2] Reduce size of struct gdlm_lock + * [GFS2] Clean up inode number handling + * [GFS2] Quotas non-functional - fix bug + * [DLM] keep dlm from panicing when traversing rsb list in debugfs + * [DLM] block scand during recovery [1/6] + * [DLM] add lock timeouts and warnings [2/6] + * [DLM] dlm_device interface changes [3/6] + * [DLM] cancel in conversion deadlock [4/6] + * [DLM] fix new_lockspace error exit [5/6] + * [DLM] wait for config check during join [6/6] + * [DLM] fix compile breakage + * [GFS2] latest gfs2-nmw headers break userland build + * [DLM] Compile fix + * [DLM] timeout fixes + * [DLM] canceling deadlocked lock + * [DLM] dumping master locks + * [DLM] show default protocol + * [GFS2] Quotas non-functional - fix another bug + * [GFS2] Make the log reserved blocks depend on block size + * [DLM] fix socket shutdown + * [GFS2] fix jdata issues + * [GFS2] Fix sign problem in quota/statfs and cleanup _host structures + * [GFS2] Add nanosecond timestamp feature + * [DLM] fix reference counting + * [DLM] variable allocation + * [GFS2] Fix typo in rename of directories + * [GFS2] Fix bug in error path of inode + * [GFS2] Can't mount GFS2 file system on AoE device + * [GFS2] Recovery for lost unlinked inodes + * [GFS2] gfs2_lookupi() uninitialised var fix + * [GFS2] set plock owner in GETLK info + * [GFS2] return conflicts for GETLK + * [GFS2] Fix deallocation issues + * [DLM] don't require FS flag on all nodes + * [GFS2] Journaled file write/unstuff bug + * [GFS2] Remove bogus '\0' in rgrp.c + * [GFS2] Use zero_user_page() in stuffed_readpage() + * [GFS2] assertion failure after writing to journaled file, umount + * [GFS2] Simplify multiple glock aquisition + * [GFS2] Addendum to the journaled file/unmount patch + + -- Ben Collins Fri, 01 Jun 2007 12:15:58 -0400 + +linux-source-2.6.22 (2.6.22-6.13) gutsy; urgency=low + + [Ben Collins] + + * Bump ABI + * build/scripts: Remove all remnants of debconf from control scripts + * build/config: Re-enable paravirt/vmi + * build/config: Build ide-core as a module + * i386/x86_64: Allow disabling the putstr's from compressed boot wrapper + * PM: Do not require dev spew to get PM_DEBUG + * RTC: Ratelimit "lost interrupts" message + * UNUSUAL_DEV: Sync up some reported devices from Ubuntu + * build/d-i: Include ide-core in storage-core udeb, not that it's modular + * build/d-i: Make ide-modules depend on storage-code-modules + * build/config: Enable CONFIG_TIMER_STATS on x86_64. + * build/config: Disable CONFIG_RTC_DRV_CMOS + * build/config: Enable TIMER_STATS everywhere. + * build/config: Enable SND_AC97_POWER_SAVE + - LP: #116679 + * kmod: Improve call_usermodehelper_pipe to handle data close + * coredump: Convert to new call_usermodehelper_pipe symantics + * PPC: Only set hwif stuff when ide-core is non-modular + * PPC/MEDIABAY: Export some functions for modular ide-core/ppc-ide + + [Colin Watson] + + * Move isofs to storage-core-modules udeb from fs-core-modules. + + [Upstream Kernel Changes] + + * Input: logips2pp - add type 72 (PS/2 TrackMan Marble) + * Input: adbhid - do not access input_dev->private directly + * sh: Shut up compiler warnings in __do_page_fault(). + * sh: Fix up psw build rules for r7780rp. + * sh: Kill off pmb slab cache destructor. + * sh: landisk: rtc-rs5c313 support. + * sh: landisk: Header cleanups. + * input: hp680_ts compile fixes. + * [ARM] 4375/1: sharpsl_pm: Fix compile warnings + * [ARM] 4376/1: Selects GENERIC_GPIO for ARCH_IXP4XX in Kconfig + * [ARM] 4378/1: KS8695: Serial driver fix + * [ARM] Remove Integrator/CP SMP platform support + * [ARM] 4382/1: iop13xx: fix msi support + * [ARM] 4383/1: iop: fix usage of '__init' and 'inline' in iop files + * [ARM] 4384/1: S3C2412/13 SPI registers offset correction + * [ARM] Update ARM syscalls + * [ARM] Silence OMAP kernel configuration warning + * [ARM] gic: Fix gic cascade irq handling + * [ARM] integrator: fix pci_v3 compile error with DEBUG_LL + * [ARM] ARMv6: add CPU_HAS_ASID configuration + * [CRYPTO] padlock: Make CRYPTO_DEV_PADLOCK a tristate again + * [CRYPTO] tcrypt: Add missing error check + * eventfd use waitqueue lock ... + * timerfd use waitqueue lock ... + * [IA64] Fix bogus messages about system calls not implemented. + * [IA64] Yet another section mismatch warning + * Fix roundup_pow_of_two(1) + * Further update of the i386 boot documentation + * cciss: Fix pci_driver.shutdown while device is still active + * Linux v2.6.22-rc2 + * [CRYPTO] api: Read module pointer before freeing algorithm + * powerpc: Fix the MODALIAS generation in modpost for of devices + * kbuild: include limits.h in sumversion.c for PATH_MAX + * kconfig: search harder for curses library in check-lxdialog.sh + * kbuild: make modpost section warnings clearer + * kbuild: make better section mismatch reports on i386, arm and mips + * kbuild: add "Section mismatch" warning whitelist for powerpc + * all-archs: consolidate .text section definition in asm-generic + * all-archs: consolidate .data section definition in asm-generic + * kbuild: introduce __init_refok/__initdata_refok to supress section + mismatch warnings + * init/main: use __init_refok to fix section mismatch + * mm: fix section mismatch warnings + * mm/slab: fix section mismatch warning + * IB/core: Free umem when mm is already gone + * IB/ipath: Fix potential deadlock with multicast spinlocks + * IB/core: Add helpers for uncached GID and P_Key searches + * IB/core: Use start_port() and end_port() + * IPoIB: Handle P_Key table reordering + * IB/ehca: Return proper error code if register_mr fails + * IB/mthca: Fix use-after-free on device restart + * IB/mlx4: Fix check of max_qp_dest_rdma in modify QP + * IB/mthca: Set GRH:HopLimit when building MLX headers + * IB/mlx4: Set GRH:HopLimit when sending globally routed MADs + * IB/mthca: Fix RESET to ERROR transition + * IB/mlx4: Fix RESET to RESET and RESET to ERROR transitions + * mlx4_core: Fix array overrun in dump_dev_cap_flags() + * IB/mlx4: Fix check of opcode in mlx4_ib_post_send() + * [IPV6]: Add ip6_tunnel.h to headers_install + * [RFKILL]: Fix check for correct rfkill allocation + * [NET]: Fix net/core/skbuff.c gcc-3.2.3 compilation error + * [TCP] FRTO: Add missing ECN CWR sending to one of the responses + * [TCP] FRTO: Prevent state inconsistency in corner cases + * [IPSEC] pfkey: Load specific algorithm in pfkey_add rather than all + * [NETFILTER]: nf_conntrack: fix use-after-free in helper destroy + callback invocation + * [NETFILTER]: nf_conntrack_ipv4: fix incorrect #ifdef config name + * [IPV4]: icmp: fix crash with sysctl_icmp_errors_use_inbound_ifaddr + * [NET]: Fix race condition about network device name allocation. + * IB/mlx4: Pass send queue sizes from userspace to kernel + * [ARM] 4387/1: fix /proc/cpuinfo formatting for pre-ARM7 parts + * [ARM] 4388/1: no need for arm/mm mmap range checks for non-mmu + * [ARM] 4395/1: S3C24XX: add include of to relevant + machines + * [ARM] 4396/1: S3C2443: Add missing HCLK clocks + * [ARM] 4397/1: S3C2443: remove SDI0/1 IRQ ambiguity + * [ARM] 4398/1: S3C2443: Fix watchdog IRQ number + * [ARM] 4399/2: S3C2443: Fix SMDK2443 nand timings + * [ARM] 4400/1: S3C24XX: Add high-speed MMC device definition + * [ARM] at91_adc parenthesis balance + * [ARM] spelling fixes + * IB/mlx4: Check if SRQ is full when posting receive + * spelling fixes: arch/sh/ + * sh: revert addition of page fault notifiers + * sh: Wire up signalfd/timerfd/eventfd syscalls. + * sh: Fix up various compile warnings for SE boards. + * sh: Fix page size alignment in __copy_user_page(). + * sh: Disable psw support for R7785RP. + * fs: Kill sh dependency for binfmt_flat. + * sh: disable genrtc support. + * sh: sr.bl toggling around idle sleep. + * sh: Wire up kdump crash kernel exec in die(). + * sh: Fix clock multiplier on SH7722. + * sh: Fix dreamcast build for IRQ changes. + * [S390] cio: Update documentation. + * [S390] Wire up sys_utimensat. + * [S390] Wire up signald, timerfd and eventfd syscalls. + * [S390] Make use of kretprobe_assert. + * [S390] More verbose show_mem() like other architectures. + * Fix "fs: convert core functions to zero_user_page" + * Detach sched.h from mm.h + * Blackfin arch: Add Workaround for ANOMALY 05000257 + * Blackfin arch: add SPI MMC driver support on bf533-stamp, tested on + STAMP-BF533 + * Blackfin arch: ISP1761 doesn't work for USB flash disk + * Blackfin arch: fix a few random warnings + * Blackfin arch: Add configuration data for ISP176x on BF561 + * Blackfin arch: mark a bunch of local functions as static + * Blackfin arch: Fix reserved map after we changed PORT_H definition + * Blackfin arch: Move write to VR_CTL closer to IDLE + * Blackfin arch: DMA operation cleanup + * Blackfin arch: GPIO fix some defines + * Blackfin arch: fix trace output for FLAT binaries + * Blackfin arch: Fix bug using usb keyboard crashes kernel + * Blackfin arch: initial tepla-bf561 board support + * Blackfin arch: make sure we declare the revid functions as pure (since + they are) + * Blackfin arch: dont clear status register bits in SWRST so we can + actually use it + * Blackfin arch: finish removing p* volatile defines for MMRs + * Blackfin arch: move board specific setup out of common init code and + into the board specific init code + * Blackfin arch: issue reset via SWRST so we dont clobber the watchdog + state + * Blackfin arch: document why we have to touch the UART peripheral in our + boot up code + * Blackfin arch: dma_memcpy borken for > 64K + * Blackfin arch: dont clear the bit that tells coreb to start booting + * Blackfin arch: make sure we use local labels + * Blackfin arch: update blackfin header files to latest one in VDSP. + * Blackfin arch: cache SWRST value at bootup so other things like + watchdog can non-destructively query it + * Blackfin arch: fix signal handling bug + * Blackfin arch: Change NO_ACCESS_CHECK to ACCESS_CHECK + * Blackfin arch: add board default configs to blackfin arch + * Blackfin arch: update defconfig files + * Blackfin arch: update pm.c according to power management API change. + * Blackfin serial driver: fix overhead issue + * Blackfin serial driver: implement support for ignoring parity/break + errors + * Blackfin SPI: cleanup according to David Brownell's review + * x86_64: Update defconfig + * i386: Update defconfig + * x86_64: Support x86_64 in make buildtar + * i386: Fix K8/core2 oprofile on multiple CPUs + * x86_64: Support gcc 5 properly + * i386: Clear MCE flag on AMD K6 + * i386: Fix wrong CPU error message in early boot path + * i386: Enable CX8/PGE CPUID bits early on VIA C3 + * x86_64: early_print kernel console should send CRLF not LFCR + * x86_64: vsyscall time() fix + * i386: fix PGE mask + * LDM: Fix for Windows Vista dynamic disks + * IB/ipoib: Fix typos in error messages + * IPoIB/cm: Fix SRQ WR leak + * IB/cm: Improve local id allocation + * e1000: Don't enable polling in open() (was: e1000: assertion hit in + e1000_clean(), kernel 2.6.21.1) + * declance: Remove a dangling spin_unlock_irq() thingy + * Add constant for FCS/CRC length (frame check sequence) + * ahci: disable 64bit dma on sb600 + * libata: Add Seagate STT20000A to DMA blacklist. + * pata_hpt366: Enable bits are unreliable so don't use them + * ata_piix: clean up + * libata: Kiss post_set_mode goodbye + * libata: Trim trailing whitespace + * partitions/LDM: build fix + * Make 'headerscheck' stop immediately on an error + * Fix headers check fallout + * [POWERPC] Fix smp_call_function to be preempt-safe + * [POWERPC] Add missing pmc_type fields in cpu_table + * [POWERPC] Fix typo: MMCR0_PMA0 != MMCR0_PMAO + * [POWERPC] Fix powerpc vmlinux.lds.S + * [POWERPC] Fix warning in 32-bit builds with CONFIG_HIGHMEM + * libertas: skb dereferenced after netif_rx + * drivers/net/wireless/libertas/fw.c: fix use-before-check + * drivers/net/wireless/libertas/rx.c: fix use-after-free + * [IA64] Improve unwind checking. + * [IA64] Only unwind non-running tasks. + * [IA64] fix kmalloc(0) in arch/ia64/pci/pci.c + * i2c: Legacy i2c drivers shouldn't issue uevents + * i2c-tiny-usb: Fix truncated adapter name + * i2c-s3c2410: Fix build warning + * V4L/DVB (5639): Fix Kconfig dependencies for ivtv + * V4L/DVB (5640): Fix: em28xx shouldn't be selecting VIDEO_BUF + * V4L/DVB (5670): Adding new fields to v4l2_pix_format broke the ABI, + reverted that change + * V4L/DVB (5639a): Fix dst usage count + * V4L/DVB (5630): Dvb-core: Handle failures to create devices + * V4L/DVB (5680): Tuner-simple.c fix suport for SECAM with FI1216MF + * V4L/DVB (5690): Cafe_ccic: Properly power down the sensor + * V4L/DVB (5691): Ov7670: reset clkrc in rgb565 mode + * [IPSEC]: Fix warnings with casting int to pointer + * [AF_RXRPC]: AF_RXRPC depends on IPv4 + * [AF_RXRPC]: Make call state names available if CONFIG_PROC_FS=n + * [RTNETLINK]: Allow changing of subsets of netdevice flags in + rtnl_setlink + * [RTNETLINK]: Remove remains of wireless extensions over rtnetlink + * Input: iforce - fix force feedback not working + * Input: iforce - minor clean-ups + * Input: ALPS - force stream mode + * Input: ucb1400_ts - use sched_setscheduler() + * Input: ucb1x00-ts - remove commented out code + * Input: input-polldev - add module info + * Input: ads7846 - document that it handles tsc2046 too + * Input: ads7846 - SPI_CPHA mode bugfix + * USB: fix omninet memory leak found by coverity + * USB: remove useless check in mos7840 found by coverity + * usb-storage: ignore Sitecom WL-117 USB-WLAN + * USB: fix more ftdi-elan/u132-hcd #include lossage + * USB: handle more rndis_host oddities + * USB: remove usb DocBook warnings + * USB: address FIXME in usbnet w.r.t drivers claiming multiple interfaces + * EHCI: fix problem with BIOS handoff + * USB: more autosuspend timer stuff + * USB: remove unneeded WARN_ON + * USB: New device PID for ftdi_sio driver + * USB: set the correct Interrupt interval in usb_bulk_msg + * USB: fsl_usb2_udc: Fix UMTI_WIDE support and a compile warning + * USB: auerswald: fix file release handler + * USB: Remove duplicate IDs from option card driver + * USB: Deref URB after usbmon is done with it + * USB: remove short initial timeout for device descriptor fetch + * USB: don't try to kzalloc 0 bytes + * USB: Onetouch - switch to using input_dev->dev.parent + * USB: Fix debug output of ark3116 + * USB: usblp: Use correct DMA address in case of probe error + * USB: Fix USB OHCI Subvendor for Toshiba Portege 4000 + * USB: make the autosuspend workqueue thread freezable + * USB: handle errors in power/level attribute + * USB: fix ratelimit call semantics + * USB: ftdi_sio: Add USB Product Id for OpenDCC + * USB: ldusb bugfix + * USB: Add support for Sierra Wireless Aircard 595U + * USB: Add support for Olimex arm-usb-ocd JTAG interface serial port + * IB/mlx4: Don't allocate RQ doorbell if using SRQ + * [IA64] start_secondary() and smp_callin() should be __cpuinit + * add the IDE device ID for ATI SB700 + * ide/pci/serverworks.c: Fix corruption/timeouts with MegaIDE + * Add two missing chipsets to drivers/ide/ide-proc.c + * Match DMA blacklist entries between ide-dma.c and libata-core.c + * ide serverworks warning fixes + * freezer: close potential race between refrigerator and thaw_tasks + * freezer: fix vfork problem + * freezer: take kernel_execve into consideration + * freezer: fix kthread_create vs freezer theoretical race + * freezer: fix PF_NOFREEZE vs freezeable race + * freezer: move frozen_process() to kernel/power/process.c + * Ignore bogus ACPI info for offline CPUs + * SLUB Debug: Fix object size calculation + * fuse: fix mknod of regular file + * mpc52xx_psc_spi: fix it for CONFIG_PPC_MERGE + * spi doc update: describe clock mode bits + * NOHZ: Rate limit the local softirq pending warning output + * genhd: expose AN to user space + * genhd: send async notification on media change + * capability.h warning fix + * spi/spidev: check message size before copying + * uml: improve PTRACE_SYSEMU checking + * prohibit rcutorture from being compiled into the kernel + * Documentation: fix the explanation of Kconfig files + * Avoid zero size allocation in cache_k8_northbridges() + * recalc_sigpending_tsk fixes + * optimize compat_core_sys_select() by a using stack space for small fd + sets + * spi: potential memleak in spidev_ioctl + * fbdev: cleanup of sparc FB options + * pm2fb: RDAC_WR barriers clean up + * pm3fb: various fixes + * w100fb: fix compile warnings + * ps3fb: use FB_SYS_* instead of FB_CFB_* + * imxfb: remove ifdefs + * imxfb: fix memory hole + * Missing 'const' from reiserfs MIN_KEY declaration. + * uselib: add missing MNT_NOEXEC check + * fuse: generic_write_checks() for direct_io + * fuse: delete inode on drop + * fix unused setup_nr_node_ids + * SLUB Debug: fix check for super sized slabs (>512k 64bit, >256k 32bit) + * Char: cyclades, fix deadlock + * simplify cleanup_workqueue_thread() + * phantom: move to unlocked_ioctl + * Misc: phantom, take care of pci posting + * power: Fix sizeof(PAGE_SIZE) typo + * update dontdiff file + * signalfd: retrieve multiple signals with one read() call + * i2o: destroy event queue only when drv->event is set + * i2o: fix notifiers when max_drivers is configured + * i2o: eliminate a peculiar constraint on i2o_max_drivers + * i386, x86-64: show that CONFIG_HOTPLUG_CPU is required for suspend on + SMP + * md: avoid overflow in raid0 calculation with large components + * md: don't write more than is required of the last page of a bitmap + * md: fix bug with linear hot-add and elsewhere + * documentation: Documentation/initrd.txt + * HiSax: fix error checking for hisax_register()] + * applesmc - sensors patch missing from 2.6.22-rc2 + * Off by one in floppy.c + * eCryptfs: delay writing 0's after llseek until write + * document clocksources + * ehci-fsl: fix cache coherency problem on system with large memory + * Prevent going idle with softirq pending + * i386: fix early usage of atomic_add_return and local_add_return on real + i386 + * Documentation/memory-barriers.txt: various fixes + * omap_uwire: SPI_CPHA mode bugfix + * capifunc warning fixes + * drivers/isdn/hardware/eicon/message.c warning fixes + * i386 bigsmp: section mismatch fixes + * boot documentation: clarifications + * mmc: clean up unused parts of block driver + * mmc: mark unmaintained drivers + * mmc: Add maintainers for TI OMAP MMC interface + * mmc: add maintainer for iMX MMC interface + * mmc: add maintainer for ARM Primecell controller + * [CRYPTO] geode: Fix in-place operations and set key + * [Bluetooth] Always send HCI_Reset for Broadcom devices + * [Bluetooth] Fix L2CAP configuration parameter handling + * NFS: Avoid a deadlock situation on write + * NFS: Fix handful of compiler warnings in direct.c + * NFS: Fix nfs_direct_dirty_pages() + * Don't call a warnign a bug. It's a warning. + * [IA64] Fix using uninitialized data in _PDC setup + * [IA64] Cleanup acpi header to reuse the generic _PDC defines + * Documentation: Fix up docs still talking about i_sem + * [IA64] acpi_get_sysname() should be __init + * IB/mlx4: Initialize send queue entry ownership bits + * IB/ehca: Fix number of send WRs reported for new QP + * IPoIB/cm: Fix timeout check in ipoib_cm_dev_stop() + * IPoIB/cm: Drain cq in ipoib_cm_dev_stop() + * ucc_geth: Fix MODULE_DEVICE_TABLE() duplication + * ucc_geth:trivial fix + * asix.c - Add Belkin F5D5055 ids + * fix compiler warning in fixed.c + * remove unnecessary dependency on VIA velocity config + * meth driver renovation + * spidernet: skb used after netif_receive_skb + * chelsio parenthesis fix + * forcedeth: fix cpu irq mask + * [NET_SCHED]: Fix qdisc_restart return value when dequeue is empty + * [IPV6]: Ignore ipv6 events on non-IPV6 capable devices. + * [ATM]: Use mutex instead of binary semaphore in idt77252 driver. + * [DCCP]: Use menuconfig objects. + * [IPVS]: Use menuconfig objects. + * [SCTP]: Use menuconfig objects. + * [TIPC]: Use menuconfig objects. + * [ARCNET]: Use menuconfig objects. + * [TR]: Use menuconfig objects. + * [RTNETLINK]: Fix sending netlink message when replace route. + * [TIPC]: Fixed erroneous introduction of for_each_netdev + * [DCCP]: Fix build warning when debugging is disabled. + * [NET_SCHED]: sch_htb: fix event cache time calculation + * [NETFILTER]: nf_conntrack_ftp: fix newline sequence number update + * [NETFILTER]: nf_conntrack_ftp: fix newline sequence number calculation + * [NETFILTER]: nf_conntrack_h323: fix ASN.1 types + * [NETFILTER]: nf_conntrack_h323: fix get_h225_addr() for IPv6 address + access + * [NETFILTER]: nf_conntrack_h323: remove unnecessary process of + Information signal + * [NETFILTER]: nf_conntrack_h323: add missing T.120 address in OLCA + * [NETFILTER]: nf_nat_h323: call set_h225_addr instead of + set_h225_addr_hook + * [NET]: "wrong timeout value" in sk_wait_data() v2 + * hpt3x2n: Correct revision boundary + * pata_sis: Fix and clean up some timing setups + * ata_piix: add short 40c quirk for Acer Aspire 2030, take #2 + * libata: don't consider 0xff as port empty if SStatus is available + * libata: -ENODEV during prereset isn't an error + * pata_via: Handle laptops via DMI + * [CASSINI]: Check pci_set_mwi() return value. + * [XFRM]: Allow packet drops during larval state resolution. + * [libata] sata_promise: fix flags typo + * [libata] sata_mv: add TODO list + * Fix build failure for drivers/ata/pata_scc.c + * libata: sata_sis fixes + * [libata] Fix decoding of 6-byte commands + * [libata] sata_via, pata_via: Add PCI IDs. + * ocfs2: trylock in ocfs2_readpage() + * ocfs2: unmap_mapping_range() in ocfs2_truncate() + * ocfs2: use zero_user_page + * ocfs2: fix inode leak + * ocfs2: use generic_segment_checks + * pata: Trivia + * pata_hpt37x: Further improvements based on the IDE updates and vendor + drivers + * fix compat console unimap regression + * Linux 2.6.22-rc3 + + -- Ben Collins Thu, 31 May 2007 12:35:44 -0400 + +linux-source-2.6.22 (2.6.22-5.11) gutsy; urgency=low + + [Ben Collins] + + * build/headers/ppc: Correct asm-ppc -> asm for arch symlink + * build/headers/ia64: Fix find command line to correctly pull in *.lds + files + * Bump ABI + + [Upstream Kernel Changes] + + * [IA64] spelling fixes: arch/ia64/ + * [AVR32] Remove bogus comment in arch/avr32/kernel/irq.c + * [AVR32] optimize pagefault path + * [AVR32] Wire up signalfd, timerfd and eventfd + * [IA64] wire up {signal,timer,event}fd syscalls + * [IA64] kdump on INIT needs multi-nodes sync-up (v.2) + * [IA64] s/scalibility/scalability/ + * [AVR32] Implement platform hooks for atmel_lcdfb driver + * [IA64] Fix section conflict of ia64_mlogbuf_finish + * [SPARC64]: Add hypervisor API negotiation and fix console bugs. + * pata_scc had been missed by ata_std_prereset() switch + * libata: separate out ata_dev_reread_id() + * libata: during revalidation, check n_sectors after device is configured + * libata-acpi: add ATA_FLAG_ACPI_SATA port flag + * libata: fix shutdown warning message printing + * libata: track spindown status and skip spindown_compat if possible + * [ALSA] usb-audio: another Logitech QuickCam ID + * [ALSA] hda-codec - Make the mixer capability check more robust + * [ALSA] ASoC AC97 static GPL symbol fix + * [ALSA] ASoC AC97 device reg bugfix + * [ALSA] hda-codec - Fix ALC882/861VD codec support on some laptops + * [ALSA] version 1.0.14rc4 + * [ALSA] Fix probe of non-PnP ISA devices + * [ALSA] Include quirks from Ubuntu Dapper/Edgy/Feisty + * [ALSA] usbaudio - Coping with short replies in usbmixer + * [IA64] optimize pagefaults a little + * Fix ACPI suspend / device suspend ordering problem + * AFS: write back dirty data on unmount + * SLUB: It is legit to allocate a slab of the maximum permitted size + * slub: don't confuse ctor and dtor + * AFS: Fix afs_prepare_write() + * spi: fix spidev for >sizeof(long)/32 devices + * parport_pc needs dma-mapping.h + * Fix: find_or_create_page skips cpuset memory spreading. + * slob: implement RCU freeing + * Slab allocators: Drop support for destructors + * SLUB: Remove depends on EXPERIMENTAL and !ARCH_USES_SLAB_PAGE_STRUCT + * SLAB: Move two remaining SLAB specific definitions to slab_def.h + * SLUB: Define functions for cpu slab handling instead of using + PageActive + * slab: warn on zero-length allocations + * slub: fix handling of oversized slabs + * SLUB: slabinfo fixes + * SLUB: Do our own flags based on PG_active and PG_error + * Remove SLAB_CTOR_CONSTRUCTOR + * SLUB: Simplify debug code + * Slab allocators: define common size limitations + * acpi: fix potential call to a freed memory section. + * i386/x86-64: fix section mismatch + * Make __vunmap static + * simplify compat_sys_timerfd + * Let smp_call_function_single return -EBUSY on UP + * Refine SCREEN_INFO sanity check for vgacon initialization + * make freezeable workqueues singlethread + * parport: mailing list is subscribers-only + * docbook: make kernel-locking table readable + * gpio interface loosens call restrictions + * rtc-omap build fix + * rtc kconfig clarification + * icom: add new sub-device-id to support new adapter + * make sysctl/kernel/core_pattern and fs/exec.c agree on maximum core + filename size + * ecryptfs: use zero_user_page + * i386: don't check_pgt_cache in flush_tlb_mm + * circular locking dependency found in QUOTA OFF + * swsusp: fix sysfs interface + * Fix page allocation flags in grow_dev_page() + * mm: more rmap checking + * NS16550A: Restore HS settings in EXCR2 on resume + * Fix incorrect prototype for ipxrtr_route_packet() + * sky2: remove Gigabyte 88e8056 restriction + * sky2: PHY register settings + * sky2: keep track of receive alloc failures + * sky2: MIB counter overflow handling + * sky2: remove dual port workaround + * sky2: memory barriers change + * small netdevices.txt fix + * ibm_emac: fix section mismatch warnings + * ibm_emac: improved PHY support + * ibm_emac: fix link speed detection change + * gianfar: Add I/O barriers when touching buffer descriptor ownership. + * spidernet: node-aware skbuff allocation + * NetXen: Fix NetXen driver ping on system-p + * ixgb: don't print error if pci_enable_msi() fails, cleanup minor leak + * e1000: Fix msi enable leak on error, don't print error message, cleanup + * drivers/ata: remove the wildcard from sata_nv driver + * sata_nv: fix fallout of devres conversion + * libata: remove libata.spindown_compat + * sata_via: pcim_iomap_regions() conversion missed BAR5 + + -- Ben Collins Thu, 17 May 2007 14:54:16 -0400 + +linux-source-2.6.22 (2.6.22-4.10) gutsy; urgency=low + + [Ben Collins] + + * Bump ABI + * build/config: Disable obsolete tsdev driver. + * build: Add tsdev to list of modules intentionally removed. + * build/headers: Include *.lds files (fixes ia64 headers). + * build/headers: Add arch/powerpc/include/asm symlink to get all headers. + * build/module-check: Fix logic for printed messages. + * build/maintainer: Use linux instead of upstream-linux for local diffs + * build/config: Enable SLUB slab allocator (vs. SLAB). + * build/config: Disable orinoco_nortel, use prefered hostap_plx + * build/config: Disable ir-usb in favor of irda-usb + * build/config: Disable sis5513(ide) in favor of pata_sis(libata) + * build/config: Disable piix(ide) in favour of pata_oldpiix, ata_piix and + pata_mpiix (libata) + * build/config: Disable zaurus driver in favour of the cdc_ether driver + * build/abi: Note a few modules intentionally removed. + * build/config: Disable mxb and dpc7146 driver in favour of hexium_orion + * build/config: Disable usbtest driver (for development only) + * build/config: Disable keyspan driver in favour of keyspan_pda + * build/abi: Add mxb and usbtest to list of removed modules. + + [Upstream Kernel Changes] + + * net: Trivial MLX4_DEBUG dependency fix. + * mlx4_core: Remove unused doorbell_lock + * [CPUFREQ] Support rev H AMD64s in powernow-k8 + * [CPUFREQ] powernow-k7: fix MHz rounding issue with perflib + * [AGPGART] Fix wrong ID in via-agp.c + * sh64: ROUND_UP macro cleanup in arch/sh64/kernel/pci_sh5.c + * spelling fixes: arch/sh64/ + * sh64: Wire up many new syscalls. + * sh64: Fixups for the irq_regs changes. + * sh64: dma-mapping updates. + * sh64: ppoll/pselect6() and restartable syscalls. + * sh64: Fixup sh-sci build. + * sh64: Update cayman defconfig. + * sh64: generic quicklist support. + * sh64: Add .gitignore entry for syscalltab. + * IB/mlx4: Fix uninitialized spinlock for 32-bit archs + * IB/ipath: Shadow the gpio_mask register + * IB/ehca: Serialize hypervisor calls in ehca_register_mr() + * IB/ehca: Correctly set GRH mask bit in ehca_modify_qp() + * IB/ehca: Fix AQP0/1 QP number + * IB/ehca: Remove _irqsave, move #ifdef + * IB/ehca: Beautify sysfs attribute code and fix compiler warnings + * IB/ehca: Disable scaling code by default, bump version number + * RDMA/cma: Simplify device removal handling code + * RDMA/cma: Fix synchronization with device removal in cma_iw_handler + * RDMA/cma: Add check to validate that cm_id is bound to a device + * IB/mthca: Fix posting >255 recv WRs for Tavor + * IB/mthca: Set cleaned CQEs back to HW ownership when cleaning CQ + * IPoIB/cm: Optimize stale connection detection + * [CPUFREQ] Correct revision mask for powernow-k8 + * fix epoll single pass code and add wait-exclusive flag + * epoll locks changes and cleanups + * epoll: fix some comments + * epoll: move kfree inside ep_free + * nommu: add ioremap_page_range() + * h8300 atomic.h update + * alpha: fix hard_smp_processor_id compile error + * m68k: implement __clear_user() + * Remove cpu hotplug defines for __INIT & __INITDATA + * i386: move common parts of smp into their own file + * i386: fix voyager build + * SLUB: CONFIG_LARGE_ALLOCS must consider MAX_ORDER limit + * ll_rw_blk: fix gcc 4.2 warning on current_io_context() + * pasemi_mac: Fix register defines + * pasemi_mac: Interrupt ack fixes + * pasemi_mac: Terminate PCI ID list + * pasemi_mac: Fix local-mac-address parsing + * smc911x: fix compilation breakage + * ucc_geth: eliminate max-speed, change interface-type to + phy-connection-type + * pdc202xx_old: rewrite mode programming code (v2) + * serverworks: PIO mode setup fixes + * sis5513: PIO mode setup fixes + * alim15x3: use ide_tune_dma() + * pdc202xx_new: use ide_tune_dma() + * ide: always disable DMA before tuning it + * cs5530/sc1200: add ->udma_filter methods + * ide: use ide_tune_dma() part #2 + * cs5530/sc1200: DMA support cleanup + * cs5530/sc1200: add ->speedproc support + * sl82c105: add speedproc() method and MWDMA0/1 support + * ide: remove ide_dma_enable() + * ide: add missing validity checks for identify words 62 and 63 + * ide: remove ide_use_dma() + * sl82c105: Switch to ref counting API + * Use menuconfig objects: IDE + * x86: Fix discontigmem + non-HIGHMEM compile + * missing mm.h in fw-ohci + * missing dependencies for USB drivers in input + * missing includes in mlx4 + * em28xx and ivtv should depend on PCI + * rpadlpar breakage - fallout of struct subsystem removal + * m32r: __xchg() should be always_inline + * audit_match_signal() and friends are used only if CONFIG_AUDITSYSCALL + is set + * fix uml-x86_64 + * arm: walk_stacktrace() needs to be exported + + -- Ben Collins Tue, 15 May 2007 10:13:23 -0400 + +linux-source-2.6.22 (2.6.22-3.9) gutsy; urgency=low + + * Fixup firmware-modules -> efi-modules in exclude files. + + [Ben Collins] + + * build/config: Enable CONFIG_TIMER_STATS + * build/config: Disable CONFIG_IRQBALANCE, handled in userspace now + * build: Update modules that have been deprecated + * sparc64: Get some drivers compiling, till patches get upstream. + * powerpc: Add 64-bit cmp op for 32-bit. + * build/config: Disable apm_emu, pasemi_mac and cbe_cpufreq on ppc64 + * build/d-i(cjwatson): Rename firmware-modules to efi-modules + + -- Ben Collins Fri, 11 May 2007 09:38:50 +0200 + +linux-source-2.6.22 (2.6.22-2.7) gutsy; urgency=low + + [Changes for 2.7] + + * Added some more modules going missing to ignore. + * Disable ADB_PMU_LED on powerpc64. FTBFS. + + [Ben Collins] + + * XXX: Well, xen and rt got disabled in this upload. Hopefully things will + get working again soon. + + * build: Add check for nrcpus on buildd's for CONCURRENCY_LEVEL + * build: No longer provide ndiswrapper or ivtv modules (l-u-m does). + * build/d-i: Remove firmware lists, since we no longer supply those udebs + * build: Remove more firmware stuff + * build/control: Build-dep on coreutils + * Update configuration files + * build/custom: Updated xen/rt patches and configs. + * build: Make sure to use /bin/bash for headers_install + * build: Add SHELL=/bin/bash to headers_install + * Update configuration files + * Bump ABI + * Update module lists to match module name changes and merges. + * build/rt: Trimmed down real-time patch from Alessio Igor Bogani. + * Update configuration files + * Update configuration files + * build/rt: Fix typo in diff + * Update configuration files + * build: make explicit binary-headers target + * Update configuration files + * build/control-scripts: Remove debconf from pre-rm script + * build/ia64: Compress and use vmlinuz for target install + * build/config: Diable OSS i810_audio driver (Alsa driver prefered) + * build/config: Disable OSS cs4232 driver (Alsa prefered) + * build/config: Disable OSS via82xx driver (Alsa prefered) + * build/config: Disable OSS trident driver (Alsa prefered) + * build/config: Disable OSS Sound Blaster driver (Alsa prefered) + * build/config: Disable IDE generic, ata_generic prefered + * build/config: Disable siimage, pata_sil680 prefered + * build/module-check: More robust module checking + * build: Call module-check with perl, not $SHELL + * Update configuration files + * build: Fixup calling conventions of module-check + * build: Add modules.ignore from 1.3 revision + * build/config: Disable obsolete MOXA_SMARTIO in favor of new driver. + * build/config: Disable orinoco_cs in favor of hostap_cs + * build/config: Disable orinoco_pci in favor of hostap_pci + * build/config: Disable orinoco_{plx,tmd} in favor of hostap_plx + * build/config: Disable sk98lin in favor of skge + * build: Add more modules intentionally removed since 1.3 + + -- Ben Collins Fri, 27 Apr 2007 09:04:29 -0400 + +linux-source-2.6.22 (2.6.22-1.3) gutsy; urgency=low + + [Ben Collins] + + * build: Only use bzip2 for linux-image, and pre-depend on proper dpkg + + [2.6.22-1.2] + + [Ben Collins] + + * build: Add build-arch target. FTBFS + + [2.6.22-1.1] + + [Ben Collins] + + * debian: New build system, from scratch + * debian: Rename place holder so debian/stamps/ sticks around + * debian: Create stamp-flavours at start of build (for build scripts) + * debian/abi: Add revision 0.0 bootstrap module list. + * debian: Fix backwards logic in module/abi checkers. + * debian: Add arch= to vars.* files + * Update configuration files + * build: Added control scripts for images + * build/config: Disable CONFIG_PARAVIRT for now + * build/config: Enable CONFIG_FB_VESA + * build: Take CONCURRENCY_LEVEL from env if it exists. + * build: Do not print SHAs by default for changelog + * build/config(i386): Disable NO_HZ on all but generic + * build: Implement udeb rules + * build/d-i: Remove speakup-modules udeb + * build/udebs: Fix a couple trivial errors in the build. + * build/config: Disable CONFIG_FB_IMSTT on powerpc64-smp (no NVRAM) + * build/config: Disable some modules for ppc64 that don't use DMA API + * build/config: Yet another module to disable on ppc64 + * build/tests: New test infrastructure + * build: Special kernel build infrastructure + * build: Fix typo from last commit + * build/custom: Move custom files for each flavour into subdir. + * build/config: Disable some drivers on sparc that don't support DMA API + * build/sparc: Add new compress_file config, and use it for sparc + * build: Fix typo in compress_file commit. + * build/schedcfs: Update to v6 of the patch. + * build: Fix control file generation for custom images + * build: Correct message in link-headers + * build: 2.6.21 is released, force our SUBLEVEL to .22 + * build/vars: kvm API is at 4, provide that. + * build/custom: Allow custom builds to override things like build_image + * build/custom: Fix type causing custom rules not to be included. + * build/custom: Hello Xen 3.0.5 + * build/custom: Remove sched-cfs. Superseded in use by rt. + * build/custom: Add 2.6.21-rt1 patch for -rt custom flavour + * build/link-headers: Make sure to copy new files for custom + + -- Ben Collins Fri, 27 Apr 2007 08:29:00 -0400 --- linux-2.6.24.orig/debian/scripts/abi-check +++ linux-2.6.24/debian/scripts/abi-check @@ -0,0 +1,44 @@ +#!/bin/bash -e + +flavour="$1" +prev_abinum="$2" +abinum="$3" +prev_abidir="$4" +abidir="$5" +skipabi="$6" + +echo -n "Checking ABI for $flavour..." + +if [ -f "$prev_abidir/ignore" -o -f "$prev_abidir/$flavour.ignore" -o -n "$skipabi" ]; then + echo "explicitly asked to ignore ABI (probably not good)" + exit +fi + +if [ "$prev_abinum" = "0" -o "$prev_abinum" != "$abinum" ]; then + echo "different ABI numbers, no check needed." + exit +fi + +if [ ! -f "$abidir/$flavour" -o ! -f "$prev_abidir/$flavour" ]; then + echo "previous or current ABI file missing!" + echo " $abidir/$flavour" + echo " $prev_abidir/$flavour" + exit 1 +fi + +if [ "`diff -u $prev_abidir/$flavour $abidir/$flavour | grep ^-[^-] | wc -l`" != "0" ] +then + echo "check FAILED (nice one Tonto, go get the Lone Ranger)" + diff -u $prev_abidir/$flavour $abidir/$flavour + exit 1 +fi + +if [ "`diff -u $prev_abidir/$flavour $abidir/$flavour | grep ^+[^+] | wc -l`" != "0" ] +then + echo "new symbols in ABI (continuing reluctantly)" + diff -u $prev_abidir/$flavour $abidir/$flavour || true + exit +fi + +echo "check PASSED (good job, you saved yourself some work)" +exit --- linux-2.6.24.orig/debian/scripts/control-create +++ linux-2.6.24/debian/scripts/control-create @@ -0,0 +1,33 @@ +#!/bin/bash + +stub=debian/control.d/flavour-control.stub +dstub=debian/control.d/flavour-control-debug.stub +vars=$1 + +# Defaults +section_image=base +section_headers=devel + +. $vars + +flavour=$(basename $vars | sed 's/.*\.//') +# Custom is a little different +if [ "$flavour" = "vars" ]; then + flavour=$(basename `dirname $vars`) +fi + +if [ -n "$do_debug" ]; then + stub="$stub $dstub" +fi + +cat $stub | grep -v '^#' | sed \ + -e "s#FLAVOUR#$flavour#g" \ + -e "s#DESC#$desc#g" \ + -e "s#ARCH#$arch#g" \ + -e "s#SUPPORTED#$supported#g" \ + -e "s#TARGET#$target#g" \ + -e "s#BOOTLOADER#$bootloader#g" \ + -e "s#=PROVIDES=#$provides#g" \ + -e "s#SECTION_IMAGE#$section_image#g" \ + -e "s#SECTION_HEADERS#$section_headers#g" \ + -e "s#=HEADER_DEPENDS=#$header_depends#g" --- linux-2.6.24.orig/debian/scripts/module-check +++ linux-2.6.24/debian/scripts/module-check @@ -0,0 +1,119 @@ +#!/usr/bin/perl -w + +$flavour = shift; +$prev_abidir = shift; +$abidir = shift; +$skipmodule = shift; + +print "II: Checking modules for $flavour..."; + +if (-f "$prev_abidir/ignore.modules" + or -f "$prev_abidir/$flavour.ignore.modules") { + print "explicitly ignoring modules\n"; + exit(0); +} + +if (not -f "$abidir/$flavour.modules" or not -f + "$prev_abidir/$flavour.modules") { + print "previous or current modules file missing!\n"; + print " $abidir/$flavour.modules\n"; + print " $prev_abidir/$flavour.modules\n"; + if (defined($skipmodule)) { + exit(0); + } else { + exit(1); + } +} + +print "\n"; + +my %modules; +my %modules_ignore; +my $missing = 0; +my $new = 0; +my $errors = 0; + +# See if we have any ignores +if (-f "$prev_abidir/../modules.ignore") { + my $ignore = 0; + open(IGNORE, "< $prev_abidir/../modules.ignore") or + die "Could not open $prev_abidir/../modules.ignore"; + print " reading modules to ignore..."; + while () { + chomp; + $modules_ignore{$_} = 1; + $ignore++; + } + close(IGNORE); + print "read $ignore modules.\n"; +} + +# Read new modules first +print " reading new modules..."; +$new_count = 0; +open(NEW, "< $abidir/$flavour.modules") or + die "Could not open $abidir/$flavour.modules"; +while () { + chomp; + $modules{$_} = 1; + $new_count++; +} +close(NEW); +print "read $new_count modules.\n"; + +# Now the old modules, checking for missing ones +print " reading old modules..."; +$old_count = 0; +open(OLD, "< $prev_abidir/$flavour.modules") or + die "Could not open $prev_abidir/$flavour.modules"; +while () { + chomp; + if (not defined($modules{$_})) { + print "\n" if not $missing; + $missing++; + if (not defined($modules_ignore{$_})) { + print " MISS: $_\n"; + $errors++; + } else { + print " MISS: $_ (ignored)\n"; + } + } else { + $modules{$_}++; + } + $old_count++; +} +close(OLD); +# Check for new modules +foreach $mod (keys(%modules)) { + if ($modules{$mod} < 2) { + print "\n" if not $missing and not $new; + print " NEW : $mod\n"; + $new++; + } +} +if ($new or $missing) { + print " read $old_count modules : new($new) missing($missing)\n"; +} else { + print "read $old_count modules.\n"; +} + + +# Let's see where we stand... +if ($errors) { + if (defined($skipmodule)) { + print "WW: Explicitly asked to ignore failures (probably not good)\n"; + } else { + print "EE: Missing modules (start begging for mercy)\n"; + exit 1 + } +} + +if ($new) { + print "II: New modules (you've been busy, wipe the poop off your nose)\n"; +} else { + print "II: No new modules (hope you're happy, slacker)\n"; +} + +print "II: Done\n"; + +exit(0); --- linux-2.6.24.orig/debian/scripts/link-headers +++ linux-2.6.24/debian/scripts/link-headers @@ -0,0 +1,79 @@ +#!/bin/bash -e + +hdrdir="$1" +symdir="$2" +srcdir="$3" +build_arch="$4" +flavour="$5" + +echo "Symlinking and copying headers for $flavour..." + +# XXX Special case for ppc +if [ "$build_arch" = "powerpc" ]; then + install -d -m755 $hdrdir/arch/powerpc/include + ln -fsn ../../../include/asm-ppc $hdrdir/arch/powerpc/include/asm +fi + +excludes='( -path ./debian -prune -o -path ./.git ) -prune -o' + +# For custom builds, we have to take care of a few things. First, we want +# to check for files to symlink and copy in the srcdir, not the stock src. +# We compare against stock source, copying for files that aren't the same, +# and later symlinking for same files. +if [ -n "$srcdir" ]; then + ( + cd $srcdir + find . $excludes -type f \ + \( -name 'Makefile*' -o -name 'Kconfig*' -o -name 'Kbuild*' -o \ + -name '*.sh' -o -name '*.pl' -o -name '*.lds' \) -print + find ./include ./scripts -name .gitignore -prune -o -type f -print + ) | ( + while read file; do + if [ -e "$hdrdir/$file" ]; then + continue + fi + + # If the files are not the same, copy it + if ! cmp -s "$file" "$srcdir/$file"; then + echo $file + fi + done + ) | ( + cd $srcdir + cpio -pd --preserve-modification-time "$hdrdir" + ) +else + srcdir="." +fi + +( +cd $srcdir +find . $excludes -type f \ + \( -name 'Makefile*' -o -name 'Kconfig*' -o -name 'Kbuild*' -o \ + -name '*.sh' -o -name '*.pl' -o -name '*.lds' \) -print +find ./include ./scripts -name .gitignore -prune -o -type f -print +find ./include -mindepth 1 -maxdepth 1 $excludes -type d -print +) | ( +while read file; do + dir=$file + lastdir=$file + + if [ -f "$hdrdir/$file" ]; then + continue + fi + + while [ ! -e "$hdrdir/$dir" -a ! -L "$hdrdir/$dir" ]; do + lastdir=$dir + dir=`dirname $dir` + done + # If the last item to exist is a symlink we assume all is good + if [ ! -L "$hdrdir/$dir" ]; then + # Turns things like "./foo" into "../" + deref="`echo -n $lastdir | sed -e 's/^\.//' -e's,/[^/]*,../,g'`" + item="`echo -n $lastdir | sed -e 's/^\.\///'`" + ln -s $deref$symdir/$item $hdrdir/$item + fi +done +) + +exit --- linux-2.6.24.orig/debian/scripts/misc/ppa-cron-job +++ linux-2.6.24/debian/scripts/misc/ppa-cron-job @@ -0,0 +1,47 @@ +#!/bin/sh + +# +# Use this script as a template for the daily kernel build cron job. +# You should copy it somewhere outside of the git tree 'cause the whole +# git tree gets removed and recreated. +# +KNAME=hardy +DAILY_BUILD_DIR=${KBDIR:=${HOME}/${KNAME}} +KERNEL_GIT_REPO=${KREPO:=/srv/kernel.ubuntu.com/git/ubuntu/ubuntu-${KNAME}.git} + +# +# Nothing works unless there is a dput configuration. +# +if [ ! -f ${HOME}/.dput.cf ] +then + echo No dput configuration. + exit 1 +fi + +if [ ! -d ${DAILY_BUILD_DIR} ] +then + rm -rf ${DAILY_BUILD_DIR} + mkdir -p ${DAILY_BUILD_DIR} +fi + +# +# Start with a fresh repo. +# +cd ${DAILY_BUILD_DIR} +rm -rf ubuntu-${KNAME} +git clone ${KERNEL_GIT_REPO} + +# +# Remember that the success of prepare-ppa depends on +# this user account having an un-passworded GPG key. +# Otherwise it requires user intervention, e.g., a +# user must enter the GPG key password. +# +rm -f *.changes +(cd ubuntu-${KNAME}; debian/scripts/misc/prepare-ppa-source) + +find . -maxdepth 1 -type f -name "*.changes" | while read f +do + echo dput my-ppa $f +done + --- linux-2.6.24.orig/debian/scripts/misc/doconfig +++ linux-2.6.24/debian/scripts/misc/doconfig @@ -0,0 +1,67 @@ +#!/bin/bash + +# We have to be in the top level kernel source directory +if [ ! -f MAINTAINERS ] || [ ! -f Makefile ]; then + echo "This does not appear to be the kernel source directory." 1>&2 + exit 1 +fi + + +# One arg, and that's it. Just pass an architecture +if [ $# -ne 1 ]; then + echo "Usage: $0 " 1>&2 + exit 1 +fi + +arch="$1" + +case "$arch" in + sparc) kernarch="sparc64" ;; + amd64) kernarch="x86_64" ;; + hppa) kernarch="parisc" ;; + lpia) kernarch="i386" ;; + *) kernarch="$arch" ;; +esac + +confdir="`pwd`/debian/config/$arch" +bindir="`pwd`/debian/scripts/misc" + +# Make sure the architecture exists +if [ ! -d $confdir ]; then + echo "Could not find config directory for $arch" 1>&2 + exit 1 +fi + +echo "Processing $arch ($kernarch) ... " + +configs=$(cd $confdir && ls config.*) + +if [ -f $confdir/config ]; then + for config in $configs; do + case $config in + *) + cat $confdir/config >> $confdir/$config + ;; + esac + done + rm -f $confdir/config +fi + +test -d build || mkdir build +cd build +for config in $configs; do + + cat $confdir/$config > .config + + echo About to configure $arch $config + read + make -C ../ O=`pwd` ARCH=$kernarch menuconfig + + cat .config > $confdir/$config +done +cd .. + +echo "Running splitconfig.pl ... " +echo + +(cd $confdir ; $bindir/splitconfig.pl) --- linux-2.6.24.orig/debian/scripts/misc/insert-changes.pl +++ linux-2.6.24/debian/scripts/misc/insert-changes.pl @@ -0,0 +1,30 @@ +#!/usr/bin/perl -w + +system("make -s -f debian/rules printchanges > debian/changes"); + +open(CHANGELOG, "< debian/changelog") or die "Cannot open changelog"; +open(CHANGES, "< debian/changes") or die "Cannot open new changes"; +open(NEW, "> debian/changelog.new") or die "Cannot open new changelog"; + +$printed = 0; + +while () { + if (/^ CHANGELOG: /) { + next if $printed; + + while () { + print NEW; + } + + $printed = 1; + } else { + print NEW; + } +} + +close(NEW); +close(CHANGES); +close(CHANGELOG); + +rename("debian/changelog.new", "debian/changelog"); +unlink("debian/changes"); --- linux-2.6.24.orig/debian/scripts/misc/oldconfig +++ linux-2.6.24/debian/scripts/misc/oldconfig @@ -0,0 +1,66 @@ +#!/bin/bash + +# We have to be in the top level kernel source directory +if [ ! -f MAINTAINERS ] || [ ! -f Makefile ]; then + echo "This does not appear to be the kernel source directory." 1>&2 + exit 1 +fi + + +# One arg, and that's it. Just pass an architecture +if [ $# -ne 1 ]; then + echo "Usage: $0 " 1>&2 + exit 1 +fi + +arch="$1" + +case "$arch" in + sparc) kernarch="sparc64" ;; + amd64) kernarch="x86_64" ;; + hppa) kernarch="parisc" ;; + lpia) kernarch="i386" ;; + *) kernarch="$arch" ;; +esac + +confdir="`pwd`/debian/config/$arch" +bindir="`pwd`/debian/scripts/misc" + +# Make sure the architecture exists +if [ ! -d $confdir ]; then + echo "Could not find config directory for $arch" 1>&2 + exit 1 +fi + +echo "Processing $arch ($kernarch) ... " + +configs=$(cd $confdir && ls config.*) + +if [ -f $confdir/config ]; then + for config in $configs; do + case $config in + *) + cat $confdir/config >> $confdir/$config + ;; + esac + done + rm -f $confdir/config +fi + +test -d build || mkdir build +cd build +for config in $configs; do + echo "Running silentoldconfig for $config ... " + + cat $confdir/$config > .config + + make -C ../ O=`pwd` silentoldconfig ARCH=$kernarch + + cat .config > $confdir/$config +done +cd .. + +echo "Running splitconfig.pl ... " +echo + +(cd $confdir ; $bindir/splitconfig.pl) --- linux-2.6.24.orig/debian/scripts/misc/getabis +++ linux-2.6.24/debian/scripts/misc/getabis @@ -0,0 +1,86 @@ +#!/bin/bash + +if [ "$#" != "2" ]; then + echo "Usage: $0 " 1>&2 + exit 1 +fi + +ver=$1 +revision=$2 +abi=$(echo $revision | awk -F. '{print $1}') + +verabi=$ver-$abi +verfull=$ver-$revision + +repo="http://archive.ubuntu.com/ubuntu/pool/main/l" +repo_ports="http://ports.ubuntu.com/ubuntu-ports/pool/main/l" +repo_uni="http://archive.ubuntu.com/ubuntu/pool/universe/l" + +WGET="wget --quiet -c" + +abidir="`pwd`/debian/abi/$verfull" +tmpdir="`pwd`/abi-tmp-$verfull" +origdir="`pwd`" + +test -d $tmpdir || mkdir $tmpdir + +getall() { + arch=$1 + shift + + mkdir -p $abidir/$arch + + for sub in $@; do + if [ -f $abidir/$arch/$sub ]; then + echo "Exists: $sub" + continue + fi + echo -n "Fetching $sub..." + filename=linux-image-${verabi}-${sub}_${verfull}_${arch}.deb + cd $tmpdir + if ! [ -f $filename ]; then + $WGET $repo/linux/$filename + fi + if ! [ -f $filename ]; then + $WGET $repo_ports/linux/$filename + fi + if ! [ -f $filename ]; then + $WGET $repo_uni/linux/$filename + fi + if [ "$?" = "0" ]; then + echo -n "extracting..." + dpkg-deb --extract $filename tmp + if [ -f tmp/boot/abi-* ]; then + mv tmp/boot/abi-* $abidir/$arch/$sub + else + echo -n "NO ABI FILE..." + fi + (cd tmp; find lib/modules/$verabi-$sub/kernel -name '*.ko') | \ + sed -e 's/.*\/\([^\/]*\)\.ko/\1/' | sort > \ + $abidir/$arch/$sub.modules + rm -rf tmp $filename + echo "done." + else + echo "FAILED." + fi + cd $origdir + done +} + +# MAIN + +# Setup abi directory +mkdir -p $abidir +echo $abi > $abidir/abiname + +# NOTE: The flavours are hardcoded, because they may have changed from the +# current build. + +getall powerpc powerpc{,-smp,64-smp} +getall amd64 generic server +getall i386 386 generic server virtual +getall sparc sparc64{,-smp} +getall ia64 itanium mckinley +getall hppa hppa32 hppa64 + +rmdir $tmpdir --- linux-2.6.24.orig/debian/scripts/misc/splitconfig.pl +++ linux-2.6.24/debian/scripts/misc/splitconfig.pl @@ -0,0 +1,110 @@ +#!/usr/bin/perl -w + +%configs = (); +%common = (); + +print "Reading config's ...\n"; + +opendir(DIR, "."); + +while (defined($config = readdir(DIR))) { + # Only config.* + next if $config !~ /^config\..*/; + # Nothing that is disabled, or remnant + next if $config =~ /.*\.(default|disabled|stub)$/; + # Server config's are standalone + #next if $config =~ /config.server-.*/; + + %{$configs{$config}} = (); + + print " processing $config ... "; + + open(CONFIG, "< $config"); + + while () { + /^#*\s*CONFIG_(\w+)[\s=](.*)$/ or next; + + ${$configs{$config}}{$1} = $2; + + $common{$1} = $2; + } + + close(CONFIG); + + print "done.\n"; +} + +closedir(DIR); + +print "\n"; + +print "Merging lists ... \n"; + +for $config (keys(%configs)) { + my %options = %{$configs{$config}}; + + print " processing $config ... "; + + for $key (keys(%common)) { + next if not defined $common{$key}; + + # If we don't have the common option, then it isn't + # common. If we do have that option, it must have the same + # value (this is where the old split.py was broken). It + # also did the common check while it was parsing files, so + # that there were cases where a non-common option was in + # common anyway (ordering). + if (not defined($options{$key})) { + undef $common{$key}; + } elsif ($common{$key} ne $options{$key}) { + undef $common{$key}; + } + } + + print "done.\n"; +} + +print "\n"; + +print "Creating common config ... "; + +open(COMMON, "> config"); +print COMMON "#\n# Common config options automatically generated by splitconfig.pl\n#\n"; + +for $key (sort(keys(%common))) { + next if not defined $common{$key}; + + if ($common{$key} eq "is not set") { + print COMMON "# CONFIG_$key is not set\n"; + } else { + print COMMON "CONFIG_$key=$common{$key}\n"; + } +} +close(COMMON); + +print "done.\n\n"; + +print "Creating stub configs ...\n"; + +for $config (keys(%configs)) { + my %options = %{$configs{$config}}; + + print " processing $config ... "; + + open(STUB, "> $config"); + print STUB "#\n# Config options for $config automatically generated by splitconfig.pl\n#\n"; + + for $key (sort(keys(%options))) { + next if defined $common{$key}; + + if ($options{$key} eq "is not set") { + print STUB "# CONFIG_$key is not set\n"; + } else { + print STUB "CONFIG_$key=$options{$key}\n"; + } + } + + close(STUB); + + print "done.\n"; +} --- linux-2.6.24.orig/debian/scripts/misc/prepare-ppa-source +++ linux-2.6.24/debian/scripts/misc/prepare-ppa-source @@ -0,0 +1,106 @@ +#!/bin/sh +# +# This script prepares a source upload for a PPA build. +# +LAST_UPLOAD=../last-ppa-upload +LAST_GIT_CHANGELOG=../last_git_changelog +LAST_PPA_CHANGELOG=../last_ppa_changelog +PPA_FILE="`make --no-print-directory -f debian/rules print-ppa-file-name`" + +if [ "$1" = "scrub" ] +then + SCRUB=1 +fi + +# +# The identity of the git committer must be known. +# +if [ ! -z "$GIT_AUTHOR_NAME" ] && [ ! -z "$GIT_AUTHOR_EMAIL" ] +then + SIGNER_NAME="$GIT_AUTHOR_NAME" + SIGNER_EMAIL="$GIT_AUTHOR_EMAIL" +elif [ ! -z "$GIT_COMMITTER_NAME" ] && [ ! -z "$GIT_COMMITTER_EMAIL" ] +then + SIGNER_NAME="$GIT_COMMITTER_NAME" + SIGNER_EMAIL="$GIT_COMMITTER_EMAIL" +else + echo Error: Unknown committer. + exit 1 +fi + +# +# git current and cleanup. +# +git checkout -f +git ls-files --others | xargs rm -rf + +# +# Don't bother if the repo hasn't changed since the last upload. +# +if [ ! -f ${LAST_UPLOAD} ] +then + touch ${LAST_UPLOAD} +fi +git log|head -n 1|sed 's/commit //' > ${LAST_UPLOAD}.tmp +if cmp ${LAST_UPLOAD} ${LAST_UPLOAD}.tmp > /dev/null +then + rm -f ${LAST_UPLOAD}.tmp + echo No upload needed. + exit 0 +fi +mv ${LAST_UPLOAD}.tmp ${LAST_UPLOAD} + +# +# The git HEAD can change without anyone updating the debian/changelog. +# However, if the changelog version is updated, then we want to work +# forward from that version. +# +cp debian/changelog changelog.sav +if [ -f ${LAST_GIT_CHANGELOG} ] && [ -f ${LAST_PPA_CHANGELOG} ] +then + # + # If the changelog has not changed, then work forward from the + # last daily build version. + # + if cmp ${LAST_GIT_CHANGELOG} debian/changelog > /dev/null + then + cp ${LAST_PPA_CHANGELOG} debian/changelog + fi +fi +mv changelog.sav ${LAST_GIT_CHANGELOG} + +# +# Notify the build scripts that this is a PPA build. +# +cp -v ${LAST_UPLOAD} ${PPA_FILE} + +# +# In order to sign the package you must override the first signer's changelog entry. +# +export DEBEMAIL="$SIGNER_EMAIL" +export DEBFULLNAME="$SIGNER_NAME" +DEBCHANGE_COMMENT="PPA Upload from git HEAD `cat ${LAST_UPLOAD}`" +debchange --increment --preserve "${DEBCHANGE_COMMENT}" +if ! head -n 1 debian/changelog | grep ubuntu > /dev/null +then + echo debchange did not work. + exit 1 +fi + +# +# Make sure the third changelog field says hardy. +# +sed -i 's/) .*;/) hardy;/1' debian/changelog + +# +# Make sure the next daily build works forward from this version if the git +# changelog has not changed. +# +cp debian/changelog ${LAST_PPA_CHANGELOG} + +rm -rf ../linux* include/config .config +dpkg-buildpackage -S -sa -rfakeroot -I.git -I.gitignore -i'\.git.*' + +rm -f ${PPA_FILE} +exit 0 + --- linux-2.6.24.orig/debian/scripts/misc/git-ubuntu-log +++ linux-2.6.24/debian/scripts/misc/git-ubuntu-log @@ -0,0 +1,223 @@ +#!/usr/bin/perl -w + +use strict; +use Text::Wrap; + +my $kernel_auth = "Upstream Kernel Changes"; + +my (%map, @reverts); +my $pstate = 1; +my $no_kern_log = 0; +my $print_shas = 0; +my $first_print = 1; + +while (@ARGV) { + my $opt = $ARGV[0]; + shift; + if ($opt eq "--no-kern-log") { + $no_kern_log = 1; + } elsif ($opt eq "--print-shas") { + $print_shas = 1; + } else { + print STDERR "Unknown options: $opt\n"; + exit(1); + } +} + +sub check_reverts($) { + my ($entry) = @_; + my ($check); + + foreach $check (reverse @reverts) { + my $desc = "Revert \"" . $entry->{'desc'} . "\""; + if ($check->{'desc'} eq $desc) { + @reverts = grep($_->{'desc'} ne $desc, @reverts); + return 1; + } + } + + return 0; +} + +sub add_entry($) { + my ($entry) = @_; + my $key = $entry->{'author'}; + + # store description in array, in email->{desc list} map + if (exists $map{$key}) { + # grab ref + my $obj = $map{$key}; + + # add desc to array + push(@$obj, $entry); + } else { + # create new array, containing 1 item + my @arr = ($entry); + + # store ref to array + $map{$key} = \@arr; + } +} + +sub shortlog_entry($$$$$) { + my ($name, $desc, $bug, $cve, $commit) = @_; + my $entry; + + $desc =~ s#/pub/scm/linux/kernel/git/#/.../#g; + $desc =~ s#\[PATCH\] ##g; + + $desc =~ s#^\s*##g; + $desc =~ s# *UBUNTU: ##g; + + $entry->{'desc'} = $desc; + $entry->{'bugno'} = $bug; + $entry->{'cve'} = $cve; + $entry->{'commit'} = $commit; + $entry->{'author'} = $name; + + if ($desc =~ /^Revert "/) { + push(@reverts, $entry); + return; + } + + return if check_reverts($entry); + + add_entry($entry); +} + +# sort comparison function +sub by_name($$) { + my ($a, $b) = @_; + + uc($a) cmp uc($b); +} + +sub shortlog_output { + my ($obj, $key, $entry); + + foreach $key (sort by_name keys %map) { + next if $key eq $kernel_auth and $no_kern_log; + + print "\n" unless $first_print; + $first_print = 0; + + # output author + printf " [%s]\n\n", $key; + + # output author's 1-line summaries + $obj = $map{$key}; + foreach $entry (reverse @$obj) { + print wrap(" * ", " ", $entry->{'desc'}) . "\n"; + # For non upstream changes, add other info. + if ($key ne $kernel_auth) { + if ($print_shas) { + print " - GIT-SHA " . $entry->{'commit'} . + "\n"; + } + } + # Upstream cherry-picks can have a bug number as well. + if (defined($entry->{'bugno'})) { + print " - LP: #" . + $entry->{'bugno'} . "\n"; + } + if (defined($entry->{'cve'})) { + print " - " . $entry->{'cve'} . "\n"; + } + } + } +} + +sub changelog_input { + my ($author, $desc, $commit, $entry, $cve); + + while () { + # get commit + if ($pstate == 1) { + next unless /^commit (.*)/; + + $commit = $1; + + $pstate++; + } + + # get author and email + elsif ($pstate == 2) { + my ($email); + + next unless /^[Aa]uthor:?\s*(.*?)\s*<(.*)>/; + + $author = $1; + $email = $2; + $desc = undef; + $cve = undef; + + # cset author fixups + if (!$author) { + $author = $email; + } + $pstate++; + } + + # skip to blank line + elsif ($pstate == 3) { + next unless /^\s*$/; + $pstate++; + } + + # skip to non-blank line + elsif ($pstate == 4) { + next unless /^\s*?(.*)/; + my $ignore = 0; + my $bug = undef; + + # skip lines that are obviously not + # a 1-line cset description + next if /^\s*From: /; + + chomp; + $desc = $1; + + if ($desc =~ /^ *(Revert "|)UBUNTU:/) { + while () { + $ignore = 1 if /^ *Ignore: yes/i; + $bug = $2 if /^ *Bug: *(#|)(.*)/; + $cve = $1 if /^ *(CVE-.*)/; + last if /^commit /; + } + } else { + $author = $kernel_auth; + $ignore = 1 if $desc =~ /Merge /; + while () { + $bug = $2 if /^ *Bug: *(#|)(.*)/; + $cve = $1 if /^ *(CVE-.*)/; + last if /^commit /; + } + } + + if (!$ignore) { + &shortlog_entry($author, $desc, $bug, + $cve, $commit, 0); + } + + $pstate = 1; + if ($_ && /^commit (.*)/) { + $commit = $1; + $pstate++; + } + } + + else { + die "invalid parse state $pstate"; + } + } + + foreach $entry (@reverts) { + print STDERR "Adding revert entry '" . $entry->{'desc'} . "'\n"; + add_entry($entry); + } +} + +&changelog_input; +&shortlog_output; + +exit(0); --- linux-2.6.24.orig/debian/commit-templates/missing-modules +++ linux-2.6.24/debian/commit-templates/missing-modules @@ -0,0 +1,2 @@ +UBUNTU: build/modules: Add modules that have intentionally gone missing +Ignore: yes --- linux-2.6.24.orig/debian/commit-templates/bumpabi +++ linux-2.6.24/debian/commit-templates/bumpabi @@ -0,0 +1,2 @@ +UBUNTU: Bump ABI +Ignore: yes --- linux-2.6.24.orig/debian/commit-templates/external-driver +++ linux-2.6.24/debian/commit-templates/external-driver @@ -0,0 +1,19 @@ +# Ubuntu external driver commit. +# +# NOTE: This gets reformatted for README.Ubuntu-External-Drivers and +# debian/changelog. +# +# This is only needed when a driver is added, updated or removed. It is +# not needed when patches or fixes are applied to the driver. If the +# driver is being removed, add the line: +# +# Removing: yes +# +# to the commit, and you can remove all other tags (except UBUNTU:). +# +UBUNTU: +ExternalDriver: +Description: +Url: +Mask: +Version: --- linux-2.6.24.orig/debian/commit-templates/patch +++ linux-2.6.24/debian/commit-templates/patch @@ -0,0 +1,27 @@ +# Ubuntu commit template. +# +# NOTE: This gets reformatted for debian/changelog +# +# The initial UBUNTU is a flag that this is an Ubuntu commit. It will be +# referenced to the Author in the debian/changelog entry. +# +# The text following is the short message that will be placed in the +# changelog. Extra text on the following lines will be ignored, but left +# in the git commit. Lines with # will be ignored in the commit. +# +# OriginalAuthor allows for alternate attribution. +# +# OriginalLocation allows for a URL or description of where the patch came +# from. +# +# Bug is a reference to a Malone bug number. Be sure to include the '#' as +# part of the bug number, e.g., 'Bug: #1'. +# +# Ignore: yes will keep this commit from showing up in the changelog. +# +UBUNTU: +# OriginalAuthor: +# OriginalLocation: +# Bug: # +# Ignore: yes +# Other text below here. --- linux-2.6.24.orig/debian/commit-templates/newrelease +++ linux-2.6.24/debian/commit-templates/newrelease @@ -0,0 +1,2 @@ +UBUNTU: Start new release +Ignore: yes --- linux-2.6.24.orig/debian/commit-templates/update-configs +++ linux-2.6.24/debian/commit-templates/update-configs @@ -0,0 +1,9 @@ +UBUNTU: Put your _meaningful_ one line commit message here. +# +# This template is used for commit messages that don't need to +# show up in debian/changelog. Administrative stuff like config +# updates, ABI bumps, etc. Setting 'Ignore: yes' prevents +# 'debian/rules insertchanges' from inserting this commit meesage +# as a changelog entry. +# +Ignore: yes --- linux-2.6.24.orig/debian/commit-templates/sauce-patch +++ linux-2.6.24/debian/commit-templates/sauce-patch @@ -0,0 +1,37 @@ +# Ubuntu commit template. +# +# NOTE: This gets reformatted for debian/changelog +# +# +# SAUCE refers to the fact that this patch might not go upstream, but we need to +# carry it to successive releases. In most cases you DONOT want to use this +# template. +# +# An example of a SAUCE patch is the ACPI DSDT-in-initramfs patch which has been +# refused upstream, but still provides useful functionality to users with broken +# BIOSes. +# +#------------------------------------------------------------------------- +# +# The initial UBUNTU is a flag that this is an Ubuntu commit. It will be +# referenced to the Author in the debian/changelog entry. +# +# The text following is the short message that will be placed in the +# changelog. Extra text on the following lines will be ignored, but left +# in the git commit. Lines with # will be ignored in the commit. +# +# OriginalAuthor allows for alternate attribution. +# +# OriginalLocation allows for a URL or description of where the patch came +# from. +# +# Bug is a reference to a Malone bug number. +# +# Ignore: yes will keep this commit from showing up in the changelog. +# +UBUNTU: SAUCE: +# OriginalAuthor: +# OriginalLocation: +# Bug: +# Ignore: yes +# Other text below here. --- linux-2.6.24.orig/debian/config/powerpc/config.powerpc-smp +++ linux-2.6.24/debian/config/powerpc/config.powerpc-smp @@ -0,0 +1,206 @@ +# +# Config options for config.powerpc-smp automatically generated by splitconfig.pl +# +# CONFIG_40x is not set +# CONFIG_44x is not set +CONFIG_6xx=y +CONFIG_ADB=y +CONFIG_ADB_CUDA=y +CONFIG_ADB_MACIO=y +CONFIG_ADB_PMU_LED=y +# CONFIG_ADB_PMU_LED_IDE is not set +# CONFIG_ADVANCED_OPTIONS is not set +CONFIG_AEDSP16_MSS=y +# CONFIG_AEDSP16_SBPRO is not set +CONFIG_ANSLCD=m +CONFIG_APM_EMULATION=m +CONFIG_APM_POWER=m +CONFIG_ARCH_FLATMEM_ENABLE=y +# CONFIG_ARCH_NO_VIRT_TO_BUS is not set +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATM_AMBASSADOR=m +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +CONFIG_ATM_FIRESTREAM=m +CONFIG_ATM_HORIZON=m +# CONFIG_ATM_HORIZON_DEBUG is not set +CONFIG_ATM_IA=m +# CONFIG_ATM_IA_DEBUG is not set +CONFIG_ATM_NICSTAR=m +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set +# CONFIG_ATM_NICSTAR_USE_SUNI is not set +CONFIG_ATM_ZATM=m +# CONFIG_ATM_ZATM_DEBUG is not set +CONFIG_BATTERY_PMU=m +CONFIG_BAYCOM_EPP=m +# CONFIG_BDI_SWITCH is not set +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_DEV_IDECS=m +CONFIG_BMAC=m +CONFIG_BOOT_LOAD=0x00800000 +CONFIG_BRIQ_PANEL=m +CONFIG_CLASSIC32=y +CONFIG_CPUSETS=y +CONFIG_CPU_FREQ_DEBUG=y +CONFIG_CPU_FREQ_PMAC=y +# CONFIG_DEBUG_HIGHMEM is not set +# CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_DEVICE_TREE="" +# CONFIG_E200 is not set +CONFIG_FB_CONTROL=y +CONFIG_FB_CT65550=y +CONFIG_FB_IMSTT=y +CONFIG_FB_PLATINUM=y +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +CONFIG_FB_VALKYRIE=y +CONFIG_FEC_MPC52xx=m +CONFIG_FEC_MPC52xx_MDIO=y +CONFIG_FLATMEM=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_FSL_SOC=y +# CONFIG_GENERIC_IOMAP is not set +CONFIG_GENERIC_NVRAM=y +CONFIG_GENERIC_TBSYNC=y +CONFIG_HIGHMEM=y +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_HOTPLUG_CPU=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_I2C_HYDRA=m +CONFIG_I2C_MPC=m +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_IBMLS=m +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +CONFIG_INPUT_ADBHID=y +# CONFIG_IRQ_ALL_CPUS is not set +# CONFIG_ISA is not set +CONFIG_KERNEL_START=0xc0000000 +CONFIG_LANMEDIA=m +# CONFIG_LBD is not set +CONFIG_LEDS_CLASS=y +CONFIG_LOCK_KERNEL=y +CONFIG_LOWMEM_SIZE=0x30000000 +# CONFIG_LSF is not set +CONFIG_MACE=m +# CONFIG_MACE_AAUI_PORT is not set +CONFIG_MAC_FLOPPY=m +# CONFIG_MMIO_NVRAM is not set +CONFIG_MPC5200_WDT=m +CONFIG_MV643XX_ETH=m +CONFIG_NR_CPUS=4 +CONFIG_NVRAM=y +CONFIG_PARIDE_BPCK6=m +CONFIG_PATA_MPC52xx=m +CONFIG_PCMCIA_AHA152X=m +CONFIG_PCMCIA_IBMTR=m +CONFIG_PCMCIA_NINJA_SCSI=m +CONFIG_PMAC_APM_EMU=m +CONFIG_PMAC_BACKLIGHT=y +CONFIG_PMAC_BACKLIGHT_LEGACY=y +CONFIG_PMAC_MEDIABAY=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_PPC32=y +# CONFIG_PPC601_SYNC_FIX is not set +# CONFIG_PPC64 is not set +# CONFIG_PPC_85xx is not set +# CONFIG_PPC_8xx is not set +# CONFIG_PPC_970_NAP is not set +CONFIG_PPC_BESTCOMM=m +CONFIG_PPC_BESTCOMM_ATA=m +CONFIG_PPC_BESTCOMM_FEC=m +# CONFIG_PPC_BESTCOMM_GEN_BD is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +CONFIG_PPC_CHRP=y +CONFIG_PPC_CLOCK=y +# CONFIG_PPC_DCR_MMIO is not set +CONFIG_PPC_EFIKA=y +# CONFIG_PPC_INDIRECT_IO is not set +CONFIG_PPC_INDIRECT_PCI=y +CONFIG_PPC_LIB_RHEAP=y +CONFIG_PPC_LITE5200=y +# CONFIG_PPC_MM_SLICES is not set +CONFIG_PPC_MPC106=y +CONFIG_PPC_MPC5200=y +# CONFIG_PPC_MPC5200_BUGFIX is not set +CONFIG_PPC_MPC52xx=y +CONFIG_PPC_STD_MMU_32=y +CONFIG_PREEMPT_BKL=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_PSS_MIXER=y +# CONFIG_RTAS_ERROR_LOGGING is not set +CONFIG_SC6600=y +CONFIG_SC6600_CDROM=4 +CONFIG_SC6600_CDROMBASE=0 +CONFIG_SC6600_JOY=y +CONFIG_SCSI_ADVANSYS=m +CONFIG_SCSI_BUSLOGIC=m +CONFIG_SCSI_DC390T=m +CONFIG_SCSI_DPT_I2O=m +CONFIG_SCSI_MAC53C94=m +CONFIG_SCSI_MESH=m +CONFIG_SCSI_MESH_RESET_DELAY_MS=4000 +CONFIG_SCSI_MESH_SYNC_RATE=5 +CONFIG_SCSI_NSP32=m +# CONFIG_SCSI_OMIT_FLASHPOINT is not set +CONFIG_SENSORS_AMS=m +CONFIG_SENSORS_AMS_I2C=y +CONFIG_SENSORS_AMS_PMU=y +CONFIG_SENSORS_M41T00=m +CONFIG_SERIAL_MPC52xx=m +CONFIG_SERIAL_PMACZILOG=m +# CONFIG_SERIAL_PMACZILOG_TTYS is not set +CONFIG_SERIAL_UARTLITE=m +CONFIG_SERIO_I8042=y +CONFIG_SMP=y +CONFIG_SOUND_AEDSP16=m +CONFIG_SOUND_DMAP=y +CONFIG_SOUND_KAHLUA=m +CONFIG_SOUND_MPU401=m +CONFIG_SOUND_MSS=m +CONFIG_SOUND_OSS=m +CONFIG_SOUND_PAS=m +CONFIG_SOUND_PSS=m +CONFIG_SOUND_SB=m +CONFIG_SOUND_SSCAPE=m +# CONFIG_SOUND_TRACEINIT is not set +CONFIG_SOUND_TRIX=m +CONFIG_SOUND_UART6850=m +CONFIG_SOUND_VMIDI=m +CONFIG_SOUND_YM3812=m +# CONFIG_SPARSEMEM_MANUAL is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SPI_MPC52xx_PSC=m +CONFIG_STOP_MACHINE=y +CONFIG_SUSPEND_SMP_POSSIBLE=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_TASK_SIZE=0xc0000000 +CONFIG_TAU=y +# CONFIG_TAU_AVERAGE is not set +# CONFIG_TAU_INT is not set +CONFIG_THERM_ADT746X=m +CONFIG_THERM_WINDTUNNEL=m +CONFIG_TLAN=m +CONFIG_TOSHIBA_FIR=m +# CONFIG_UDBG_RTAS_CONSOLE is not set +# CONFIG_USB_OHCI_HCD_PPC_SOC is not set +CONFIG_VERSION_SIGNATURE="Ubuntu 2.6.24-6.10-powerpc-smp" +CONFIG_VIDEO_STRADIS=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VIRT_TO_BUS=y +CONFIG_WANT_DEVICE_TREE=y +CONFIG_WORD_SIZE=32 --- linux-2.6.24.orig/debian/config/powerpc/config.powerpc64-smp +++ linux-2.6.24/debian/config/powerpc/config.powerpc64-smp @@ -0,0 +1,182 @@ +# +# Config options for config.powerpc64-smp automatically generated by splitconfig.pl +# +CONFIG_64BIT=y +# CONFIG_ADB_PMU_LED is not set +CONFIG_ARCH_HAS_ILOG2_U64=y +CONFIG_ARCH_MEMORY_PROBE=y +CONFIG_ARCH_NO_VIRT_TO_BUS=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ATA_NONSTANDARD=y +CONFIG_AXON_RAM=m +CONFIG_BLK_DEV_IDECS=m +CONFIG_BLOCK_COMPAT=y +# CONFIG_CBE_CPUFREQ is not set +CONFIG_CBE_RAS=y +CONFIG_CBE_THERM=m +CONFIG_COMPAT=y +CONFIG_CPUSETS=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_PMAC64=y +# CONFIG_CRASH_DUMP is not set +CONFIG_EDAC_PASEMI=m +CONFIG_EEH=y +CONFIG_EHEA=m +CONFIG_ELECTRA_CF=m +CONFIG_ELECTRA_IDE=m +# CONFIG_FB_IMSTT is not set +CONFIG_FB_PS3=y +CONFIG_FB_PS3_DEFAULT_SIZE_M=18 +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_FOPS=y +CONFIG_FB_SYS_IMAGEBLIT=y +# CONFIG_FLATMEM_MANUAL is not set +CONFIG_FORCE_MAX_ZONEORDER=13 +CONFIG_GELIC_NET=m +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_TBSYNC=y +CONFIG_HANGCHECK_TIMER=m +CONFIG_HAVE_MEMORY_PRESENT=y +# CONFIG_HCALL_STATS is not set +CONFIG_HIBERNATION=y +CONFIG_HIBERNATION_SMP_POSSIBLE=y +CONFIG_HOTPLUG_CPU=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y +CONFIG_HVCS=m +CONFIG_HVC_CONSOLE=y +CONFIG_HVC_DRIVER=y +CONFIG_HW_RANDOM_PASEMI=m +CONFIG_I2C_PASEMI=m +CONFIG_I2O_EXT_ADAPTEC_DMA64=y +CONFIG_IBMEBUS=y +CONFIG_IBMVETH=m +CONFIG_IBMVIO=y +CONFIG_IBM_NEW_EMAC=m +# CONFIG_IBM_NEW_EMAC_DEBUG is not set +CONFIG_IBM_NEW_EMAC_EMAC4=y +CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32 +CONFIG_IBM_NEW_EMAC_RGMII=y +CONFIG_IBM_NEW_EMAC_RXB=128 +CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256 +CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0 +CONFIG_IBM_NEW_EMAC_TAH=y +CONFIG_IBM_NEW_EMAC_TXB=64 +CONFIG_IBM_NEW_EMAC_ZMII=y +CONFIG_INFINIBAND_EHCA=m +CONFIG_INFINIBAND_IPATH=m +# CONFIG_IOMMU_VMERGE is not set +# CONFIG_IRQSTACKS is not set +CONFIG_IRQ_ALL_CPUS=y +CONFIG_KERNEL_START=0xc000000000000000 +CONFIG_KEYS_COMPAT=y +CONFIG_LEDS_CLASS=m +CONFIG_LOCK_KERNEL=y +CONFIG_LPARCFG=y +CONFIG_MEMORY_HOTPLUG=y +CONFIG_MEMORY_HOTPLUG_SPARSE=y +CONFIG_MIGRATION=y +CONFIG_MMC_SPI=m +CONFIG_MMIO_NVRAM=y +CONFIG_MPIC_BROKEN_REGREAD=y +CONFIG_MPIC_U3_HT_IRQS=y +CONFIG_NEED_MULTIPLE_NODES=y +CONFIG_NODES_SHIFT=4 +CONFIG_NODES_SPAN_OTHER_NODES=y +CONFIG_NR_CPUS=32 +CONFIG_NUMA=y +CONFIG_OPROFILE_CELL=y +CONFIG_PASEMI_MAC=m +CONFIG_PATA_PLATFORM=m +CONFIG_PMAC_SMU=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_PM_STD_PARTITION="" +CONFIG_POWER3=y +CONFIG_POWER4=y +# CONFIG_POWER4_ONLY is not set +CONFIG_PPC64=y +CONFIG_PPC64_SWSUSP=y +# CONFIG_PPC_64K_PAGES is not set +CONFIG_PPC_970_NAP=y +CONFIG_PPC_CELL=y +# CONFIG_PPC_CELLEB is not set +CONFIG_PPC_CELL_NATIVE=y +# CONFIG_PPC_CLOCK is not set +CONFIG_PPC_DCR=y +CONFIG_PPC_DCR_MMIO=y +CONFIG_PPC_HAS_HASH_64K=y +CONFIG_PPC_IBM_CELL_BLADE=y +CONFIG_PPC_INDIRECT_IO=y +# CONFIG_PPC_INDIRECT_PCI is not set +# CONFIG_PPC_ISERIES is not set +CONFIG_PPC_MAPLE=y +CONFIG_PPC_MM_SLICES=y +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_MPC52xx is not set +CONFIG_PPC_OF_PLATFORM_PCI=y +CONFIG_PPC_PASEMI=y +CONFIG_PPC_PASEMI_CPUFREQ=y +CONFIG_PPC_PASEMI_IOMMU=y +# CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE is not set +CONFIG_PPC_PASEMI_MDIO=m +CONFIG_PPC_PMAC64=y +CONFIG_PPC_PMI=m +CONFIG_PPC_PS3=y +CONFIG_PPC_PSERIES=y +CONFIG_PPC_SPLPAR=y +CONFIG_PREEMPT_BKL=y +CONFIG_PROC_PID_CPUSET=y +# CONFIG_PS3_ADVANCED is not set +CONFIG_PS3_DISK=m +# CONFIG_PS3_DYNAMIC_DMA is not set +CONFIG_PS3_FLASH=m +CONFIG_PS3_HTAB_SIZE=20 +CONFIG_PS3_PS3AV=y +CONFIG_PS3_ROM=m +CONFIG_PS3_STORAGE=m +CONFIG_PS3_SYS_MANAGER=y +CONFIG_PS3_USE_LPAR_ADDR=y +CONFIG_PS3_VUART=y +CONFIG_RTAS_ERROR_LOGGING=y +CONFIG_RTAS_FLASH=m +CONFIG_SCANLOG=m +CONFIG_SCHED_SMT=y +# CONFIG_SCSI_DC390T is not set +CONFIG_SCSI_IBMVSCSI=m +CONFIG_SCSI_IBMVSCSIS=m +CONFIG_SERIAL_ICOM=m +# CONFIG_SERIAL_PMACZILOG is not set +# CONFIG_SERIO_I8042 is not set +CONFIG_SMP=y +CONFIG_SND_PS3=m +CONFIG_SND_PS3_DEFAULT_START_DELAY=2000 +CONFIG_SPARSEMEM=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPIDER_NET=m +CONFIG_SPU_BASE=y +CONFIG_SPU_FS=m +CONFIG_SPU_FS_64K_LS=y +CONFIG_STOP_MACHINE=y +CONFIG_SUSPEND_SMP_POSSIBLE=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_THERM_PM72=m +# CONFIG_TUNE_CELL is not set +CONFIG_U3_DART=y +CONFIG_UDBG_RTAS_CONSOLE=y +CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y +CONFIG_VERSION_SIGNATURE="Ubuntu 2.6.24-6.10-powerpc64-smp" +CONFIG_VIRT_CPU_ACCOUNTING=y +# CONFIG_WANT_DEVICE_TREE is not set +CONFIG_WINDFARM_PM112=m +CONFIG_WINDFARM_PM81=m +CONFIG_WINDFARM_PM91=m +CONFIG_WORD_SIZE=64 +CONFIG_XICS=y --- linux-2.6.24.orig/debian/config/powerpc/config +++ linux-2.6.24/debian/config/powerpc/config @@ -0,0 +1,2714 @@ +# +# Common config options automatically generated by splitconfig.pl +# +CONFIG_3C359=m +CONFIG_6PACK=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_8129=y +CONFIG_8139TOO_PIO=y +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_9P_FS=m +CONFIG_ABYSS=m +CONFIG_AC97_BUS=m +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_ACORN_PARTITION=y +# CONFIG_ACORN_PARTITION_ADFS is not set +# CONFIG_ACORN_PARTITION_CUMANA is not set +# CONFIG_ACORN_PARTITION_EESOX is not set +CONFIG_ACORN_PARTITION_ICS=y +# CONFIG_ACORN_PARTITION_POWERTEC is not set +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_ACT200L_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_ADAPTEC_STARFIRE=m +# CONFIG_ADAPTEC_STARFIRE_NAPI is not set +CONFIG_ADB_PMU=y +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_ADM8211=m +CONFIG_AFFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_AFS_FS=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_AGP=m +CONFIG_AGP_UNINORTH=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +CONFIG_AIC79XX_DEBUG_ENABLE=y +CONFIG_AIC79XX_DEBUG_MASK=0 +CONFIG_AIC79XX_REG_PRETTY_PRINT=y +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 +CONFIG_AIC7XXX_DEBUG_ENABLE=y +CONFIG_AIC7XXX_DEBUG_MASK=0 +CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_AIRO=m +CONFIG_AIRO_CS=m +CONFIG_ALI_FIR=m +CONFIG_ALTIVEC=y +# CONFIG_AMD8111E_NAPI is not set +CONFIG_AMD8111_ETH=m +CONFIG_AMIGA_PARTITION=y +CONFIG_ANON_INODES=y +CONFIG_APPLE_AIRPORT=m +CONFIG_APPLICOM=m +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_ILOG2_U32=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SUPPORTS_MSI=y +CONFIG_ARCNET=m +CONFIG_ARCNET_1051=m +CONFIG_ARCNET_1201=m +CONFIG_ARCNET_CAP=m +CONFIG_ARCNET_COM20020=m +CONFIG_ARCNET_COM20020_CS=m +CONFIG_ARCNET_COM20020_PCI=m +CONFIG_ARCNET_COM90xx=m +CONFIG_ARCNET_COM90xxIO=m +CONFIG_ARCNET_RAW=m +CONFIG_ARCNET_RIM_I=m +# CONFIG_ARPD is not set +CONFIG_ASK_IP_FIB_HASH=y +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_ATA=m +CONFIG_ATALK=m +CONFIG_ATARI_PARTITION=y +CONFIG_ATA_GENERIC=m +CONFIG_ATA_OVER_ETH=m +CONFIG_ATA_PIIX=m +CONFIG_ATL1=m +CONFIG_ATM=y +CONFIG_ATMEL=m +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_ATM_CLIP=y +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +CONFIG_ATM_ENI=m +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +CONFIG_ATM_FORE200E=m +CONFIG_ATM_FORE200E_DEBUG=0 +CONFIG_ATM_FORE200E_MAYBE=m +CONFIG_ATM_FORE200E_PCA=y +CONFIG_ATM_FORE200E_PCA_DEFAULT_FW=y +CONFIG_ATM_FORE200E_TX_RETRY=16 +# CONFIG_ATM_FORE200E_USE_TASKLET is not set +CONFIG_ATM_HE=m +CONFIG_ATM_HE_USE_SUNI=y +CONFIG_ATM_IDT77252=m +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +CONFIG_ATM_IDT77252_USE_SUNI=y +CONFIG_ATM_LANAI=m +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_TCP=m +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y +CONFIG_AUDIT_ARCH=y +CONFIG_AUDIT_TREE=y +CONFIG_AUTOFS4_FS=m +CONFIG_AUTOFS_FS=m +CONFIG_AUXDISPLAY=y +CONFIG_AX25=m +CONFIG_AX25_DAMA_SLAVE=y +CONFIG_B43=m +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_DEBUG=y +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y +CONFIG_B43LEGACY_PCI_AUTOSELECT=y +CONFIG_B43LEGACY_PIO=y +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_B43_DEBUG=y +CONFIG_B43_DMA=y +CONFIG_B43_DMA_AND_PIO_MODE=y +# CONFIG_B43_DMA_MODE is not set +CONFIG_B43_LEDS=y +CONFIG_B43_PCICORE_AUTOSELECT=y +CONFIG_B43_PCI_AUTOSELECT=y +# CONFIG_B43_PCMCIA is not set +CONFIG_B43_PIO=y +# CONFIG_B43_PIO_MODE is not set +CONFIG_B43_RFKILL=y +CONFIG_B44=m +CONFIG_B44_PCI=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI_AUTOSELECT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_CORGI=m +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BASE_FULL=y +CONFIG_BASE_SMALL=0 +CONFIG_BATTERY_DS2760=m +CONFIG_BAYCOM_PAR=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_BCM43XX=m +# CONFIG_BCM43XX_DEBUG is not set +CONFIG_BCM43XX_DMA=y +CONFIG_BCM43XX_DMA_AND_PIO_MODE=y +# CONFIG_BCM43XX_DMA_MODE is not set +CONFIG_BCM43XX_PIO=y +# CONFIG_BCM43XX_PIO_MODE is not set +# CONFIG_BEFS_DEBUG is not set +CONFIG_BEFS_FS=m +CONFIG_BFS_FS=m +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_BITREVERSE=y +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_BLK_DEV=y +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_BLK_DEV_AEC62XX=m +CONFIG_BLK_DEV_ALI15X3=m +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_BLK_DEV_BSG is not set +CONFIG_BLK_DEV_CMD64X=m +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_CRYPTOLOOP=m +# CONFIG_BLK_DEV_CS5520 is not set +CONFIG_BLK_DEV_CS5530=m +CONFIG_BLK_DEV_CY82C693=m +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_DELKIN=m +CONFIG_BLK_DEV_DM=m +CONFIG_BLK_DEV_FD=m +CONFIG_BLK_DEV_GENERIC=m +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_HPT34X=m +CONFIG_BLK_DEV_HPT366=m +CONFIG_BLK_DEV_IDE=y +CONFIG_BLK_DEV_IDECD=m +CONFIG_BLK_DEV_IDEDISK=m +CONFIG_BLK_DEV_IDEDMA=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_IDEDMA_PMAC=y +CONFIG_BLK_DEV_IDEFLOPPY=m +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_BLK_DEV_IDESCSI=m +CONFIG_BLK_DEV_IDETAPE=m +CONFIG_BLK_DEV_IDE_PMAC=y +CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_BLK_DEV_IT8213=m +CONFIG_BLK_DEV_IT821X=m +CONFIG_BLK_DEV_JMICRON=m +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_MD=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_NS87415=m +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_PDC202XX_NEW=m +CONFIG_BLK_DEV_PDC202XX_OLD=m +CONFIG_BLK_DEV_PIIX=m +CONFIG_BLK_DEV_PLATFORM=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_BLK_DEV_SC1200=m +CONFIG_BLK_DEV_SD=m +CONFIG_BLK_DEV_SIIMAGE=m +CONFIG_BLK_DEV_SL82C105=m +CONFIG_BLK_DEV_SLC90E66=m +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_BLK_DEV_SVWKS=m +CONFIG_BLK_DEV_SX8=m +CONFIG_BLK_DEV_TC86C001=m +CONFIG_BLK_DEV_TRIFLEX=m +CONFIG_BLK_DEV_TRM290=m +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_UMEM=m +# CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_BLOCK=y +CONFIG_BNX2=m +CONFIG_BONDING=m +# CONFIG_BOOTX_TEXT is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +CONFIG_BOUNCE=y +CONFIG_BPQETHER=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_NETFILTER=y +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BROADCOM_PHY=m +CONFIG_BSD_DISKLABEL=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_BT=m +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HIDP=m +CONFIG_BT_L2CAP=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_SCO=m +CONFIG_BUG=y +CONFIG_CARDBUS=y +# CONFIG_CARDMAN_4000 is not set +# CONFIG_CARDMAN_4040 is not set +CONFIG_CASSINI=m +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_CFG80211=m +CONFIG_CGROUPS=y +CONFIG_CGROUP_CPUACCT=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_NS=y +CONFIG_CHECK_SIGNATURE=y +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T1_NAPI=y +CONFIG_CHELSIO_T3=m +CONFIG_CHR_DEV_OSST=m +CONFIG_CHR_DEV_SCH=m +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_ST=m +CONFIG_CICADA_PHY=m +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG2 is not set +CONFIG_CIFS_EXPERIMENTAL=y +# CONFIG_CIFS_STATS is not set +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_WEAK_PW_HASH=y +# CONFIG_CIFS_XATTR is not set +CONFIG_CISS_SCSI_TAPE=y +CONFIG_CLS_U32_MARK=y +# CONFIG_CLS_U32_PERF is not set +# CONFIG_CMDLINE_BOOL is not set +CONFIG_CODA_FS=m +# CONFIG_CODA_FS_OLD_API is not set +CONFIG_COMPUTONE=m +CONFIG_CONFIGFS_FS=m +CONFIG_CONNECTOR=m +# CONFIG_CPM2 is not set +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CRAMFS=y +CONFIG_CRC16=m +CONFIG_CRC32=y +CONFIG_CRC7=m +CONFIG_CRC_CCITT=m +CONFIG_CRC_ITU_T=m +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ABLKCIPHER=m +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_XTS=m +CONFIG_CYCLADES=m +CONFIG_CYCLADES_SYNC=m +CONFIG_CYCLOMX_X25=y +# CONFIG_CYZ_INTR is not set +CONFIG_DAB=y +CONFIG_DAVICOM_PHY=m +CONFIG_DE2104X=m +CONFIG_DE4X5=m +CONFIG_DE600=m +CONFIG_DE620=m +# CONFIG_DEBUGGER is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_DRIVER is not set +CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_MUTEXES is not set +CONFIG_DEBUG_RODATA=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_VM is not set +CONFIG_DECNET=m +CONFIG_DECNET_NF_GRABULATOR=m +# CONFIG_DECNET_ROUTER is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_BIC is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_CUBIC is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_HTCP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_RELATIME=y +CONFIG_DEFAULT_RELATIME_VAL=1 +CONFIG_DEFAULT_RENO=y +CONFIG_DEFAULT_TCP_CONG="reno" +# CONFIG_DEFAULT_UIMAGE is not set +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_WESTWOOD is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_DEFXX=m +# CONFIG_DEFXX_MMIO is not set +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_DEVPORT=y +CONFIG_DEV_APPLETALK=m +# CONFIG_DEV_KMEM is not set +CONFIG_DIGIEPCA=m +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_DISPLAY_SUPPORT=m +CONFIG_DL2K=m +CONFIG_DLCI=m +CONFIG_DLCI_MAX=8 +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +CONFIG_DM9102=m +CONFIG_DM_CRYPT=m +# CONFIG_DM_DEBUG is not set +# CONFIG_DM_DELAY is not set +CONFIG_DM_MIRROR=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_EMC=m +CONFIG_DM_MULTIPATH_HP=m +CONFIG_DM_MULTIPATH_RDAC=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_UEVENT=y +CONFIG_DM_ZERO=m +CONFIG_DNOTIFY=y +CONFIG_DONGLE=y +CONFIG_DRM=m +CONFIG_DRM_MGA=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_SAVAGE=m +CONFIG_DRM_SIS=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_VIA=m +# CONFIG_DRM_VIA_CHROME9 is not set +CONFIG_DS1682=m +CONFIG_DSCC4=m +CONFIG_DSCC4_PCISYNC=y +CONFIG_DSCC4_PCI_RST=y +CONFIG_DUMMY=m +CONFIG_DUMMY_CONSOLE=y +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_B2C2_FLEXCOP=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_BT8XX=m +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_PATCH=m +CONFIG_DVB_CAPTURE_DRIVERS=y +CONFIG_DVB_CINERGYT2=m +CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y +CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250 +CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100 +CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512 +CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32 +CONFIG_DVB_CINERGYT2_TUNING=y +CONFIG_DVB_CORE=m +CONFIG_DVB_CORE_ATTACH=y +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_ISL6421=m +CONFIG_DVB_L64781=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_MT312=m +CONFIG_DVB_MT352=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_PLL=m +CONFIG_DVB_PLUTO2=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TDA827X=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_TUNER_MT2060=m +CONFIG_DVB_TUNER_MT2131=m +CONFIG_DVB_TUNER_MT2266=m +CONFIG_DVB_TUNER_QT1010=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_CXUSB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_ZL10353=m +CONFIG_E100=m +CONFIG_E1000=m +CONFIG_E1000E=m +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +CONFIG_E1000_NAPI=y +CONFIG_EARLY_PRINTK=y +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +CONFIG_ECRYPT_FS=m +CONFIG_EDAC=y +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_MM_EDAC=m +CONFIG_EEPRO100=m +CONFIG_EEPROM_93CX6=m +# CONFIG_EFI_PARTITION is not set +CONFIG_EFS_FS=m +CONFIG_ELF_CORE=y +# CONFIG_EMBEDDED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +CONFIG_EPIC100=m +CONFIG_EPOLL=y +CONFIG_EQUALIZER=m +CONFIG_ESI_DONGLE=m +CONFIG_EVENTFD=y +CONFIG_EXPERIMENTAL=y +CONFIG_EXPORTFS=m +CONFIG_EXT2_FS=m +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT4DEV_FS is not set +CONFIG_FAIR_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_FAIR_USER_SCHED is not set +CONFIG_FARSYNC=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_FAT_FS=m +# CONFIG_FAULT_INJECTION is not set +CONFIG_FB=y +CONFIG_FB_3DFX=y +# CONFIG_FB_3DFX_ACCEL is not set +CONFIG_FB_ARK=m +CONFIG_FB_ASILIANT=y +CONFIG_FB_ATY=y +CONFIG_FB_ATY128=y +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY_BACKLIGHT=y +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +CONFIG_FB_CIRRUS=m +CONFIG_FB_CYBER2000=m +CONFIG_FB_DDC=y +CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_IBM_GXT4500=m +CONFIG_FB_KYRO=m +CONFIG_FB_MACMODES=y +CONFIG_FB_MATROX=y +CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MULTIHEAD=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_NEOMAGIC=m +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_BACKLIGHT=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_I2C=y +CONFIG_FB_OF=y +CONFIG_FB_PM2=m +CONFIG_FB_PM2_FIFO_DISCONNECT=y +CONFIG_FB_PM3=m +CONFIG_FB_RADEON=y +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RIVA=m +CONFIG_FB_RIVA_BACKLIGHT=y +# CONFIG_FB_RIVA_DEBUG is not set +CONFIG_FB_RIVA_I2C=y +CONFIG_FB_S1D13XXX=m +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_ACCEL=y +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SIS=m +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +CONFIG_FB_SM501=m +CONFIG_FB_SVGALIB=m +CONFIG_FB_TILEBLITTING=y +CONFIG_FB_TRIDENT=m +CONFIG_FB_TRIDENT_ACCEL=y +CONFIG_FB_UVESA=m +# CONFIG_FB_VGA16 is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_FB_VOODOO1=y +CONFIG_FB_VT8623=m +CONFIG_FDDI=y +CONFIG_FEALNX=m +CONFIG_FIB_RULES=y +# CONFIG_FIREWIRE is not set +CONFIG_FIRMWARE_EDID=y +CONFIG_FIXED_MII_1000_FDX=y +# CONFIG_FIXED_MII_100_FDX is not set +# CONFIG_FIXED_MII_10_FDX is not set +CONFIG_FIXED_MII_AMNT=1 +CONFIG_FIXED_PHY=m +# CONFIG_FONTS is not set +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +CONFIG_FORCEDETH=m +# CONFIG_FORCEDETH_NAPI is not set +# CONFIG_FORCED_INLINING is not set +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FSL_ULI1575 is not set +CONFIG_FS_MBCACHE=m +CONFIG_FS_POSIX_ACL=y +CONFIG_FTL=m +CONFIG_FUSE_FS=m +CONFIG_FUSION=y +CONFIG_FUSION_CTL=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_LAN=m +CONFIG_FUSION_LOGGING=y +CONFIG_FUSION_MAX_SGE=128 +CONFIG_FUSION_SAS=m +CONFIG_FUSION_SPI=m +CONFIG_FUTEX=y +CONFIG_FW_LOADER=y +CONFIG_GACT_PROB=y +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GENERIC_ACL=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GEN_RTC=y +# CONFIG_GEN_RTC_X is not set +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=m +CONFIG_GFS2_FS_LOCKING_NOLOCK=m +CONFIG_GIRBIL_DONGLE=m +CONFIG_HAMACHI=m +CONFIG_HAMRADIO=y +CONFIG_HAPPYMEAL=m +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HDLC=m +CONFIG_HDLC_CISCO=m +CONFIG_HDLC_FR=m +CONFIG_HDLC_PPP=m +CONFIG_HDLC_RAW=m +CONFIG_HDLC_RAW_ETH=m +CONFIG_HDLC_X25=m +# CONFIG_HEADERS_CHECK is not set +CONFIG_HERMES=m +CONFIG_HFSPLUS_FS=m +CONFIG_HFS_FS=m +CONFIG_HID=m +CONFIG_HIDRAW=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HID_FF is not set +CONFIG_HID_SUPPORT=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_HIPPI=y +CONFIG_HOSTAP=m +CONFIG_HOSTAP_CS=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_PLX=m +CONFIG_HOTPLUG=y +# CONFIG_HOTPLUG_PCI is not set +CONFIG_HP100=m +CONFIG_HPFS_FS=m +# CONFIG_HPT34X_AUTODMA is not set +# CONFIG_HVC_RTAS is not set +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HWMON_VID=m +CONFIG_HW_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +CONFIG_I2C=y +CONFIG_I2C_ALGOBIT=y +CONFIG_I2C_ALGOPCA=m +CONFIG_I2C_ALGOPCF=m +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C_DEBUG_CORE is not set +CONFIG_I2C_I801=m +CONFIG_I2C_I810=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_POWERMAC=y +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_STUB=m +CONFIG_I2C_TAOS_EVM=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_BUS=m +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_PROC=m +CONFIG_I2O_SCSI=m +CONFIG_I82092=m +CONFIG_IBMOL=m +CONFIG_ICPLUS_PHY=m +CONFIG_IDE=y +# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_IDEPCI_PCIBUS_ORDER=y +CONFIG_IDEPCI_SHARE_IRQ=y +CONFIG_IDE_ARCH_OBSOLETE_INIT=y +# CONFIG_IDE_ARM is not set +CONFIG_IDE_GENERIC=m +CONFIG_IDE_PROC_FS=y +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IEEE1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_OHCI1394=m +CONFIG_IEEE1394_PCILYNX=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE80211=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_CRYPT_WEP=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_IFB=m +# CONFIG_IKCONFIG is not set +CONFIG_INET=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET_AH=m +CONFIG_INET_DCCP_DIAG=m +CONFIG_INET_DIAG=y +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_LRO=m +CONFIG_INET_TCP_DIAG=y +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_AMSO1100=m +CONFIG_INFINIBAND_AMSO1100_DEBUG=y +CONFIG_INFINIBAND_CXGB3=m +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_IPOIB_DEBUG=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set +CONFIG_INFINIBAND_ISER=m +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INFTL=m +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_INPUT=y +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_EVBUG=m +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_INPUT_KEYBOARD=y +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_PCSPKR=m +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_TABLET=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_YEALINK=m +CONFIG_INSTRUMENTATION=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_CFQ=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IP1000=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IPDDP=m +CONFIG_IPDDP_DECAP=y +CONFIG_IPDDP_ENCAP=y +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_POWEROFF=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPV6=m +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_IPV6_SIT=m +CONFIG_IPV6_TUNNEL=m +CONFIG_IPW2100=m +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +# CONFIG_IPW2200_DEBUG is not set +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_DCCP=m +CONFIG_IP_DCCP_ACKVEC=y +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_IP_DCCP_TFRC_LIB=m +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_MROUTE=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_IP_PNP is not set +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_SCTP=m +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_TAB_BITS=12 +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_WRR=m +CONFIG_IRCOMM=m +CONFIG_IRDA=m +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_DEBUG=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_ULTRA=y +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRQ_PER_CPU=y +CONFIG_IRTTY_SIR=m +CONFIG_ISA_DMA_API=y +CONFIG_ISCSI_TCP=m +# CONFIG_ISDN is not set +# CONFIG_ISI is not set +CONFIG_ISO9660_FS=m +# CONFIG_IWLWIFI is not set +CONFIG_IXGB=m +CONFIG_IXGBE=m +# CONFIG_IXGB_NAPI is not set +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_JFFS2_CMODE_FAVOURLZO=y +# CONFIG_JFFS2_CMODE_NONE is not set +# CONFIG_JFFS2_CMODE_PRIORITY is not set +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_LZO=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFS_DEBUG is not set +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +CONFIG_JFS_STATISTICS=y +CONFIG_JOLIET=y +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_232=y +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_KARMA_PARTITION=y +CONFIG_KEXEC=y +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_KINGSUN_DONGLE=m +CONFIG_KMOD=y +CONFIG_KPROBES=y +CONFIG_KS0108=m +CONFIG_KS0108_DELAY=2 +CONFIG_KS0108_PORT=0x378 +CONFIG_KS959_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +CONFIG_LAPB=m +CONFIG_LAPBETHER=m +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_LTV350QV=m +# CONFIG_LDM_DEBUG is not set +CONFIG_LDM_PARTITION=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_IDE_DISK=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_LIBCRC32C=m +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_CS=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_SDIO=m +CONFIG_LIBERTAS_USB=m +CONFIG_LITELINK_DONGLE=m +# CONFIG_LKDTM is not set +CONFIG_LLC=y +CONFIG_LLC2=m +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +# CONFIG_LOGO is not set +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_LP_CONSOLE is not set +CONFIG_LXT_PHY=m +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +CONFIG_MA600_DONGLE=m +CONFIG_MAC80211=m +# CONFIG_MAC80211_DEBUG is not set +CONFIG_MAC80211_DEBUGFS=y +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_RCSIMPLE=y +CONFIG_MACINTOSH_DRIVERS=y +CONFIG_MACVLAN=m +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_MAC_PARTITION=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_MARKERS is not set +CONFIG_MARVELL_PHY=m +CONFIG_MAX_RAW_DEVS=256 +CONFIG_MCP2120_DONGLE=m +CONFIG_MCS_FIR=m +CONFIG_MD=y +CONFIG_MDIO_BITBANG=m +CONFIG_MD_FAULTY=m +CONFIG_MD_LINEAR=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID5_RESHAPE=y +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_SAS=m +CONFIG_MFD_SM501=m +CONFIG_MII=m +CONFIG_MINIX_FS=m +CONFIG_MINIX_SUBPARTITION=y +CONFIG_MISC_DEVICES=y +CONFIG_MKISS=m +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_MLX4_INFINIBAND=m +CONFIG_MMC=m +CONFIG_MMC_BLOCK=m +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_RICOH_MMC=m +CONFIG_MMC_SDHCI=m +CONFIG_MMC_TIFM_SD=m +# CONFIG_MMC_UNSAFE_RESUME is not set +CONFIG_MMC_WBSD=m +CONFIG_MMU=y +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_PS2=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_PS2_TRACKPOINT=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_MOXA_INTELLIO=m +# CONFIG_MOXA_SMARTIO is not set +CONFIG_MOXA_SMARTIO_NEW=m +CONFIG_MPIC=y +# CONFIG_MPIC_WEIRD is not set +CONFIG_MSDOS_FS=m +CONFIG_MSDOS_PARTITION=y +CONFIG_MSNDCLAS_INIT_FILE="/etc/sound/msndinit.bin" +CONFIG_MSNDCLAS_PERM_FILE="/etc/sound/msndperm.bin" +CONFIG_MSNDPIN_INIT_FILE="/etc/sound/pndspini.bin" +CONFIG_MSNDPIN_PERM_FILE="/etc/sound/pndsperm.bin" +# CONFIG_MSS is not set +CONFIG_MTD=m +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTD_ABSENT=m +CONFIG_MTD_ALAUDA=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK2MTD=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_MTD_CFI=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_CHAR=m +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_CONCAT=m +CONFIG_MTD_DATAFLASH=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_DOC2000=m +CONFIG_MTD_DOC2001=m +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCECC=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCPROBE_ADDRESS=0 +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_INTEL_VR_NOR=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_M25P80=m +CONFIG_MTD_MAP_BANK_WIDTH_1=y +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +CONFIG_MTD_MTDRAM=m +CONFIG_MTD_NAND=m +CONFIG_MTD_NAND_CAFE=m +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_NANDSIM=m +CONFIG_MTD_NAND_PLATFORM=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_ONENAND=m +CONFIG_MTD_ONENAND_2X_PROGRAM=y +# CONFIG_MTD_ONENAND_OTP is not set +CONFIG_MTD_ONENAND_SIM=m +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +CONFIG_MTD_OOPS=m +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_PCI=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PHYSMAP_LEN=0x4000000 +CONFIG_MTD_PHYSMAP_OF=m +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PLATRAM=m +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +CONFIG_MTD_RAM=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS=m +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +CONFIG_MTD_ROM=m +CONFIG_MTD_SLRAM=m +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_DEBUG is not set +CONFIG_MTD_UBI_GLUEBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MYRI10GE=m +CONFIG_NATSEMI=m +CONFIG_NCPFS_EXTRAS=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_OS2_NS=y +CONFIG_NCPFS_PACKET_SIGNING=y +# CONFIG_NCPFS_SMALLDOS is not set +CONFIG_NCPFS_STRONG=y +CONFIG_NCP_FS=m +CONFIG_NE2K_PCI=m +CONFIG_NET=y +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETDEVICES=y +CONFIG_NETDEVICES_MULTIQUEUE=y +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +# CONFIG_NETLABEL is not set +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NETROM=m +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NETWORK_SECMARK=y +CONFIG_NETXEN_NIC=m +CONFIG_NET_9P=m +# CONFIG_NET_9P_DEBUG is not set +CONFIG_NET_9P_FD=m +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_FW=m +# CONFIG_NET_CLS_IND is not set +# CONFIG_NET_CLS_POLICE is not set +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_DCCPPROBE=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_ETHERNET=y +CONFIG_NET_FC=y +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_NET_IPIP=m +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_NET_PCI=y +CONFIG_NET_PCMCIA=y +CONFIG_NET_PKTGEN=m +CONFIG_NET_POCKET=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_FIFO=y +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_RR=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_TCPPROBE=m +CONFIG_NET_TULIP=y +CONFIG_NET_VENDOR_3COM=y +CONFIG_NEW_LEDS=y +CONFIG_NFSD=m +CONFIG_NFSD_TCP=y +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_ENABLED=m +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_NF_CONNTRACK_SANE is not set +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_TFTP=m +# CONFIG_NIU is not set +CONFIG_NL80211=y +CONFIG_NLS=y +CONFIG_NLS_ASCII=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +# CONFIG_NORTEL_HERMES is not set +CONFIG_NO_HZ=y +CONFIG_NS83820=m +CONFIG_NSC_FIR=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_FS=m +# CONFIG_NTFS_RW is not set +CONFIG_N_HDLC=m +# CONFIG_OCFS2_DEBUG_FS is not set +CONFIG_OCFS2_DEBUG_MASKLOG=y +CONFIG_OCFS2_FS=m +CONFIG_OF=y +CONFIG_OF_DEVICE=y +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_OPROFILE=m +CONFIG_OSF_PARTITION=y +CONFIG_P54_COMMON=m +CONFIG_P54_PCI=m +CONFIG_P54_USB=m +CONFIG_PACKET=m +CONFIG_PACKET_MMAP=y +CONFIG_PARIDE=m +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_EPAT=m +# CONFIG_PARIDE_EPATC8 is not set +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PG=m +CONFIG_PARIDE_PT=m +CONFIG_PARPORT=m +CONFIG_PARPORT_1284=y +CONFIG_PARPORT_AX88796=m +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_NOT_PC=y +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_FIFO=y +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_SERIAL=m +CONFIG_PARTITION_ADVANCED=y +# CONFIG_PATA_ALI is not set +CONFIG_PATA_AMD=m +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +CONFIG_PATA_CS5520=m +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +CONFIG_PATA_EFAR=m +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +CONFIG_PATA_IT8213=m +CONFIG_PATA_IT821X=m +CONFIG_PATA_JMICRON=m +CONFIG_PATA_MARVELL=m +CONFIG_PATA_MPIIX=m +CONFIG_PATA_NETCELL=m +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_NS87415 is not set +CONFIG_PATA_OLDPIIX=m +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +CONFIG_PATA_PCMCIA=m +CONFIG_PATA_PDC2027X=m +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +CONFIG_PATA_RZ1000=m +# CONFIG_PATA_SC1200 is not set +CONFIG_PATA_SERVERWORKS=m +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +CONFIG_PATA_TRIFLEX=m +CONFIG_PATA_VIA=m +CONFIG_PATA_WINBOND=m +CONFIG_PC300=m +# CONFIG_PC300TOO is not set +CONFIG_PC300_MLPPP=y +CONFIG_PCCARD=m +CONFIG_PCCARD_NONSTATIC=m +CONFIG_PCI=y +CONFIG_PCI200SYN=m +CONFIG_PCIEAER=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIPCWATCHDOG=m +CONFIG_PCI_ATMEL=m +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_DOMAINS=y +# CONFIG_PCI_HERMES is not set +CONFIG_PCI_LEGACY=y +CONFIG_PCI_MSI=y +CONFIG_PCI_SYSCALL=y +CONFIG_PCMCIA=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_PCMCIA_AXNET=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_HERMES=m +CONFIG_PCMCIA_IOCTL=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_NETWAVE=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_RAYCS=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_SPECTRUM=m +CONFIG_PCMCIA_SYM53C500=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_WL3501=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_PCNET32=m +# CONFIG_PCNET32_NAPI is not set +CONFIG_PD6729=m +CONFIG_PDA_POWER=m +# CONFIG_PDC202XX_BURST is not set +CONFIG_PDC_ADMA=m +CONFIG_PHANTOM=m +CONFIG_PHONE=m +CONFIG_PHONE_IXJ=m +CONFIG_PHONE_IXJ_PCMCIA=m +CONFIG_PHYLIB=m +# CONFIG_PID_NS is not set +CONFIG_PLIP=m +CONFIG_PLIST=y +# CONFIG_PLX_HERMES is not set +CONFIG_PM=y +CONFIG_PMAC_RACKMETER=m +# CONFIG_PM_DEBUG is not set +CONFIG_PM_DISABLE_CONSOLE=y +CONFIG_PM_LEGACY=y +CONFIG_PM_SLEEP=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POWER_SUPPLY=m +# CONFIG_POWER_SUPPLY_DEBUG is not set +CONFIG_PPC=y +# CONFIG_PPC_82xx is not set +# CONFIG_PPC_83xx is not set +# CONFIG_PPC_86xx is not set +# CONFIG_PPC_DCR_NATIVE is not set +# CONFIG_PPC_EARLY_DEBUG is not set +CONFIG_PPC_FPU=y +CONFIG_PPC_I8259=y +CONFIG_PPC_MERGE=y +CONFIG_PPC_MULTIPLATFORM=y +CONFIG_PPC_NATIVE=y +CONFIG_PPC_OF=y +CONFIG_PPC_PMAC=y +CONFIG_PPC_RTAS=y +CONFIG_PPC_STD_MMU=y +CONFIG_PPC_UDBG_16550=y +CONFIG_PPDEV=m +CONFIG_PPP=m +CONFIG_PPPOATM=m +CONFIG_PPPOE=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_SYNC_TTY=m +# CONFIG_PQ2ADS is not set +# CONFIG_PREEMPT is not set +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_PRINTER=m +CONFIG_PRINTK=y +CONFIG_PRINTK_TIME=y +CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_PRISM54=m +CONFIG_PROC_DEVICETREE=y +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROFILING=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_QLA3XXX=m +CONFIG_QNX4FS_FS=m +CONFIG_QSEMI_PHY=m +CONFIG_QUOTA=y +CONFIG_QUOTACTL=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +CONFIG_R3964=m +CONFIG_R8169=m +# CONFIG_R8169_NAPI is not set +CONFIG_R8169_VLAN=y +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAESTRO=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RAID_ATTRS=m +CONFIG_RAW_DRIVER=m +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_FS=m +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_REISERFS_FS_XATTR=y +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_RELAY=y +CONFIG_RESOURCES_64BIT=y +CONFIG_RFD_FTL=m +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +CONFIG_RFKILL_LEDS=y +# CONFIG_RIO is not set +CONFIG_ROADRUNNER=m +# CONFIG_ROADRUNNER_LARGE_RINGS is not set +CONFIG_ROCKETPORT=m +CONFIG_ROMFS_FS=m +CONFIG_ROSE=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_RT2400PCI=m +CONFIG_RT2400PCI_RFKILL=y +CONFIG_RT2500PCI=m +CONFIG_RT2500PCI_RFKILL=y +CONFIG_RT2500USB=m +CONFIG_RT2X00=m +# CONFIG_RT2X00_DEBUG is not set +CONFIG_RT2X00_LIB=m +# CONFIG_RT2X00_LIB_DEBUGFS is not set +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_PCI=m +CONFIG_RT2X00_LIB_RFKILL=y +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT61PCI=m +CONFIG_RT61PCI_RFKILL=y +CONFIG_RT73USB=m +CONFIG_RTAS_PROC=y +CONFIG_RTC_CLASS=m +CONFIG_RTC_DRV_CMOS=m +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_M41T80_WDT=y +CONFIG_RTC_DRV_M48T59=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_STK17TA8=m +CONFIG_RTC_DRV_TEST=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_LIB=m +CONFIG_RTL8187=m +CONFIG_RT_MUTEXES=y +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_RXKAD=m +CONFIG_S2IO=m +# CONFIG_S2IO_NAPI is not set +# CONFIG_SAMPLES is not set +CONFIG_SATA_AHCI=m +CONFIG_SATA_INIC162X=m +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIL24=m +CONFIG_SATA_SIS=m +CONFIG_SATA_SVW=m +CONFIG_SATA_SX4=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m +CONFIG_SC92031=m +# CONFIG_SCHEDSTATS is not set +CONFIG_SCHED_DEBUG=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_SCSI=m +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AIC79XX=m +CONFIG_SCSI_AIC7XXX=m +# CONFIG_SCSI_AIC7XXX_OLD is not set +CONFIG_SCSI_AIC94XX=m +CONFIG_SCSI_ARCMSR=m +CONFIG_SCSI_ARCMSR_AER=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_DC395x=m +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_DMA=y +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_EATA=m +CONFIG_SCSI_EATA_LINKED_COMMANDS=y +CONFIG_SCSI_EATA_MAX_TAGS=16 +CONFIG_SCSI_EATA_TAGGED_QUEUE=y +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_FC_TGT_ATTRS=y +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_SCSI_GDTH=m +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_IMM=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_DUMP is not set +# CONFIG_SCSI_IPR_TRACE is not set +CONFIG_SCSI_IPS=m +CONFIG_SCSI_ISCSI_ATTRS=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_LOWLEVEL=y +CONFIG_SCSI_LOWLEVEL_PCMCIA=y +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_NETLINK=y +CONFIG_SCSI_PPA=m +CONFIG_SCSI_PROC_FS=y +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_SAS_ATA=y +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_SRP=m +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_TGT=m +CONFIG_SCSI_WAIT_SCAN=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_HMAC_MD5=y +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SDIO_UART=m +CONFIG_SECCOMP=y +CONFIG_SECURITY=y +CONFIG_SECURITY_APPARMOR=y +CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 +# CONFIG_SECURITY_APPARMOR_DISABLE is not set +CONFIG_SECURITY_CAPABILITIES=y +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_DISABLE=y +# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_IBMPEX=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_LM93=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_TSL2550=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SERIAL_8250=m +CONFIG_SERIAL_8250_CS=m +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_NR_UARTS=48 +CONFIG_SERIAL_8250_PCI=m +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_CORE=m +CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_SERIAL_OF_PLATFORM=m +CONFIG_SERIO=y +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_PARKBD=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SERIO_RAW=m +CONFIG_SERIO_SERPORT=m +CONFIG_SGI_IOC4=m +CONFIG_SGI_PARTITION=y +CONFIG_SHAPER=m +CONFIG_SHMEM=y +CONFIG_SIGMATEL_FIR=m +CONFIG_SIGNALFD=y +CONFIG_SIS190=m +CONFIG_SIS900=m +# CONFIG_SK98LIN is not set +CONFIG_SKFP=m +CONFIG_SKGE=m +# CONFIG_SKGE_DEBUG is not set +CONFIG_SKY2=m +# CONFIG_SKY2_DEBUG is not set +# CONFIG_SLAB is not set +CONFIG_SLABINFO=y +CONFIG_SLHC=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_MODE_SLIP6=y +CONFIG_SLIP_SMART=y +# CONFIG_SLOB is not set +CONFIG_SLUB=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLUB_DEBUG_ON is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_SMC_IRCC_FIR=m +CONFIG_SMSC_PHY=m +CONFIG_SND=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_AC97_POWER_SAVE=y +CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0 +CONFIG_SND_AD1889=m +CONFIG_SND_ALI5451=m +CONFIG_SND_ALS300=m +CONFIG_SND_ALS4000=m +CONFIG_SND_AOA=m +CONFIG_SND_AOA_FABRIC_LAYOUT=m +CONFIG_SND_AOA_ONYX=m +CONFIG_SND_AOA_SOUNDBUS=m +CONFIG_SND_AOA_SOUNDBUS_I2S=m +CONFIG_SND_AOA_TAS=m +CONFIG_SND_AOA_TOONIE=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +CONFIG_SND_AZT3328=m +CONFIG_SND_BT87X=m +CONFIG_SND_BT87X_OVERCLOCK=y +CONFIG_SND_CA0106=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_CS4281=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_CS5530=m +CONFIG_SND_DARLA20=m +CONFIG_SND_DARLA24=m +# CONFIG_SND_DEBUG is not set +CONFIG_SND_DUMMY=m +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_ECHO3G=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_EMU10K1X=m +CONFIG_SND_ENS1370=m +CONFIG_SND_ENS1371=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_FM801=m +CONFIG_SND_FM801_TEA575X=m +CONFIG_SND_FM801_TEA575X_BOOL=y +CONFIG_SND_GINA20=m +CONFIG_SND_GINA24=m +CONFIG_SND_HDA_CODEC_ANALOG=y +CONFIG_SND_HDA_CODEC_ATIHDMI=y +CONFIG_SND_HDA_CODEC_CMEDIA=y +CONFIG_SND_HDA_CODEC_CONEXANT=y +CONFIG_SND_HDA_CODEC_REALTEK=y +CONFIG_SND_HDA_CODEC_SI3054=y +CONFIG_SND_HDA_CODEC_SIGMATEL=y +CONFIG_SND_HDA_CODEC_VIA=y +CONFIG_SND_HDA_GENERIC=y +CONFIG_SND_HDA_HWDEP=y +CONFIG_SND_HDA_INTEL=m +CONFIG_SND_HDA_POWER_SAVE=y +CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 +CONFIG_SND_HDSP=m +CONFIG_SND_HDSPM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INDIGO=m +CONFIG_SND_INDIGODJ=m +CONFIG_SND_INDIGOIO=m +CONFIG_SND_INTEL8X0=m +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_KORG1212=m +CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL=y +CONFIG_SND_LAYLA20=m +CONFIG_SND_LAYLA24=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL=y +CONFIG_SND_MIA=m +CONFIG_SND_MIXART=m +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_MONA=m +CONFIG_SND_MPU401=m +CONFIG_SND_MPU401_UART=m +CONFIG_SND_MTPAV=m +CONFIG_SND_MTS64=m +CONFIG_SND_NM256=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_PCM=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_PCXHR=m +CONFIG_SND_PDAUDIOCF=m +CONFIG_SND_PORTMAN2X4=m +CONFIG_SND_POWERMAC=m +CONFIG_SND_POWERMAC_AUTO_DRC=y +CONFIG_SND_RAWMIDI=m +CONFIG_SND_RIPTIDE=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_SB16_DSP=m +CONFIG_SND_SB_COMMON=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_SOC=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_TIMER=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_USX2Y=m +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_VERBOSE_PROCFS is not set +CONFIG_SND_VIA82XX=m +CONFIG_SND_VIA82XX_MODEM=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_VX222=m +CONFIG_SND_VXPOCKET=m +CONFIG_SND_VX_LIB=m +CONFIG_SND_YMFPCI=m +CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL=y +CONFIG_SOFT_WATCHDOG=m +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_SOUND=m +CONFIG_SOUND_MSNDCLAS=m +CONFIG_SOUND_MSNDPIN=m +CONFIG_SOUND_PRIME=m +CONFIG_SOUND_TRIDENT=m +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPECIALIX=m +# CONFIG_SPECIALIX_RTSCTS is not set +CONFIG_SPI=y +CONFIG_SPI_AT25=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_LM70_LLP=m +CONFIG_SPI_MASTER=y +CONFIG_SPI_SPIDEV=m +CONFIG_SPI_TLE62X0=m +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_SSB=m +CONFIG_SSB_DEBUG=y +CONFIG_SSB_DRIVER_PCICORE=y +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +# CONFIG_SSB_PCMCIAHOST is not set +CONFIG_SSB_PCMCIAHOST_POSSIBLE=y +CONFIG_SSB_POSSIBLE=y +CONFIG_SSFDC=m +CONFIG_STALDRV=y +CONFIG_STANDALONE=y +CONFIG_STRIP=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_SUNGEM=m +CONFIG_SUNRPC=m +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_SUNRPC_GSS=m +CONFIG_SUNRPC_XPRT_RDMA=m +CONFIG_SUN_PARTITION=y +CONFIG_SUSPEND=y +CONFIG_SWAP=y +CONFIG_SX=m +CONFIG_SYNCLINK=m +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_CS=m +CONFIG_SYNCLINK_GT=m +CONFIG_SYN_COOKIES=y +CONFIG_SYSCTL=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSFS=y +# CONFIG_SYSFS_DEPRECATED is not set +CONFIG_SYSV68_PARTITION=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_SYSV_FS=m +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +CONFIG_TASKSTATS=y +# CONFIG_TASK_DELAY_ACCT is not set +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_TASK_XACCT=y +CONFIG_TCG_ATMEL=m +CONFIG_TCG_TPM=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_MD5SIG=y +CONFIG_TEHUTI=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TICK_ONESHOT=y +CONFIG_TIFM_7XX1=m +CONFIG_TIFM_CORE=m +CONFIG_TIGON3=m +CONFIG_TIMER_STATS=y +# CONFIG_TINY_SHMEM is not set +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +# CONFIG_TMD_HERMES is not set +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMS380TR=m +CONFIG_TMSPCI=m +# CONFIG_TOIM3232_DONGLE is not set +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_UCB1400=m +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TR=y +CONFIG_TULIP=m +# CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_NAPI is not set +CONFIG_TUN=m +CONFIG_TUNER_3036=m +CONFIG_TUNER_MT20XX=m +CONFIG_TUNER_SIMPLE=m +CONFIG_TUNER_TDA8290=m +CONFIG_TUNER_TEA5761=m +CONFIG_TUNER_TEA5767=m +CONFIG_TYPHOON=m +# CONFIG_UCC_SLOW is not set +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_UFS_DEBUG is not set +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +CONFIG_UIO=m +CONFIG_UIO_CIF=m +CONFIG_ULI526X=m +CONFIG_ULTRIX_PARTITION=y +CONFIG_UNIX=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_USB=m +CONFIG_USBPCWATCHDOG=m +CONFIG_USB_ACM=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_ATM=m +CONFIG_USB_AUERSWALD=m +CONFIG_USB_BELKIN=y +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_CATC=m +CONFIG_USB_CXACRU=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_DABUSB=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +CONFIG_USB_DSBR=m +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EMI26=m +CONFIG_USB_EMI62=m +CONFIG_USB_EPSON2888=y +CONFIG_USB_ET61X251=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_EZUSB=y +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_GADGET=m +CONFIG_USB_GADGETFS=m +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_M66592 is not set +CONFIG_USB_GADGET_NET2280=y +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_S3C2410 is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_G_SERIAL=m +CONFIG_USB_HID=m +CONFIG_USB_HIDDEV=y +CONFIG_USB_HIDINPUT_POWERBOOK=y +CONFIG_USB_IBMCAM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_IRDA=m +CONFIG_USB_ISP116X_HCD=m +CONFIG_USB_KAWETH=m +CONFIG_USB_KBD=m +CONFIG_USB_KC2190=y +CONFIG_USB_KONICAWC=m +CONFIG_USB_LCD=m +CONFIG_USB_LD=m +CONFIG_USB_LED=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LIBUSUAL=y +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_USB_MON=y +CONFIG_USB_MOUSE=m +CONFIG_USB_NET2280=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +# CONFIG_USB_NET_ZAURUS is not set +CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y +CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_OHCI_HCD_PCI=y +CONFIG_USB_OHCI_HCD_PPC_OF=y +CONFIG_USB_OHCI_HCD_PPC_OF_BE=y +# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set +# CONFIG_USB_OHCI_HCD_SSB is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OV511 is not set +CONFIG_USB_PEGASUS=m +CONFIG_USB_PERSIST=y +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_PRINTER=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_R8A66597_HCD=m +CONFIG_USB_RIO500=m +CONFIG_USB_RTL8150=m +CONFIG_USB_SE401=m +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_AIRPRIME=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IPW=m +# CONFIG_USB_SERIAL_IR is not set +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SISUSBVGA=m +# CONFIG_USB_SISUSBVGA_CON is not set +CONFIG_USB_SL811_CS=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SN9C102=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_STORAGE=m +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_DATAFAB=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STV680=m +CONFIG_USB_SUPPORT=y +CONFIG_USB_SUSPEND=y +# CONFIG_USB_TEST is not set +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_UHCI_HCD=m +CONFIG_USB_USBNET=m +CONFIG_USB_USS720=m +CONFIG_USB_VICAM=m +CONFIG_USB_W9968CF=m +CONFIG_USB_XUSBATM=m +CONFIG_USB_ZC0301=m +CONFIG_USB_ZD1201=m +CONFIG_USB_ZERO=m +CONFIG_USB_ZR364XX=m +# CONFIG_USER_NS is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VETH=m +CONFIG_VFAT_FS=m +CONFIG_VGASTATE=m +# CONFIG_VGA_CONSOLE is not set +CONFIG_VIA_FIR=m +CONFIG_VIA_RHINE=m +CONFIG_VIA_RHINE_MMIO=y +CONFIG_VIA_RHINE_NAPI=y +CONFIG_VIA_VELOCITY=m +CONFIG_VIDEOBUF_DMA_SG=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CAFE_CCIC=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_CPIA_PP=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_CX23885=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_ALSA=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_DEV=m +# CONFIG_VIDEO_DPC is not set +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_FB_IVTV=m +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_MSP3400=m +# CONFIG_VIDEO_MXB is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_24XXX=y +CONFIG_VIDEO_PVRUSB2_29XXX=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA7111=m +CONFIG_VIDEO_SAA7114=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_ALSA=m +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_SAA7134_OSS=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_SAA7191=m +CONFIG_VIDEO_TCM825X=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TDA9875=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_TLV320AIC23B=m +CONFIG_VIDEO_TUNER=m +# CONFIG_VIDEO_TUNER_CUSTOMIZE is not set +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_VP27SMPX=m +CONFIG_VIDEO_VPX3220=m +CONFIG_VIDEO_W9966=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_WM8775=m +# CONFIG_VIRQ_DEBUG is not set +CONFIG_VITESSE_PHY=m +CONFIG_VLAN_8021Q=m +CONFIG_VLSI_FIR=m +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VORTEX=m +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_VXFS_FS=m +CONFIG_W1=m +CONFIG_W1_CON=y +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_DS2760=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_THERM=m +CONFIG_WAN=y +CONFIG_WANXL=m +CONFIG_WAN_ROUTER=m +CONFIG_WAN_ROUTER_DRIVERS=m +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +CONFIG_WATCHDOG_RTAS=m +# CONFIG_WDC_ALI15X3 is not set +CONFIG_WDTPCI=m +CONFIG_WDT_501_PCI=y +CONFIG_WINBOND_840=m +CONFIG_WINBOND_FIR=m +CONFIG_WINDFARM=m +CONFIG_WIRELESS_EXT=y +CONFIG_WLAN_80211=y +CONFIG_WLAN_PRE80211=y +CONFIG_X25=m +CONFIG_X25_ASY=m +CONFIG_XFRM=y +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_XFRM_USER=m +CONFIG_XFS_FS=m +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_QUOTA=y +CONFIG_XFS_RT=y +CONFIG_XFS_SECURITY=y +CONFIG_XOR_BLOCKS=m +CONFIG_YAM=m +CONFIG_YELLOWFIN=m +CONFIG_YENTA=m +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_ZISOFS=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZONE_DMA=y +CONFIG_ZONE_DMA_FLAG=1 --- linux-2.6.24.orig/debian/config/powerpc/config.powerpc +++ linux-2.6.24/debian/config/powerpc/config.powerpc @@ -0,0 +1,216 @@ +# +# Config options for config.powerpc automatically generated by splitconfig.pl +# +# CONFIG_40x is not set +# CONFIG_44x is not set +CONFIG_6xx=y +CONFIG_ACT200L_DONGLE_OLD=m +CONFIG_ACTISYS_DONGLE_OLD=m +CONFIG_ADB=y +CONFIG_ADB_CUDA=y +CONFIG_ADB_MACIO=y +CONFIG_ADB_PMU_LED=y +# CONFIG_ADB_PMU_LED_IDE is not set +# CONFIG_ADVANCED_OPTIONS is not set +CONFIG_AEDSP16_MSS=y +# CONFIG_AEDSP16_SBPRO is not set +CONFIG_ANSLCD=m +CONFIG_APM_EMULATION=m +CONFIG_APM_POWER=m +CONFIG_ARCH_FLATMEM_ENABLE=y +# CONFIG_ARCH_NO_VIRT_TO_BUS is not set +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATM_AMBASSADOR=m +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +CONFIG_ATM_FIRESTREAM=m +CONFIG_ATM_HORIZON=m +# CONFIG_ATM_HORIZON_DEBUG is not set +CONFIG_ATM_IA=m +# CONFIG_ATM_IA_DEBUG is not set +CONFIG_ATM_NICSTAR=m +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set +# CONFIG_ATM_NICSTAR_USE_SUNI is not set +CONFIG_ATM_ZATM=m +# CONFIG_ATM_ZATM_DEBUG is not set +CONFIG_BATTERY_PMU=m +CONFIG_BAYCOM_EPP=m +# CONFIG_BDI_SWITCH is not set +CONFIG_BLK_CPQ_DA=m +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BMAC=m +CONFIG_BOOT_LOAD=0x00800000 +CONFIG_BRIQ_PANEL=m +CONFIG_BROKEN_ON_SMP=y +CONFIG_CLASSIC32=y +CONFIG_CPU_FREQ_DEBUG=y +CONFIG_CPU_FREQ_PMAC=y +# CONFIG_DEBUG_HIGHMEM is not set +CONFIG_DEVICE_TREE="" +CONFIG_DONGLE_OLD=y +# CONFIG_E200 is not set +# CONFIG_EMBEDDED6xx is not set +CONFIG_ESI_DONGLE_OLD=m +CONFIG_FB_CONTROL=y +CONFIG_FB_CT65550=y +CONFIG_FB_IMSTT=y +CONFIG_FB_PLATINUM=y +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +CONFIG_FB_VALKYRIE=y +CONFIG_FEC_MPC52xx=m +CONFIG_FEC_MPC52xx_MDIO=y +CONFIG_FLATMEM=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_FSL_SOC=y +# CONFIG_GENERIC_IOMAP is not set +CONFIG_GENERIC_NVRAM=y +# CONFIG_GENERIC_TBSYNC is not set +CONFIG_GIRBIL_DONGLE_OLD=m +CONFIG_HIBERNATION=y +CONFIG_HIBERNATION_UP_POSSIBLE=y +CONFIG_HIGHMEM=y +CONFIG_HIGHMEM_START=0xfe000000 +# CONFIG_HUGETLB_PAGE is not set +CONFIG_I2C_HYDRA=m +CONFIG_I2C_MPC=m +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_IBMLS=m +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +CONFIG_INPUT_ADBHID=y +CONFIG_IRPORT_SIR=m +# CONFIG_ISA is not set +CONFIG_ISTALLION=m +CONFIG_KERNEL_START=0xc0000000 +CONFIG_LANMEDIA=m +# CONFIG_LBD is not set +CONFIG_LEDS_CLASS=y +CONFIG_LITELINK_DONGLE_OLD=m +CONFIG_LOWMEM_SIZE=0x30000000 +# CONFIG_LSF is not set +CONFIG_MA600_DONGLE_OLD=m +CONFIG_MACE=m +# CONFIG_MACE_AAUI_PORT is not set +CONFIG_MAC_FLOPPY=m +CONFIG_MCP2120_DONGLE_OLD=m +# CONFIG_MMIO_NVRAM is not set +CONFIG_MPC5200_WDT=m +CONFIG_MV643XX_ETH=m +CONFIG_NVRAM=y +CONFIG_OLD_BELKIN_DONGLE_OLD=m +CONFIG_PARIDE_BPCK6=m +CONFIG_PATA_MPC52xx=m +CONFIG_PCMCIA_AHA152X=m +CONFIG_PCMCIA_IBMTR=m +CONFIG_PCMCIA_NINJA_SCSI=m +CONFIG_PCMCIA_XIRTULIP=m +CONFIG_PMAC_APM_EMU=m +CONFIG_PMAC_BACKLIGHT=y +CONFIG_PMAC_BACKLIGHT_LEGACY=y +CONFIG_PMAC_MEDIABAY=y +CONFIG_PM_STD_PARTITION="" +CONFIG_PPC32=y +# CONFIG_PPC601_SYNC_FIX is not set +# CONFIG_PPC64 is not set +# CONFIG_PPC_85xx is not set +# CONFIG_PPC_8xx is not set +# CONFIG_PPC_970_NAP is not set +CONFIG_PPC_BESTCOMM=m +CONFIG_PPC_BESTCOMM_ATA=m +CONFIG_PPC_BESTCOMM_FEC=m +CONFIG_PPC_BESTCOMM_GEN_BD=m +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +CONFIG_PPC_CHRP=y +CONFIG_PPC_CLOCK=y +# CONFIG_PPC_DCR_MMIO is not set +CONFIG_PPC_EFIKA=y +# CONFIG_PPC_INDIRECT_IO is not set +CONFIG_PPC_INDIRECT_PCI=y +CONFIG_PPC_LIB_RHEAP=y +CONFIG_PPC_LITE5200=y +# CONFIG_PPC_MM_SLICES is not set +CONFIG_PPC_MPC106=y +CONFIG_PPC_MPC5200=y +# CONFIG_PPC_MPC5200_BUGFIX is not set +CONFIG_PPC_MPC52xx=y +CONFIG_PPC_STD_MMU_32=y +CONFIG_PSS_MIXER=y +CONFIG_RISCOM8=m +# CONFIG_RTAS_ERROR_LOGGING is not set +CONFIG_SC6600=y +CONFIG_SC6600_CDROM=4 +CONFIG_SC6600_CDROMBASE=0 +CONFIG_SC6600_JOY=y +CONFIG_SCSI_ADVANSYS=m +CONFIG_SCSI_BUSLOGIC=m +CONFIG_SCSI_DC390T=m +CONFIG_SCSI_DPT_I2O=m +CONFIG_SCSI_MAC53C94=m +CONFIG_SCSI_MESH=m +CONFIG_SCSI_MESH_RESET_DELAY_MS=4000 +CONFIG_SCSI_MESH_SYNC_RATE=5 +CONFIG_SCSI_NSP32=m +# CONFIG_SCSI_OMIT_FLASHPOINT is not set +CONFIG_SENSORS_AMS=m +CONFIG_SENSORS_AMS_I2C=y +CONFIG_SENSORS_AMS_PMU=y +CONFIG_SENSORS_M41T00=m +CONFIG_SERIAL_MPC52xx=m +CONFIG_SERIAL_PMACZILOG=m +# CONFIG_SERIAL_PMACZILOG_TTYS is not set +CONFIG_SERIAL_UARTLITE=m +CONFIG_SERIO_I8042=y +# CONFIG_SMP is not set +CONFIG_SOUND_AEDSP16=m +CONFIG_SOUND_DMAP=y +CONFIG_SOUND_KAHLUA=m +CONFIG_SOUND_MPU401=m +CONFIG_SOUND_MSS=m +CONFIG_SOUND_OSS=m +CONFIG_SOUND_PAS=m +CONFIG_SOUND_PSS=m +CONFIG_SOUND_SB=m +CONFIG_SOUND_SSCAPE=m +# CONFIG_SOUND_TRACEINIT is not set +CONFIG_SOUND_TRIX=m +CONFIG_SOUND_UART6850=m +CONFIG_SOUND_VMIDI=m +CONFIG_SOUND_YM3812=m +# CONFIG_SPARSEMEM_MANUAL is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SPI_MPC52xx_PSC=m +CONFIG_STALLION=m +CONFIG_SUSPEND_UP_POSSIBLE=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_TASK_SIZE=0xc0000000 +CONFIG_TAU=y +# CONFIG_TAU_AVERAGE is not set +# CONFIG_TAU_INT is not set +CONFIG_TEKRAM_DONGLE_OLD=m +CONFIG_THERM_ADT746X=m +CONFIG_THERM_WINDTUNNEL=m +CONFIG_TLAN=m +CONFIG_TOSHIBA_FIR=m +# CONFIG_UDBG_RTAS_CONSOLE is not set +# CONFIG_USB_OHCI_HCD_PPC_SOC is not set +CONFIG_VERSION_SIGNATURE="Ubuntu 2.6.24-6.10-powerpc" +CONFIG_VIDEO_STRADIS=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VIRT_TO_BUS=y +CONFIG_WANT_DEVICE_TREE=y +CONFIG_WORD_SIZE=32 --- linux-2.6.24.orig/debian/config/i386/config +++ linux-2.6.24/debian/config/i386/config @@ -0,0 +1,1298 @@ +# +# Common config options automatically generated by splitconfig.pl +# +# CONFIG_4KSTACKS is not set +# CONFIG_64BIT is not set +CONFIG_8139TOO=m +CONFIG_8139TOO_PIO=y +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_AC97_BUS=m +CONFIG_ACORN_PARTITION=y +# CONFIG_ACORN_PARTITION_ADFS is not set +# CONFIG_ACORN_PARTITION_CUMANA is not set +# CONFIG_ACORN_PARTITION_EESOX is not set +CONFIG_ACORN_PARTITION_ICS=y +# CONFIG_ACORN_PARTITION_POWERTEC is not set +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_ACPI=y +CONFIG_ACPI_AC=m +CONFIG_ACPI_BLACKLIST_YEAR=2000 +CONFIG_ACPI_BUTTON=m +CONFIG_ACPI_CONTAINER=m +CONFIG_ACPI_CUSTOM_DSDT_INITRD=y +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_EC=y +CONFIG_ACPI_FAN=m +CONFIG_ACPI_POWER=y +CONFIG_ACPI_PROCESSOR=m +CONFIG_ACPI_PROCFS=y +CONFIG_ACPI_PROCFS_POWER=y +CONFIG_ACPI_PROC_EVENT=y +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_SYSFS_POWER=y +CONFIG_ACPI_SYSTEM=y +CONFIG_ACPI_THERMAL=m +CONFIG_AGP=m +CONFIG_AGP_INTEL=m +CONFIG_AMIGA_PARTITION=y +CONFIG_ANON_INODES=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_FLATMEM_ENABLE=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUPPORTS_MSI=y +CONFIG_ARCH_SUPPORTS_OPROFILE=y +# CONFIG_ARPD is not set +CONFIG_ASK_IP_FIB_HASH=y +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_ATA=m +CONFIG_ATALK=m +CONFIG_ATARI_PARTITION=y +CONFIG_ATA_ACPI=y +CONFIG_ATA_GENERIC=m +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_PIIX=m +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y +# CONFIG_AUDIT_ARCH is not set +CONFIG_AUDIT_GENERIC=y +CONFIG_AUDIT_TREE=y +CONFIG_AUTOFS4_FS=m +CONFIG_AUTOFS_FS=m +CONFIG_AUXDISPLAY=y +CONFIG_BASE_FULL=y +CONFIG_BASE_SMALL=0 +CONFIG_BATTERY_DS2760=m +# CONFIG_BEFS_DEBUG is not set +CONFIG_BEFS_FS=m +CONFIG_BFS_FS=m +CONFIG_BINFMT_AOUT=m +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_BITREVERSE=y +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_CRYPTOLOOP=m +# CONFIG_BLK_DEV_CS5520 is not set +CONFIG_BLK_DEV_DM=m +CONFIG_BLK_DEV_FD=m +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_BLK_DEV_HD is not set +# CONFIG_BLK_DEV_HD_IDE is not set +CONFIG_BLK_DEV_IDECD=m +CONFIG_BLK_DEV_IDEDISK=m +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_JMICRON is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_MD=m +CONFIG_BLK_DEV_NBD=m +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_PIIX is not set +CONFIG_BLK_DEV_PLATFORM=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +# CONFIG_BLK_DEV_RZ1000 is not set +CONFIG_BLK_DEV_SD=m +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_BLOCK=y +CONFIG_BONDING=m +CONFIG_BOOT_IOREMAP=y +# CONFIG_BOOT_PRINTK_DELAY is not set +CONFIG_BOUNCE=y +CONFIG_BRIDGE=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_NETFILTER=y +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BSD_DISKLABEL=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_BUG=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_CGROUPS=y +CONFIG_CGROUP_CPUACCT=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_NS=y +CONFIG_CHR_DEV_SG=m +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG2 is not set +CONFIG_CIFS_EXPERIMENTAL=y +# CONFIG_CIFS_STATS is not set +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_WEAK_PW_HASH=y +# CONFIG_CIFS_XATTR is not set +CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_CLS_U32_MARK=y +# CONFIG_CLS_U32_PERF is not set +CONFIG_CODA_FS=m +# CONFIG_CODA_FS_OLD_API is not set +# CONFIG_COMPAT_VDSO is not set +CONFIG_CONFIGFS_FS=m +CONFIG_CONNECTOR=m +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEBUG is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CRAMFS=y +CONFIG_CRASH_DUMP=y +CONFIG_CRC16=m +CONFIG_CRC32=y +CONFIG_CRC7=m +CONFIG_CRC_CCITT=m +CONFIG_CRC_ITU_T=m +CONFIG_CRYPTO=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_AES_586=m +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_DEV_GEODE=m +CONFIG_CRYPTO_DEV_PADLOCK_AES=m +CONFIG_CRYPTO_DEV_PADLOCK_SHA=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_586=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_XTS=m +CONFIG_DCA=m +CONFIG_DCDBAS=m +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_DRIVER is not set +CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_HIGHMEM is not set +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_DEBUG_MUTEXES is not set +CONFIG_DEBUG_RODATA=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_VM is not set +CONFIG_DECNET=m +# CONFIG_DECNET_ROUTER is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_BIC is not set +# CONFIG_DEFAULT_CUBIC is not set +# CONFIG_DEFAULT_HTCP is not set +CONFIG_DEFAULT_IO_DELAY_TYPE=1 +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_RELATIME=y +CONFIG_DEFAULT_RELATIME_VAL=1 +CONFIG_DEFAULT_RENO=y +CONFIG_DEFAULT_TCP_CONG="reno" +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_WESTWOOD is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_DELL_RBU=m +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_DEVPORT=y +CONFIG_DEV_APPLETALK=m +# CONFIG_DEV_KMEM is not set +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +CONFIG_DMADEVICES=y +CONFIG_DMA_ENGINE=y +CONFIG_DMI=y +CONFIG_DMIID=y +CONFIG_DM_CRYPT=m +# CONFIG_DM_DEBUG is not set +# CONFIG_DM_DELAY is not set +CONFIG_DM_MIRROR=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_EMC=m +CONFIG_DM_MULTIPATH_HP=m +CONFIG_DM_MULTIPATH_RDAC=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_UEVENT=y +CONFIG_DM_ZERO=m +CONFIG_DNOTIFY=y +CONFIG_DOUBLEFAULT=y +CONFIG_DS1682=m +CONFIG_DUMMY=m +CONFIG_DUMMY_CONSOLE=y +CONFIG_E1000=m +CONFIG_E1000E=m +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +CONFIG_E1000_NAPI=y +CONFIG_EARLY_PRINTK=y +CONFIG_ECRYPT_FS=m +CONFIG_EEPROM_93CX6=m +CONFIG_EFI=y +CONFIG_EFI_PARTITION=y +CONFIG_EFI_VARS=y +CONFIG_EFS_FS=m +CONFIG_ELF_CORE=y +CONFIG_EMBEDDED=y +# CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +CONFIG_EPOLL=y +CONFIG_EQUALIZER=m +CONFIG_EVENTFD=y +CONFIG_EXPERIMENTAL=y +CONFIG_EXPORTFS=m +CONFIG_EXT2_FS=m +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT4DEV_FS is not set +CONFIG_FAIR_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_FAIR_USER_SCHED is not set +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_FAT_FS=m +# CONFIG_FAULT_INJECTION is not set +CONFIG_FB=y +CONFIG_FB_ARC=m +CONFIG_FB_ASILIANT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +CONFIG_FB_CIRRUS=m +CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_EFI=y +CONFIG_FB_IMSTT=y +# CONFIG_FB_MACMODES is not set +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_SYS_COPYAREA=m +CONFIG_FB_SYS_FILLRECT=m +CONFIG_FB_SYS_FOPS=m +CONFIG_FB_SYS_IMAGEBLIT=m +CONFIG_FB_TILEBLITTING=y +CONFIG_FB_UVESA=m +CONFIG_FB_VESA=m +CONFIG_FB_VGA16=m +# CONFIG_FB_VIRTUAL is not set +CONFIG_FIB_RULES=y +# CONFIG_FIREWIRE is not set +CONFIG_FIRMWARE_EDID=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_FLATMEM=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +# CONFIG_FORCED_INLINING is not set +CONFIG_FRAMEBUFFER_CONSOLE=m +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FRAME_POINTER is not set +CONFIG_FS_MBCACHE=m +CONFIG_FS_POSIX_ACL=y +CONFIG_FUSE_FS=m +CONFIG_FUSION=y +CONFIG_FUSION_CTL=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_MAX_SGE=128 +CONFIG_FUSION_SAS=m +CONFIG_FUSION_SPI=m +CONFIG_FUTEX=y +CONFIG_FW_LOADER=y +CONFIG_GACT_PROB=y +CONFIG_GAMEPORT=m +CONFIG_GENERIC_ACL=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_CMOS_UPDATE=y +# CONFIG_GENERIC_CPU is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_TIME=y +# CONFIG_GENERIC_TIME_VSYSCALL is not set +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=m +CONFIG_GFS2_FS_LOCKING_NOLOCK=m +CONFIG_HANGCHECK_TIMER=m +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAVE_KVM=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_HFSPLUS_FS=m +CONFIG_HFS_FS=m +CONFIG_HIBERNATION=y +CONFIG_HID_SUPPORT=y +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_HOTPLUG=y +CONFIG_HPET=y +CONFIG_HPET_MMAP=y +# CONFIG_HPET_RTC_IRQ is not set +CONFIG_HPET_TIMER=y +CONFIG_HPFS_FS=m +CONFIG_HT_IRQ=y +CONFIG_HVC_DRIVER=y +CONFIG_HW_CONSOLE=y +CONFIG_HW_RANDOM_INTEL=m +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_300 is not set +CONFIG_I2C=m +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCA=m +CONFIG_I2C_ALGOPCF=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C_DEBUG_CORE is not set +CONFIG_I2C_PIIX4=m +CONFIG_I2C_TAOS_EVM=m +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +CONFIG_ICPLUS_PHY=m +CONFIG_IDE=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +CONFIG_IDE_ARCH_OBSOLETE_INIT=y +# CONFIG_IDE_ARM is not set +CONFIG_IDE_GENERIC=m +CONFIG_IDE_MAX_HWIFS=4 +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IFB=m +# CONFIG_IKCONFIG is not set +CONFIG_INET=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET_AH=m +CONFIG_INET_DCCP_DIAG=m +CONFIG_INET_DIAG=y +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_LRO=m +CONFIG_INET_TCP_DIAG=y +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_INPUT=y +CONFIG_INPUT_EVBUG=m +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_KEYBOARD=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_PCSPKR=m +CONFIG_INSTRUMENTATION=y +CONFIG_INTEL_IOATDMA=m +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_CFQ=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_NOOP=y +# CONFIG_IO_DELAY_0X80 is not set +CONFIG_IO_DELAY_0XED=y +# CONFIG_IO_DELAY_NONE is not set +CONFIG_IO_DELAY_TYPE_0X80=0 +CONFIG_IO_DELAY_TYPE_0XED=1 +CONFIG_IO_DELAY_TYPE_NONE=3 +CONFIG_IO_DELAY_TYPE_UDELAY=2 +# CONFIG_IO_DELAY_UDELAY is not set +CONFIG_IP1000=m +CONFIG_IPDDP=m +CONFIG_IPDDP_DECAP=y +CONFIG_IPDDP_ENCAP=y +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_POWEROFF=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPV6=m +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_IPV6_SIT=m +CONFIG_IPV6_TUNNEL=m +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_DCCP=m +CONFIG_IP_DCCP_ACKVEC=y +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_IP_DCCP_TFRC_LIB=m +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_MROUTE=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_IP_PNP is not set +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_SCTP=m +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_TAB_BITS=12 +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_WRR=m +CONFIG_ISA_DMA_API=y +CONFIG_ISCSI_TCP=m +CONFIG_ISO9660_FS=m +CONFIG_IT8712F_WDT=m +CONFIG_ITCO_VENDOR_SUPPORT=y +CONFIG_ITCO_WDT=m +CONFIG_IXGBE=m +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +# CONFIG_JFS_DEBUG is not set +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +CONFIG_JFS_STATISTICS=y +CONFIG_JOLIET=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_KARMA_PARTITION=y +CONFIG_KEXEC=y +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_KMOD=y +CONFIG_KPROBES=y +CONFIG_KTIME_SCALAR=y +CONFIG_LBD=y +# CONFIG_LDM_DEBUG is not set +CONFIG_LDM_PARTITION=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_LIBCRC32C=m +# CONFIG_LKDTM is not set +CONFIG_LLC2=m +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_LOCKD=m +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_LOCKD_V4=y +# CONFIG_LOCK_STAT is not set +# CONFIG_LOGO is not set +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_LP_CONSOLE is not set +# CONFIG_LSF is not set +# CONFIG_M386 is not set +# CONFIG_M586MMX is not set +# CONFIG_M586TSC is not set +CONFIG_MACVLAN=m +CONFIG_MAC_PARTITION=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_MARKERS is not set +CONFIG_MAX_RAW_DEVS=256 +# CONFIG_MCORE2 is not set +# CONFIG_MCRUSOE is not set +# CONFIG_MCYRIXIII is not set +CONFIG_MD=y +CONFIG_MDIO_BITBANG=m +CONFIG_MD_FAULTY=m +CONFIG_MD_LINEAR=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID5_RESHAPE=y +# CONFIG_MEFFICEON is not set +# CONFIG_MGEODEGX1 is not set +# CONFIG_MGEODE_LX is not set +CONFIG_MICROCODE=m +CONFIG_MICROCODE_OLD_INTERFACE=y +CONFIG_MII=m +CONFIG_MINIX_SUBPARTITION=y +CONFIG_MISC_DEVICES=y +# CONFIG_MK6 is not set +# CONFIG_MK7 is not set +# CONFIG_MK8 is not set +CONFIG_MMU=y +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MOUSE_PS2=m +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +# CONFIG_MPENTIUM4 is not set +# CONFIG_MPENTIUMII is not set +# CONFIG_MPENTIUMIII is not set +# CONFIG_MPENTIUMM is not set +# CONFIG_MPSC is not set +CONFIG_MSDOS_FS=m +CONFIG_MSDOS_PARTITION=y +# CONFIG_MSS is not set +CONFIG_MTRR=y +# CONFIG_MVIAC3_2 is not set +# CONFIG_MVIAC7 is not set +# CONFIG_MWINCHIP2 is not set +# CONFIG_MWINCHIP3D is not set +# CONFIG_MWINCHIPC6 is not set +CONFIG_NE2K_PCI=m +CONFIG_NET=y +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETDEVICES=y +CONFIG_NETDEVICES_MULTIQUEUE=y +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NETWORK_SECMARK=y +CONFIG_NET_9P=m +# CONFIG_NET_9P_DEBUG is not set +CONFIG_NET_9P_FD=m +CONFIG_NET_9P_VIRTIO=m +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_FW=m +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_DMA=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_ETHERNET=y +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_NET_IPIP=m +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_NET_PCI=y +CONFIG_NET_PKTGEN=m +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_NET_SB1000=m +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_FIFO=y +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_RR=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_TULIP=y +CONFIG_NFSD=m +CONFIG_NFSD_TCP=y +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_ENABLED=m +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_NF_CONNTRACK_SANE is not set +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NIU=m +CONFIG_NLS=y +CONFIG_NLS_ASCII=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +# CONFIG_NOHIGHMEM is not set +CONFIG_NONPROMISC_DEVMEM=y +CONFIG_NR_QUICK=1 +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_FS=m +CONFIG_NVRAM=m +# CONFIG_OCFS2_DEBUG_FS is not set +CONFIG_OCFS2_DEBUG_MASKLOG=y +CONFIG_OCFS2_FS=m +CONFIG_OPROFILE=m +CONFIG_OSF_PARTITION=y +CONFIG_PACKET=m +CONFIG_PACKET_MMAP=y +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PARAVIRT=y +CONFIG_PARAVIRT_GUEST=y +CONFIG_PARPORT=m +CONFIG_PARPORT_1284=y +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_PC=m +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARTITION_ADVANCED=y +CONFIG_PATA_ACPI=m +# CONFIG_PATA_ALI is not set +CONFIG_PATA_AMD=m +CONFIG_PATA_ARTOP=m +CONFIG_PATA_ATIIXP=m +# CONFIG_PATA_CMD640_PCI is not set +CONFIG_PATA_CMD64X=m +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CS5535 is not set +CONFIG_PATA_CS5536=m +# CONFIG_PATA_CYPRESS is not set +CONFIG_PATA_HPT366=m +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +CONFIG_PATA_HPT3X3=m +# CONFIG_PATA_HPT3X3_DMA is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_NS87415 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC_OLD is not set +CONFIG_PATA_PLATFORM=m +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_SC1200 is not set +CONFIG_PATA_VIA=m +CONFIG_PCI=y +CONFIG_PCI_BIOS=y +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_DIRECT=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_GOANY=y +# CONFIG_PCI_GOBIOS is not set +# CONFIG_PCI_GODIRECT is not set +# CONFIG_PCI_GOMMCONFIG is not set +CONFIG_PCI_LEGACY=y +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_MSI=y +CONFIG_PCNET32=m +# CONFIG_PCNET32_NAPI is not set +CONFIG_PDA_POWER=m +CONFIG_PHYLIB=m +CONFIG_PHYSICAL_ALIGN=0x100000 +CONFIG_PHYSICAL_START=0x100000 +# CONFIG_PID_NS is not set +CONFIG_PLIST=y +CONFIG_PM=y +CONFIG_PM_DEBUG=y +CONFIG_PM_DISABLE_CONSOLE=y +CONFIG_PM_LEGACY=y +CONFIG_PM_SLEEP=y +CONFIG_PM_STD_PARTITION="" +CONFIG_PM_TRACE=y +# CONFIG_PM_VERBOSE is not set +CONFIG_PNP=y +CONFIG_PNPACPI=y +# CONFIG_PNP_DEBUG is not set +CONFIG_POSIX_MQUEUE=y +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +CONFIG_PPDEV=m +CONFIG_PPP=m +CONFIG_PPPOE=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_SYNC_TTY=m +# CONFIG_PREEMPT is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_PRINTER=m +CONFIG_PRINTK=y +CONFIG_PRINTK_TIME=y +CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_VMCORE=y +CONFIG_PROFILING=y +# CONFIG_PROVE_LOCKING is not set +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_QNX4FS_FS=m +CONFIG_QUICKLIST=y +CONFIG_QUOTA=y +CONFIG_QUOTACTL=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +CONFIG_RAID_ATTRS=m +CONFIG_RAW_DRIVER=m +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_FS=m +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_REISERFS_FS_XATTR=y +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_RELAY=y +CONFIG_RELOCATABLE=y +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_RT_MUTEXES=y +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +# CONFIG_SAMPLES is not set +CONFIG_SBC7240_WDT=m +# CONFIG_SCHEDSTATS is not set +CONFIG_SCHED_DEBUG=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_SCSI=m +# CONFIG_SCSI_AIC7XXX_OLD is not set +CONFIG_SCSI_BUSLOGIC=m +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_DMA=y +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_LOWLEVEL=y +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_NETLINK=y +# CONFIG_SCSI_OMIT_FLASHPOINT is not set +CONFIG_SCSI_PROC_FS=y +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_SAS_ATA=y +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_WAIT_SCAN=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_HMAC_MD5=y +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SECCOMP=y +CONFIG_SECURITY=y +CONFIG_SECURITY_APPARMOR=y +CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 +# CONFIG_SECURITY_APPARMOR_DISABLE is not set +CONFIG_SECURITY_CAPABILITIES=y +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_DISABLE=y +# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SEMAPHORE_SLEEPERS=y +CONFIG_SENSORS_TSL2550=m +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_NR_UARTS=48 +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_PNP=y +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_RAW=m +CONFIG_SERIO_SERPORT=m +CONFIG_SGI_PARTITION=y +CONFIG_SHAPER=m +CONFIG_SHMEM=y +CONFIG_SIGNALFD=y +# CONFIG_SK98LIN is not set +# CONFIG_SLAB is not set +CONFIG_SLABINFO=y +CONFIG_SLHC=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_MODE_SLIP6=y +CONFIG_SLIP_SMART=y +# CONFIG_SLOB is not set +CONFIG_SLUB=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLUB_DEBUG_ON is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_SOFT_WATCHDOG=m +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_SOUND=m +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_SPARSEMEM_STATIC=y +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_SSB=m +CONFIG_SSB_DEBUG=y +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB_SILENT is not set +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_STANDALONE=y +CONFIG_SUNRPC=m +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_SUNRPC_GSS=m +CONFIG_SUN_PARTITION=y +CONFIG_SUSPEND=y +CONFIG_SWAP=y +CONFIG_SYN_COOKIES=y +CONFIG_SYSCTL=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSFS=y +# CONFIG_SYSFS_DEPRECATED is not set +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_SYSV_FS=m +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_TASKSTATS=y +# CONFIG_TASK_DELAY_ACCT is not set +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_TASK_XACCT=y +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_MD5SIG=y +CONFIG_TEHUTI=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TICK_ONESHOT=y +CONFIG_TIMER_STATS=y +# CONFIG_TINY_SHMEM is not set +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_TULIP=m +# CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_NAPI is not set +CONFIG_TUN=m +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_UFS_DEBUG is not set +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +CONFIG_UID16=y +CONFIG_UIO=m +CONFIG_UIO_CIF=m +CONFIG_ULTRIX_PARTITION=y +CONFIG_UNIX=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_USB=m +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_ISP116X_HCD=m +# CONFIG_USB_OTG is not set +CONFIG_USB_PERSIST=y +CONFIG_USB_R8A66597_HCD=m +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_SUPPORT=y +# CONFIG_USB_TEST is not set +CONFIG_USB_UHCI_HCD=m +# CONFIG_USER_NS is not set +CONFIG_VETH=m +CONFIG_VFAT_FS=m +# CONFIG_VGACON_SOFT_SCROLLBACK is not set +CONFIG_VGASTATE=m +CONFIG_VGA_CONSOLE=y +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_VIDEO_SELECT=y +CONFIG_VIRTIO=m +CONFIG_VIRTIO_BALLOON=m +CONFIG_VIRTIO_BLK=m +CONFIG_VIRTIO_NET=m +CONFIG_VIRTIO_PCI=m +CONFIG_VIRTIO_RING=m +CONFIG_VIRTUALIZATION=y +CONFIG_VIRT_TO_BUS=y +CONFIG_VLAN_8021Q=m +CONFIG_VM86=y +CONFIG_VMI=y +# CONFIG_VMSPLIT_1G is not set +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_2G_OPT is not set +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_3G_OPT is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_VXFS_FS=m +CONFIG_W1=m +CONFIG_W1_CON=y +CONFIG_W1_SLAVE_DS2760=m +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_WRAPPER_PRINT is not set +CONFIG_X86=y +CONFIG_X86_32=y +# CONFIG_X86_64 is not set +CONFIG_X86_ACPI_CPUFREQ=m +# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set +# CONFIG_X86_BIGSMP is not set +CONFIG_X86_BIOS_REBOOT=y +CONFIG_X86_BSWAP=y +CONFIG_X86_CMPXCHG=y +CONFIG_X86_CPUID=m +# CONFIG_X86_ELAN is not set +# CONFIG_X86_ES7000 is not set +# CONFIG_X86_E_POWERSAVER is not set +CONFIG_X86_FIND_SMP_CONFIG=y +CONFIG_X86_GENERIC=y +# CONFIG_X86_GENERICARCH is not set +CONFIG_X86_GX_SUSPMOD=m +CONFIG_X86_INTEL_USERCOPY=y +CONFIG_X86_INVLPG=y +CONFIG_X86_IO_APIC=y +CONFIG_X86_L1_CACHE_SHIFT=7 +CONFIG_X86_LOCAL_APIC=y +CONFIG_X86_LONGHAUL=m +CONFIG_X86_LONGRUN=m +# CONFIG_X86_MCE is not set +CONFIG_X86_MINIMUM_CPU_FAMILY=4 +CONFIG_X86_MPPARSE=y +CONFIG_X86_MSR=m +# CONFIG_X86_NUMAQ is not set +CONFIG_X86_P4_CLOCKMOD=m +CONFIG_X86_PC=y +CONFIG_X86_PM_TIMER=y +CONFIG_X86_POPAD_OK=y +CONFIG_X86_POWERNOW_K6=m +CONFIG_X86_POWERNOW_K7=m +CONFIG_X86_POWERNOW_K7_ACPI=y +CONFIG_X86_POWERNOW_K8=m +CONFIG_X86_POWERNOW_K8_ACPI=y +CONFIG_X86_PPRO_FENCE=y +CONFIG_X86_REBOOTFIXUPS=y +CONFIG_X86_SPEEDSTEP_CENTRINO=m +CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y +CONFIG_X86_SPEEDSTEP_ICH=m +CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK=y +# CONFIG_X86_SUMMIT is not set +# CONFIG_X86_VISWS is not set +# CONFIG_X86_VOYAGER is not set +# CONFIG_X86_VSMP is not set +CONFIG_X86_WP_WORKS_OK=y +CONFIG_X86_XADD=y +CONFIG_XFRM=y +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_XFRM_USER=m +CONFIG_XFS_FS=m +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_QUOTA=y +CONFIG_XFS_RT=y +CONFIG_XFS_SECURITY=y +CONFIG_XOR_BLOCKS=m +CONFIG_ZISOFS=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZONE_DMA=y +# CONFIG_ZONE_DMA32 is not set +CONFIG_ZONE_DMA_FLAG=1 --- linux-2.6.24.orig/debian/config/i386/config.generic +++ linux-2.6.24/debian/config/i386/config.generic @@ -0,0 +1,1969 @@ +# +# Config options for config.generic automatically generated by splitconfig.pl +# +CONFIG_3C359=m +CONFIG_3C515=m +CONFIG_60XX_WDT=m +CONFIG_6PACK=m +CONFIG_8139CP=m +CONFIG_8139TOO_8129=y +CONFIG_9P_FS=m +CONFIG_ABYSS=m +CONFIG_AC3200=m +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_ACPI_ASUS=m +CONFIG_ACPI_BATTERY=m +CONFIG_ACPI_BAY=m +CONFIG_ACPI_DOCK=m +CONFIG_ACPI_HOTPLUG_CPU=y +CONFIG_ACPI_SBS=m +CONFIG_ACPI_TOSHIBA=m +CONFIG_ACPI_VIDEO=m +CONFIG_ACQUIRE_WDT=m +CONFIG_ACT200L_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_ADAPTEC_STARFIRE=m +# CONFIG_ADAPTEC_STARFIRE_NAPI is not set +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_ADM8211=m +CONFIG_ADVANTECH_WDT=m +CONFIG_AFFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_AFS_FS=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_AGP_ALI=m +CONFIG_AGP_AMD=m +CONFIG_AGP_AMD64=m +CONFIG_AGP_ATI=m +CONFIG_AGP_EFFICEON=m +CONFIG_AGP_NVIDIA=m +CONFIG_AGP_SIS=m +CONFIG_AGP_SWORKS=m +CONFIG_AGP_VIA=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +CONFIG_AIC79XX_DEBUG_ENABLE=y +CONFIG_AIC79XX_DEBUG_MASK=0 +CONFIG_AIC79XX_REG_PRETTY_PRINT=y +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 +CONFIG_AIC7XXX_DEBUG_ENABLE=y +CONFIG_AIC7XXX_DEBUG_MASK=0 +CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_AIRO=m +CONFIG_AIRO_CS=m +CONFIG_ALIM1535_WDT=m +CONFIG_ALIM7101_WDT=m +CONFIG_ALI_FIR=m +# CONFIG_AMD8111E_NAPI is not set +CONFIG_AMD8111_ETH=m +CONFIG_APM=m +# CONFIG_APM_ALLOW_INTS is not set +# CONFIG_APM_CPU_IDLE is not set +# CONFIG_APM_DISPLAY_BLANK is not set +# CONFIG_APM_DO_ENABLE is not set +# CONFIG_APM_IGNORE_USER_SUSPEND is not set +# CONFIG_APM_REAL_MODE_POWER_OFF is not set +CONFIG_APPLICOM=m +CONFIG_APRICOT=m +CONFIG_ARCNET=m +CONFIG_ARCNET_1051=m +CONFIG_ARCNET_1201=m +CONFIG_ARCNET_CAP=m +CONFIG_ARCNET_COM20020=m +CONFIG_ARCNET_COM20020_CS=m +CONFIG_ARCNET_COM20020_ISA=m +CONFIG_ARCNET_COM20020_PCI=m +CONFIG_ARCNET_COM90xx=m +CONFIG_ARCNET_COM90xxIO=m +CONFIG_ARCNET_RAW=m +CONFIG_ARCNET_RIM_I=m +CONFIG_ARLAN=m +CONFIG_ASUS_LAPTOP=m +CONFIG_AT1700=m +CONFIG_ATA_OVER_ETH=m +CONFIG_ATL1=m +CONFIG_ATM=y +CONFIG_ATMEL=m +CONFIG_ATM_AMBASSADOR=m +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_ATM_CLIP=y +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +CONFIG_ATM_ENI=m +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +CONFIG_ATM_FIRESTREAM=m +CONFIG_ATM_FORE200E=m +CONFIG_ATM_FORE200E_DEBUG=0 +CONFIG_ATM_FORE200E_MAYBE=m +CONFIG_ATM_FORE200E_PCA=y +CONFIG_ATM_FORE200E_PCA_DEFAULT_FW=y +CONFIG_ATM_FORE200E_TX_RETRY=16 +# CONFIG_ATM_FORE200E_USE_TASKLET is not set +CONFIG_ATM_HE=m +CONFIG_ATM_HE_USE_SUNI=y +CONFIG_ATM_HORIZON=m +# CONFIG_ATM_HORIZON_DEBUG is not set +CONFIG_ATM_IA=m +# CONFIG_ATM_IA_DEBUG is not set +CONFIG_ATM_IDT77252=m +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +CONFIG_ATM_IDT77252_USE_SUNI=y +CONFIG_ATM_LANAI=m +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_NICSTAR=m +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set +# CONFIG_ATM_NICSTAR_USE_SUNI is not set +CONFIG_ATM_TCP=m +CONFIG_ATM_ZATM=m +# CONFIG_ATM_ZATM_DEBUG is not set +CONFIG_ATP=m +CONFIG_AX25=m +CONFIG_AX25_DAMA_SLAVE=y +CONFIG_B43=m +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_DEBUG=y +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y +CONFIG_B43LEGACY_PCI_AUTOSELECT=y +CONFIG_B43LEGACY_PIO=y +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_B43_DEBUG=y +CONFIG_B43_DMA=y +CONFIG_B43_DMA_AND_PIO_MODE=y +# CONFIG_B43_DMA_MODE is not set +CONFIG_B43_LEDS=y +CONFIG_B43_PCICORE_AUTOSELECT=y +CONFIG_B43_PCI_AUTOSELECT=y +# CONFIG_B43_PCMCIA is not set +CONFIG_B43_PIO=y +# CONFIG_B43_PIO_MODE is not set +CONFIG_B43_RFKILL=y +CONFIG_B44=m +CONFIG_B44_PCI=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI_AUTOSELECT=y +CONFIG_BACKLIGHT_CARILLO_RANCH=m +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_CORGI=m +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_PROGEAR=m +CONFIG_BAYCOM_EPP=m +CONFIG_BAYCOM_PAR=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_BCM43XX=m +# CONFIG_BCM43XX_DEBUG is not set +CONFIG_BCM43XX_DMA=y +CONFIG_BCM43XX_DMA_AND_PIO_MODE=y +# CONFIG_BCM43XX_DMA_MODE is not set +CONFIG_BCM43XX_PIO=y +# CONFIG_BCM43XX_PIO_MODE is not set +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_BLK_DEV_4DRIVES=y +CONFIG_BLK_DEV_AEC62XX=m +CONFIG_BLK_DEV_ALI14XX=m +CONFIG_BLK_DEV_ALI15X3=m +CONFIG_BLK_DEV_ATIIXP=m +CONFIG_BLK_DEV_CMD640=y +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +CONFIG_BLK_DEV_CMD64X=m +CONFIG_BLK_DEV_CS5530=m +CONFIG_BLK_DEV_CS5535=m +CONFIG_BLK_DEV_CY82C693=m +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_DELKIN=m +CONFIG_BLK_DEV_DTC2278=m +CONFIG_BLK_DEV_HPT34X=m +CONFIG_BLK_DEV_HPT366=m +CONFIG_BLK_DEV_HT6560B=m +CONFIG_BLK_DEV_IDE=m +CONFIG_BLK_DEV_IDEACPI=y +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDEDMA=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_IDEFLOPPY=m +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_BLK_DEV_IDEPNP=y +CONFIG_BLK_DEV_IDESCSI=m +CONFIG_BLK_DEV_IDETAPE=m +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_BLK_DEV_NS87415=m +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_OPTI621=m +CONFIG_BLK_DEV_PDC202XX_OLD=m +CONFIG_BLK_DEV_QD65XX=m +CONFIG_BLK_DEV_SC1200=m +CONFIG_BLK_DEV_SX8=m +CONFIG_BLK_DEV_TC86C001=m +CONFIG_BLK_DEV_TRM290=m +CONFIG_BLK_DEV_UMC8672=m +CONFIG_BLK_DEV_UMEM=m +CONFIG_BLK_DEV_XD=m +CONFIG_BNX2=m +CONFIG_BPQETHER=m +CONFIG_BROADCOM_PHY=m +CONFIG_BT=m +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_CMTP=m +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HIDP=m +CONFIG_BT_L2CAP=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_SCO=m +CONFIG_C101=m +CONFIG_CAPI_AVM=y +CONFIG_CAPI_EICON=y +CONFIG_CAPI_TRACE=y +CONFIG_CARDBUS=y +CONFIG_CARDMAN_4000=m +CONFIG_CARDMAN_4040=m +CONFIG_CASSINI=m +CONFIG_CFAG12864B=m +CONFIG_CFAG12864B_RATE=20 +CONFIG_CFG80211=m +CONFIG_CHECK_SIGNATURE=y +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T1_NAPI=y +CONFIG_CHELSIO_T3=m +CONFIG_CHR_DEV_OSST=m +CONFIG_CHR_DEV_SCH=m +CONFIG_CHR_DEV_ST=m +CONFIG_CICADA_PHY=m +CONFIG_CISS_SCSI_TAPE=y +# CONFIG_COMPUTONE is not set +CONFIG_COPS=m +CONFIG_COPS_DAYNA=y +CONFIG_COPS_TANGENT=y +CONFIG_COSA=m +CONFIG_CPU5_WDT=m +CONFIG_CPUSETS=y +CONFIG_CPU_FREQ_TABLE=m +CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_CRYPTO_ABLKCIPHER=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_DEV_PADLOCK=y +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CS5535_GPIO=m +CONFIG_CS89x0=m +CONFIG_CYCLADES=m +CONFIG_CYCLADES_SYNC=m +CONFIG_CYCLOMX_X25=y +# CONFIG_CYZ_INTR is not set +CONFIG_DAB=y +CONFIG_DAVICOM_PHY=m +CONFIG_DE2104X=m +CONFIG_DE4X5=m +CONFIG_DE600=m +CONFIG_DE620=m +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DECNET_NF_GRABULATOR=m +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_DEFXX=m +# CONFIG_DEFXX_MMIO is not set +CONFIG_DEPCA=m +CONFIG_DE_AOC=y +CONFIG_DIGIEPCA=m +CONFIG_DISPLAY_SUPPORT=m +CONFIG_DL2K=m +CONFIG_DLCI=m +CONFIG_DLCI_MAX=8 +CONFIG_DM9102=m +CONFIG_DONGLE=y +CONFIG_DRM=m +CONFIG_DRM_I810=m +CONFIG_DRM_I830=m +CONFIG_DRM_I915=m +CONFIG_DRM_MGA=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_SAVAGE=m +CONFIG_DRM_SIS=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_VIA=m +CONFIG_DRM_VIA_CHROME9=m +CONFIG_DSCC4=m +CONFIG_DSCC4_PCISYNC=y +CONFIG_DSCC4_PCI_RST=y +CONFIG_DTLK=m +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_B2C2_FLEXCOP=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_BT8XX=m +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_PATCH=m +CONFIG_DVB_CAPTURE_DRIVERS=y +CONFIG_DVB_CINERGYT2=m +CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y +CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250 +CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100 +CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512 +CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32 +CONFIG_DVB_CINERGYT2_TUNING=y +CONFIG_DVB_CORE=m +CONFIG_DVB_CORE_ATTACH=y +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_ISL6421=m +CONFIG_DVB_L64781=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_MT312=m +CONFIG_DVB_MT352=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_PLL=m +CONFIG_DVB_PLUTO2=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TDA827X=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_TUNER_MT2060=m +CONFIG_DVB_TUNER_MT2131=m +CONFIG_DVB_TUNER_MT2266=m +CONFIG_DVB_TUNER_QT1010=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_CXUSB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_ZL10353=m +CONFIG_E100=m +CONFIG_E2100=m +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +CONFIG_EDAC=y +# CONFIG_EDAC_AMD76X is not set +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_E752X=m +CONFIG_EDAC_E7XXX=m +CONFIG_EDAC_I3000=m +CONFIG_EDAC_I5000=m +CONFIG_EDAC_I82860=m +CONFIG_EDAC_I82875P=m +CONFIG_EDAC_I82975X=m +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC_R82600=m +CONFIG_EDD=y +CONFIG_EDD_OFF=y +CONFIG_EEPRO100=m +CONFIG_EEXPRESS=m +CONFIG_EEXPRESS_PRO=m +CONFIG_EISA=y +CONFIG_EISA_NAMES=y +CONFIG_EISA_PCI_EISA=y +CONFIG_EISA_VIRTUAL_ROOT=y +CONFIG_EISA_VLB_PRIMING=y +CONFIG_EL1=m +CONFIG_EL16=m +CONFIG_EL2=m +CONFIG_EL3=m +CONFIG_ELMC=m +CONFIG_ELMC_II=m +CONFIG_ELPLUS=m +CONFIG_EPIC100=m +CONFIG_ES3210=m +CONFIG_ESI_DONGLE=m +# CONFIG_ESPSERIAL is not set +CONFIG_ETH16I=m +CONFIG_EUROTECH_WDT=m +CONFIG_EWRK3=m +CONFIG_FARSYNC=m +CONFIG_FB_3DFX=m +# CONFIG_FB_3DFX_ACCEL is not set +CONFIG_FB_ARK=m +CONFIG_FB_ATY=m +CONFIG_FB_ATY128=m +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY_BACKLIGHT=y +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_CARILLO_RANCH=m +CONFIG_FB_CYBER2000=m +CONFIG_FB_CYBLA=m +CONFIG_FB_DDC=m +CONFIG_FB_GEODE=y +CONFIG_FB_GEODE_GX=m +CONFIG_FB_GEODE_GX1=m +# CONFIG_FB_GEODE_GX_SET_FBSIZE is not set +CONFIG_FB_GEODE_LX=m +CONFIG_FB_HECUBA=m +CONFIG_FB_HGA=m +# CONFIG_FB_HGA_ACCEL is not set +CONFIG_FB_I810=m +# CONFIG_FB_I810_GTF is not set +CONFIG_FB_IMAC=y +CONFIG_FB_INTEL=m +# CONFIG_FB_INTEL_DEBUG is not set +CONFIG_FB_INTEL_I2C=y +CONFIG_FB_KYRO=m +CONFIG_FB_LE80578=m +CONFIG_FB_MATROX=m +CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MULTIHEAD=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_NEOMAGIC=m +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_BACKLIGHT=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_I2C=y +CONFIG_FB_PM2=m +CONFIG_FB_PM2_FIFO_DISCONNECT=y +CONFIG_FB_PM3=m +CONFIG_FB_RADEON=m +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RIVA=m +CONFIG_FB_RIVA_BACKLIGHT=y +# CONFIG_FB_RIVA_DEBUG is not set +CONFIG_FB_RIVA_I2C=y +CONFIG_FB_S1D13XXX=m +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_ACCEL=y +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SIS=m +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +CONFIG_FB_SM501=m +CONFIG_FB_SVGALIB=m +CONFIG_FB_TRIDENT=m +# CONFIG_FB_TRIDENT_ACCEL is not set +CONFIG_FB_VOODOO1=m +CONFIG_FB_VT8623=m +CONFIG_FDDI=y +CONFIG_FEALNX=m +CONFIG_FIXED_MII_1000_FDX=y +# CONFIG_FIXED_MII_100_FDX is not set +# CONFIG_FIXED_MII_10_FDX is not set +CONFIG_FIXED_MII_AMNT=1 +CONFIG_FIXED_PHY=m +CONFIG_FORCEDETH=m +# CONFIG_FORCEDETH_NAPI is not set +CONFIG_FTL=m +CONFIG_FUJITSU_LAPTOP=m +CONFIG_FUSION_LAN=m +CONFIG_FUSION_LOGGING=y +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_GIGASET_BASE=m +# CONFIG_GIGASET_DEBUG is not set +CONFIG_GIGASET_M101=m +CONFIG_GIGASET_M105=m +# CONFIG_GIGASET_UNDOCREQ is not set +CONFIG_GIRBIL_DONGLE=m +CONFIG_HAMACHI=m +CONFIG_HAMRADIO=y +CONFIG_HAPPYMEAL=m +CONFIG_HDLC=m +CONFIG_HDLC_CISCO=m +CONFIG_HDLC_FR=m +CONFIG_HDLC_PPP=m +CONFIG_HDLC_RAW=m +CONFIG_HDLC_RAW_ETH=m +CONFIG_HDLC_X25=m +CONFIG_HERMES=m +CONFIG_HIBERNATION_SMP_POSSIBLE=y +CONFIG_HID=m +CONFIG_HIDRAW=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HID_FF is not set +CONFIG_HIGHMEM4G=y +# CONFIG_HIGHMEM64G is not set +CONFIG_HIPPI=y +CONFIG_HISAX_16_0=y +CONFIG_HISAX_16_3=y +CONFIG_HISAX_1TR6=y +CONFIG_HISAX_ASUSCOM=y +CONFIG_HISAX_AVM_A1=y +CONFIG_HISAX_AVM_A1_CS=m +CONFIG_HISAX_AVM_A1_PCMCIA=y +CONFIG_HISAX_BKM_A4T=y +# CONFIG_HISAX_DEBUG is not set +CONFIG_HISAX_DIEHLDIVA=y +CONFIG_HISAX_ELSA=y +CONFIG_HISAX_ELSA_CS=m +CONFIG_HISAX_ENTERNOW_PCI=y +CONFIG_HISAX_EURO=y +CONFIG_HISAX_FRITZPCI=y +CONFIG_HISAX_FRITZ_PCIPNP=m +CONFIG_HISAX_GAZEL=y +CONFIG_HISAX_HDLC=y +CONFIG_HISAX_HFC4S8S=m +CONFIG_HISAX_HFCS=y +CONFIG_HISAX_HFCUSB=m +CONFIG_HISAX_HFC_PCI=y +CONFIG_HISAX_HFC_SX=y +CONFIG_HISAX_HSTSAPHIR=y +CONFIG_HISAX_ISURF=y +CONFIG_HISAX_IX1MICROR2=y +CONFIG_HISAX_MAX_CARDS=8 +CONFIG_HISAX_MIC=y +CONFIG_HISAX_NETJET=y +CONFIG_HISAX_NETJET_U=y +CONFIG_HISAX_NI1=y +CONFIG_HISAX_NICCY=y +# CONFIG_HISAX_NO_KEYPAD is not set +# CONFIG_HISAX_NO_LLC is not set +# CONFIG_HISAX_NO_SENDCOMPLETE is not set +CONFIG_HISAX_S0BOX=y +CONFIG_HISAX_SCT_QUADRO=y +CONFIG_HISAX_SEDLBAUER=y +CONFIG_HISAX_SEDLBAUER_CS=m +CONFIG_HISAX_SPORTSTER=y +CONFIG_HISAX_ST5481=m +CONFIG_HISAX_TELEINT=y +CONFIG_HISAX_TELESPCI=y +CONFIG_HISAX_TELES_CS=m +CONFIG_HISAX_W6692=y +CONFIG_HOSTAP=m +CONFIG_HOSTAP_CS=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_PLX=m +CONFIG_HOSTESS_SV11=m +CONFIG_HOTPLUG_CPU=y +CONFIG_HOTPLUG_PCI=m +CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +CONFIG_HOTPLUG_PCI_COMPAQ=m +CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM=y +CONFIG_HOTPLUG_PCI_CPCI=y +CONFIG_HOTPLUG_PCI_CPCI_GENERIC=m +CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m +CONFIG_HOTPLUG_PCI_FAKE=m +CONFIG_HOTPLUG_PCI_IBM=m +CONFIG_HOTPLUG_PCI_PCIE=m +CONFIG_HOTPLUG_PCI_SHPC=m +CONFIG_HP100=m +CONFIG_HPET_EMULATE_RTC=y +CONFIG_HPLAN=m +CONFIG_HPLAN_PLUS=m +# CONFIG_HPT34X_AUTODMA is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HWMON_VID=m +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_AMD=m +CONFIG_HW_RANDOM_GEODE=m +CONFIG_HW_RANDOM_VIA=m +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_I801=m +CONFIG_I2C_I810=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PCA_ISA=m +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_STUB=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_BUS=m +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_PROC=m +CONFIG_I2O_SCSI=m +CONFIG_I6300ESB_WDT=m +CONFIG_I82092=m +CONFIG_I82365=m +CONFIG_I8K=m +CONFIG_IB700_WDT=m +CONFIG_IBMASR=m +CONFIG_IBMLANA=m +CONFIG_IBMLS=m +# CONFIG_IBMMCA_SCSI_DEV_RESET is not set +CONFIG_IBMMCA_SCSI_ORDER_STANDARD=y +CONFIG_IBMOL=m +CONFIG_IBMTR=m +CONFIG_IBM_ASM=m +CONFIG_IDEPCI_SHARE_IRQ=y +CONFIG_IDE_PROC_FS=y +CONFIG_IEEE1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_OHCI1394=m +CONFIG_IEEE1394_PCILYNX=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE80211=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_CRYPT_WEP=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_AMSO1100=m +CONFIG_INFINIBAND_AMSO1100_DEBUG=y +CONFIG_INFINIBAND_CXGB3=m +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_IPOIB_DEBUG=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set +CONFIG_INFINIBAND_ISER=m +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INFTL=m +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_ATLAS_BTNS=m +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_TABLET=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_WISTRON_BTNS=m +CONFIG_INPUT_YEALINK=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IPPP_FILTER=y +# CONFIG_IPV6_MULTIPLE_TABLES is not set +CONFIG_IPW2100=m +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +# CONFIG_IPW2200_DEBUG is not set +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IRCOMM=m +CONFIG_IRDA=m +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_DEBUG=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_ULTRA=y +CONFIG_IRLAN=m +CONFIG_IRNET=m +# CONFIG_IRQBALANCE is not set +CONFIG_IRTTY_SIR=m +CONFIG_ISA=y +CONFIG_ISAPNP=y +CONFIG_ISDN=m +CONFIG_ISDN_AUDIO=y +CONFIG_ISDN_CAPI=m +CONFIG_ISDN_CAPI_CAPI20=m +CONFIG_ISDN_CAPI_CAPIDRV=m +CONFIG_ISDN_CAPI_CAPIFS=m +CONFIG_ISDN_CAPI_CAPIFS_BOOL=y +CONFIG_ISDN_CAPI_MIDDLEWARE=y +CONFIG_ISDN_DIVAS=m +CONFIG_ISDN_DIVAS_BRIPCI=y +CONFIG_ISDN_DIVAS_DIVACAPI=m +CONFIG_ISDN_DIVAS_MAINT=m +CONFIG_ISDN_DIVAS_PRIPCI=y +CONFIG_ISDN_DIVAS_USERIDI=m +CONFIG_ISDN_DIVERSION=m +CONFIG_ISDN_DRV_ACT2000=m +CONFIG_ISDN_DRV_AVMB1_AVM_CS=m +CONFIG_ISDN_DRV_AVMB1_B1ISA=m +CONFIG_ISDN_DRV_AVMB1_B1PCI=m +CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m +CONFIG_ISDN_DRV_AVMB1_C4=m +CONFIG_ISDN_DRV_AVMB1_T1ISA=m +CONFIG_ISDN_DRV_AVMB1_T1PCI=m +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y +CONFIG_ISDN_DRV_GIGASET=m +CONFIG_ISDN_DRV_HISAX=m +CONFIG_ISDN_DRV_ICN=m +CONFIG_ISDN_DRV_PCBIT=m +CONFIG_ISDN_DRV_SC=m +CONFIG_ISDN_I4L=m +CONFIG_ISDN_MPP=y +CONFIG_ISDN_PPP=y +CONFIG_ISDN_PPP_BSDCOMP=m +CONFIG_ISDN_PPP_VJ=y +CONFIG_ISDN_TTY_FAX=y +CONFIG_ISDN_X25=y +# CONFIG_ISI is not set +# CONFIG_IWLWIFI is not set +CONFIG_IXGB=m +# CONFIG_IXGB_NAPI is not set +CONFIG_JFFS2_CMODE_FAVOURLZO=y +# CONFIG_JFFS2_CMODE_NONE is not set +# CONFIG_JFFS2_CMODE_PRIORITY is not set +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_LZO=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_232=y +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_K8_NB=y +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KINGSUN_DONGLE=m +CONFIG_KS0108=m +CONFIG_KS0108_DELAY=2 +CONFIG_KS0108_PORT=0x378 +CONFIG_KS959_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +CONFIG_KVM=m +CONFIG_KVM_AMD=m +CONFIG_KVM_INTEL=m +CONFIG_LANCE=m +CONFIG_LANMEDIA=m +CONFIG_LAPB=m +CONFIG_LAPBETHER=m +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_LTV350QV=m +CONFIG_LEDS_CLASS=m +CONFIG_LEDS_NET48XX=m +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=m +CONFIG_LEDS_TRIGGER_IDE_DISK=y +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_WRAP=m +CONFIG_LGUEST=m +# CONFIG_LGUEST_GUEST is not set +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_CS=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_SDIO=m +CONFIG_LIBERTAS_USB=m +CONFIG_LITELINK_DONGLE=m +CONFIG_LLC=y +CONFIG_LNE390=m +CONFIG_LOCK_KERNEL=y +CONFIG_LP486E=m +CONFIG_LTPC=m +CONFIG_LXT_PHY=m +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +# CONFIG_M486 is not set +CONFIG_M586=y +# CONFIG_M686 is not set +CONFIG_MA600_DONGLE=m +CONFIG_MAC80211=m +# CONFIG_MAC80211_DEBUG is not set +CONFIG_MAC80211_DEBUGFS=y +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_RCSIMPLE=y +CONFIG_MACHZ_WDT=m +CONFIG_MACINTOSH_DRIVERS=y +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_MADGEMC=m +CONFIG_MARVELL_PHY=m +# CONFIG_MATH_EMULATION is not set +CONFIG_MCA=y +CONFIG_MCA_LEGACY=y +# CONFIG_MCA_PROC_FS is not set +CONFIG_MCP2120_DONGLE=m +CONFIG_MCS_FIR=m +CONFIG_MDA_CONSOLE=m +CONFIG_MD_RAID10=m +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_SAS=m +CONFIG_MFD_SM501=m +CONFIG_MINIX_FS=m +CONFIG_MIXCOMWD=m +CONFIG_MKISS=m +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_MLX4_INFINIBAND=m +CONFIG_MMC=m +CONFIG_MMC_BLOCK=m +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_RICOH_MMC=m +CONFIG_MMC_SDHCI=m +CONFIG_MMC_TIFM_SD=m +# CONFIG_MMC_UNSAFE_RESUME is not set +CONFIG_MMC_WBSD=m +CONFIG_MOUSE_APPLETOUCH=m +# CONFIG_MOUSE_ATIXL is not set +CONFIG_MOUSE_INPORT=m +CONFIG_MOUSE_LOGIBM=m +CONFIG_MOUSE_PC110PAD=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_VSXXXAA=m +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +CONFIG_MOXA_SMARTIO_NEW=m +CONFIG_MSI_LAPTOP=m +CONFIG_MTD=m +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTD_ABSENT=m +CONFIG_MTD_ALAUDA=m +CONFIG_MTD_AMD76XROM=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK2MTD=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_MTD_CFI=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_CHAR=m +CONFIG_MTD_CK804XROM=m +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_CONCAT=m +CONFIG_MTD_DATAFLASH=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_DILNETPC=m +CONFIG_MTD_DILNETPC_BOOTSIZE=0x80000 +CONFIG_MTD_DOC2000=m +CONFIG_MTD_DOC2001=m +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCECC=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCPROBE_ADDRESS=0 +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_ESB2ROM=m +CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_ICHXROM=m +CONFIG_MTD_INTEL_VR_NOR=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_L440GX=m +CONFIG_MTD_M25P80=m +CONFIG_MTD_MAP_BANK_WIDTH_1=y +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +CONFIG_MTD_MTDRAM=m +CONFIG_MTD_NAND=m +CONFIG_MTD_NAND_CAFE=m +CONFIG_MTD_NAND_CS553X=m +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_NANDSIM=m +CONFIG_MTD_NAND_PLATFORM=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NETSC520=m +CONFIG_MTD_NETtel=m +CONFIG_MTD_ONENAND=m +CONFIG_MTD_ONENAND_2X_PROGRAM=y +# CONFIG_MTD_ONENAND_OTP is not set +CONFIG_MTD_ONENAND_SIM=m +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +CONFIG_MTD_OOPS=m +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_PCI=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PHYSMAP_LEN=0x4000000 +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PLATRAM=m +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +CONFIG_MTD_PNC2000=m +CONFIG_MTD_RAM=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS=m +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +CONFIG_MTD_ROM=m +CONFIG_MTD_SBC_GXX=m +CONFIG_MTD_SC520CDP=m +CONFIG_MTD_SCB2_FLASH=m +CONFIG_MTD_SCx200_DOCFLASH=m +CONFIG_MTD_SLRAM=m +CONFIG_MTD_TS5500=m +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_DEBUG is not set +CONFIG_MTD_UBI_GLUEBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MWAVE=m +CONFIG_MYRI10GE=m +CONFIG_N2=m +CONFIG_NATSEMI=m +CONFIG_NCPFS_EXTRAS=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_OS2_NS=y +CONFIG_NCPFS_PACKET_SIGNING=y +# CONFIG_NCPFS_SMALLDOS is not set +CONFIG_NCPFS_STRONG=y +CONFIG_NCP_FS=m +CONFIG_NE2000=m +CONFIG_NE2_MCA=m +CONFIG_NE3210=m +# CONFIG_NETLABEL is not set +CONFIG_NETROM=m +CONFIG_NETXEN_NIC=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +# CONFIG_NET_CLS_POLICE is not set +CONFIG_NET_DCCPPROBE=m +CONFIG_NET_FC=y +CONFIG_NET_ISA=y +CONFIG_NET_PCMCIA=y +CONFIG_NET_POCKET=y +CONFIG_NET_SCH_ATM=m +CONFIG_NET_TCPPROBE=m +CONFIG_NET_VENDOR_3COM=y +CONFIG_NET_VENDOR_RACAL=y +CONFIG_NET_VENDOR_SMC=y +CONFIG_NEW_LEDS=y +CONFIG_NFS_V4=y +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NI52=m +CONFIG_NI65=m +CONFIG_NL80211=y +# CONFIG_NORTEL_HERMES is not set +CONFIG_NO_HZ=y +CONFIG_NR_CPUS=8 +CONFIG_NS83820=m +CONFIG_NSC_FIR=m +CONFIG_NSC_GPIO=m +# CONFIG_NTFS_RW is not set +CONFIG_N_HDLC=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_P54_COMMON=m +CONFIG_P54_PCI=m +CONFIG_P54_USB=m +CONFIG_PARIDE=m +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +CONFIG_PARIDE_BPCK6=m +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_EPAT=m +# CONFIG_PARIDE_EPATC8 is not set +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PG=m +CONFIG_PARIDE_PT=m +CONFIG_PARPORT_AX88796=m +CONFIG_PARPORT_NOT_PC=y +CONFIG_PARPORT_PC_FIFO=y +CONFIG_PARPORT_PC_PCMCIA=m +CONFIG_PARPORT_SERIAL=m +CONFIG_PATA_CS5520=m +CONFIG_PATA_EFAR=m +# CONFIG_PATA_ISAPNP is not set +CONFIG_PATA_IT8213=m +CONFIG_PATA_IT821X=m +CONFIG_PATA_JMICRON=m +# CONFIG_PATA_LEGACY is not set +CONFIG_PATA_MARVELL=m +CONFIG_PATA_MPIIX=m +CONFIG_PATA_NETCELL=m +CONFIG_PATA_OLDPIIX=m +CONFIG_PATA_PCMCIA=m +CONFIG_PATA_PDC2027X=m +CONFIG_PATA_QDI=m +CONFIG_PATA_RZ1000=m +CONFIG_PATA_SERVERWORKS=m +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +CONFIG_PATA_TRIFLEX=m +CONFIG_PATA_WINBOND=m +# CONFIG_PATA_WINBOND_VLB is not set +CONFIG_PC300=m +# CONFIG_PC300TOO is not set +CONFIG_PC300_MLPPP=y +CONFIG_PC8736x_GPIO=m +CONFIG_PC87413_WDT=m +CONFIG_PCCARD=m +CONFIG_PCCARD_NONSTATIC=m +CONFIG_PCI200SYN=m +CONFIG_PCIEAER=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIPCWATCHDOG=m +CONFIG_PCI_ATMEL=m +# CONFIG_PCI_HERMES is not set +CONFIG_PCMCIA=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_AHA152X=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_PCMCIA_AXNET=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_HERMES=m +CONFIG_PCMCIA_IBMTR=m +CONFIG_PCMCIA_IOCTL=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_NETWAVE=m +CONFIG_PCMCIA_NINJA_SCSI=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_PROBE=y +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_RAYCS=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_SPECTRUM=m +CONFIG_PCMCIA_SYM53C500=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_WL3501=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_PCWATCHDOG=m +CONFIG_PD6729=m +CONFIG_PDC202XX_BURST=y +CONFIG_PDC_ADMA=m +CONFIG_PHANTOM=m +CONFIG_PHONE=m +CONFIG_PHONE_IXJ=m +CONFIG_PHONE_IXJ_PCMCIA=m +CONFIG_PLIP=m +# CONFIG_PLX_HERMES is not set +CONFIG_PM_SLEEP_SMP=y +CONFIG_PNPBIOS=y +CONFIG_PNPBIOS_PROC_FS=y +CONFIG_PPPOATM=m +CONFIG_PREEMPT_BKL=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_NOTIFIERS=y +CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_PRISM54=m +CONFIG_PROC_PID_CPUSET=y +CONFIG_PROTEON=m +CONFIG_QLA3XXX=m +CONFIG_QSEMI_PHY=m +CONFIG_R3964=m +CONFIG_R8169=m +# CONFIG_R8169_NAPI is not set +CONFIG_R8169_VLAN=y +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_AZTECH=m +CONFIG_RADIO_CADET=m +CONFIG_RADIO_GEMTEK=m +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAESTRO=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RADIO_RTRACK=m +CONFIG_RADIO_RTRACK2=m +CONFIG_RADIO_SF16FMI=m +CONFIG_RADIO_SF16FMR2=m +CONFIG_RADIO_TERRATEC=m +CONFIG_RADIO_TRUST=m +CONFIG_RADIO_TYPHOON=m +# CONFIG_RADIO_TYPHOON_PROC_FS is not set +CONFIG_RADIO_ZOLTRIX=m +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y +# CONFIG_RESOURCES_64BIT is not set +CONFIG_RFD_FTL=m +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +CONFIG_RFKILL_LEDS=y +# CONFIG_RIO is not set +CONFIG_ROADRUNNER=m +# CONFIG_ROADRUNNER_LARGE_RINGS is not set +CONFIG_ROCKETPORT=m +CONFIG_ROMFS_FS=m +CONFIG_ROSE=m +CONFIG_RT2400PCI=m +CONFIG_RT2400PCI_RFKILL=y +CONFIG_RT2500PCI=m +CONFIG_RT2500PCI_RFKILL=y +CONFIG_RT2500USB=m +CONFIG_RT2X00=m +# CONFIG_RT2X00_DEBUG is not set +CONFIG_RT2X00_LIB=m +# CONFIG_RT2X00_LIB_DEBUGFS is not set +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_PCI=m +CONFIG_RT2X00_LIB_RFKILL=y +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT61PCI=m +CONFIG_RT61PCI_RFKILL=y +CONFIG_RT73USB=m +CONFIG_RTC=y +CONFIG_RTC_CLASS=m +# CONFIG_RTC_DRV_CMOS is not set +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_M41T80_WDT=y +CONFIG_RTC_DRV_M48T59=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_STK17TA8=m +CONFIG_RTC_DRV_TEST=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_LIB=m +CONFIG_RTL8187=m +CONFIG_RXKAD=m +CONFIG_S2IO=m +# CONFIG_S2IO_NAPI is not set +CONFIG_SATA_AHCI=m +CONFIG_SATA_INIC162X=m +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIL24=m +CONFIG_SATA_SIS=m +CONFIG_SATA_SVW=m +CONFIG_SATA_SX4=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m +CONFIG_SBC8360_WDT=m +CONFIG_SBC_EPX_C3_WATCHDOG=m +CONFIG_SBNI=m +# CONFIG_SBNI_MULTILINE is not set +CONFIG_SC1200_WDT=m +CONFIG_SC520_WDT=m +CONFIG_SC92031=m +CONFIG_SCC=m +# CONFIG_SCC_DELAY is not set +# CONFIG_SCC_TRXECHO is not set +CONFIG_SCHED_MC=y +CONFIG_SCHED_SMT=y +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_7000FASST=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_ADVANSYS=m +CONFIG_SCSI_AHA152X=m +CONFIG_SCSI_AHA1542=m +CONFIG_SCSI_AHA1740=m +CONFIG_SCSI_AIC79XX=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_SCSI_AIC94XX=m +CONFIG_SCSI_ARCMSR=m +CONFIG_SCSI_ARCMSR_AER=y +CONFIG_SCSI_DC390T=m +CONFIG_SCSI_DC395x=m +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_DPT_I2O=m +CONFIG_SCSI_DTC3280=m +CONFIG_SCSI_EATA=m +CONFIG_SCSI_EATA_LINKED_COMMANDS=y +CONFIG_SCSI_EATA_MAX_TAGS=16 +CONFIG_SCSI_EATA_TAGGED_QUEUE=y +CONFIG_SCSI_FC_TGT_ATTRS=y +CONFIG_SCSI_FD_MCS=m +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_SCSI_GDTH=m +CONFIG_SCSI_GENERIC_NCR5380=m +CONFIG_SCSI_GENERIC_NCR5380_MMIO=m +CONFIG_SCSI_GENERIC_NCR53C400=y +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_IBMMCA=m +CONFIG_SCSI_IMM=m +CONFIG_SCSI_IN2000=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_DUMP is not set +# CONFIG_SCSI_IPR_TRACE is not set +CONFIG_SCSI_IPS=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +CONFIG_SCSI_LOWLEVEL_PCMCIA=y +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_NCR53C406A=m +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=4 +CONFIG_SCSI_NCR53C8XX_SYNC=5 +CONFIG_SCSI_NCR_D700=m +CONFIG_SCSI_NCR_Q720=m +CONFIG_SCSI_NSP32=m +CONFIG_SCSI_PAS16=m +CONFIG_SCSI_PPA=m +CONFIG_SCSI_PSI240I=m +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_QLOGIC_FAS=m +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_SEAGATE=m +CONFIG_SCSI_SIM710=m +CONFIG_SCSI_SRP=m +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C416=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_T128=m +CONFIG_SCSI_TGT=m +CONFIG_SCSI_U14_34F=m +CONFIG_SCSI_U14_34F_LINKED_COMMANDS=y +CONFIG_SCSI_U14_34F_MAX_TAGS=8 +CONFIG_SCSI_U14_34F_TAGGED_QUEUE=y +CONFIG_SCSI_ULTRASTOR=m +CONFIG_SCx200=m +CONFIG_SCx200HR_TIMER=m +CONFIG_SCx200_ACB=m +CONFIG_SCx200_GPIO=m +CONFIG_SCx200_I2C=m +CONFIG_SCx200_I2C_SCL=12 +CONFIG_SCx200_I2C_SDA=13 +CONFIG_SCx200_WDT=m +CONFIG_SDIO_UART=m +CONFIG_SDLA=m +CONFIG_SEALEVEL_4021=m +CONFIG_SEEQ8005=m +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_ABITUGURU3=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_APPLESMC=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_FSCHMD=m +CONFIG_SENSORS_FSCPOS=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_HDAPS=m +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_IBMPEX=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_K8TEMP=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_LM93=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SERIAL_8250_ACCENT=m +CONFIG_SERIAL_8250_BOCA=m +CONFIG_SERIAL_8250_CS=m +CONFIG_SERIAL_8250_EXAR_ST16C554=m +CONFIG_SERIAL_8250_FOURPORT=m +CONFIG_SERIAL_8250_HUB6=m +CONFIG_SERIAL_8250_MCA=m +CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_SERIO_CT82C710=m +CONFIG_SERIO_PARKBD=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SGI_IOC4=m +CONFIG_SIGMATEL_FIR=m +CONFIG_SIS190=m +CONFIG_SIS900=m +CONFIG_SKFP=m +CONFIG_SKGE=m +# CONFIG_SKGE_DEBUG is not set +CONFIG_SKISA=m +CONFIG_SKY2=m +# CONFIG_SKY2_DEBUG is not set +CONFIG_SMC9194=m +CONFIG_SMCTR=m +CONFIG_SMC_IRCC_FIR=m +CONFIG_SMP=y +CONFIG_SMSC37B787_WDT=m +CONFIG_SMSC_PHY=m +# CONFIG_SND is not set +CONFIG_SONYPI=m +CONFIG_SONYPI_COMPAT=y +CONFIG_SONY_LAPTOP=m +# CONFIG_SOUND_PRIME is not set +CONFIG_SPECIALIX=m +# CONFIG_SPECIALIX_RTSCTS is not set +CONFIG_SPI=y +CONFIG_SPI_AT25=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_LM70_LLP=m +CONFIG_SPI_MASTER=y +CONFIG_SPI_SPIDEV=m +CONFIG_SPI_TLE62X0=m +CONFIG_SSB_DRIVER_PCICORE=y +# CONFIG_SSB_PCMCIAHOST is not set +CONFIG_SSB_PCMCIAHOST_POSSIBLE=y +CONFIG_SSFDC=m +CONFIG_STALDRV=y +CONFIG_STOP_MACHINE=y +CONFIG_STRIP=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_SUNGEM=m +CONFIG_SUNRPC_XPRT_RDMA=m +CONFIG_SUSPEND_SMP_POSSIBLE=y +CONFIG_SX=m +CONFIG_SYNCLINK=m +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_CS=m +CONFIG_SYNCLINK_GT=m +CONFIG_SYSV68_PARTITION=y +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +CONFIG_TCG_ATMEL=m +CONFIG_TCG_INFINEON=m +CONFIG_TCG_NSC=m +CONFIG_TCG_TIS=m +CONFIG_TCG_TPM=m +CONFIG_TCIC=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TELCLOCK=m +CONFIG_THINKPAD_ACPI=m +CONFIG_THINKPAD_ACPI_BAY=y +# CONFIG_THINKPAD_ACPI_DEBUG is not set +CONFIG_TIFM_7XX1=m +CONFIG_TIFM_CORE=m +CONFIG_TIGON3=m +CONFIG_TLAN=m +# CONFIG_TMD_HERMES is not set +CONFIG_TMS380TR=m +CONFIG_TMSPCI=m +# CONFIG_TOIM3232_DONGLE is not set +CONFIG_TOSHIBA=m +CONFIG_TOSHIBA_FIR=m +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_UCB1400=m +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TR=y +CONFIG_TUNER_3036=m +CONFIG_TUNER_MT20XX=m +CONFIG_TUNER_SIMPLE=m +CONFIG_TUNER_TDA8290=m +CONFIG_TUNER_TEA5761=m +CONFIG_TUNER_TEA5767=m +CONFIG_TYPHOON=m +CONFIG_ULI526X=m +CONFIG_ULTRA=m +CONFIG_ULTRA32=m +CONFIG_ULTRAMCA=m +CONFIG_USBPCWATCHDOG=m +CONFIG_USB_ACM=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_ARMLINUX=y +CONFIG_USB_ATM=m +CONFIG_USB_AUERSWALD=m +CONFIG_USB_BELKIN=y +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_CATC=m +CONFIG_USB_CXACRU=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_DABUSB=m +CONFIG_USB_DSBR=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EMI26=m +CONFIG_USB_EMI62=m +CONFIG_USB_EPSON2888=y +CONFIG_USB_ET61X251=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_EZUSB=y +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_GADGET=m +CONFIG_USB_GADGETFS=m +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_M66592 is not set +CONFIG_USB_GADGET_NET2280=y +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_S3C2410 is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_G_SERIAL=m +CONFIG_USB_HID=m +CONFIG_USB_HIDDEV=y +CONFIG_USB_HIDINPUT_POWERBOOK=y +CONFIG_USB_IBMCAM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_IRDA=m +CONFIG_USB_KAWETH=m +CONFIG_USB_KBD=m +CONFIG_USB_KC2190=y +CONFIG_USB_KONICAWC=m +CONFIG_USB_LCD=m +CONFIG_USB_LD=m +CONFIG_USB_LED=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LIBUSUAL=y +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_USB_MON=y +CONFIG_USB_MOUSE=m +CONFIG_USB_NET2280=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_HCD_SSB is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OV511 is not set +CONFIG_USB_PEGASUS=m +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_PRINTER=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_RIO500=m +CONFIG_USB_RTL8150=m +CONFIG_USB_SE401=m +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_AIRPRIME=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IPW=m +# CONFIG_USB_SERIAL_IR is not set +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SISUSBVGA=m +# CONFIG_USB_SISUSBVGA_CON is not set +CONFIG_USB_SL811_CS=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SN9C102=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STV680=m +CONFIG_USB_SUSPEND=y +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_USBNET=m +CONFIG_USB_USS720=m +CONFIG_USB_VICAM=m +CONFIG_USB_W9968CF=m +CONFIG_USB_XUSBATM=m +CONFIG_USB_ZC0301=m +CONFIG_USB_ZD1201=m +CONFIG_USB_ZERO=m +CONFIG_USB_ZR364XX=m +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VERSION_SIGNATURE="Ubuntu 2.6.24-4.6-generic" +CONFIG_VIA_FIR=m +CONFIG_VIA_RHINE=m +CONFIG_VIA_RHINE_MMIO=y +CONFIG_VIA_RHINE_NAPI=y +CONFIG_VIA_VELOCITY=m +CONFIG_VIDEOBUF_DMA_SG=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CAFE_CCIC=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_CPIA_PP=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_CX23885=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_DEV=m +# CONFIG_VIDEO_DPC is not set +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_FB_IVTV=m +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_MEYE=m +CONFIG_VIDEO_MSP3400=m +# CONFIG_VIDEO_MXB is not set +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_VIDEO_PMS=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_24XXX=y +CONFIG_VIDEO_PVRUSB2_29XXX=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA7111=m +CONFIG_VIDEO_SAA7114=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_SAA7191=m +CONFIG_VIDEO_STRADIS=m +CONFIG_VIDEO_TCM825X=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TDA9875=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_TLV320AIC23B=m +CONFIG_VIDEO_TUNER=m +# CONFIG_VIDEO_TUNER_CUSTOMIZE is not set +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_VP27SMPX=m +CONFIG_VIDEO_VPX3220=m +CONFIG_VIDEO_W9966=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VITESSE_PHY=m +CONFIG_VLSI_FIR=m +CONFIG_VORTEX=m +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_THERM=m +CONFIG_W83627HF_WDT=m +CONFIG_W83697HF_WDT=m +CONFIG_W83877F_WDT=m +CONFIG_W83977F_WDT=m +CONFIG_WAFER_WDT=m +CONFIG_WAN=y +CONFIG_WANXL=m +CONFIG_WAN_ROUTER=m +CONFIG_WAN_ROUTER_DRIVERS=m +CONFIG_WAVELAN=m +CONFIG_WD80x3=m +# CONFIG_WDC_ALI15X3 is not set +CONFIG_WDT=m +CONFIG_WDTPCI=m +CONFIG_WDT_501=y +CONFIG_WDT_501_PCI=y +CONFIG_WINBOND_840=m +CONFIG_WINBOND_FIR=m +CONFIG_WIRELESS_EXT=y +CONFIG_WLAN_80211=y +CONFIG_WLAN_PRE80211=y +CONFIG_X25=m +CONFIG_X25_ASY=m +CONFIG_X86_ALIGNMENT_16=y +CONFIG_X86_CPUFREQ_NFORCE2=m +CONFIG_X86_F00F_BUG=y +CONFIG_X86_HT=y +CONFIG_X86_SMP=y +CONFIG_X86_SPEEDSTEP_LIB=m +CONFIG_X86_SPEEDSTEP_SMI=m +CONFIG_X86_TRAMPOLINE=y +CONFIG_YAM=m +CONFIG_YELLOWFIN=m +CONFIG_YENTA=m +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_ZNET=m --- linux-2.6.24.orig/debian/config/i386/config.server +++ linux-2.6.24/debian/config/i386/config.server @@ -0,0 +1,1976 @@ +# +# Config options for config.server automatically generated by splitconfig.pl +# +CONFIG_3C359=m +CONFIG_3C515=m +CONFIG_60XX_WDT=m +CONFIG_6PACK=m +CONFIG_8139CP=m +CONFIG_8139TOO_8129=y +CONFIG_9P_FS=m +CONFIG_ABYSS=m +CONFIG_AC3200=m +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_ACPI_ASUS=m +CONFIG_ACPI_BATTERY=m +CONFIG_ACPI_BAY=m +CONFIG_ACPI_DOCK=m +CONFIG_ACPI_HOTPLUG_CPU=y +CONFIG_ACPI_SBS=m +CONFIG_ACPI_TOSHIBA=m +CONFIG_ACPI_VIDEO=m +CONFIG_ACQUIRE_WDT=m +CONFIG_ACT200L_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_ADAPTEC_STARFIRE=m +# CONFIG_ADAPTEC_STARFIRE_NAPI is not set +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_ADM8211=m +CONFIG_ADVANTECH_WDT=m +CONFIG_AFFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_AFS_FS=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_AGP_ALI=m +CONFIG_AGP_AMD=m +CONFIG_AGP_AMD64=m +CONFIG_AGP_ATI=m +CONFIG_AGP_EFFICEON=m +CONFIG_AGP_NVIDIA=m +CONFIG_AGP_SIS=m +CONFIG_AGP_SWORKS=m +CONFIG_AGP_VIA=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +CONFIG_AIC79XX_DEBUG_ENABLE=y +CONFIG_AIC79XX_DEBUG_MASK=0 +CONFIG_AIC79XX_REG_PRETTY_PRINT=y +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 +CONFIG_AIC7XXX_DEBUG_ENABLE=y +CONFIG_AIC7XXX_DEBUG_MASK=0 +CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_AIRO=m +CONFIG_AIRO_CS=m +CONFIG_ALIM1535_WDT=m +CONFIG_ALIM7101_WDT=m +CONFIG_ALI_FIR=m +# CONFIG_AMD8111E_NAPI is not set +CONFIG_AMD8111_ETH=m +CONFIG_APM=m +# CONFIG_APM_ALLOW_INTS is not set +# CONFIG_APM_CPU_IDLE is not set +# CONFIG_APM_DISPLAY_BLANK is not set +# CONFIG_APM_DO_ENABLE is not set +# CONFIG_APM_IGNORE_USER_SUSPEND is not set +# CONFIG_APM_REAL_MODE_POWER_OFF is not set +CONFIG_APPLICOM=m +CONFIG_APRICOT=m +CONFIG_ARCNET=m +CONFIG_ARCNET_1051=m +CONFIG_ARCNET_1201=m +CONFIG_ARCNET_CAP=m +CONFIG_ARCNET_COM20020=m +CONFIG_ARCNET_COM20020_CS=m +CONFIG_ARCNET_COM20020_ISA=m +CONFIG_ARCNET_COM20020_PCI=m +CONFIG_ARCNET_COM90xx=m +CONFIG_ARCNET_COM90xxIO=m +CONFIG_ARCNET_RAW=m +CONFIG_ARCNET_RIM_I=m +CONFIG_ARLAN=m +CONFIG_ASUS_LAPTOP=m +CONFIG_AT1700=m +CONFIG_ATA_OVER_ETH=m +CONFIG_ATL1=m +CONFIG_ATM=y +CONFIG_ATMEL=m +CONFIG_ATM_AMBASSADOR=m +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_ATM_CLIP=y +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +CONFIG_ATM_ENI=m +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +CONFIG_ATM_FIRESTREAM=m +CONFIG_ATM_FORE200E=m +CONFIG_ATM_FORE200E_DEBUG=0 +CONFIG_ATM_FORE200E_MAYBE=m +CONFIG_ATM_FORE200E_PCA=y +CONFIG_ATM_FORE200E_PCA_DEFAULT_FW=y +CONFIG_ATM_FORE200E_TX_RETRY=16 +# CONFIG_ATM_FORE200E_USE_TASKLET is not set +CONFIG_ATM_HE=m +CONFIG_ATM_HE_USE_SUNI=y +CONFIG_ATM_HORIZON=m +# CONFIG_ATM_HORIZON_DEBUG is not set +CONFIG_ATM_IA=m +# CONFIG_ATM_IA_DEBUG is not set +CONFIG_ATM_IDT77252=m +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +CONFIG_ATM_IDT77252_USE_SUNI=y +CONFIG_ATM_LANAI=m +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_NICSTAR=m +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set +# CONFIG_ATM_NICSTAR_USE_SUNI is not set +CONFIG_ATM_TCP=m +CONFIG_ATM_ZATM=m +# CONFIG_ATM_ZATM_DEBUG is not set +CONFIG_ATP=m +CONFIG_AX25=m +CONFIG_AX25_DAMA_SLAVE=y +CONFIG_B43=m +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_DEBUG=y +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y +CONFIG_B43LEGACY_PCI_AUTOSELECT=y +CONFIG_B43LEGACY_PIO=y +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_B43_DEBUG=y +CONFIG_B43_DMA=y +CONFIG_B43_DMA_AND_PIO_MODE=y +# CONFIG_B43_DMA_MODE is not set +CONFIG_B43_LEDS=y +CONFIG_B43_PCICORE_AUTOSELECT=y +CONFIG_B43_PCI_AUTOSELECT=y +# CONFIG_B43_PCMCIA is not set +CONFIG_B43_PIO=y +# CONFIG_B43_PIO_MODE is not set +CONFIG_B43_RFKILL=y +CONFIG_B44=m +CONFIG_B44_PCI=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI_AUTOSELECT=y +CONFIG_BACKLIGHT_CARILLO_RANCH=m +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_CORGI=m +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_PROGEAR=m +CONFIG_BAYCOM_EPP=m +CONFIG_BAYCOM_PAR=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_BCM43XX=m +# CONFIG_BCM43XX_DEBUG is not set +CONFIG_BCM43XX_DMA=y +CONFIG_BCM43XX_DMA_AND_PIO_MODE=y +# CONFIG_BCM43XX_DMA_MODE is not set +CONFIG_BCM43XX_PIO=y +# CONFIG_BCM43XX_PIO_MODE is not set +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_BLK_DEV_4DRIVES=y +CONFIG_BLK_DEV_AEC62XX=m +CONFIG_BLK_DEV_ALI14XX=m +CONFIG_BLK_DEV_ALI15X3=m +CONFIG_BLK_DEV_ATIIXP=m +CONFIG_BLK_DEV_CMD640=y +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +CONFIG_BLK_DEV_CMD64X=m +CONFIG_BLK_DEV_CS5530=m +CONFIG_BLK_DEV_CS5535=m +CONFIG_BLK_DEV_CY82C693=m +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_DELKIN=m +CONFIG_BLK_DEV_DTC2278=m +CONFIG_BLK_DEV_HPT34X=m +CONFIG_BLK_DEV_HPT366=m +CONFIG_BLK_DEV_HT6560B=m +CONFIG_BLK_DEV_IDE=m +CONFIG_BLK_DEV_IDEACPI=y +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDEDMA=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_IDEFLOPPY=m +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_BLK_DEV_IDEPNP=y +CONFIG_BLK_DEV_IDESCSI=m +CONFIG_BLK_DEV_IDETAPE=m +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_BLK_DEV_NS87415=m +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_OPTI621=m +CONFIG_BLK_DEV_PDC202XX_OLD=m +CONFIG_BLK_DEV_QD65XX=m +CONFIG_BLK_DEV_SC1200=m +CONFIG_BLK_DEV_SX8=m +CONFIG_BLK_DEV_TC86C001=m +CONFIG_BLK_DEV_TRM290=m +CONFIG_BLK_DEV_UMC8672=m +CONFIG_BLK_DEV_UMEM=m +CONFIG_BLK_DEV_XD=m +CONFIG_BNX2=m +CONFIG_BPQETHER=m +CONFIG_BROADCOM_PHY=m +CONFIG_BT=m +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_CMTP=m +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HIDP=m +CONFIG_BT_L2CAP=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_SCO=m +CONFIG_C101=m +CONFIG_CAPI_AVM=y +CONFIG_CAPI_EICON=y +CONFIG_CAPI_TRACE=y +CONFIG_CARDBUS=y +CONFIG_CARDMAN_4000=m +CONFIG_CARDMAN_4040=m +CONFIG_CASSINI=m +CONFIG_CFAG12864B=m +CONFIG_CFAG12864B_RATE=20 +CONFIG_CFG80211=m +CONFIG_CHECK_SIGNATURE=y +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T1_NAPI=y +CONFIG_CHELSIO_T3=m +CONFIG_CHR_DEV_OSST=m +CONFIG_CHR_DEV_SCH=m +CONFIG_CHR_DEV_ST=m +CONFIG_CICADA_PHY=m +CONFIG_CISS_SCSI_TAPE=y +# CONFIG_COMPUTONE is not set +CONFIG_COPS=m +CONFIG_COPS_DAYNA=y +CONFIG_COPS_TANGENT=y +CONFIG_COSA=m +CONFIG_CPU5_WDT=m +CONFIG_CPUSETS=y +CONFIG_CPU_FREQ_TABLE=m +CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_CRYPTO_ABLKCIPHER=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_DEV_PADLOCK=y +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CS5535_GPIO=m +CONFIG_CS89x0=m +CONFIG_CYCLADES=m +CONFIG_CYCLADES_SYNC=m +CONFIG_CYCLOMX_X25=y +# CONFIG_CYZ_INTR is not set +CONFIG_DAB=y +CONFIG_DAVICOM_PHY=m +CONFIG_DE2104X=m +CONFIG_DE4X5=m +CONFIG_DE600=m +CONFIG_DE620=m +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DECNET_NF_GRABULATOR=m +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_DEADLINE=y +CONFIG_DEFAULT_IOSCHED="deadline" +CONFIG_DEFXX=m +# CONFIG_DEFXX_MMIO is not set +CONFIG_DEPCA=m +CONFIG_DE_AOC=y +CONFIG_DIGIEPCA=m +CONFIG_DISPLAY_SUPPORT=m +CONFIG_DL2K=m +CONFIG_DLCI=m +CONFIG_DLCI_MAX=8 +CONFIG_DM9102=m +CONFIG_DONGLE=y +CONFIG_DRM=m +CONFIG_DRM_I810=m +CONFIG_DRM_I830=m +CONFIG_DRM_I915=m +CONFIG_DRM_MGA=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_SAVAGE=m +CONFIG_DRM_SIS=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_VIA=m +CONFIG_DRM_VIA_CHROME9=m +CONFIG_DSCC4=m +CONFIG_DSCC4_PCISYNC=y +CONFIG_DSCC4_PCI_RST=y +CONFIG_DTLK=m +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_B2C2_FLEXCOP=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_BT8XX=m +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_PATCH=m +CONFIG_DVB_CAPTURE_DRIVERS=y +CONFIG_DVB_CINERGYT2=m +CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y +CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250 +CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100 +CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512 +CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32 +CONFIG_DVB_CINERGYT2_TUNING=y +CONFIG_DVB_CORE=m +CONFIG_DVB_CORE_ATTACH=y +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_ISL6421=m +CONFIG_DVB_L64781=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_MT312=m +CONFIG_DVB_MT352=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_PLL=m +CONFIG_DVB_PLUTO2=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TDA827X=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_TUNER_MT2060=m +CONFIG_DVB_TUNER_MT2131=m +CONFIG_DVB_TUNER_MT2266=m +CONFIG_DVB_TUNER_QT1010=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_CXUSB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_ZL10353=m +CONFIG_E100=m +CONFIG_E2100=m +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +CONFIG_EDAC=y +# CONFIG_EDAC_AMD76X is not set +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_E752X=m +CONFIG_EDAC_E7XXX=m +CONFIG_EDAC_I3000=m +CONFIG_EDAC_I5000=m +CONFIG_EDAC_I82860=m +CONFIG_EDAC_I82875P=m +CONFIG_EDAC_I82975X=m +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC_R82600=m +CONFIG_EDD=y +# CONFIG_EDD_OFF is not set +CONFIG_EEPRO100=m +CONFIG_EEXPRESS=m +CONFIG_EEXPRESS_PRO=m +CONFIG_EISA=y +CONFIG_EISA_NAMES=y +CONFIG_EISA_PCI_EISA=y +CONFIG_EISA_VIRTUAL_ROOT=y +CONFIG_EISA_VLB_PRIMING=y +CONFIG_EL1=m +CONFIG_EL16=m +CONFIG_EL2=m +CONFIG_EL3=m +CONFIG_ELMC=m +CONFIG_ELMC_II=m +CONFIG_ELPLUS=m +CONFIG_EPIC100=m +CONFIG_ES3210=m +CONFIG_ESI_DONGLE=m +# CONFIG_ESPSERIAL is not set +CONFIG_ETH16I=m +CONFIG_EUROTECH_WDT=m +CONFIG_EWRK3=m +CONFIG_FARSYNC=m +CONFIG_FB_3DFX=m +# CONFIG_FB_3DFX_ACCEL is not set +CONFIG_FB_ARK=m +CONFIG_FB_ATY=m +CONFIG_FB_ATY128=m +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY_BACKLIGHT=y +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_CARILLO_RANCH=m +CONFIG_FB_CYBER2000=m +CONFIG_FB_CYBLA=m +CONFIG_FB_DDC=m +CONFIG_FB_GEODE=y +CONFIG_FB_GEODE_GX=m +CONFIG_FB_GEODE_GX1=m +# CONFIG_FB_GEODE_GX_SET_FBSIZE is not set +CONFIG_FB_GEODE_LX=m +CONFIG_FB_HECUBA=m +CONFIG_FB_HGA=m +# CONFIG_FB_HGA_ACCEL is not set +CONFIG_FB_I810=m +# CONFIG_FB_I810_GTF is not set +CONFIG_FB_IMAC=y +CONFIG_FB_INTEL=m +# CONFIG_FB_INTEL_DEBUG is not set +CONFIG_FB_INTEL_I2C=y +CONFIG_FB_KYRO=m +CONFIG_FB_LE80578=m +CONFIG_FB_MATROX=m +CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MULTIHEAD=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_NEOMAGIC=m +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_BACKLIGHT=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_I2C=y +CONFIG_FB_PM2=m +CONFIG_FB_PM2_FIFO_DISCONNECT=y +CONFIG_FB_PM3=m +CONFIG_FB_RADEON=m +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RIVA=m +CONFIG_FB_RIVA_BACKLIGHT=y +# CONFIG_FB_RIVA_DEBUG is not set +CONFIG_FB_RIVA_I2C=y +CONFIG_FB_S1D13XXX=m +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_ACCEL=y +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SIS=m +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +CONFIG_FB_SM501=m +CONFIG_FB_SVGALIB=m +CONFIG_FB_TRIDENT=m +# CONFIG_FB_TRIDENT_ACCEL is not set +CONFIG_FB_VOODOO1=m +CONFIG_FB_VT8623=m +CONFIG_FDDI=y +CONFIG_FEALNX=m +CONFIG_FIXED_MII_1000_FDX=y +# CONFIG_FIXED_MII_100_FDX is not set +# CONFIG_FIXED_MII_10_FDX is not set +CONFIG_FIXED_MII_AMNT=1 +CONFIG_FIXED_PHY=m +CONFIG_FORCEDETH=m +# CONFIG_FORCEDETH_NAPI is not set +CONFIG_FTL=m +CONFIG_FUJITSU_LAPTOP=m +CONFIG_FUSION_LAN=m +CONFIG_FUSION_LOGGING=y +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_GIGASET_BASE=m +# CONFIG_GIGASET_DEBUG is not set +CONFIG_GIGASET_M101=m +CONFIG_GIGASET_M105=m +# CONFIG_GIGASET_UNDOCREQ is not set +CONFIG_GIRBIL_DONGLE=m +CONFIG_HAMACHI=m +CONFIG_HAMRADIO=y +CONFIG_HAPPYMEAL=m +CONFIG_HDLC=m +CONFIG_HDLC_CISCO=m +CONFIG_HDLC_FR=m +CONFIG_HDLC_PPP=m +CONFIG_HDLC_RAW=m +CONFIG_HDLC_RAW_ETH=m +CONFIG_HDLC_X25=m +CONFIG_HERMES=m +CONFIG_HIBERNATION_SMP_POSSIBLE=y +CONFIG_HID=m +CONFIG_HIDRAW=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HID_FF is not set +# CONFIG_HIGHMEM4G is not set +CONFIG_HIGHMEM64G=y +CONFIG_HIPPI=y +CONFIG_HISAX_16_0=y +CONFIG_HISAX_16_3=y +CONFIG_HISAX_1TR6=y +CONFIG_HISAX_ASUSCOM=y +CONFIG_HISAX_AVM_A1=y +CONFIG_HISAX_AVM_A1_CS=m +CONFIG_HISAX_AVM_A1_PCMCIA=y +CONFIG_HISAX_BKM_A4T=y +# CONFIG_HISAX_DEBUG is not set +CONFIG_HISAX_DIEHLDIVA=y +CONFIG_HISAX_ELSA=y +CONFIG_HISAX_ELSA_CS=m +CONFIG_HISAX_ENTERNOW_PCI=y +CONFIG_HISAX_EURO=y +CONFIG_HISAX_FRITZPCI=y +CONFIG_HISAX_FRITZ_PCIPNP=m +CONFIG_HISAX_GAZEL=y +CONFIG_HISAX_HDLC=y +CONFIG_HISAX_HFC4S8S=m +CONFIG_HISAX_HFCS=y +CONFIG_HISAX_HFCUSB=m +CONFIG_HISAX_HFC_PCI=y +CONFIG_HISAX_HFC_SX=y +CONFIG_HISAX_HSTSAPHIR=y +CONFIG_HISAX_ISURF=y +CONFIG_HISAX_IX1MICROR2=y +CONFIG_HISAX_MAX_CARDS=8 +CONFIG_HISAX_MIC=y +CONFIG_HISAX_NETJET=y +CONFIG_HISAX_NETJET_U=y +CONFIG_HISAX_NI1=y +CONFIG_HISAX_NICCY=y +# CONFIG_HISAX_NO_KEYPAD is not set +# CONFIG_HISAX_NO_LLC is not set +# CONFIG_HISAX_NO_SENDCOMPLETE is not set +CONFIG_HISAX_S0BOX=y +CONFIG_HISAX_SCT_QUADRO=y +CONFIG_HISAX_SEDLBAUER=y +CONFIG_HISAX_SEDLBAUER_CS=m +CONFIG_HISAX_SPORTSTER=y +CONFIG_HISAX_ST5481=m +CONFIG_HISAX_TELEINT=y +CONFIG_HISAX_TELESPCI=y +CONFIG_HISAX_TELES_CS=m +CONFIG_HISAX_W6692=y +CONFIG_HOSTAP=m +CONFIG_HOSTAP_CS=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_PLX=m +CONFIG_HOSTESS_SV11=m +CONFIG_HOTPLUG_CPU=y +CONFIG_HOTPLUG_PCI=m +CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +CONFIG_HOTPLUG_PCI_COMPAQ=m +CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM=y +CONFIG_HOTPLUG_PCI_CPCI=y +CONFIG_HOTPLUG_PCI_CPCI_GENERIC=m +CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m +CONFIG_HOTPLUG_PCI_FAKE=m +CONFIG_HOTPLUG_PCI_IBM=m +CONFIG_HOTPLUG_PCI_PCIE=m +CONFIG_HOTPLUG_PCI_SHPC=m +CONFIG_HP100=m +CONFIG_HPET_EMULATE_RTC=y +CONFIG_HPLAN=m +CONFIG_HPLAN_PLUS=m +# CONFIG_HPT34X_AUTODMA is not set +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_HVC_XEN=y +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HWMON_VID=m +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_AMD=m +CONFIG_HW_RANDOM_GEODE=m +CONFIG_HW_RANDOM_VIA=m +CONFIG_HZ=100 +CONFIG_HZ_100=y +# CONFIG_HZ_250 is not set +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_I801=m +CONFIG_I2C_I810=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PCA_ISA=m +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_STUB=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_BUS=m +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_EXT_ADAPTEC_DMA64=y +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_PROC=m +CONFIG_I2O_SCSI=m +CONFIG_I6300ESB_WDT=m +CONFIG_I82092=m +CONFIG_I82365=m +CONFIG_I8K=m +CONFIG_IB700_WDT=m +CONFIG_IBMASR=m +CONFIG_IBMLANA=m +CONFIG_IBMLS=m +# CONFIG_IBMMCA_SCSI_DEV_RESET is not set +CONFIG_IBMMCA_SCSI_ORDER_STANDARD=y +CONFIG_IBMOL=m +CONFIG_IBMTR=m +CONFIG_IBM_ASM=m +CONFIG_IDEPCI_SHARE_IRQ=y +CONFIG_IDE_PROC_FS=y +CONFIG_IEEE1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_OHCI1394=m +CONFIG_IEEE1394_PCILYNX=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE80211=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_CRYPT_WEP=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_AMSO1100=m +CONFIG_INFINIBAND_AMSO1100_DEBUG=y +CONFIG_INFINIBAND_CXGB3=m +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_IPOIB_DEBUG=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set +CONFIG_INFINIBAND_ISER=m +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INFTL=m +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_ATLAS_BTNS=m +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_TABLET=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_WISTRON_BTNS=m +CONFIG_INPUT_YEALINK=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IPPP_FILTER=y +CONFIG_IPV6_MULTIPLE_TABLES=y +# CONFIG_IPV6_SUBTREES is not set +CONFIG_IPW2100=m +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +# CONFIG_IPW2200_DEBUG is not set +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IRCOMM=m +CONFIG_IRDA=m +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_DEBUG=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_ULTRA=y +CONFIG_IRLAN=m +CONFIG_IRNET=m +# CONFIG_IRQBALANCE is not set +CONFIG_IRTTY_SIR=m +CONFIG_ISA=y +CONFIG_ISAPNP=y +CONFIG_ISDN=m +CONFIG_ISDN_AUDIO=y +CONFIG_ISDN_CAPI=m +CONFIG_ISDN_CAPI_CAPI20=m +CONFIG_ISDN_CAPI_CAPIDRV=m +CONFIG_ISDN_CAPI_CAPIFS=m +CONFIG_ISDN_CAPI_CAPIFS_BOOL=y +CONFIG_ISDN_CAPI_MIDDLEWARE=y +CONFIG_ISDN_DIVAS=m +CONFIG_ISDN_DIVAS_BRIPCI=y +CONFIG_ISDN_DIVAS_DIVACAPI=m +CONFIG_ISDN_DIVAS_MAINT=m +CONFIG_ISDN_DIVAS_PRIPCI=y +CONFIG_ISDN_DIVAS_USERIDI=m +CONFIG_ISDN_DIVERSION=m +CONFIG_ISDN_DRV_ACT2000=m +CONFIG_ISDN_DRV_AVMB1_AVM_CS=m +CONFIG_ISDN_DRV_AVMB1_B1ISA=m +CONFIG_ISDN_DRV_AVMB1_B1PCI=m +CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m +CONFIG_ISDN_DRV_AVMB1_C4=m +CONFIG_ISDN_DRV_AVMB1_T1ISA=m +CONFIG_ISDN_DRV_AVMB1_T1PCI=m +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y +CONFIG_ISDN_DRV_GIGASET=m +CONFIG_ISDN_DRV_HISAX=m +CONFIG_ISDN_DRV_ICN=m +CONFIG_ISDN_DRV_PCBIT=m +CONFIG_ISDN_DRV_SC=m +CONFIG_ISDN_I4L=m +CONFIG_ISDN_MPP=y +CONFIG_ISDN_PPP=y +CONFIG_ISDN_PPP_BSDCOMP=m +CONFIG_ISDN_PPP_VJ=y +CONFIG_ISDN_TTY_FAX=y +CONFIG_ISDN_X25=y +# CONFIG_ISI is not set +# CONFIG_IWLWIFI is not set +CONFIG_IXGB=m +# CONFIG_IXGB_NAPI is not set +CONFIG_JFFS2_CMODE_FAVOURLZO=y +# CONFIG_JFFS2_CMODE_NONE is not set +# CONFIG_JFFS2_CMODE_PRIORITY is not set +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_LZO=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_232=y +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_K8_NB=y +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KINGSUN_DONGLE=m +CONFIG_KS0108=m +CONFIG_KS0108_DELAY=2 +CONFIG_KS0108_PORT=0x378 +CONFIG_KS959_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +CONFIG_KVM=m +CONFIG_KVM_AMD=m +CONFIG_KVM_INTEL=m +CONFIG_LANCE=m +CONFIG_LANMEDIA=m +CONFIG_LAPB=m +CONFIG_LAPBETHER=m +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_LTV350QV=m +CONFIG_LEDS_CLASS=m +CONFIG_LEDS_NET48XX=m +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=m +CONFIG_LEDS_TRIGGER_IDE_DISK=y +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_WRAP=m +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_CS=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_SDIO=m +CONFIG_LIBERTAS_USB=m +CONFIG_LITELINK_DONGLE=m +CONFIG_LLC=y +CONFIG_LNE390=m +CONFIG_LOCK_KERNEL=y +CONFIG_LP486E=m +CONFIG_LTPC=m +CONFIG_LXT_PHY=m +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +# CONFIG_M486 is not set +# CONFIG_M586 is not set +CONFIG_M686=y +CONFIG_MA600_DONGLE=m +CONFIG_MAC80211=m +# CONFIG_MAC80211_DEBUG is not set +CONFIG_MAC80211_DEBUGFS=y +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_RCSIMPLE=y +CONFIG_MACHZ_WDT=m +CONFIG_MACINTOSH_DRIVERS=y +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_MADGEMC=m +CONFIG_MARVELL_PHY=m +# CONFIG_MATH_EMULATION is not set +CONFIG_MCA=y +CONFIG_MCA_LEGACY=y +# CONFIG_MCA_PROC_FS is not set +CONFIG_MCP2120_DONGLE=m +CONFIG_MCS_FIR=m +CONFIG_MDA_CONSOLE=m +CONFIG_MD_RAID10=m +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_SAS=m +CONFIG_MFD_SM501=m +CONFIG_MINIX_FS=m +CONFIG_MIXCOMWD=m +CONFIG_MKISS=m +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_MLX4_INFINIBAND=m +CONFIG_MMC=m +CONFIG_MMC_BLOCK=m +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_RICOH_MMC=m +CONFIG_MMC_SDHCI=m +CONFIG_MMC_TIFM_SD=m +# CONFIG_MMC_UNSAFE_RESUME is not set +CONFIG_MMC_WBSD=m +CONFIG_MOUSE_APPLETOUCH=m +# CONFIG_MOUSE_ATIXL is not set +CONFIG_MOUSE_INPORT=m +CONFIG_MOUSE_LOGIBM=m +CONFIG_MOUSE_PC110PAD=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_VSXXXAA=m +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +CONFIG_MOXA_SMARTIO_NEW=m +CONFIG_MSI_LAPTOP=m +CONFIG_MTD=m +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTD_ABSENT=m +CONFIG_MTD_ALAUDA=m +CONFIG_MTD_AMD76XROM=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK2MTD=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_MTD_CFI=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_CHAR=m +CONFIG_MTD_CK804XROM=m +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_CONCAT=m +CONFIG_MTD_DATAFLASH=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_DILNETPC=m +CONFIG_MTD_DILNETPC_BOOTSIZE=0x80000 +CONFIG_MTD_DOC2000=m +CONFIG_MTD_DOC2001=m +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCECC=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCPROBE_ADDRESS=0 +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_ESB2ROM=m +CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_ICHXROM=m +CONFIG_MTD_INTEL_VR_NOR=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_L440GX=m +CONFIG_MTD_M25P80=m +CONFIG_MTD_MAP_BANK_WIDTH_1=y +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +CONFIG_MTD_MTDRAM=m +CONFIG_MTD_NAND=m +CONFIG_MTD_NAND_CAFE=m +CONFIG_MTD_NAND_CS553X=m +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_NANDSIM=m +CONFIG_MTD_NAND_PLATFORM=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NETSC520=m +CONFIG_MTD_NETtel=m +CONFIG_MTD_ONENAND=m +CONFIG_MTD_ONENAND_2X_PROGRAM=y +# CONFIG_MTD_ONENAND_OTP is not set +CONFIG_MTD_ONENAND_SIM=m +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +CONFIG_MTD_OOPS=m +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_PCI=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PHYSMAP_LEN=0x4000000 +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PLATRAM=m +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +CONFIG_MTD_PNC2000=m +CONFIG_MTD_RAM=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS=m +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +CONFIG_MTD_ROM=m +CONFIG_MTD_SBC_GXX=m +CONFIG_MTD_SC520CDP=m +CONFIG_MTD_SCB2_FLASH=m +CONFIG_MTD_SCx200_DOCFLASH=m +CONFIG_MTD_SLRAM=m +CONFIG_MTD_TS5500=m +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_DEBUG is not set +CONFIG_MTD_UBI_GLUEBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MWAVE=m +CONFIG_MYRI10GE=m +CONFIG_N2=m +CONFIG_NATSEMI=m +CONFIG_NCPFS_EXTRAS=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_OS2_NS=y +CONFIG_NCPFS_PACKET_SIGNING=y +# CONFIG_NCPFS_SMALLDOS is not set +CONFIG_NCPFS_STRONG=y +CONFIG_NCP_FS=m +CONFIG_NE2000=m +CONFIG_NE2_MCA=m +CONFIG_NE3210=m +CONFIG_NETLABEL=y +CONFIG_NETROM=m +CONFIG_NETXEN_NIC=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +# CONFIG_NET_CLS_POLICE is not set +CONFIG_NET_DCCPPROBE=m +CONFIG_NET_FC=y +CONFIG_NET_ISA=y +CONFIG_NET_PCMCIA=y +CONFIG_NET_POCKET=y +CONFIG_NET_SCH_ATM=m +CONFIG_NET_TCPPROBE=m +CONFIG_NET_VENDOR_3COM=y +CONFIG_NET_VENDOR_RACAL=y +CONFIG_NET_VENDOR_SMC=y +CONFIG_NEW_LEDS=y +CONFIG_NFS_V4=y +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NI52=m +CONFIG_NI65=m +CONFIG_NL80211=y +# CONFIG_NORTEL_HERMES is not set +CONFIG_NO_HZ=y +CONFIG_NR_CPUS=8 +CONFIG_NS83820=m +CONFIG_NSC_FIR=m +CONFIG_NSC_GPIO=m +# CONFIG_NTFS_RW is not set +CONFIG_N_HDLC=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_P54_COMMON=m +CONFIG_P54_PCI=m +CONFIG_P54_USB=m +CONFIG_PARIDE=m +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +CONFIG_PARIDE_BPCK6=m +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_EPAT=m +# CONFIG_PARIDE_EPATC8 is not set +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PG=m +CONFIG_PARIDE_PT=m +CONFIG_PARPORT_AX88796=m +CONFIG_PARPORT_NOT_PC=y +CONFIG_PARPORT_PC_FIFO=y +CONFIG_PARPORT_PC_PCMCIA=m +CONFIG_PARPORT_SERIAL=m +CONFIG_PATA_CS5520=m +CONFIG_PATA_EFAR=m +# CONFIG_PATA_ISAPNP is not set +CONFIG_PATA_IT8213=m +CONFIG_PATA_IT821X=m +CONFIG_PATA_JMICRON=m +# CONFIG_PATA_LEGACY is not set +CONFIG_PATA_MARVELL=m +CONFIG_PATA_MPIIX=m +CONFIG_PATA_NETCELL=m +CONFIG_PATA_OLDPIIX=m +CONFIG_PATA_PCMCIA=m +CONFIG_PATA_PDC2027X=m +CONFIG_PATA_QDI=m +CONFIG_PATA_RZ1000=m +CONFIG_PATA_SERVERWORKS=m +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +CONFIG_PATA_TRIFLEX=m +CONFIG_PATA_WINBOND=m +# CONFIG_PATA_WINBOND_VLB is not set +CONFIG_PC300=m +# CONFIG_PC300TOO is not set +CONFIG_PC300_MLPPP=y +CONFIG_PC8736x_GPIO=m +CONFIG_PC87413_WDT=m +CONFIG_PCCARD=m +CONFIG_PCCARD_NONSTATIC=m +CONFIG_PCI200SYN=m +CONFIG_PCIEAER=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIPCWATCHDOG=m +CONFIG_PCI_ATMEL=m +# CONFIG_PCI_HERMES is not set +CONFIG_PCMCIA=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_AHA152X=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_PCMCIA_AXNET=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_HERMES=m +CONFIG_PCMCIA_IBMTR=m +CONFIG_PCMCIA_IOCTL=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_NETWAVE=m +CONFIG_PCMCIA_NINJA_SCSI=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_PROBE=y +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_RAYCS=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_SPECTRUM=m +CONFIG_PCMCIA_SYM53C500=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_WL3501=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_PCWATCHDOG=m +CONFIG_PD6729=m +CONFIG_PDC202XX_BURST=y +CONFIG_PDC_ADMA=m +CONFIG_PHANTOM=m +CONFIG_PHONE=m +CONFIG_PHONE_IXJ=m +CONFIG_PHONE_IXJ_PCMCIA=m +CONFIG_PLIP=m +# CONFIG_PLX_HERMES is not set +CONFIG_PM_SLEEP_SMP=y +CONFIG_PNPBIOS=y +CONFIG_PNPBIOS_PROC_FS=y +CONFIG_PPPOATM=m +# CONFIG_PREEMPT_BKL is not set +CONFIG_PREEMPT_NONE=y +CONFIG_PREEMPT_NOTIFIERS=y +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PRISM54=m +CONFIG_PROC_PID_CPUSET=y +CONFIG_PROTEON=m +CONFIG_QLA3XXX=m +CONFIG_QSEMI_PHY=m +CONFIG_R3964=m +CONFIG_R8169=m +# CONFIG_R8169_NAPI is not set +CONFIG_R8169_VLAN=y +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_AZTECH=m +CONFIG_RADIO_CADET=m +CONFIG_RADIO_GEMTEK=m +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAESTRO=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RADIO_RTRACK=m +CONFIG_RADIO_RTRACK2=m +CONFIG_RADIO_SF16FMI=m +CONFIG_RADIO_SF16FMR2=m +CONFIG_RADIO_TERRATEC=m +CONFIG_RADIO_TRUST=m +CONFIG_RADIO_TYPHOON=m +# CONFIG_RADIO_TYPHOON_PROC_FS is not set +CONFIG_RADIO_ZOLTRIX=m +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y +CONFIG_RESOURCES_64BIT=y +CONFIG_RFD_FTL=m +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +CONFIG_RFKILL_LEDS=y +# CONFIG_RIO is not set +CONFIG_ROADRUNNER=m +# CONFIG_ROADRUNNER_LARGE_RINGS is not set +CONFIG_ROCKETPORT=m +CONFIG_ROMFS_FS=m +CONFIG_ROSE=m +CONFIG_RT2400PCI=m +CONFIG_RT2400PCI_RFKILL=y +CONFIG_RT2500PCI=m +CONFIG_RT2500PCI_RFKILL=y +CONFIG_RT2500USB=m +CONFIG_RT2X00=m +# CONFIG_RT2X00_DEBUG is not set +CONFIG_RT2X00_LIB=m +# CONFIG_RT2X00_LIB_DEBUGFS is not set +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_PCI=m +CONFIG_RT2X00_LIB_RFKILL=y +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT61PCI=m +CONFIG_RT61PCI_RFKILL=y +CONFIG_RT73USB=m +CONFIG_RTC=y +CONFIG_RTC_CLASS=m +# CONFIG_RTC_DRV_CMOS is not set +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_M41T80_WDT=y +CONFIG_RTC_DRV_M48T59=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_STK17TA8=m +CONFIG_RTC_DRV_TEST=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_LIB=m +CONFIG_RTL8187=m +CONFIG_RXKAD=m +CONFIG_S2IO=m +# CONFIG_S2IO_NAPI is not set +CONFIG_SATA_AHCI=m +CONFIG_SATA_INIC162X=m +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIL24=m +CONFIG_SATA_SIS=m +CONFIG_SATA_SVW=m +CONFIG_SATA_SX4=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m +CONFIG_SBC8360_WDT=m +CONFIG_SBC_EPX_C3_WATCHDOG=m +CONFIG_SBNI=m +# CONFIG_SBNI_MULTILINE is not set +CONFIG_SC1200_WDT=m +CONFIG_SC520_WDT=m +CONFIG_SC92031=m +CONFIG_SCC=m +# CONFIG_SCC_DELAY is not set +# CONFIG_SCC_TRXECHO is not set +CONFIG_SCHED_MC=y +CONFIG_SCHED_SMT=y +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_7000FASST=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_ADVANSYS=m +CONFIG_SCSI_AHA152X=m +CONFIG_SCSI_AHA1542=m +CONFIG_SCSI_AHA1740=m +CONFIG_SCSI_AIC79XX=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_SCSI_AIC94XX=m +CONFIG_SCSI_ARCMSR=m +CONFIG_SCSI_ARCMSR_AER=y +CONFIG_SCSI_DC390T=m +CONFIG_SCSI_DC395x=m +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_DPT_I2O=m +CONFIG_SCSI_DTC3280=m +CONFIG_SCSI_EATA=m +CONFIG_SCSI_EATA_LINKED_COMMANDS=y +CONFIG_SCSI_EATA_MAX_TAGS=16 +CONFIG_SCSI_EATA_TAGGED_QUEUE=y +CONFIG_SCSI_FC_TGT_ATTRS=y +CONFIG_SCSI_FD_MCS=m +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_SCSI_GDTH=m +CONFIG_SCSI_GENERIC_NCR5380=m +CONFIG_SCSI_GENERIC_NCR5380_MMIO=m +CONFIG_SCSI_GENERIC_NCR53C400=y +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_IBMMCA=m +CONFIG_SCSI_IMM=m +CONFIG_SCSI_IN2000=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_DUMP is not set +# CONFIG_SCSI_IPR_TRACE is not set +CONFIG_SCSI_IPS=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +CONFIG_SCSI_LOWLEVEL_PCMCIA=y +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_NCR53C406A=m +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=4 +CONFIG_SCSI_NCR53C8XX_SYNC=5 +CONFIG_SCSI_NCR_D700=m +CONFIG_SCSI_NCR_Q720=m +CONFIG_SCSI_NSP32=m +CONFIG_SCSI_PAS16=m +CONFIG_SCSI_PPA=m +CONFIG_SCSI_PSI240I=m +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_QLOGIC_FAS=m +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_SEAGATE=m +CONFIG_SCSI_SIM710=m +CONFIG_SCSI_SRP=m +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C416=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_T128=m +CONFIG_SCSI_TGT=m +CONFIG_SCSI_U14_34F=m +CONFIG_SCSI_U14_34F_LINKED_COMMANDS=y +CONFIG_SCSI_U14_34F_MAX_TAGS=8 +CONFIG_SCSI_U14_34F_TAGGED_QUEUE=y +CONFIG_SCSI_ULTRASTOR=m +CONFIG_SCx200=m +CONFIG_SCx200HR_TIMER=m +CONFIG_SCx200_ACB=m +CONFIG_SCx200_GPIO=m +CONFIG_SCx200_I2C=m +CONFIG_SCx200_I2C_SCL=12 +CONFIG_SCx200_I2C_SDA=13 +CONFIG_SCx200_WDT=m +CONFIG_SDIO_UART=m +CONFIG_SDLA=m +CONFIG_SEALEVEL_4021=m +CONFIG_SEEQ8005=m +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_ABITUGURU3=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_APPLESMC=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_FSCHMD=m +CONFIG_SENSORS_FSCPOS=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_HDAPS=m +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_IBMPEX=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_K8TEMP=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_LM93=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SERIAL_8250_ACCENT=m +CONFIG_SERIAL_8250_BOCA=m +CONFIG_SERIAL_8250_CS=m +CONFIG_SERIAL_8250_EXAR_ST16C554=m +CONFIG_SERIAL_8250_FOURPORT=m +CONFIG_SERIAL_8250_HUB6=m +CONFIG_SERIAL_8250_MCA=m +CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_SERIO_CT82C710=m +CONFIG_SERIO_PARKBD=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SGI_IOC4=m +CONFIG_SIGMATEL_FIR=m +CONFIG_SIS190=m +CONFIG_SIS900=m +CONFIG_SKFP=m +CONFIG_SKGE=m +# CONFIG_SKGE_DEBUG is not set +CONFIG_SKISA=m +CONFIG_SKY2=m +# CONFIG_SKY2_DEBUG is not set +CONFIG_SMC9194=m +CONFIG_SMCTR=m +CONFIG_SMC_IRCC_FIR=m +CONFIG_SMP=y +CONFIG_SMSC37B787_WDT=m +CONFIG_SMSC_PHY=m +# CONFIG_SND is not set +CONFIG_SONYPI=m +CONFIG_SONYPI_COMPAT=y +CONFIG_SONY_LAPTOP=m +# CONFIG_SOUND_PRIME is not set +CONFIG_SPECIALIX=m +# CONFIG_SPECIALIX_RTSCTS is not set +CONFIG_SPI=y +CONFIG_SPI_AT25=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_LM70_LLP=m +CONFIG_SPI_MASTER=y +CONFIG_SPI_SPIDEV=m +CONFIG_SPI_TLE62X0=m +CONFIG_SSB_DRIVER_PCICORE=y +# CONFIG_SSB_PCMCIAHOST is not set +CONFIG_SSB_PCMCIAHOST_POSSIBLE=y +CONFIG_SSFDC=m +CONFIG_STALDRV=y +CONFIG_STOP_MACHINE=y +CONFIG_STRIP=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_SUNGEM=m +CONFIG_SUNRPC_XPRT_RDMA=m +CONFIG_SUSPEND_SMP_POSSIBLE=y +CONFIG_SX=m +CONFIG_SYNCLINK=m +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_CS=m +CONFIG_SYNCLINK_GT=m +CONFIG_SYSV68_PARTITION=y +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +CONFIG_TCG_ATMEL=m +CONFIG_TCG_INFINEON=m +CONFIG_TCG_NSC=m +CONFIG_TCG_TIS=m +CONFIG_TCG_TPM=m +CONFIG_TCIC=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TELCLOCK=m +CONFIG_THINKPAD_ACPI=m +CONFIG_THINKPAD_ACPI_BAY=y +# CONFIG_THINKPAD_ACPI_DEBUG is not set +CONFIG_TIFM_7XX1=m +CONFIG_TIFM_CORE=m +CONFIG_TIGON3=m +CONFIG_TLAN=m +# CONFIG_TMD_HERMES is not set +CONFIG_TMS380TR=m +CONFIG_TMSPCI=m +# CONFIG_TOIM3232_DONGLE is not set +CONFIG_TOSHIBA=m +CONFIG_TOSHIBA_FIR=m +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_UCB1400=m +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TR=y +CONFIG_TUNER_3036=m +CONFIG_TUNER_MT20XX=m +CONFIG_TUNER_SIMPLE=m +CONFIG_TUNER_TDA8290=m +CONFIG_TUNER_TEA5761=m +CONFIG_TUNER_TEA5767=m +CONFIG_TYPHOON=m +CONFIG_ULI526X=m +CONFIG_ULTRA=m +CONFIG_ULTRA32=m +CONFIG_ULTRAMCA=m +CONFIG_USBPCWATCHDOG=m +CONFIG_USB_ACM=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_ARMLINUX=y +CONFIG_USB_ATM=m +CONFIG_USB_AUERSWALD=m +CONFIG_USB_BELKIN=y +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_CATC=m +CONFIG_USB_CXACRU=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_DABUSB=m +CONFIG_USB_DSBR=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EMI26=m +CONFIG_USB_EMI62=m +CONFIG_USB_EPSON2888=y +CONFIG_USB_ET61X251=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_EZUSB=y +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_GADGET=m +CONFIG_USB_GADGETFS=m +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_M66592 is not set +CONFIG_USB_GADGET_NET2280=y +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_S3C2410 is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_G_SERIAL=m +CONFIG_USB_HID=m +CONFIG_USB_HIDDEV=y +CONFIG_USB_HIDINPUT_POWERBOOK=y +CONFIG_USB_IBMCAM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_IRDA=m +CONFIG_USB_KAWETH=m +CONFIG_USB_KBD=m +CONFIG_USB_KC2190=y +CONFIG_USB_KONICAWC=m +CONFIG_USB_LCD=m +CONFIG_USB_LD=m +CONFIG_USB_LED=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LIBUSUAL=y +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_USB_MON=y +CONFIG_USB_MOUSE=m +CONFIG_USB_NET2280=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_HCD_SSB is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OV511 is not set +CONFIG_USB_PEGASUS=m +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_PRINTER=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_RIO500=m +CONFIG_USB_RTL8150=m +CONFIG_USB_SE401=m +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_AIRPRIME=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IPW=m +# CONFIG_USB_SERIAL_IR is not set +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SISUSBVGA=m +# CONFIG_USB_SISUSBVGA_CON is not set +CONFIG_USB_SL811_CS=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SN9C102=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STV680=m +CONFIG_USB_SUSPEND=y +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_USBNET=m +CONFIG_USB_USS720=m +CONFIG_USB_VICAM=m +CONFIG_USB_W9968CF=m +CONFIG_USB_XUSBATM=m +CONFIG_USB_ZC0301=m +CONFIG_USB_ZD1201=m +CONFIG_USB_ZERO=m +CONFIG_USB_ZR364XX=m +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VERSION_SIGNATURE="Ubuntu 2.6.24-4.6-server" +CONFIG_VIA_FIR=m +CONFIG_VIA_RHINE=m +CONFIG_VIA_RHINE_MMIO=y +CONFIG_VIA_RHINE_NAPI=y +CONFIG_VIA_VELOCITY=m +CONFIG_VIDEOBUF_DMA_SG=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CAFE_CCIC=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_CPIA_PP=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_CX23885=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_DEV=m +# CONFIG_VIDEO_DPC is not set +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_FB_IVTV=m +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_MEYE=m +CONFIG_VIDEO_MSP3400=m +# CONFIG_VIDEO_MXB is not set +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_VIDEO_PMS=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_24XXX=y +CONFIG_VIDEO_PVRUSB2_29XXX=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA7111=m +CONFIG_VIDEO_SAA7114=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_SAA7191=m +CONFIG_VIDEO_STRADIS=m +CONFIG_VIDEO_TCM825X=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TDA9875=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_TLV320AIC23B=m +CONFIG_VIDEO_TUNER=m +# CONFIG_VIDEO_TUNER_CUSTOMIZE is not set +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_VP27SMPX=m +CONFIG_VIDEO_VPX3220=m +CONFIG_VIDEO_W9966=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VITESSE_PHY=m +CONFIG_VLSI_FIR=m +CONFIG_VORTEX=m +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_THERM=m +CONFIG_W83627HF_WDT=m +CONFIG_W83697HF_WDT=m +CONFIG_W83877F_WDT=m +CONFIG_W83977F_WDT=m +CONFIG_WAFER_WDT=m +CONFIG_WAN=y +CONFIG_WANXL=m +CONFIG_WAN_ROUTER=m +CONFIG_WAN_ROUTER_DRIVERS=m +CONFIG_WAVELAN=m +CONFIG_WD80x3=m +# CONFIG_WDC_ALI15X3 is not set +CONFIG_WDT=m +CONFIG_WDTPCI=m +CONFIG_WDT_501=y +CONFIG_WDT_501_PCI=y +CONFIG_WINBOND_840=m +CONFIG_WINBOND_FIR=m +CONFIG_WIRELESS_EXT=y +CONFIG_WLAN_80211=y +CONFIG_WLAN_PRE80211=y +CONFIG_X25=m +CONFIG_X25_ASY=m +CONFIG_X86_CMOV=y +CONFIG_X86_CPUFREQ_NFORCE2=m +CONFIG_X86_GOOD_APIC=y +CONFIG_X86_HT=y +CONFIG_X86_PAE=y +CONFIG_X86_SMP=y +CONFIG_X86_SPEEDSTEP_LIB=m +CONFIG_X86_SPEEDSTEP_SMI=m +CONFIG_X86_TRAMPOLINE=y +CONFIG_X86_TSC=y +CONFIG_X86_USE_PPRO_CHECKSUM=y +CONFIG_XEN=y +CONFIG_XEN_BLKDEV_FRONTEND=m +CONFIG_XEN_NETDEV_FRONTEND=m +CONFIG_YAM=m +CONFIG_YELLOWFIN=m +CONFIG_YENTA=m +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_ZNET=m --- linux-2.6.24.orig/debian/config/i386/config.virtual +++ linux-2.6.24/debian/config/i386/config.virtual @@ -0,0 +1,669 @@ +# +# Config options for config.virtual automatically generated by splitconfig.pl +# +# CONFIG_60XX_WDT is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_9P_FS is not set +# CONFIG_ACENIC is not set +# CONFIG_ACPI_ASUS is not set +# CONFIG_ACPI_BATTERY is not set +# CONFIG_ACPI_DOCK is not set +CONFIG_ACPI_HOTPLUG_CPU=y +# CONFIG_ACPI_SBS is not set +# CONFIG_ACPI_TOSHIBA is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADVANTECH_WDT is not set +CONFIG_AEDSP16_MSS=y +# CONFIG_AEDSP16_SBPRO is not set +# CONFIG_AFFS_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_AGP_ALI is not set +# CONFIG_AGP_AMD is not set +# CONFIG_AGP_AMD64 is not set +# CONFIG_AGP_ATI is not set +# CONFIG_AGP_EFFICEON is not set +# CONFIG_AGP_NVIDIA is not set +# CONFIG_AGP_SIS is not set +# CONFIG_AGP_SWORKS is not set +# CONFIG_AGP_VIA is not set +# CONFIG_ALIM1535_WDT is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_APM is not set +# CONFIG_APPLICOM is not set +# CONFIG_ARCNET is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_ATL1 is not set +# CONFIG_ATM is not set +# CONFIG_B44 is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_ATIIXP is not set +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_CS5535 is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_BLK_DEV_HPT366 is not set +CONFIG_BLK_DEV_IDE=y +# CONFIG_BLK_DEV_IDEACPI is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDEPNP is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_TC86C001 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BNX2 is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_BT is not set +# CONFIG_CASSINI is not set +# CONFIG_CFG80211 is not set +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_CPU5_WDT is not set +CONFIG_CPUSETS=y +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_IDLE_GOV_MENU=y +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_DEV_PADLOCK=m +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CS5535_GPIO is not set +# CONFIG_DAB is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_DE2104X is not set +# CONFIG_DE4X5 is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DECNET_NF_GRABULATOR is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_DL2K is not set +# CONFIG_DM9102 is not set +# CONFIG_DRM is not set +# CONFIG_DVB_CORE is not set +# CONFIG_E100 is not set +# CONFIG_ECONET is not set +# CONFIG_EDAC is not set +# CONFIG_EDD is not set +# CONFIG_EEPRO100 is not set +# CONFIG_EPIC100 is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_CYBLA is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_GEODE is not set +# CONFIG_FB_HECUBA is not set +# CONFIG_FB_HGA is not set +# CONFIG_FB_I810 is not set +# CONFIG_FB_IMAC is not set +# CONFIG_FB_INTEL is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_LE80578 is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FDDI is not set +# CONFIG_FEALNX is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_FORCEDETH is not set +# CONFIG_FUSION_LOGGING is not set +# CONFIG_GAMEPORT_EMU10K1 is not set +# CONFIG_GAMEPORT_FM801 is not set +# CONFIG_GAMEPORT_L4 is not set +# CONFIG_GAMEPORT_NS558 is not set +CONFIG_GENERIC_PENDING_IRQ=y +# CONFIG_HAMACHI is not set +# CONFIG_HAMRADIO is not set +# CONFIG_HAPPYMEAL is not set +CONFIG_HIBERNATION_SMP_POSSIBLE=y +# CONFIG_HID is not set +CONFIG_HIGHMEM4G=y +# CONFIG_HIGHMEM64G is not set +# CONFIG_HIPPI is not set +CONFIG_HOTPLUG_CPU=y +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HP100 is not set +CONFIG_HPET_EMULATE_RTC=y +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_HWMON is not set +CONFIG_HW_RANDOM=m +# CONFIG_HW_RANDOM_AMD is not set +# CONFIG_HW_RANDOM_GEODE is not set +# CONFIG_HW_RANDOM_VIA is not set +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_TINY_USB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2O is not set +# CONFIG_I6300ESB_WDT is not set +# CONFIG_I8K is not set +# CONFIG_IB700_WDT is not set +# CONFIG_IBMASR is not set +# CONFIG_IBM_ASM is not set +# CONFIG_IDE_PROC_FS is not set +# CONFIG_IEEE1394 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +# CONFIG_INFINIBAND is not set +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_ATLAS_BTNS is not set +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_UINPUT is not set +# CONFIG_INPUT_WISTRON_BTNS is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_IP6_NF_IPTABLES is not set +# CONFIG_IP6_NF_QUEUE is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IP_NF_TARGET_CLUSTERIP is not set +# CONFIG_IRDA is not set +# CONFIG_IRQBALANCE is not set +# CONFIG_ISA is not set +# CONFIG_ISDN is not set +# CONFIG_IXGB is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KS0108 is not set +# CONFIG_KVM is not set +# CONFIG_LAPB is not set +CONFIG_LGUEST=m +# CONFIG_LGUEST_GUEST is not set +CONFIG_LLC=m +CONFIG_LOCK_KERNEL=y +# CONFIG_LXT_PHY is not set +# CONFIG_M486 is not set +CONFIG_M586=y +# CONFIG_M686 is not set +# CONFIG_MAC80211 is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_MACINTOSH_DRIVERS is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_MATH_EMULATION is not set +# CONFIG_MCA is not set +# CONFIG_MD_RAID10 is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MINIX_FS is not set +# CONFIG_MLX4_CORE is not set +# CONFIG_MMC is not set +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_PS2_ALPS is not set +# CONFIG_MOUSE_PS2_LIFEBOOK is not set +# CONFIG_MOUSE_PS2_LOGIPS2PP is not set +# CONFIG_MOUSE_PS2_SYNAPTICS is not set +# CONFIG_MOUSE_PS2_TRACKPOINT is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +CONFIG_MSNDCLAS_INIT_FILE="/etc/sound/msndinit.bin" +CONFIG_MSNDCLAS_PERM_FILE="/etc/sound/msndperm.bin" +CONFIG_MSNDPIN_INIT_FILE="/etc/sound/pndspini.bin" +CONFIG_MSNDPIN_PERM_FILE="/etc/sound/pndsperm.bin" +# CONFIG_MTD is not set +# CONFIG_MWAVE is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NATSEMI is not set +# CONFIG_NCP_FS is not set +# CONFIG_NETLABEL is not set +# CONFIG_NETXEN_NIC is not set +CONFIG_NET_ACT_POLICE=y +# CONFIG_NET_ACT_SIMP is not set +CONFIG_NET_CLS_POLICE=y +# CONFIG_NET_DCCPPROBE is not set +# CONFIG_NET_FC is not set +# CONFIG_NET_POCKET is not set +# CONFIG_NET_TCPPROBE is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NF_CONNTRACK_H323 is not set +# CONFIG_NF_CONNTRACK_IPV6 is not set +# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set +# CONFIG_NF_CONNTRACK_SIP is not set +# CONFIG_NF_CT_PROTO_SCTP is not set +# CONFIG_NF_NAT_H323 is not set +# CONFIG_NF_NAT_SIP is not set +# CONFIG_NF_NAT_SNMP_BASIC is not set +CONFIG_NO_HZ=y +CONFIG_NR_CPUS=8 +# CONFIG_NS83820 is not set +# CONFIG_NSC_GPIO is not set +CONFIG_NTFS_RW=y +# CONFIG_PARIDE is not set +# CONFIG_PARPORT_AX88796 is not set +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_SERIAL is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_WINBOND is not set +# CONFIG_PC8736x_GPIO is not set +# CONFIG_PC87413_WDT is not set +# CONFIG_PCCARD is not set +# CONFIG_PCIEPORTBUS is not set +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_PHANTOM is not set +# CONFIG_PHONE is not set +# CONFIG_PLIP is not set +CONFIG_PM_SLEEP_SMP=y +CONFIG_PREEMPT_BKL=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_PSS_MIXER=y +# CONFIG_QLA3XXX is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_R3964 is not set +# CONFIG_R8169 is not set +# CONFIG_RESOURCES_64BIT is not set +# CONFIG_RFKILL is not set +# CONFIG_ROMFS_FS is not set +CONFIG_RTC=y +# CONFIG_RTC_CLASS is not set +# CONFIG_S2IO is not set +# CONFIG_SATA_AHCI is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_SIL is not set +# CONFIG_SATA_SIL24 is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_SVW is not set +# CONFIG_SATA_SX4 is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_SBC8360_WDT is not set +# CONFIG_SBC_EPX_C3_WATCHDOG is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_SC520_WDT is not set +CONFIG_SC6600=y +CONFIG_SC6600_CDROM=4 +CONFIG_SC6600_CDROMBASE=0 +CONFIG_SC6600_JOY=y +# CONFIG_SC92031 is not set +CONFIG_SCHED_MC=y +CONFIG_SCHED_SMT=y +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_IMM is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +# CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_SRP_ATTRS is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_TGT is not set +# CONFIG_SCx200 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_SIS190 is not set +# CONFIG_SIS900 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +CONFIG_SMP=y +# CONFIG_SMSC37B787_WDT is not set +# CONFIG_SMSC_PHY is not set +CONFIG_SND=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_AC97_POWER_SAVE=y +CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0 +CONFIG_SND_AD1889=m +CONFIG_SND_ALI5451=m +CONFIG_SND_ALS300=m +CONFIG_SND_ALS4000=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +CONFIG_SND_AZT3328=m +CONFIG_SND_BT87X=m +# CONFIG_SND_BT87X_OVERCLOCK is not set +CONFIG_SND_CA0106=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_CS4281=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_CS5530=m +CONFIG_SND_CS5535AUDIO=m +CONFIG_SND_DARLA20=m +CONFIG_SND_DARLA24=m +# CONFIG_SND_DEBUG is not set +CONFIG_SND_DUMMY=m +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_ECHO3G=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_EMU10K1X=m +CONFIG_SND_ENS1370=m +CONFIG_SND_ENS1371=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_FM801=m +# CONFIG_SND_FM801_TEA575X_BOOL is not set +CONFIG_SND_GINA20=m +CONFIG_SND_GINA24=m +CONFIG_SND_HDA_CODEC_ANALOG=y +CONFIG_SND_HDA_CODEC_ATIHDMI=y +CONFIG_SND_HDA_CODEC_CMEDIA=y +CONFIG_SND_HDA_CODEC_CONEXANT=y +CONFIG_SND_HDA_CODEC_REALTEK=y +CONFIG_SND_HDA_CODEC_SI3054=y +CONFIG_SND_HDA_CODEC_SIGMATEL=y +CONFIG_SND_HDA_CODEC_VIA=y +CONFIG_SND_HDA_GENERIC=y +# CONFIG_SND_HDA_HWDEP is not set +CONFIG_SND_HDA_INTEL=m +CONFIG_SND_HDA_POWER_SAVE=y +CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 +CONFIG_SND_HDSP=m +CONFIG_SND_HDSPM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INDIGO=m +CONFIG_SND_INDIGODJ=m +CONFIG_SND_INDIGOIO=m +CONFIG_SND_INTEL8X0=m +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_KORG1212=m +CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL=y +CONFIG_SND_LAYLA20=m +CONFIG_SND_LAYLA24=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL=y +CONFIG_SND_MIA=m +CONFIG_SND_MIXART=m +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_MONA=m +CONFIG_SND_MPU401=m +CONFIG_SND_MPU401_UART=m +CONFIG_SND_MTPAV=m +CONFIG_SND_MTS64=m +CONFIG_SND_NM256=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_PCM=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_PCXHR=m +CONFIG_SND_PORTMAN2X4=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_RIPTIDE=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_RTCTIMER=m +CONFIG_SND_SB16_DSP=m +CONFIG_SND_SB_COMMON=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_SOC=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_TIMER=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_USX2Y=m +# CONFIG_SND_VERBOSE_PRINTK is not set +CONFIG_SND_VERBOSE_PROCFS=y +CONFIG_SND_VIA82XX=m +CONFIG_SND_VIA82XX_MODEM=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_VX222=m +CONFIG_SND_VX_LIB=m +CONFIG_SND_YMFPCI=m +CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL=y +# CONFIG_SONYPI is not set +# CONFIG_SONY_LAPTOP is not set +CONFIG_SOUND_AEDSP16=m +CONFIG_SOUND_DMAP=y +CONFIG_SOUND_KAHLUA=m +CONFIG_SOUND_MPU401=m +CONFIG_SOUND_MSNDCLAS=m +CONFIG_SOUND_MSNDPIN=m +CONFIG_SOUND_MSS=m +CONFIG_SOUND_OSS=m +CONFIG_SOUND_PAS=m +CONFIG_SOUND_PRIME=m +CONFIG_SOUND_PSS=m +CONFIG_SOUND_SB=m +CONFIG_SOUND_SSCAPE=m +# CONFIG_SOUND_TRACEINIT is not set +CONFIG_SOUND_TRIDENT=m +CONFIG_SOUND_TRIX=m +CONFIG_SOUND_UART6850=m +CONFIG_SOUND_VMIDI=m +CONFIG_SOUND_YM3812=m +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_SSB_DRIVER_PCICORE is not set +CONFIG_STOP_MACHINE=y +# CONFIG_SUNDANCE is not set +# CONFIG_SUNGEM is not set +CONFIG_SUSPEND_SMP_POSSIBLE=y +# CONFIG_SYSV68_PARTITION is not set +# CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set +# CONFIG_THINKPAD_ACPI is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_TIGON3 is not set +# CONFIG_TLAN is not set +# CONFIG_TOSHIBA is not set +# CONFIG_TR is not set +# CONFIG_ULI526X is not set +# CONFIG_USBPCWATCHDOG is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_EHCI_SPLIT_ISO is not set +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_GADGET is not set +# CONFIG_USB_HID is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_KBD is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LIBUSUAL is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_USS720 is not set +CONFIG_VERSION_SIGNATURE="Ubuntu 2.6.24-4.6-virtual" +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_VIDEO_DEV is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_W1_MASTER_DS2482 is not set +# CONFIG_W1_MASTER_DS2490 is not set +# CONFIG_W1_MASTER_MATROX is not set +# CONFIG_W1_SLAVE_DS2433 is not set +# CONFIG_W1_SLAVE_SMEM is not set +# CONFIG_W1_SLAVE_THERM is not set +# CONFIG_W83627HF_WDT is not set +# CONFIG_W83697HF_WDT is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_W83977F_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_WAN is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_WDTPCI is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_X25 is not set +CONFIG_X86_ALIGNMENT_16=y +# CONFIG_X86_CPUFREQ_NFORCE2 is not set +CONFIG_X86_F00F_BUG=y +CONFIG_X86_HT=y +CONFIG_X86_SMP=y +CONFIG_X86_SPEEDSTEP_LIB=y +CONFIG_X86_SPEEDSTEP_SMI=y +CONFIG_X86_TRAMPOLINE=y +# CONFIG_YELLOWFIN is not set --- linux-2.6.24.orig/debian/config/i386/config.386 +++ linux-2.6.24/debian/config/i386/config.386 @@ -0,0 +1,1970 @@ +# +# Config options for config.386 automatically generated by splitconfig.pl +# +CONFIG_3C359=m +CONFIG_3C515=m +CONFIG_60XX_WDT=m +CONFIG_6PACK=m +CONFIG_8139CP=m +CONFIG_8139TOO_8129=y +CONFIG_9P_FS=m +CONFIG_ABYSS=m +CONFIG_AC3200=m +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_ACPI_ASUS=m +CONFIG_ACPI_BATTERY=m +CONFIG_ACPI_BAY=m +CONFIG_ACPI_DOCK=m +CONFIG_ACPI_SBS=m +CONFIG_ACPI_TOSHIBA=m +CONFIG_ACPI_VIDEO=m +CONFIG_ACQUIRE_WDT=m +CONFIG_ACT200L_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_ADAPTEC_STARFIRE=m +# CONFIG_ADAPTEC_STARFIRE_NAPI is not set +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_ADM8211=m +CONFIG_ADVANTECH_WDT=m +CONFIG_AFFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_AFS_FS=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_AGP_ALI=m +CONFIG_AGP_AMD=m +CONFIG_AGP_AMD64=m +CONFIG_AGP_ATI=m +CONFIG_AGP_EFFICEON=m +CONFIG_AGP_NVIDIA=m +CONFIG_AGP_SIS=m +CONFIG_AGP_SWORKS=m +CONFIG_AGP_VIA=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +CONFIG_AIC79XX_DEBUG_ENABLE=y +CONFIG_AIC79XX_DEBUG_MASK=0 +CONFIG_AIC79XX_REG_PRETTY_PRINT=y +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 +CONFIG_AIC7XXX_DEBUG_ENABLE=y +CONFIG_AIC7XXX_DEBUG_MASK=0 +CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_AIRO=m +CONFIG_AIRO_CS=m +CONFIG_ALIM1535_WDT=m +CONFIG_ALIM7101_WDT=m +CONFIG_ALI_FIR=m +# CONFIG_AMD8111E_NAPI is not set +CONFIG_AMD8111_ETH=m +CONFIG_APM=m +# CONFIG_APM_ALLOW_INTS is not set +# CONFIG_APM_CPU_IDLE is not set +# CONFIG_APM_DISPLAY_BLANK is not set +# CONFIG_APM_DO_ENABLE is not set +# CONFIG_APM_IGNORE_USER_SUSPEND is not set +# CONFIG_APM_REAL_MODE_POWER_OFF is not set +CONFIG_APPLICOM=m +CONFIG_APRICOT=m +CONFIG_ARCNET=m +CONFIG_ARCNET_1051=m +CONFIG_ARCNET_1201=m +CONFIG_ARCNET_CAP=m +CONFIG_ARCNET_COM20020=m +CONFIG_ARCNET_COM20020_CS=m +CONFIG_ARCNET_COM20020_ISA=m +CONFIG_ARCNET_COM20020_PCI=m +CONFIG_ARCNET_COM90xx=m +CONFIG_ARCNET_COM90xxIO=m +CONFIG_ARCNET_RAW=m +CONFIG_ARCNET_RIM_I=m +CONFIG_ARLAN=m +CONFIG_ASUS_LAPTOP=m +CONFIG_AT1700=m +CONFIG_ATA_OVER_ETH=m +CONFIG_ATL1=m +CONFIG_ATM=y +CONFIG_ATMEL=m +CONFIG_ATM_AMBASSADOR=m +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_ATM_CLIP=y +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +CONFIG_ATM_ENI=m +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +CONFIG_ATM_FIRESTREAM=m +CONFIG_ATM_FORE200E=m +CONFIG_ATM_FORE200E_DEBUG=0 +CONFIG_ATM_FORE200E_MAYBE=m +CONFIG_ATM_FORE200E_PCA=y +CONFIG_ATM_FORE200E_PCA_DEFAULT_FW=y +CONFIG_ATM_FORE200E_TX_RETRY=16 +# CONFIG_ATM_FORE200E_USE_TASKLET is not set +CONFIG_ATM_HE=m +CONFIG_ATM_HE_USE_SUNI=y +CONFIG_ATM_HORIZON=m +# CONFIG_ATM_HORIZON_DEBUG is not set +CONFIG_ATM_IA=m +# CONFIG_ATM_IA_DEBUG is not set +CONFIG_ATM_IDT77252=m +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +CONFIG_ATM_IDT77252_USE_SUNI=y +CONFIG_ATM_LANAI=m +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_NICSTAR=m +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set +# CONFIG_ATM_NICSTAR_USE_SUNI is not set +CONFIG_ATM_TCP=m +CONFIG_ATM_ZATM=m +# CONFIG_ATM_ZATM_DEBUG is not set +CONFIG_ATP=m +CONFIG_AX25=m +CONFIG_AX25_DAMA_SLAVE=y +CONFIG_B43=m +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_DEBUG=y +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y +CONFIG_B43LEGACY_PCI_AUTOSELECT=y +CONFIG_B43LEGACY_PIO=y +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_B43_DEBUG=y +CONFIG_B43_DMA=y +CONFIG_B43_DMA_AND_PIO_MODE=y +# CONFIG_B43_DMA_MODE is not set +CONFIG_B43_LEDS=y +CONFIG_B43_PCICORE_AUTOSELECT=y +CONFIG_B43_PCI_AUTOSELECT=y +# CONFIG_B43_PCMCIA is not set +CONFIG_B43_PIO=y +# CONFIG_B43_PIO_MODE is not set +CONFIG_B43_RFKILL=y +CONFIG_B44=m +CONFIG_B44_PCI=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI_AUTOSELECT=y +CONFIG_BACKLIGHT_CARILLO_RANCH=m +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_CORGI=m +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_PROGEAR=m +CONFIG_BAYCOM_EPP=m +CONFIG_BAYCOM_PAR=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_BCM43XX=m +# CONFIG_BCM43XX_DEBUG is not set +CONFIG_BCM43XX_DMA=y +CONFIG_BCM43XX_DMA_AND_PIO_MODE=y +# CONFIG_BCM43XX_DMA_MODE is not set +CONFIG_BCM43XX_PIO=y +# CONFIG_BCM43XX_PIO_MODE is not set +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_BLK_DEV_4DRIVES=y +CONFIG_BLK_DEV_AEC62XX=m +CONFIG_BLK_DEV_ALI14XX=m +CONFIG_BLK_DEV_ALI15X3=m +CONFIG_BLK_DEV_ATIIXP=m +CONFIG_BLK_DEV_CMD640=y +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +CONFIG_BLK_DEV_CMD64X=m +CONFIG_BLK_DEV_CS5530=m +CONFIG_BLK_DEV_CS5535=m +CONFIG_BLK_DEV_CY82C693=m +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_DELKIN=m +CONFIG_BLK_DEV_DTC2278=m +CONFIG_BLK_DEV_HPT34X=m +CONFIG_BLK_DEV_HPT366=m +CONFIG_BLK_DEV_HT6560B=m +CONFIG_BLK_DEV_IDE=m +CONFIG_BLK_DEV_IDEACPI=y +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDEDMA=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_IDEFLOPPY=m +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_BLK_DEV_IDEPNP=y +CONFIG_BLK_DEV_IDESCSI=m +CONFIG_BLK_DEV_IDETAPE=m +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_BLK_DEV_NS87415=m +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_OPTI621=m +CONFIG_BLK_DEV_PDC202XX_OLD=m +CONFIG_BLK_DEV_QD65XX=m +CONFIG_BLK_DEV_SC1200=m +CONFIG_BLK_DEV_SX8=m +CONFIG_BLK_DEV_TC86C001=m +CONFIG_BLK_DEV_TRM290=m +CONFIG_BLK_DEV_UMC8672=m +CONFIG_BLK_DEV_UMEM=m +CONFIG_BLK_DEV_XD=m +CONFIG_BNX2=m +CONFIG_BPQETHER=m +CONFIG_BROADCOM_PHY=m +CONFIG_BROKEN_ON_SMP=y +CONFIG_BT=m +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_CMTP=m +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HIDP=m +CONFIG_BT_L2CAP=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_SCO=m +CONFIG_C101=m +CONFIG_CAPI_AVM=y +CONFIG_CAPI_EICON=y +CONFIG_CAPI_TRACE=y +CONFIG_CARDBUS=y +CONFIG_CARDMAN_4000=m +CONFIG_CARDMAN_4040=m +CONFIG_CASSINI=m +CONFIG_CFAG12864B=m +CONFIG_CFAG12864B_RATE=20 +CONFIG_CFG80211=m +CONFIG_CHECK_SIGNATURE=y +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T1_NAPI=y +CONFIG_CHELSIO_T3=m +CONFIG_CHR_DEV_OSST=m +CONFIG_CHR_DEV_SCH=m +CONFIG_CHR_DEV_ST=m +CONFIG_CICADA_PHY=m +CONFIG_CISS_SCSI_TAPE=y +CONFIG_COMPUTONE=m +CONFIG_COPS=m +CONFIG_COPS_DAYNA=y +CONFIG_COPS_TANGENT=y +CONFIG_COSA=m +CONFIG_CPU5_WDT=m +CONFIG_CPU_FREQ_TABLE=m +CONFIG_CRYPTO_ABLKCIPHER=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_DEV_PADLOCK=y +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CS5535_GPIO=m +CONFIG_CS89x0=m +CONFIG_CYCLADES=m +CONFIG_CYCLADES_SYNC=m +CONFIG_CYCLOMX_X25=y +# CONFIG_CYZ_INTR is not set +CONFIG_DAB=y +CONFIG_DAVICOM_PHY=m +CONFIG_DE2104X=m +CONFIG_DE4X5=m +CONFIG_DE600=m +CONFIG_DE620=m +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DECNET_NF_GRABULATOR=m +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_DEFXX=m +# CONFIG_DEFXX_MMIO is not set +CONFIG_DEPCA=m +CONFIG_DE_AOC=y +CONFIG_DIGIEPCA=m +CONFIG_DISPLAY_SUPPORT=m +CONFIG_DL2K=m +CONFIG_DLCI=m +CONFIG_DLCI_MAX=8 +CONFIG_DM9102=m +CONFIG_DMASCC=m +CONFIG_DONGLE=y +# CONFIG_DONGLE_OLD is not set +CONFIG_DRM=m +CONFIG_DRM_I810=m +CONFIG_DRM_I830=m +CONFIG_DRM_I915=m +CONFIG_DRM_MGA=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_SAVAGE=m +CONFIG_DRM_SIS=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_VIA=m +CONFIG_DRM_VIA_CHROME9=m +CONFIG_DSCC4=m +CONFIG_DSCC4_PCISYNC=y +CONFIG_DSCC4_PCI_RST=y +CONFIG_DTLK=m +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_B2C2_FLEXCOP=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_BT8XX=m +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_PATCH=m +CONFIG_DVB_CAPTURE_DRIVERS=y +CONFIG_DVB_CINERGYT2=m +CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y +CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250 +CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100 +CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512 +CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32 +CONFIG_DVB_CINERGYT2_TUNING=y +CONFIG_DVB_CORE=m +CONFIG_DVB_CORE_ATTACH=y +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_ISL6421=m +CONFIG_DVB_L64781=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_MT312=m +CONFIG_DVB_MT352=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_PLL=m +CONFIG_DVB_PLUTO2=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TDA827X=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_TUNER_MT2060=m +CONFIG_DVB_TUNER_MT2131=m +CONFIG_DVB_TUNER_MT2266=m +CONFIG_DVB_TUNER_QT1010=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_CXUSB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_ZL10353=m +CONFIG_E100=m +CONFIG_E2100=m +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +CONFIG_EDAC=y +# CONFIG_EDAC_AMD76X is not set +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_E752X=m +CONFIG_EDAC_E7XXX=m +CONFIG_EDAC_I3000=m +CONFIG_EDAC_I5000=m +CONFIG_EDAC_I82860=m +CONFIG_EDAC_I82875P=m +CONFIG_EDAC_I82975X=m +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC_R82600=m +CONFIG_EDD=y +CONFIG_EDD_OFF=y +CONFIG_EEPRO100=m +CONFIG_EEXPRESS=m +CONFIG_EEXPRESS_PRO=m +CONFIG_EISA=y +CONFIG_EISA_NAMES=y +CONFIG_EISA_PCI_EISA=y +CONFIG_EISA_VIRTUAL_ROOT=y +CONFIG_EISA_VLB_PRIMING=y +CONFIG_EL1=m +CONFIG_EL16=m +CONFIG_EL2=m +CONFIG_EL3=m +CONFIG_ELMC=m +CONFIG_ELMC_II=m +CONFIG_ELPLUS=m +CONFIG_EPIC100=m +CONFIG_ES3210=m +CONFIG_ESI_DONGLE=m +# CONFIG_ESPSERIAL is not set +CONFIG_ETH16I=m +CONFIG_EUROTECH_WDT=m +CONFIG_EWRK3=m +CONFIG_FARSYNC=m +CONFIG_FB_3DFX=m +# CONFIG_FB_3DFX_ACCEL is not set +CONFIG_FB_ARK=m +CONFIG_FB_ATY=m +CONFIG_FB_ATY128=m +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY_BACKLIGHT=y +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_CARILLO_RANCH=m +CONFIG_FB_CYBER2000=m +CONFIG_FB_CYBLA=m +CONFIG_FB_DDC=m +CONFIG_FB_GEODE=y +CONFIG_FB_GEODE_GX=m +CONFIG_FB_GEODE_GX1=m +# CONFIG_FB_GEODE_GX_SET_FBSIZE is not set +CONFIG_FB_GEODE_LX=m +CONFIG_FB_HECUBA=m +CONFIG_FB_HGA=m +# CONFIG_FB_HGA_ACCEL is not set +CONFIG_FB_I810=m +# CONFIG_FB_I810_GTF is not set +CONFIG_FB_IMAC=y +CONFIG_FB_INTEL=m +# CONFIG_FB_INTEL_DEBUG is not set +CONFIG_FB_INTEL_I2C=y +CONFIG_FB_KYRO=m +CONFIG_FB_LE80578=m +CONFIG_FB_MATROX=m +CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MULTIHEAD=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_NEOMAGIC=m +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_BACKLIGHT=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_I2C=y +CONFIG_FB_PM2=m +CONFIG_FB_PM2_FIFO_DISCONNECT=y +CONFIG_FB_PM3=m +CONFIG_FB_RADEON=m +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RIVA=m +CONFIG_FB_RIVA_BACKLIGHT=y +# CONFIG_FB_RIVA_DEBUG is not set +CONFIG_FB_RIVA_I2C=y +CONFIG_FB_S1D13XXX=m +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_ACCEL=y +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SIS=m +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +CONFIG_FB_SM501=m +CONFIG_FB_SVGALIB=m +CONFIG_FB_TRIDENT=m +# CONFIG_FB_TRIDENT_ACCEL is not set +CONFIG_FB_VOODOO1=m +CONFIG_FB_VT8623=m +CONFIG_FDDI=y +CONFIG_FEALNX=m +CONFIG_FIXED_MII_1000_FDX=y +# CONFIG_FIXED_MII_100_FDX is not set +# CONFIG_FIXED_MII_10_FDX is not set +CONFIG_FIXED_MII_AMNT=1 +CONFIG_FIXED_PHY=m +CONFIG_FORCEDETH=m +# CONFIG_FORCEDETH_NAPI is not set +CONFIG_FTL=m +CONFIG_FUJITSU_LAPTOP=m +CONFIG_FUSION_LAN=m +CONFIG_FUSION_LOGGING=y +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GEN_RTC=m +CONFIG_GEN_RTC_X=y +CONFIG_GIGASET_BASE=m +# CONFIG_GIGASET_DEBUG is not set +CONFIG_GIGASET_M101=m +CONFIG_GIGASET_M105=m +# CONFIG_GIGASET_UNDOCREQ is not set +CONFIG_GIRBIL_DONGLE=m +CONFIG_HAMACHI=m +CONFIG_HAMRADIO=y +CONFIG_HAPPYMEAL=m +CONFIG_HDLC=m +CONFIG_HDLC_CISCO=m +CONFIG_HDLC_FR=m +CONFIG_HDLC_PPP=m +CONFIG_HDLC_RAW=m +CONFIG_HDLC_RAW_ETH=m +CONFIG_HDLC_X25=m +CONFIG_HERMES=m +CONFIG_HIBERNATION_UP_POSSIBLE=y +CONFIG_HID=m +CONFIG_HIDRAW=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HID_FF is not set +CONFIG_HIGHMEM4G=y +# CONFIG_HIGHMEM64G is not set +CONFIG_HIPPI=y +CONFIG_HISAX_16_0=y +CONFIG_HISAX_16_3=y +CONFIG_HISAX_1TR6=y +CONFIG_HISAX_ASUSCOM=y +CONFIG_HISAX_AVM_A1=y +CONFIG_HISAX_AVM_A1_CS=m +CONFIG_HISAX_AVM_A1_PCMCIA=y +CONFIG_HISAX_BKM_A4T=y +# CONFIG_HISAX_DEBUG is not set +CONFIG_HISAX_DIEHLDIVA=y +CONFIG_HISAX_ELSA=y +CONFIG_HISAX_ELSA_CS=m +CONFIG_HISAX_ENTERNOW_PCI=y +CONFIG_HISAX_EURO=y +CONFIG_HISAX_FRITZPCI=y +CONFIG_HISAX_FRITZ_PCIPNP=m +CONFIG_HISAX_GAZEL=y +CONFIG_HISAX_HDLC=y +CONFIG_HISAX_HFC4S8S=m +CONFIG_HISAX_HFCS=y +CONFIG_HISAX_HFCUSB=m +CONFIG_HISAX_HFC_PCI=y +CONFIG_HISAX_HFC_SX=y +CONFIG_HISAX_HSTSAPHIR=y +CONFIG_HISAX_ISURF=y +CONFIG_HISAX_IX1MICROR2=y +CONFIG_HISAX_MAX_CARDS=8 +CONFIG_HISAX_MIC=y +CONFIG_HISAX_NETJET=y +CONFIG_HISAX_NETJET_U=y +CONFIG_HISAX_NI1=y +CONFIG_HISAX_NICCY=y +# CONFIG_HISAX_NO_KEYPAD is not set +# CONFIG_HISAX_NO_LLC is not set +# CONFIG_HISAX_NO_SENDCOMPLETE is not set +CONFIG_HISAX_S0BOX=y +CONFIG_HISAX_SCT_QUADRO=y +CONFIG_HISAX_SEDLBAUER=y +CONFIG_HISAX_SEDLBAUER_CS=m +CONFIG_HISAX_SPORTSTER=y +CONFIG_HISAX_ST5481=m +CONFIG_HISAX_TELEINT=y +CONFIG_HISAX_TELESPCI=y +CONFIG_HISAX_TELES_CS=m +CONFIG_HISAX_W6692=y +CONFIG_HOSTAP=m +CONFIG_HOSTAP_CS=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_PLX=m +CONFIG_HOSTESS_SV11=m +CONFIG_HOTPLUG_PCI=m +CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +CONFIG_HOTPLUG_PCI_COMPAQ=m +CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM=y +CONFIG_HOTPLUG_PCI_CPCI=y +CONFIG_HOTPLUG_PCI_CPCI_GENERIC=m +CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m +CONFIG_HOTPLUG_PCI_FAKE=m +CONFIG_HOTPLUG_PCI_IBM=m +CONFIG_HOTPLUG_PCI_PCIE=m +CONFIG_HOTPLUG_PCI_SHPC=m +CONFIG_HP100=m +CONFIG_HPLAN=m +CONFIG_HPLAN_PLUS=m +# CONFIG_HPT34X_AUTODMA is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HWMON_VID=m +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_AMD=m +CONFIG_HW_RANDOM_GEODE=m +CONFIG_HW_RANDOM_VIA=m +CONFIG_HYSDN=m +CONFIG_HYSDN_CAPI=y +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_ELEKTOR=m +CONFIG_I2C_I801=m +CONFIG_I2C_I810=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PCA_ISA=m +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_STUB=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_BUS=m +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_PROC=m +CONFIG_I2O_SCSI=m +CONFIG_I6300ESB_WDT=m +CONFIG_I82092=m +CONFIG_I82365=m +CONFIG_I8K=m +CONFIG_IB700_WDT=m +CONFIG_IBMASR=m +CONFIG_IBMLANA=m +CONFIG_IBMLS=m +# CONFIG_IBMMCA_SCSI_DEV_RESET is not set +CONFIG_IBMMCA_SCSI_ORDER_STANDARD=y +CONFIG_IBMOL=m +CONFIG_IBMTR=m +CONFIG_IBM_ASM=m +CONFIG_IDEPCI_SHARE_IRQ=y +CONFIG_IDE_PROC_FS=y +CONFIG_IEEE1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_OHCI1394=m +CONFIG_IEEE1394_PCILYNX=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE80211=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_CRYPT_WEP=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_AMSO1100=m +CONFIG_INFINIBAND_AMSO1100_DEBUG=y +CONFIG_INFINIBAND_CXGB3=m +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_IPOIB_DEBUG=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set +CONFIG_INFINIBAND_ISER=m +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INFTL=m +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_ATLAS_BTNS=m +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_TABLET=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_WISTRON_BTNS=m +# CONFIG_INPUT_YEALINK is not set +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IPPP_FILTER=y +# CONFIG_IPV6_MULTIPLE_TABLES is not set +CONFIG_IPW2100=m +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +# CONFIG_IPW2200_DEBUG is not set +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IRCOMM=m +CONFIG_IRDA=m +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_DEBUG=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_ULTRA=y +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRPORT_SIR=m +CONFIG_IRTTY_SIR=m +CONFIG_ISA=y +CONFIG_ISAPNP=y +CONFIG_ISDN=m +CONFIG_ISDN_AUDIO=y +CONFIG_ISDN_CAPI=m +CONFIG_ISDN_CAPI_CAPI20=m +CONFIG_ISDN_CAPI_CAPIDRV=m +CONFIG_ISDN_CAPI_CAPIFS=m +CONFIG_ISDN_CAPI_CAPIFS_BOOL=y +CONFIG_ISDN_CAPI_MIDDLEWARE=y +CONFIG_ISDN_DIVAS=m +CONFIG_ISDN_DIVAS_BRIPCI=y +CONFIG_ISDN_DIVAS_DIVACAPI=m +CONFIG_ISDN_DIVAS_MAINT=m +CONFIG_ISDN_DIVAS_PRIPCI=y +CONFIG_ISDN_DIVAS_USERIDI=m +CONFIG_ISDN_DIVERSION=m +CONFIG_ISDN_DRV_ACT2000=m +CONFIG_ISDN_DRV_AVMB1_AVM_CS=m +CONFIG_ISDN_DRV_AVMB1_B1ISA=m +CONFIG_ISDN_DRV_AVMB1_B1PCI=m +CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m +CONFIG_ISDN_DRV_AVMB1_C4=m +CONFIG_ISDN_DRV_AVMB1_T1ISA=m +CONFIG_ISDN_DRV_AVMB1_T1PCI=m +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y +CONFIG_ISDN_DRV_GIGASET=m +CONFIG_ISDN_DRV_HISAX=m +CONFIG_ISDN_DRV_ICN=m +CONFIG_ISDN_DRV_LOOP=m +CONFIG_ISDN_DRV_PCBIT=m +CONFIG_ISDN_DRV_SC=m +CONFIG_ISDN_I4L=m +CONFIG_ISDN_MPP=y +CONFIG_ISDN_PPP=y +CONFIG_ISDN_PPP_BSDCOMP=m +CONFIG_ISDN_PPP_VJ=y +CONFIG_ISDN_TTY_FAX=y +CONFIG_ISDN_X25=y +# CONFIG_ISI is not set +CONFIG_ISTALLION=m +# CONFIG_IWLWIFI is not set +CONFIG_IXGB=m +# CONFIG_IXGB_NAPI is not set +CONFIG_JFFS2_CMODE_FAVOURLZO=y +# CONFIG_JFFS2_CMODE_NONE is not set +# CONFIG_JFFS2_CMODE_PRIORITY is not set +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_LZO=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_232=y +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_K8_NB=y +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KINGSUN_DONGLE=m +CONFIG_KS0108=m +CONFIG_KS0108_DELAY=2 +CONFIG_KS0108_PORT=0x378 +CONFIG_KS959_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +CONFIG_KVM=m +CONFIG_KVM_AMD=m +CONFIG_KVM_INTEL=m +CONFIG_LANCE=m +CONFIG_LANMEDIA=m +CONFIG_LAPB=m +CONFIG_LAPBETHER=m +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_LTV350QV=m +CONFIG_LEDS_CLASS=m +CONFIG_LEDS_NET48XX=m +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=m +CONFIG_LEDS_TRIGGER_IDE_DISK=y +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_WRAP=m +CONFIG_LGUEST=m +# CONFIG_LGUEST_GUEST is not set +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_CS=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_SDIO=m +CONFIG_LIBERTAS_USB=m +CONFIG_LITELINK_DONGLE=m +CONFIG_LLC=y +CONFIG_LNE390=m +CONFIG_LP486E=m +CONFIG_LTPC=m +CONFIG_LXT_PHY=m +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +CONFIG_M486=y +# CONFIG_M586 is not set +# CONFIG_M686 is not set +CONFIG_MA600_DONGLE=m +CONFIG_MAC80211=m +# CONFIG_MAC80211_DEBUG is not set +CONFIG_MAC80211_DEBUGFS=y +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_RCSIMPLE=y +CONFIG_MACHZ_WDT=m +CONFIG_MACINTOSH_DRIVERS=y +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_MADGEMC=m +CONFIG_MARVELL_PHY=m +CONFIG_MATH_EMULATION=y +CONFIG_MCA=y +CONFIG_MCA_LEGACY=y +# CONFIG_MCA_PROC_FS is not set +CONFIG_MCP2120_DONGLE=m +CONFIG_MCS_FIR=m +CONFIG_MDA_CONSOLE=m +CONFIG_MD_RAID10=m +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_SAS=m +CONFIG_MFD_SM501=m +CONFIG_MINIX_FS=m +CONFIG_MIXCOMWD=m +CONFIG_MKISS=m +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_MLX4_INFINIBAND=m +CONFIG_MMC=m +CONFIG_MMC_BLOCK=m +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_RICOH_MMC=m +CONFIG_MMC_SDHCI=m +CONFIG_MMC_TIFM_SD=m +# CONFIG_MMC_UNSAFE_RESUME is not set +CONFIG_MMC_WBSD=m +CONFIG_MOUSE_APPLETOUCH=m +# CONFIG_MOUSE_ATIXL is not set +CONFIG_MOUSE_INPORT=m +CONFIG_MOUSE_LOGIBM=m +CONFIG_MOUSE_PC110PAD=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_MOXA_INTELLIO=m +# CONFIG_MOXA_SMARTIO is not set +CONFIG_MOXA_SMARTIO_NEW=m +CONFIG_MSI_LAPTOP=m +CONFIG_MTD=m +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTD_ABSENT=m +CONFIG_MTD_ALAUDA=m +CONFIG_MTD_AMD76XROM=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK2MTD=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_MTD_CFI=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_CHAR=m +CONFIG_MTD_CK804XROM=m +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_CONCAT=m +CONFIG_MTD_DATAFLASH=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_DILNETPC=m +CONFIG_MTD_DILNETPC_BOOTSIZE=0x80000 +CONFIG_MTD_DOC2000=m +CONFIG_MTD_DOC2001=m +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCECC=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCPROBE_ADDRESS=0 +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_ESB2ROM=m +CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_ICHXROM=m +CONFIG_MTD_INTEL_VR_NOR=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_L440GX=m +CONFIG_MTD_M25P80=m +CONFIG_MTD_MAP_BANK_WIDTH_1=y +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +CONFIG_MTD_MTDRAM=m +CONFIG_MTD_NAND=m +CONFIG_MTD_NAND_CAFE=m +CONFIG_MTD_NAND_CS553X=m +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_NANDSIM=m +CONFIG_MTD_NAND_PLATFORM=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NETSC520=m +CONFIG_MTD_NETtel=m +CONFIG_MTD_ONENAND=m +CONFIG_MTD_ONENAND_2X_PROGRAM=y +# CONFIG_MTD_ONENAND_OTP is not set +CONFIG_MTD_ONENAND_SIM=m +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +CONFIG_MTD_OOPS=m +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_PCI=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PHYSMAP_LEN=0x4000000 +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PLATRAM=m +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +CONFIG_MTD_PNC2000=m +CONFIG_MTD_RAM=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS=m +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +CONFIG_MTD_ROM=m +CONFIG_MTD_SBC_GXX=m +CONFIG_MTD_SC520CDP=m +CONFIG_MTD_SCB2_FLASH=m +CONFIG_MTD_SCx200_DOCFLASH=m +CONFIG_MTD_SLRAM=m +CONFIG_MTD_TS5500=m +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_DEBUG is not set +CONFIG_MTD_UBI_GLUEBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MWAVE=m +CONFIG_MYRI10GE=m +CONFIG_N2=m +CONFIG_NATSEMI=m +CONFIG_NCPFS_EXTRAS=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_OS2_NS=y +CONFIG_NCPFS_PACKET_SIGNING=y +# CONFIG_NCPFS_SMALLDOS is not set +CONFIG_NCPFS_STRONG=y +CONFIG_NCP_FS=m +CONFIG_NE2000=m +CONFIG_NE2_MCA=m +CONFIG_NE3210=m +# CONFIG_NETLABEL is not set +CONFIG_NETROM=m +CONFIG_NETXEN_NIC=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +# CONFIG_NET_CLS_POLICE is not set +CONFIG_NET_DCCPPROBE=m +CONFIG_NET_FC=y +CONFIG_NET_ISA=y +CONFIG_NET_PCMCIA=y +CONFIG_NET_POCKET=y +CONFIG_NET_SCH_ATM=m +CONFIG_NET_TCPPROBE=m +CONFIG_NET_VENDOR_3COM=y +CONFIG_NET_VENDOR_RACAL=y +CONFIG_NET_VENDOR_SMC=y +CONFIG_NEW_LEDS=y +CONFIG_NFS_V4=y +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NI5010=m +CONFIG_NI52=m +CONFIG_NI65=m +CONFIG_NL80211=y +# CONFIG_NORTEL_HERMES is not set +# CONFIG_NO_HZ is not set +CONFIG_NS83820=m +CONFIG_NSC_FIR=m +CONFIG_NSC_GPIO=m +# CONFIG_NTFS_RW is not set +CONFIG_N_HDLC=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_P54_COMMON=m +CONFIG_P54_PCI=m +CONFIG_P54_USB=m +CONFIG_PARIDE=m +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +CONFIG_PARIDE_BPCK6=m +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_EPAT=m +# CONFIG_PARIDE_EPATC8 is not set +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PG=m +CONFIG_PARIDE_PT=m +CONFIG_PARPORT_AX88796=m +CONFIG_PARPORT_NOT_PC=y +CONFIG_PARPORT_PC_FIFO=y +CONFIG_PARPORT_PC_PCMCIA=m +CONFIG_PARPORT_SERIAL=m +CONFIG_PATA_CS5520=m +CONFIG_PATA_EFAR=m +# CONFIG_PATA_ISAPNP is not set +CONFIG_PATA_IT8213=m +CONFIG_PATA_IT821X=m +CONFIG_PATA_JMICRON=m +# CONFIG_PATA_LEGACY is not set +CONFIG_PATA_MARVELL=m +CONFIG_PATA_MPIIX=m +CONFIG_PATA_NETCELL=m +CONFIG_PATA_OLDPIIX=m +CONFIG_PATA_PCMCIA=m +CONFIG_PATA_PDC2027X=m +CONFIG_PATA_QDI=m +CONFIG_PATA_RZ1000=m +CONFIG_PATA_SERVERWORKS=m +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +CONFIG_PATA_TRIFLEX=m +CONFIG_PATA_WINBOND=m +# CONFIG_PATA_WINBOND_VLB is not set +CONFIG_PC300=m +# CONFIG_PC300TOO is not set +CONFIG_PC300_MLPPP=y +CONFIG_PC8736x_GPIO=m +CONFIG_PC87413_WDT=m +CONFIG_PCCARD=m +CONFIG_PCCARD_NONSTATIC=m +CONFIG_PCI200SYN=m +CONFIG_PCIEAER=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIPCWATCHDOG=m +CONFIG_PCI_ATMEL=m +# CONFIG_PCI_HERMES is not set +CONFIG_PCMCIA=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_AHA152X=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_PCMCIA_AXNET=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_HERMES=m +CONFIG_PCMCIA_IBMTR=m +CONFIG_PCMCIA_IOCTL=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_NETWAVE=m +CONFIG_PCMCIA_NINJA_SCSI=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_PROBE=y +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_RAYCS=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_SPECTRUM=m +CONFIG_PCMCIA_SYM53C500=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_WL3501=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_PCMCIA_XIRTULIP=m +CONFIG_PCWATCHDOG=m +CONFIG_PD6729=m +CONFIG_PDC202XX_BURST=y +CONFIG_PDC_ADMA=m +CONFIG_PHANTOM=m +CONFIG_PHONE=m +CONFIG_PHONE_IXJ=m +CONFIG_PHONE_IXJ_PCMCIA=m +CONFIG_PLIP=m +# CONFIG_PLX_HERMES is not set +CONFIG_PNPBIOS=y +CONFIG_PNPBIOS_PROC_FS=y +CONFIG_PPPOATM=m +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_NOTIFIERS=y +CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_PRISM54=m +CONFIG_PROTEON=m +CONFIG_QLA3XXX=m +CONFIG_QSEMI_PHY=m +CONFIG_R3964=m +CONFIG_R8169=m +# CONFIG_R8169_NAPI is not set +CONFIG_R8169_VLAN=y +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_AZTECH=m +CONFIG_RADIO_CADET=m +CONFIG_RADIO_GEMTEK=m +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAESTRO=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RADIO_RTRACK=m +CONFIG_RADIO_RTRACK2=m +CONFIG_RADIO_SF16FMI=m +CONFIG_RADIO_SF16FMR2=m +CONFIG_RADIO_TERRATEC=m +CONFIG_RADIO_TRUST=m +CONFIG_RADIO_TYPHOON=m +# CONFIG_RADIO_TYPHOON_PROC_FS is not set +CONFIG_RADIO_ZOLTRIX=m +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y +# CONFIG_RESOURCES_64BIT is not set +CONFIG_RFD_FTL=m +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +CONFIG_RFKILL_LEDS=y +CONFIG_RIO=m +CONFIG_RIO_OLDPCI=y +CONFIG_RISCOM8=m +CONFIG_ROADRUNNER=m +# CONFIG_ROADRUNNER_LARGE_RINGS is not set +CONFIG_ROCKETPORT=m +CONFIG_ROMFS_FS=m +CONFIG_ROSE=m +CONFIG_RT2400PCI=m +CONFIG_RT2400PCI_RFKILL=y +CONFIG_RT2500PCI=m +CONFIG_RT2500PCI_RFKILL=y +CONFIG_RT2500USB=m +CONFIG_RT2X00=m +# CONFIG_RT2X00_DEBUG is not set +CONFIG_RT2X00_LIB=m +# CONFIG_RT2X00_LIB_DEBUGFS is not set +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_PCI=m +CONFIG_RT2X00_LIB_RFKILL=y +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT61PCI=m +CONFIG_RT61PCI_RFKILL=y +CONFIG_RT73USB=m +CONFIG_RTC=m +CONFIG_RTC_CLASS=m +# CONFIG_RTC_DRV_CMOS is not set +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_M41T80_WDT=y +CONFIG_RTC_DRV_M48T59=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_STK17TA8=m +CONFIG_RTC_DRV_TEST=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_LIB=m +CONFIG_RTL8187=m +CONFIG_RXKAD=m +CONFIG_S2IO=m +# CONFIG_S2IO_NAPI is not set +CONFIG_SATA_AHCI=m +CONFIG_SATA_INIC162X=m +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIL24=m +CONFIG_SATA_SIS=m +CONFIG_SATA_SVW=m +CONFIG_SATA_SX4=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m +CONFIG_SBC8360_WDT=m +CONFIG_SBC_EPX_C3_WATCHDOG=m +CONFIG_SBNI=m +# CONFIG_SBNI_MULTILINE is not set +CONFIG_SC1200_WDT=m +CONFIG_SC520_WDT=m +CONFIG_SC92031=m +CONFIG_SCC=m +# CONFIG_SCC_DELAY is not set +# CONFIG_SCC_TRXECHO is not set +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_7000FASST=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_ADVANSYS=m +CONFIG_SCSI_AHA152X=m +CONFIG_SCSI_AHA1542=m +CONFIG_SCSI_AHA1740=m +CONFIG_SCSI_AIC79XX=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_SCSI_AIC94XX=m +CONFIG_SCSI_ARCMSR=m +CONFIG_SCSI_ARCMSR_AER=y +CONFIG_SCSI_DC390T=m +CONFIG_SCSI_DC395x=m +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_DPT_I2O=m +CONFIG_SCSI_DTC3280=m +CONFIG_SCSI_EATA=m +CONFIG_SCSI_EATA_LINKED_COMMANDS=y +CONFIG_SCSI_EATA_MAX_TAGS=16 +CONFIG_SCSI_EATA_TAGGED_QUEUE=y +CONFIG_SCSI_FC_TGT_ATTRS=y +CONFIG_SCSI_FD_MCS=m +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_SCSI_GDTH=m +CONFIG_SCSI_GENERIC_NCR5380=m +CONFIG_SCSI_GENERIC_NCR5380_MMIO=m +CONFIG_SCSI_GENERIC_NCR53C400=y +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_IBMMCA=m +CONFIG_SCSI_IMM=m +CONFIG_SCSI_IN2000=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_DUMP is not set +# CONFIG_SCSI_IPR_TRACE is not set +CONFIG_SCSI_IPS=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +CONFIG_SCSI_LOWLEVEL_PCMCIA=y +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_MCA_53C9X=m +CONFIG_SCSI_NCR53C406A=m +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=4 +CONFIG_SCSI_NCR53C8XX_SYNC=5 +CONFIG_SCSI_NCR_D700=m +CONFIG_SCSI_NCR_Q720=m +CONFIG_SCSI_NSP32=m +CONFIG_SCSI_PAS16=m +CONFIG_SCSI_PPA=m +CONFIG_SCSI_PSI240I=m +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_QLOGIC_FAS=m +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_SEAGATE=m +CONFIG_SCSI_SIM710=m +CONFIG_SCSI_SRP=m +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C416=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_T128=m +CONFIG_SCSI_TGT=m +CONFIG_SCSI_U14_34F=m +CONFIG_SCSI_U14_34F_LINKED_COMMANDS=y +CONFIG_SCSI_U14_34F_MAX_TAGS=8 +CONFIG_SCSI_U14_34F_TAGGED_QUEUE=y +CONFIG_SCSI_ULTRASTOR=m +CONFIG_SCx200=m +CONFIG_SCx200HR_TIMER=m +CONFIG_SCx200_ACB=m +CONFIG_SCx200_GPIO=m +CONFIG_SCx200_I2C=m +CONFIG_SCx200_I2C_SCL=12 +CONFIG_SCx200_I2C_SDA=13 +CONFIG_SCx200_WDT=m +CONFIG_SDIO_UART=m +CONFIG_SDLA=m +CONFIG_SEALEVEL_4021=m +CONFIG_SEEQ8005=m +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_ABITUGURU3=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_APPLESMC=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_FSCHMD=m +CONFIG_SENSORS_FSCPOS=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_HDAPS=m +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_IBMPEX=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_K8TEMP=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_LM93=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SERIAL_8250_ACCENT=m +CONFIG_SERIAL_8250_BOCA=m +CONFIG_SERIAL_8250_CS=m +CONFIG_SERIAL_8250_EXAR_ST16C554=m +CONFIG_SERIAL_8250_FOURPORT=m +CONFIG_SERIAL_8250_HUB6=m +CONFIG_SERIAL_8250_MCA=m +CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_SERIO_CT82C710=m +CONFIG_SERIO_PARKBD=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SGI_IOC4=m +CONFIG_SIGMATEL_FIR=m +CONFIG_SIS190=m +CONFIG_SIS900=m +CONFIG_SKFP=m +CONFIG_SKGE=m +# CONFIG_SKGE_DEBUG is not set +CONFIG_SKISA=m +CONFIG_SKY2=m +# CONFIG_SKY2_DEBUG is not set +CONFIG_SMC9194=m +CONFIG_SMCTR=m +CONFIG_SMC_IRCC_FIR=m +# CONFIG_SMP is not set +CONFIG_SMSC37B787_WDT=m +CONFIG_SMSC_PHY=m +# CONFIG_SND is not set +CONFIG_SONYPI=m +CONFIG_SONYPI_COMPAT=y +CONFIG_SONY_LAPTOP=m +# CONFIG_SOUND_PRIME is not set +CONFIG_SPECIALIX=m +# CONFIG_SPECIALIX_RTSCTS is not set +CONFIG_SPI=y +CONFIG_SPI_AT25=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_LM70_LLP=m +CONFIG_SPI_MASTER=y +# CONFIG_SPI_SPIDEV is not set +CONFIG_SPI_TLE62X0=m +CONFIG_SSB_DRIVER_PCICORE=y +# CONFIG_SSB_PCMCIAHOST is not set +CONFIG_SSB_PCMCIAHOST_POSSIBLE=y +CONFIG_SSFDC=m +CONFIG_STALDRV=y +CONFIG_STALLION=m +CONFIG_STRIP=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_SUNGEM=m +CONFIG_SUNRPC_XPRT_RDMA=m +CONFIG_SUSPEND_UP_POSSIBLE=y +CONFIG_SX=m +CONFIG_SYNCLINK=m +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_CS=m +CONFIG_SYNCLINK_GT=m +CONFIG_SYSV68_PARTITION=y +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +CONFIG_TCG_ATMEL=m +CONFIG_TCG_INFINEON=m +CONFIG_TCG_NSC=m +CONFIG_TCG_TIS=m +CONFIG_TCG_TPM=m +CONFIG_TCIC=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TELCLOCK=m +CONFIG_THINKPAD_ACPI=m +CONFIG_THINKPAD_ACPI_BAY=y +# CONFIG_THINKPAD_ACPI_DEBUG is not set +CONFIG_TIFM_7XX1=m +CONFIG_TIFM_CORE=m +CONFIG_TIGON3=m +CONFIG_TLAN=m +# CONFIG_TMD_HERMES is not set +CONFIG_TMS380TR=m +CONFIG_TMSPCI=m +# CONFIG_TOIM3232_DONGLE is not set +CONFIG_TOSHIBA=m +CONFIG_TOSHIBA_FIR=m +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_UCB1400=m +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TR=y +CONFIG_TUNER_3036=m +CONFIG_TUNER_MT20XX=m +CONFIG_TUNER_SIMPLE=m +CONFIG_TUNER_TDA8290=m +CONFIG_TUNER_TEA5761=m +CONFIG_TUNER_TEA5767=m +CONFIG_TYPHOON=m +CONFIG_ULI526X=m +CONFIG_ULTRA=m +CONFIG_ULTRA32=m +CONFIG_ULTRAMCA=m +CONFIG_USBPCWATCHDOG=m +CONFIG_USB_ACM=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_ARMLINUX=y +CONFIG_USB_ATM=m +CONFIG_USB_AUERSWALD=m +CONFIG_USB_BELKIN=y +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_CATC=m +CONFIG_USB_CXACRU=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_DABUSB=m +CONFIG_USB_DSBR=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EMI26=m +CONFIG_USB_EMI62=m +CONFIG_USB_EPSON2888=y +CONFIG_USB_ET61X251=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_EZUSB=y +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_GADGET=m +CONFIG_USB_GADGETFS=m +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_M66592 is not set +CONFIG_USB_GADGET_NET2280=y +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_S3C2410 is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_G_SERIAL=m +CONFIG_USB_HID=m +CONFIG_USB_HIDDEV=y +CONFIG_USB_HIDINPUT_POWERBOOK=y +CONFIG_USB_IBMCAM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_IRDA=m +CONFIG_USB_KAWETH=m +CONFIG_USB_KBD=m +CONFIG_USB_KC2190=y +CONFIG_USB_KONICAWC=m +CONFIG_USB_LCD=m +CONFIG_USB_LD=m +CONFIG_USB_LED=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LIBUSUAL=y +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_USB_MON=y +CONFIG_USB_MOUSE=m +CONFIG_USB_NET2280=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_HCD_SSB is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OV511 is not set +CONFIG_USB_PEGASUS=m +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_PRINTER=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_RIO500=m +CONFIG_USB_RTL8150=m +CONFIG_USB_SE401=m +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_AIRPRIME=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IPW=m +# CONFIG_USB_SERIAL_IR is not set +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SISUSBVGA=m +# CONFIG_USB_SISUSBVGA_CON is not set +CONFIG_USB_SL811_CS=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SN9C102=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STV680=m +CONFIG_USB_SUSPEND=y +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_USBNET=m +CONFIG_USB_USS720=m +CONFIG_USB_VICAM=m +CONFIG_USB_W9968CF=m +CONFIG_USB_XUSBATM=m +CONFIG_USB_ZC0301=m +CONFIG_USB_ZD1201=m +CONFIG_USB_ZERO=m +CONFIG_USB_ZR364XX=m +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VERSION_SIGNATURE="Ubuntu 2.6.24-4.6-386" +CONFIG_VIA_FIR=m +CONFIG_VIA_RHINE=m +CONFIG_VIA_RHINE_MMIO=y +CONFIG_VIA_RHINE_NAPI=y +CONFIG_VIA_VELOCITY=m +CONFIG_VIDEOBUF_DMA_SG=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CAFE_CCIC=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_CPIA_PP=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_CX23885=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_DEV=m +# CONFIG_VIDEO_DPC is not set +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_FB_IVTV=m +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_MEYE=m +CONFIG_VIDEO_MSP3400=m +# CONFIG_VIDEO_MXB is not set +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_VIDEO_PMS=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_24XXX=y +CONFIG_VIDEO_PVRUSB2_29XXX=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA7111=m +CONFIG_VIDEO_SAA7114=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_SAA7191=m +CONFIG_VIDEO_STRADIS=m +CONFIG_VIDEO_TCM825X=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TDA9875=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_TLV320AIC23B=m +CONFIG_VIDEO_TUNER=m +# CONFIG_VIDEO_TUNER_CUSTOMIZE is not set +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_VP27SMPX=m +CONFIG_VIDEO_VPX3220=m +CONFIG_VIDEO_W9966=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VITESSE_PHY=m +CONFIG_VLSI_FIR=m +CONFIG_VORTEX=m +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_THERM=m +CONFIG_W83627HF_WDT=m +CONFIG_W83697HF_WDT=m +CONFIG_W83877F_WDT=m +CONFIG_W83977F_WDT=m +CONFIG_WAFER_WDT=m +CONFIG_WAN=y +CONFIG_WANXL=m +CONFIG_WAN_ROUTER=m +CONFIG_WAN_ROUTER_DRIVERS=m +CONFIG_WAVELAN=m +CONFIG_WD80x3=m +# CONFIG_WDC_ALI15X3 is not set +CONFIG_WDT=m +CONFIG_WDTPCI=m +CONFIG_WDT_501=y +CONFIG_WDT_501_PCI=y +CONFIG_WINBOND_840=m +CONFIG_WINBOND_FIR=m +CONFIG_WIRELESS_EXT=y +CONFIG_WLAN_80211=y +CONFIG_WLAN_PRE80211=y +CONFIG_X25=m +CONFIG_X25_ASY=m +CONFIG_X86_ALIGNMENT_16=y +CONFIG_X86_CPUFREQ_NFORCE2=m +CONFIG_X86_F00F_BUG=y +CONFIG_X86_SPEEDSTEP_LIB=m +CONFIG_X86_SPEEDSTEP_SMI=m +CONFIG_X86_UP_APIC=y +CONFIG_X86_UP_IOAPIC=y +CONFIG_YAM=m +CONFIG_YELLOWFIN=m +CONFIG_YENTA=m +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_ZNET=m --- linux-2.6.24.orig/debian/config/amd64/config +++ linux-2.6.24/debian/config/amd64/config @@ -0,0 +1,2986 @@ +# +# Common config options automatically generated by splitconfig.pl +# +CONFIG_3C359=m +CONFIG_60XX_WDT=m +CONFIG_64BIT=y +CONFIG_6PACK=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_8129=y +CONFIG_8139TOO_PIO=y +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_9P_FS=m +CONFIG_ABYSS=m +CONFIG_AC97_BUS=m +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_ACORN_PARTITION=y +# CONFIG_ACORN_PARTITION_ADFS is not set +# CONFIG_ACORN_PARTITION_CUMANA is not set +# CONFIG_ACORN_PARTITION_EESOX is not set +CONFIG_ACORN_PARTITION_ICS=y +# CONFIG_ACORN_PARTITION_POWERTEC is not set +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_ACPI=y +CONFIG_ACPI_AC=m +CONFIG_ACPI_ASUS=m +CONFIG_ACPI_BATTERY=m +CONFIG_ACPI_BAY=m +CONFIG_ACPI_BLACKLIST_YEAR=0 +CONFIG_ACPI_BUTTON=m +CONFIG_ACPI_CONTAINER=m +CONFIG_ACPI_CUSTOM_DSDT_INITRD=y +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_DOCK=m +CONFIG_ACPI_EC=y +CONFIG_ACPI_FAN=m +CONFIG_ACPI_HOTPLUG_CPU=y +CONFIG_ACPI_NUMA=y +CONFIG_ACPI_POWER=y +CONFIG_ACPI_PROCESSOR=m +CONFIG_ACPI_PROCFS=y +CONFIG_ACPI_PROCFS_POWER=y +CONFIG_ACPI_PROC_EVENT=y +CONFIG_ACPI_SBS=m +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_SYSFS_POWER=y +CONFIG_ACPI_SYSTEM=y +CONFIG_ACPI_THERMAL=m +CONFIG_ACPI_TOSHIBA=m +CONFIG_ACPI_VIDEO=m +CONFIG_ACQUIRE_WDT=m +CONFIG_ACT200L_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_ADAPTEC_STARFIRE=m +# CONFIG_ADAPTEC_STARFIRE_NAPI is not set +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_ADM8211=m +CONFIG_ADVANTECH_WDT=m +CONFIG_AFFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_AFS_FS=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_AGP=y +CONFIG_AGP_AMD64=y +CONFIG_AGP_INTEL=m +CONFIG_AGP_SIS=m +CONFIG_AGP_VIA=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +CONFIG_AIC79XX_DEBUG_ENABLE=y +CONFIG_AIC79XX_DEBUG_MASK=0 +CONFIG_AIC79XX_REG_PRETTY_PRINT=y +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 +CONFIG_AIC7XXX_DEBUG_ENABLE=y +CONFIG_AIC7XXX_DEBUG_MASK=0 +CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_AIRO=m +CONFIG_AIRO_CS=m +CONFIG_ALIM1535_WDT=m +CONFIG_ALIM7101_WDT=m +CONFIG_ALI_FIR=m +# CONFIG_AMD8111E_NAPI is not set +CONFIG_AMD8111_ETH=m +CONFIG_AMIGA_PARTITION=y +CONFIG_ANON_INODES=y +CONFIG_APPLICOM=m +CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y +CONFIG_ARCH_DISCONTIGMEM_ENABLE=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_HIBERNATION_HEADER=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUPPORTS_MSI=y +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_ARCNET=m +CONFIG_ARCNET_1051=m +CONFIG_ARCNET_1201=m +CONFIG_ARCNET_CAP=m +CONFIG_ARCNET_COM20020=m +CONFIG_ARCNET_COM20020_CS=m +CONFIG_ARCNET_COM20020_PCI=m +CONFIG_ARCNET_COM90xx=m +CONFIG_ARCNET_COM90xxIO=m +CONFIG_ARCNET_RAW=m +CONFIG_ARCNET_RIM_I=m +# CONFIG_ARPD is not set +CONFIG_ASK_IP_FIB_HASH=y +CONFIG_ASUS_LAPTOP=m +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_ATA=m +CONFIG_ATALK=m +CONFIG_ATARI_PARTITION=y +CONFIG_ATA_ACPI=y +CONFIG_ATA_GENERIC=m +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_OVER_ETH=m +CONFIG_ATA_PIIX=m +CONFIG_ATL1=m +CONFIG_ATM=y +CONFIG_ATMEL=m +CONFIG_ATM_AMBASSADOR=m +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_ATM_CLIP=y +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +CONFIG_ATM_ENI=m +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +CONFIG_ATM_FIRESTREAM=m +CONFIG_ATM_FORE200E=m +CONFIG_ATM_FORE200E_DEBUG=0 +CONFIG_ATM_FORE200E_MAYBE=m +CONFIG_ATM_FORE200E_PCA=y +CONFIG_ATM_FORE200E_PCA_DEFAULT_FW=y +CONFIG_ATM_FORE200E_TX_RETRY=16 +# CONFIG_ATM_FORE200E_USE_TASKLET is not set +CONFIG_ATM_HE=m +CONFIG_ATM_HE_USE_SUNI=y +CONFIG_ATM_HORIZON=m +# CONFIG_ATM_HORIZON_DEBUG is not set +CONFIG_ATM_IDT77252=m +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +CONFIG_ATM_IDT77252_USE_SUNI=y +CONFIG_ATM_LANAI=m +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_TCP=m +CONFIG_ATM_ZATM=m +# CONFIG_ATM_ZATM_DEBUG is not set +CONFIG_ATP=m +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y +CONFIG_AUDIT_ARCH=y +CONFIG_AUDIT_TREE=y +CONFIG_AUTOFS4_FS=m +CONFIG_AUTOFS_FS=m +CONFIG_AUXDISPLAY=y +CONFIG_AX25=m +CONFIG_AX25_DAMA_SLAVE=y +CONFIG_B43=m +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_DEBUG=y +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y +CONFIG_B43LEGACY_PCI_AUTOSELECT=y +CONFIG_B43LEGACY_PIO=y +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_B43_DEBUG=y +CONFIG_B43_DMA=y +CONFIG_B43_DMA_AND_PIO_MODE=y +# CONFIG_B43_DMA_MODE is not set +CONFIG_B43_LEDS=y +CONFIG_B43_PCICORE_AUTOSELECT=y +CONFIG_B43_PCI_AUTOSELECT=y +# CONFIG_B43_PCMCIA is not set +CONFIG_B43_PIO=y +# CONFIG_B43_PIO_MODE is not set +CONFIG_B43_RFKILL=y +CONFIG_B44=m +CONFIG_B44_PCI=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI_AUTOSELECT=y +CONFIG_BACKLIGHT_CARILLO_RANCH=m +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_CORGI=m +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_PROGEAR=m +CONFIG_BASE_FULL=y +CONFIG_BASE_SMALL=0 +CONFIG_BATTERY_DS2760=m +CONFIG_BAYCOM_PAR=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_BCM43XX=m +# CONFIG_BCM43XX_DEBUG is not set +CONFIG_BCM43XX_DMA=y +CONFIG_BCM43XX_DMA_AND_PIO_MODE=y +# CONFIG_BCM43XX_DMA_MODE is not set +CONFIG_BCM43XX_PIO=y +# CONFIG_BCM43XX_PIO_MODE is not set +# CONFIG_BEFS_DEBUG is not set +CONFIG_BEFS_FS=m +CONFIG_BFS_FS=m +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_BITREVERSE=y +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_DEV=y +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_BLK_DEV_AEC62XX=m +CONFIG_BLK_DEV_ALI15X3=m +# CONFIG_BLK_DEV_AMD74XX is not set +CONFIG_BLK_DEV_ATIIXP=m +# CONFIG_BLK_DEV_BSG is not set +CONFIG_BLK_DEV_CMD640=y +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +CONFIG_BLK_DEV_CMD64X=m +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_CRYPTOLOOP=m +# CONFIG_BLK_DEV_CS5520 is not set +CONFIG_BLK_DEV_CS5530=m +CONFIG_BLK_DEV_CY82C693=m +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_DELKIN=m +CONFIG_BLK_DEV_DM=m +CONFIG_BLK_DEV_FD=m +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_BLK_DEV_HD is not set +# CONFIG_BLK_DEV_HD_IDE is not set +CONFIG_BLK_DEV_HPT34X=m +CONFIG_BLK_DEV_HPT366=m +CONFIG_BLK_DEV_IDE=m +CONFIG_BLK_DEV_IDEACPI=y +CONFIG_BLK_DEV_IDECD=m +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDEDISK=m +CONFIG_BLK_DEV_IDEDMA=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_IDEFLOPPY=m +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_BLK_DEV_IDEPNP=y +CONFIG_BLK_DEV_IDESCSI=m +CONFIG_BLK_DEV_IDETAPE=m +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_JMICRON is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_MD=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_NS87415=m +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_OPTI621=m +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +CONFIG_BLK_DEV_PDC202XX_OLD=m +# CONFIG_BLK_DEV_PIIX is not set +CONFIG_BLK_DEV_PLATFORM=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +# CONFIG_BLK_DEV_RZ1000 is not set +CONFIG_BLK_DEV_SC1200=m +CONFIG_BLK_DEV_SD=m +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_BLK_DEV_SVWKS is not set +CONFIG_BLK_DEV_SX8=m +CONFIG_BLK_DEV_TC86C001=m +# CONFIG_BLK_DEV_TRIFLEX is not set +CONFIG_BLK_DEV_TRM290=m +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_UMEM=m +# CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_BLOCK=y +CONFIG_BLOCK_COMPAT=y +CONFIG_BNX2=m +CONFIG_BONDING=m +# CONFIG_BOOT_PRINTK_DELAY is not set +CONFIG_BOUNCE=y +CONFIG_BPQETHER=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_NETFILTER=y +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BROADCOM_PHY=m +CONFIG_BSD_DISKLABEL=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_BT=m +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_CMTP=m +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HIDP=m +CONFIG_BT_L2CAP=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_SCO=m +CONFIG_BUG=y +CONFIG_CALGARY_IOMMU=y +CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT=y +CONFIG_CAPI_AVM=y +CONFIG_CAPI_EICON=y +CONFIG_CAPI_TRACE=y +CONFIG_CARDBUS=y +CONFIG_CARDMAN_4000=m +CONFIG_CARDMAN_4040=m +CONFIG_CASSINI=m +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_CC_STACKPROTECTOR=y +# CONFIG_CC_STACKPROTECTOR_ALL is not set +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_CFAG12864B=m +CONFIG_CFAG12864B_RATE=20 +CONFIG_CFG80211=m +CONFIG_CGROUPS=y +CONFIG_CGROUP_CPUACCT=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_NS=y +CONFIG_CHECK_SIGNATURE=y +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T1_NAPI=y +CONFIG_CHELSIO_T3=m +CONFIG_CHR_DEV_OSST=m +CONFIG_CHR_DEV_SCH=m +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_ST=m +CONFIG_CICADA_PHY=m +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG2 is not set +CONFIG_CIFS_EXPERIMENTAL=y +# CONFIG_CIFS_STATS is not set +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_WEAK_PW_HASH=y +# CONFIG_CIFS_XATTR is not set +CONFIG_CISS_SCSI_TAPE=y +CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_CLS_U32_MARK=y +# CONFIG_CLS_U32_PERF is not set +CONFIG_CODA_FS=m +# CONFIG_CODA_FS_OLD_API is not set +CONFIG_COMPAT=y +CONFIG_COMPAT_FOR_U64_ALIGNMENT=y +CONFIG_COMPUTONE=m +CONFIG_CONFIGFS_FS=m +CONFIG_CONNECTOR=m +CONFIG_CPU5_WDT=m +CONFIG_CPUSETS=y +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEBUG is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_TABLE=m +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_CRAMFS=y +CONFIG_CRASH_DUMP=y +CONFIG_CRC16=m +CONFIG_CRC32=y +CONFIG_CRC7=m +CONFIG_CRC_CCITT=m +CONFIG_CRC_ITU_T=m +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ABLKCIPHER=m +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_AES_X86_64=m +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_TWOFISH_X86_64=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_XTS=m +CONFIG_CYCLADES=m +CONFIG_CYCLADES_SYNC=m +CONFIG_CYCLOMX_X25=y +# CONFIG_CYZ_INTR is not set +CONFIG_DAB=y +CONFIG_DAVICOM_PHY=m +CONFIG_DCA=m +CONFIG_DCDBAS=m +CONFIG_DE2104X=m +CONFIG_DE4X5=m +CONFIG_DE600=m +CONFIG_DE620=m +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_DRIVER is not set +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_DEBUG_MUTEXES is not set +CONFIG_DEBUG_RODATA=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_VM is not set +CONFIG_DECNET=m +CONFIG_DECNET_NF_GRABULATOR=m +# CONFIG_DECNET_ROUTER is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_BIC is not set +# CONFIG_DEFAULT_CUBIC is not set +# CONFIG_DEFAULT_HTCP is not set +CONFIG_DEFAULT_IO_DELAY_TYPE=1 +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_RELATIME=y +CONFIG_DEFAULT_RELATIME_VAL=1 +CONFIG_DEFAULT_RENO=y +CONFIG_DEFAULT_TCP_CONG="reno" +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_WESTWOOD is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_DEFXX=m +# CONFIG_DEFXX_MMIO is not set +CONFIG_DELL_RBU=m +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_DEVPORT=y +CONFIG_DEV_APPLETALK=m +# CONFIG_DEV_KMEM is not set +CONFIG_DE_AOC=y +CONFIG_DIGIEPCA=m +CONFIG_DISCONTIGMEM=y +CONFIG_DISCONTIGMEM_MANUAL=y +CONFIG_DISPLAY_SUPPORT=m +CONFIG_DL2K=m +CONFIG_DLCI=m +CONFIG_DLCI_MAX=8 +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +CONFIG_DM9102=m +CONFIG_DMADEVICES=y +# CONFIG_DMAR is not set +CONFIG_DMA_ENGINE=y +CONFIG_DMI=y +CONFIG_DMIID=y +CONFIG_DM_CRYPT=m +# CONFIG_DM_DEBUG is not set +# CONFIG_DM_DELAY is not set +CONFIG_DM_MIRROR=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_EMC=m +CONFIG_DM_MULTIPATH_HP=m +CONFIG_DM_MULTIPATH_RDAC=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_UEVENT=y +CONFIG_DM_ZERO=m +CONFIG_DNOTIFY=y +CONFIG_DONGLE=y +CONFIG_DRM=m +CONFIG_DRM_I810=m +CONFIG_DRM_I830=m +CONFIG_DRM_I915=m +CONFIG_DRM_MGA=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_SAVAGE=m +CONFIG_DRM_SIS=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_VIA=m +CONFIG_DRM_VIA_CHROME9=m +CONFIG_DS1682=m +CONFIG_DSCC4=m +CONFIG_DSCC4_PCISYNC=y +CONFIG_DSCC4_PCI_RST=y +CONFIG_DUMMY=m +CONFIG_DUMMY_CONSOLE=y +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_B2C2_FLEXCOP=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_BT8XX=m +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_PATCH=m +CONFIG_DVB_CAPTURE_DRIVERS=y +CONFIG_DVB_CINERGYT2=m +CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y +CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250 +CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100 +CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512 +CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32 +CONFIG_DVB_CINERGYT2_TUNING=y +CONFIG_DVB_CORE=m +CONFIG_DVB_CORE_ATTACH=y +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_ISL6421=m +CONFIG_DVB_L64781=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_MT312=m +CONFIG_DVB_MT352=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_PLL=m +CONFIG_DVB_PLUTO2=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TDA827X=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_TUNER_MT2060=m +CONFIG_DVB_TUNER_MT2131=m +CONFIG_DVB_TUNER_MT2266=m +CONFIG_DVB_TUNER_QT1010=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_CXUSB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_ZL10353=m +CONFIG_E100=m +CONFIG_E1000=m +CONFIG_E1000E=m +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +CONFIG_E1000_NAPI=y +CONFIG_EARLY_PRINTK=y +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +CONFIG_ECRYPT_FS=m +CONFIG_EDAC=y +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_E752X=m +CONFIG_EDAC_I5000=m +CONFIG_EDAC_I82975X=m +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDD=y +CONFIG_EEPRO100=m +CONFIG_EEPROM_93CX6=m +CONFIG_EFI_PARTITION=y +CONFIG_EFS_FS=m +CONFIG_ELF_CORE=y +CONFIG_EMBEDDED=y +# CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +CONFIG_EPIC100=m +CONFIG_EPOLL=y +CONFIG_EQUALIZER=m +CONFIG_ESI_DONGLE=m +CONFIG_EUROTECH_WDT=m +CONFIG_EVENTFD=y +CONFIG_EXPERIMENTAL=y +CONFIG_EXPORTFS=m +CONFIG_EXT2_FS=m +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT4DEV_FS is not set +CONFIG_FAIR_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_FAIR_USER_SCHED is not set +CONFIG_FARSYNC=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_FAT_FS=m +# CONFIG_FAULT_INJECTION is not set +CONFIG_FB=y +CONFIG_FB_3DFX=m +# CONFIG_FB_3DFX_ACCEL is not set +CONFIG_FB_ARC=m +CONFIG_FB_ARK=m +CONFIG_FB_ASILIANT=y +CONFIG_FB_ATY=m +CONFIG_FB_ATY128=m +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY_BACKLIGHT=y +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_CARILLO_RANCH=m +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +CONFIG_FB_CIRRUS=m +CONFIG_FB_CYBER2000=m +CONFIG_FB_DDC=m +CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_EFI=y +CONFIG_FB_GEODE=y +CONFIG_FB_GEODE_GX=m +CONFIG_FB_GEODE_GX1=m +# CONFIG_FB_GEODE_GX_SET_FBSIZE is not set +CONFIG_FB_GEODE_LX=m +CONFIG_FB_HECUBA=m +CONFIG_FB_HGA=m +# CONFIG_FB_HGA_ACCEL is not set +CONFIG_FB_IMSTT=y +CONFIG_FB_INTEL=m +# CONFIG_FB_INTEL_DEBUG is not set +CONFIG_FB_INTEL_I2C=y +CONFIG_FB_KYRO=m +CONFIG_FB_LE80578=m +# CONFIG_FB_MACMODES is not set +CONFIG_FB_MATROX=m +CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MULTIHEAD=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_NEOMAGIC=m +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_BACKLIGHT=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_I2C=y +CONFIG_FB_PM2=m +CONFIG_FB_PM2_FIFO_DISCONNECT=y +CONFIG_FB_PM3=m +CONFIG_FB_RADEON=m +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RIVA=m +CONFIG_FB_RIVA_BACKLIGHT=y +# CONFIG_FB_RIVA_DEBUG is not set +CONFIG_FB_RIVA_I2C=y +CONFIG_FB_S1D13XXX=m +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_ACCEL=y +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SIS=m +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +CONFIG_FB_SM501=m +CONFIG_FB_SVGALIB=m +CONFIG_FB_SYS_COPYAREA=m +CONFIG_FB_SYS_FILLRECT=m +CONFIG_FB_SYS_FOPS=m +CONFIG_FB_SYS_IMAGEBLIT=m +CONFIG_FB_TILEBLITTING=y +CONFIG_FB_TRIDENT=m +# CONFIG_FB_TRIDENT_ACCEL is not set +CONFIG_FB_UVESA=m +CONFIG_FB_VESA=m +CONFIG_FB_VGA16=m +# CONFIG_FB_VIRTUAL is not set +CONFIG_FB_VOODOO1=m +CONFIG_FB_VT8623=m +CONFIG_FDDI=y +CONFIG_FEALNX=m +CONFIG_FIB_RULES=y +# CONFIG_FIREWIRE is not set +CONFIG_FIRMWARE_EDID=y +CONFIG_FIXED_MII_1000_FDX=y +# CONFIG_FIXED_MII_100_FDX is not set +# CONFIG_FIXED_MII_10_FDX is not set +CONFIG_FIXED_MII_AMNT=1 +CONFIG_FIXED_PHY=m +CONFIG_FIX_EARLYCON_MEM=y +# CONFIG_FLATMEM_MANUAL is not set +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +CONFIG_FORCEDETH=m +# CONFIG_FORCEDETH_NAPI is not set +# CONFIG_FORCED_INLINING is not set +CONFIG_FRAMEBUFFER_CONSOLE=m +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FRAME_POINTER is not set +CONFIG_FS_MBCACHE=m +CONFIG_FS_POSIX_ACL=y +CONFIG_FTL=m +CONFIG_FUJITSU_LAPTOP=m +CONFIG_FUSE_FS=m +CONFIG_FUSION=y +CONFIG_FUSION_CTL=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_LAN=m +CONFIG_FUSION_LOGGING=y +CONFIG_FUSION_MAX_SGE=128 +CONFIG_FUSION_SAS=m +CONFIG_FUSION_SPI=m +CONFIG_FUTEX=y +CONFIG_FW_LOADER=y +CONFIG_GACT_PROB=y +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GART_IOMMU=y +CONFIG_GENERIC_ACL=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_CPU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=m +CONFIG_GFS2_FS_LOCKING_NOLOCK=m +CONFIG_GIGASET_BASE=m +# CONFIG_GIGASET_DEBUG is not set +CONFIG_GIGASET_M101=m +CONFIG_GIGASET_M105=m +# CONFIG_GIGASET_UNDOCREQ is not set +CONFIG_GIRBIL_DONGLE=m +CONFIG_HAMACHI=m +CONFIG_HAMRADIO=y +CONFIG_HANGCHECK_TIMER=m +CONFIG_HAPPYMEAL=m +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y +CONFIG_HAVE_KVM=y +CONFIG_HDLC=m +CONFIG_HDLC_CISCO=m +CONFIG_HDLC_FR=m +CONFIG_HDLC_PPP=m +CONFIG_HDLC_RAW=m +CONFIG_HDLC_RAW_ETH=m +CONFIG_HDLC_X25=m +# CONFIG_HEADERS_CHECK is not set +CONFIG_HERMES=m +CONFIG_HFSPLUS_FS=m +CONFIG_HFS_FS=m +CONFIG_HIBERNATION=y +CONFIG_HIBERNATION_SMP_POSSIBLE=y +CONFIG_HID=m +CONFIG_HIDRAW=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HID_FF is not set +CONFIG_HID_SUPPORT=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_HIPPI=y +CONFIG_HISAX_16_3=y +CONFIG_HISAX_1TR6=y +CONFIG_HISAX_AVM_A1_CS=m +CONFIG_HISAX_AVM_A1_PCMCIA=y +CONFIG_HISAX_BKM_A4T=y +# CONFIG_HISAX_DEBUG is not set +CONFIG_HISAX_DIEHLDIVA=y +CONFIG_HISAX_ELSA=y +CONFIG_HISAX_ELSA_CS=m +CONFIG_HISAX_ENTERNOW_PCI=y +CONFIG_HISAX_EURO=y +CONFIG_HISAX_FRITZPCI=y +CONFIG_HISAX_FRITZ_PCIPNP=m +CONFIG_HISAX_GAZEL=y +CONFIG_HISAX_HDLC=y +CONFIG_HISAX_HFC4S8S=m +CONFIG_HISAX_HFCUSB=m +CONFIG_HISAX_HFC_PCI=y +CONFIG_HISAX_HFC_SX=y +CONFIG_HISAX_MAX_CARDS=8 +CONFIG_HISAX_NETJET=y +CONFIG_HISAX_NETJET_U=y +CONFIG_HISAX_NI1=y +CONFIG_HISAX_NICCY=y +# CONFIG_HISAX_NO_KEYPAD is not set +# CONFIG_HISAX_NO_LLC is not set +# CONFIG_HISAX_NO_SENDCOMPLETE is not set +CONFIG_HISAX_S0BOX=y +CONFIG_HISAX_SCT_QUADRO=y +CONFIG_HISAX_SEDLBAUER=y +CONFIG_HISAX_SEDLBAUER_CS=m +CONFIG_HISAX_ST5481=m +CONFIG_HISAX_TELESPCI=y +CONFIG_HISAX_TELES_CS=m +CONFIG_HISAX_W6692=y +CONFIG_HOSTAP=m +CONFIG_HOSTAP_CS=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_PLX=m +CONFIG_HOTPLUG=y +CONFIG_HOTPLUG_CPU=y +CONFIG_HOTPLUG_PCI=m +CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +CONFIG_HOTPLUG_PCI_CPCI=y +CONFIG_HOTPLUG_PCI_CPCI_GENERIC=m +CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m +CONFIG_HOTPLUG_PCI_FAKE=m +CONFIG_HOTPLUG_PCI_PCIE=m +CONFIG_HOTPLUG_PCI_SHPC=m +CONFIG_HP100=m +CONFIG_HPET=y +CONFIG_HPET_EMULATE_RTC=y +CONFIG_HPET_MMAP=y +# CONFIG_HPET_RTC_IRQ is not set +CONFIG_HPET_TIMER=y +CONFIG_HPFS_FS=m +# CONFIG_HPT34X_AUTODMA is not set +CONFIG_HT_IRQ=y +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HWMON_VID=m +CONFIG_HW_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_AMD=m +CONFIG_HW_RANDOM_INTEL=m +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_300 is not set +CONFIG_I2C=m +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCA=m +CONFIG_I2C_ALGOPCF=m +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C_DEBUG_CORE is not set +CONFIG_I2C_I801=m +CONFIG_I2C_I810=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_STUB=m +CONFIG_I2C_TAOS_EVM=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_BUS=m +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_EXT_ADAPTEC_DMA64=y +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_PROC=m +CONFIG_I2O_SCSI=m +CONFIG_I6300ESB_WDT=m +CONFIG_I82092=m +# CONFIG_IA32_AOUT is not set +CONFIG_IA32_EMULATION=y +CONFIG_IB700_WDT=m +CONFIG_IBMASR=m +CONFIG_IBMOL=m +CONFIG_IBM_ASM=m +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +CONFIG_ICPLUS_PHY=m +CONFIG_IDE=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +CONFIG_IDEPCI_SHARE_IRQ=y +CONFIG_IDE_ARCH_OBSOLETE_INIT=y +# CONFIG_IDE_ARM is not set +CONFIG_IDE_GENERIC=m +CONFIG_IDE_MAX_HWIFS=4 +CONFIG_IDE_PROC_FS=y +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IEEE1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_OHCI1394=m +CONFIG_IEEE1394_PCILYNX=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE80211=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_CRYPT_WEP=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_IFB=m +# CONFIG_IKCONFIG is not set +CONFIG_INET=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET_AH=m +CONFIG_INET_DCCP_DIAG=m +CONFIG_INET_DIAG=y +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_LRO=m +CONFIG_INET_TCP_DIAG=y +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_AMSO1100=m +CONFIG_INFINIBAND_AMSO1100_DEBUG=y +CONFIG_INFINIBAND_CXGB3=m +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set +CONFIG_INFINIBAND_IPATH=m +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_IPOIB_DEBUG=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set +CONFIG_INFINIBAND_ISER=m +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INFTL=m +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_INPUT=y +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_ATLAS_BTNS=m +CONFIG_INPUT_EVBUG=m +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_INPUT_KEYBOARD=y +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_PCSPKR=m +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_TABLET=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_YEALINK=m +CONFIG_INSTRUMENTATION=y +CONFIG_INTEL_IOATDMA=m +# CONFIG_IOMMU_DEBUG is not set +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_CFQ=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_NOOP=y +# CONFIG_IO_DELAY_0X80 is not set +CONFIG_IO_DELAY_0XED=y +# CONFIG_IO_DELAY_NONE is not set +CONFIG_IO_DELAY_TYPE_0X80=0 +CONFIG_IO_DELAY_TYPE_0XED=1 +CONFIG_IO_DELAY_TYPE_NONE=3 +CONFIG_IO_DELAY_TYPE_UDELAY=2 +# CONFIG_IO_DELAY_UDELAY is not set +CONFIG_IP1000=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IPDDP=m +CONFIG_IPDDP_DECAP=y +CONFIG_IPDDP_ENCAP=y +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_POWEROFF=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPPP_FILTER=y +CONFIG_IPV6=m +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_IPV6_SIT=m +CONFIG_IPV6_TUNNEL=m +CONFIG_IPW2100=m +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +# CONFIG_IPW2200_DEBUG is not set +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_DCCP=m +CONFIG_IP_DCCP_ACKVEC=y +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_IP_DCCP_TFRC_LIB=m +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_MROUTE=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_IP_PNP is not set +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_SCTP=m +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_TAB_BITS=12 +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_WRR=m +CONFIG_IRCOMM=m +CONFIG_IRDA=m +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_DEBUG=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_ULTRA=y +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRTTY_SIR=m +CONFIG_ISA_DMA_API=y +CONFIG_ISCSI_TCP=m +CONFIG_ISDN=m +CONFIG_ISDN_AUDIO=y +CONFIG_ISDN_CAPI=m +CONFIG_ISDN_CAPI_CAPI20=m +CONFIG_ISDN_CAPI_CAPIDRV=m +CONFIG_ISDN_CAPI_CAPIFS=m +CONFIG_ISDN_CAPI_CAPIFS_BOOL=y +CONFIG_ISDN_CAPI_MIDDLEWARE=y +CONFIG_ISDN_DIVAS=m +CONFIG_ISDN_DIVAS_BRIPCI=y +CONFIG_ISDN_DIVAS_DIVACAPI=m +CONFIG_ISDN_DIVAS_MAINT=m +CONFIG_ISDN_DIVAS_PRIPCI=y +CONFIG_ISDN_DIVAS_USERIDI=m +CONFIG_ISDN_DIVERSION=m +CONFIG_ISDN_DRV_AVMB1_AVM_CS=m +CONFIG_ISDN_DRV_AVMB1_B1PCI=m +CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m +CONFIG_ISDN_DRV_AVMB1_C4=m +CONFIG_ISDN_DRV_AVMB1_T1PCI=m +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y +CONFIG_ISDN_DRV_GIGASET=m +CONFIG_ISDN_DRV_HISAX=m +CONFIG_ISDN_I4L=m +CONFIG_ISDN_MPP=y +CONFIG_ISDN_PPP=y +CONFIG_ISDN_PPP_BSDCOMP=m +CONFIG_ISDN_PPP_VJ=y +CONFIG_ISDN_TTY_FAX=y +CONFIG_ISDN_X25=y +# CONFIG_ISI is not set +CONFIG_ISO9660_FS=m +CONFIG_IT8712F_WDT=m +CONFIG_ITCO_VENDOR_SUPPORT=y +CONFIG_ITCO_WDT=m +# CONFIG_IWLWIFI is not set +CONFIG_IXGB=m +CONFIG_IXGBE=m +# CONFIG_IXGB_NAPI is not set +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_JFFS2_CMODE_FAVOURLZO=y +# CONFIG_JFFS2_CMODE_NONE is not set +# CONFIG_JFFS2_CMODE_PRIORITY is not set +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_LZO=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFS_DEBUG is not set +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +CONFIG_JFS_STATISTICS=y +CONFIG_JOLIET=y +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_232=y +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_K8_NB=y +CONFIG_K8_NUMA=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_KARMA_PARTITION=y +CONFIG_KEXEC=y +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_KINGSUN_DONGLE=m +CONFIG_KMOD=y +CONFIG_KPROBES=y +CONFIG_KS0108=m +CONFIG_KS0108_DELAY=2 +CONFIG_KS0108_PORT=0x378 +CONFIG_KS959_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +# CONFIG_KTIME_SCALAR is not set +CONFIG_KVM=m +CONFIG_KVM_AMD=m +CONFIG_KVM_INTEL=m +CONFIG_LANMEDIA=m +CONFIG_LAPB=m +CONFIG_LAPBETHER=m +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_LTV350QV=m +# CONFIG_LDM_DEBUG is not set +CONFIG_LDM_PARTITION=y +CONFIG_LEDS_CLASS=m +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=m +CONFIG_LEDS_TRIGGER_IDE_DISK=y +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_LIBCRC32C=m +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_CS=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_SDIO=m +CONFIG_LIBERTAS_USB=m +CONFIG_LITELINK_DONGLE=m +# CONFIG_LKDTM is not set +CONFIG_LLC=y +CONFIG_LLC2=m +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_LOCKD=m +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_LOCKD_V4=y +CONFIG_LOCK_KERNEL=y +# CONFIG_LOCK_STAT is not set +# CONFIG_LOGO is not set +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_LP_CONSOLE is not set +CONFIG_LXT_PHY=m +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +# CONFIG_M386 is not set +# CONFIG_M486 is not set +# CONFIG_M586 is not set +# CONFIG_M586MMX is not set +# CONFIG_M586TSC is not set +# CONFIG_M686 is not set +CONFIG_MA600_DONGLE=m +CONFIG_MAC80211=m +# CONFIG_MAC80211_DEBUG is not set +CONFIG_MAC80211_DEBUGFS=y +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_RCSIMPLE=y +CONFIG_MACHZ_WDT=m +CONFIG_MACINTOSH_DRIVERS=y +CONFIG_MACVLAN=m +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_MAC_PARTITION=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_MARKERS is not set +CONFIG_MARVELL_PHY=m +CONFIG_MAX_RAW_DEVS=256 +# CONFIG_MCORE2 is not set +CONFIG_MCP2120_DONGLE=m +# CONFIG_MCRUSOE is not set +CONFIG_MCS_FIR=m +# CONFIG_MCYRIXIII is not set +CONFIG_MD=y +CONFIG_MDIO_BITBANG=m +CONFIG_MD_FAULTY=m +CONFIG_MD_LINEAR=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID5_RESHAPE=y +# CONFIG_MEFFICEON is not set +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_SAS=m +CONFIG_MFD_SM501=m +# CONFIG_MGEODEGX1 is not set +# CONFIG_MGEODE_LX is not set +CONFIG_MICROCODE=m +CONFIG_MICROCODE_OLD_INTERFACE=y +CONFIG_MIGRATION=y +CONFIG_MII=m +CONFIG_MINIX_FS=m +CONFIG_MINIX_SUBPARTITION=y +CONFIG_MISC_DEVICES=y +# CONFIG_MK6 is not set +# CONFIG_MK7 is not set +# CONFIG_MK8 is not set +CONFIG_MKISS=m +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_MLX4_INFINIBAND=m +CONFIG_MMC=m +CONFIG_MMC_BLOCK=m +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_RICOH_MMC=m +CONFIG_MMC_SDHCI=m +CONFIG_MMC_SPI=m +CONFIG_MMC_TIFM_SD=m +# CONFIG_MMC_UNSAFE_RESUME is not set +CONFIG_MMC_WBSD=m +CONFIG_MMU=y +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_PS2=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_PS2_TRACKPOINT=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_MOXA_INTELLIO=m +# CONFIG_MOXA_SMARTIO is not set +CONFIG_MOXA_SMARTIO_NEW=m +# CONFIG_MPENTIUM4 is not set +# CONFIG_MPENTIUMII is not set +# CONFIG_MPENTIUMIII is not set +# CONFIG_MPENTIUMM is not set +# CONFIG_MPSC is not set +CONFIG_MSDOS_FS=m +CONFIG_MSDOS_PARTITION=y +CONFIG_MSI_LAPTOP=m +# CONFIG_MSS is not set +CONFIG_MTD=m +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTD_ABSENT=m +CONFIG_MTD_ALAUDA=m +CONFIG_MTD_AMD76XROM=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK2MTD=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_MTD_CFI=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_CHAR=m +CONFIG_MTD_CK804XROM=m +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_CONCAT=m +CONFIG_MTD_DATAFLASH=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_DILNETPC=m +CONFIG_MTD_DILNETPC_BOOTSIZE=0x80000 +CONFIG_MTD_DOC2000=m +CONFIG_MTD_DOC2001=m +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCECC=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCPROBE_ADDRESS=0 +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_ESB2ROM=m +CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_ICHXROM=m +CONFIG_MTD_INTEL_VR_NOR=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_L440GX=m +CONFIG_MTD_M25P80=m +CONFIG_MTD_MAP_BANK_WIDTH_1=y +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +CONFIG_MTD_MTDRAM=m +CONFIG_MTD_NAND=m +CONFIG_MTD_NAND_CAFE=m +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_NANDSIM=m +CONFIG_MTD_NAND_PLATFORM=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NETSC520=m +CONFIG_MTD_NETtel=m +CONFIG_MTD_ONENAND=m +CONFIG_MTD_ONENAND_2X_PROGRAM=y +# CONFIG_MTD_ONENAND_OTP is not set +CONFIG_MTD_ONENAND_SIM=m +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +CONFIG_MTD_OOPS=m +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_PCI=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PHYSMAP_LEN=0x4000000 +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PLATRAM=m +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +CONFIG_MTD_PNC2000=m +CONFIG_MTD_RAM=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS=m +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +CONFIG_MTD_ROM=m +CONFIG_MTD_SBC_GXX=m +CONFIG_MTD_SC520CDP=m +CONFIG_MTD_SCB2_FLASH=m +CONFIG_MTD_SLRAM=m +CONFIG_MTD_TS5500=m +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_DEBUG is not set +CONFIG_MTD_UBI_GLUEBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTRR=y +# CONFIG_MVIAC3_2 is not set +# CONFIG_MVIAC7 is not set +CONFIG_MWAVE=m +# CONFIG_MWINCHIP2 is not set +# CONFIG_MWINCHIP3D is not set +# CONFIG_MWINCHIPC6 is not set +CONFIG_MYRI10GE=m +CONFIG_NATSEMI=m +CONFIG_NCPFS_EXTRAS=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_OS2_NS=y +CONFIG_NCPFS_PACKET_SIGNING=y +# CONFIG_NCPFS_SMALLDOS is not set +CONFIG_NCPFS_STRONG=y +CONFIG_NCP_FS=m +CONFIG_NE2K_PCI=m +CONFIG_NEED_MULTIPLE_NODES=y +CONFIG_NET=y +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETDEVICES=y +CONFIG_NETDEVICES_MULTIQUEUE=y +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NETROM=m +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NETWORK_SECMARK=y +CONFIG_NETXEN_NIC=m +CONFIG_NET_9P=m +# CONFIG_NET_9P_DEBUG is not set +CONFIG_NET_9P_FD=m +CONFIG_NET_9P_VIRTIO=m +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_FW=m +# CONFIG_NET_CLS_IND is not set +# CONFIG_NET_CLS_POLICE is not set +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_DCCPPROBE=m +CONFIG_NET_DMA=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_ETHERNET=y +CONFIG_NET_FC=y +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_NET_IPIP=m +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_NET_PCI=y +CONFIG_NET_PCMCIA=y +CONFIG_NET_PKTGEN=m +CONFIG_NET_POCKET=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_NET_SB1000=m +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_FIFO=y +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_RR=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_TCPPROBE=m +CONFIG_NET_TULIP=y +CONFIG_NET_VENDOR_3COM=y +CONFIG_NEW_LEDS=y +CONFIG_NFSD=m +CONFIG_NFSD_TCP=y +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_ENABLED=m +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_NF_CONNTRACK_SANE is not set +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NIU=m +CONFIG_NL80211=y +CONFIG_NLS=y +CONFIG_NLS_ASCII=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +CONFIG_NODES_SHIFT=6 +CONFIG_NONPROMISC_DEVMEM=y +# CONFIG_NORTEL_HERMES is not set +CONFIG_NO_HZ=y +CONFIG_NS83820=m +CONFIG_NSC_FIR=m +CONFIG_NSC_GPIO=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_FS=m +# CONFIG_NTFS_RW is not set +CONFIG_NUMA=y +# CONFIG_NUMA_EMU is not set +CONFIG_NVRAM=m +CONFIG_N_HDLC=m +# CONFIG_OCFS2_DEBUG_FS is not set +CONFIG_OCFS2_DEBUG_MASKLOG=y +CONFIG_OCFS2_FS=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_OPROFILE=m +CONFIG_OSF_PARTITION=y +CONFIG_OUT_OF_LINE_PFN_TO_PAGE=y +CONFIG_P54_COMMON=m +CONFIG_P54_PCI=m +CONFIG_P54_USB=m +CONFIG_PACKET=m +CONFIG_PACKET_MMAP=y +CONFIG_PARIDE=m +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_EPAT=m +# CONFIG_PARIDE_EPATC8 is not set +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PG=m +CONFIG_PARIDE_PT=m +CONFIG_PARPORT=m +CONFIG_PARPORT_1284=y +CONFIG_PARPORT_AX88796=m +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_NOT_PC=y +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_FIFO=y +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_SERIAL=m +CONFIG_PARTITION_ADVANCED=y +CONFIG_PATA_ACPI=m +# CONFIG_PATA_ALI is not set +CONFIG_PATA_AMD=m +CONFIG_PATA_ARTOP=m +CONFIG_PATA_ATIIXP=m +# CONFIG_PATA_CMD640_PCI is not set +CONFIG_PATA_CMD64X=m +CONFIG_PATA_CS5520=m +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +CONFIG_PATA_EFAR=m +CONFIG_PATA_HPT366=m +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +CONFIG_PATA_HPT3X3=m +# CONFIG_PATA_HPT3X3_DMA is not set +CONFIG_PATA_IT8213=m +CONFIG_PATA_IT821X=m +CONFIG_PATA_JMICRON=m +CONFIG_PATA_MARVELL=m +CONFIG_PATA_MPIIX=m +CONFIG_PATA_NETCELL=m +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_NS87415 is not set +CONFIG_PATA_OLDPIIX=m +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +CONFIG_PATA_PCMCIA=m +CONFIG_PATA_PDC2027X=m +# CONFIG_PATA_PDC_OLD is not set +CONFIG_PATA_PLATFORM=m +# CONFIG_PATA_RADISYS is not set +CONFIG_PATA_RZ1000=m +# CONFIG_PATA_SC1200 is not set +CONFIG_PATA_SERVERWORKS=m +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +CONFIG_PATA_TRIFLEX=m +CONFIG_PATA_VIA=m +CONFIG_PATA_WINBOND=m +CONFIG_PC300=m +# CONFIG_PC300TOO is not set +CONFIG_PC300_MLPPP=y +CONFIG_PC8736x_GPIO=m +CONFIG_PC87413_WDT=m +CONFIG_PCCARD=m +CONFIG_PCCARD_NONSTATIC=m +CONFIG_PCI=y +CONFIG_PCI200SYN=m +CONFIG_PCIEAER=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIPCWATCHDOG=m +CONFIG_PCI_ATMEL=m +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_DIRECT=y +CONFIG_PCI_DOMAINS=y +# CONFIG_PCI_HERMES is not set +CONFIG_PCI_LEGACY=y +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_MSI=y +CONFIG_PCMCIA=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_PCMCIA_AXNET=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_HERMES=m +CONFIG_PCMCIA_IOCTL=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_NETWAVE=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_RAYCS=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_SPECTRUM=m +CONFIG_PCMCIA_SYM53C500=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_WL3501=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_PCNET32=m +# CONFIG_PCNET32_NAPI is not set +CONFIG_PD6729=m +CONFIG_PDA_POWER=m +CONFIG_PDC202XX_BURST=y +CONFIG_PDC_ADMA=m +CONFIG_PHANTOM=m +CONFIG_PHONE=m +CONFIG_PHONE_IXJ=m +CONFIG_PHONE_IXJ_PCMCIA=m +CONFIG_PHYLIB=m +CONFIG_PHYSICAL_ALIGN=0x200000 +CONFIG_PHYSICAL_START=0x200000 +# CONFIG_PID_NS is not set +CONFIG_PLIP=m +CONFIG_PLIST=y +# CONFIG_PLX_HERMES is not set +CONFIG_PM=y +CONFIG_PM_DEBUG=y +CONFIG_PM_DISABLE_CONSOLE=y +CONFIG_PM_LEGACY=y +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_PM_STD_PARTITION="" +CONFIG_PM_TRACE=y +# CONFIG_PM_VERBOSE is not set +CONFIG_PNP=y +CONFIG_PNPACPI=y +# CONFIG_PNP_DEBUG is not set +CONFIG_POSIX_MQUEUE=y +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +CONFIG_PPDEV=m +CONFIG_PPP=m +CONFIG_PPPOATM=m +CONFIG_PPPOE=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_SYNC_TTY=m +# CONFIG_PREEMPT is not set +CONFIG_PREEMPT_NOTIFIERS=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_PRINTER=m +CONFIG_PRINTK=y +CONFIG_PRINTK_TIME=y +CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_PRISM54=m +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_VMCORE=y +CONFIG_PROFILING=y +# CONFIG_PROVE_LOCKING is not set +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_QLA3XXX=m +CONFIG_QNX4FS_FS=m +CONFIG_QSEMI_PHY=m +# CONFIG_QUICKLIST is not set +CONFIG_QUOTA=y +CONFIG_QUOTACTL=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +CONFIG_R3964=m +CONFIG_R8169=m +# CONFIG_R8169_NAPI is not set +CONFIG_R8169_VLAN=y +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAESTRO=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RAID_ATTRS=m +CONFIG_RAW_DRIVER=m +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_FS=m +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_REISERFS_FS_XATTR=y +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_RELAY=y +CONFIG_RELOCATABLE=y +CONFIG_RESOURCES_64BIT=y +CONFIG_RFD_FTL=m +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +CONFIG_RFKILL_LEDS=y +CONFIG_RIO=m +# CONFIG_RIO_OLDPCI is not set +CONFIG_ROADRUNNER=m +# CONFIG_ROADRUNNER_LARGE_RINGS is not set +CONFIG_ROCKETPORT=m +CONFIG_ROMFS_FS=m +CONFIG_ROSE=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_RT2400PCI=m +CONFIG_RT2400PCI_RFKILL=y +CONFIG_RT2500PCI=m +CONFIG_RT2500PCI_RFKILL=y +CONFIG_RT2500USB=m +CONFIG_RT2X00=m +# CONFIG_RT2X00_DEBUG is not set +CONFIG_RT2X00_LIB=m +# CONFIG_RT2X00_LIB_DEBUGFS is not set +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_PCI=m +CONFIG_RT2X00_LIB_RFKILL=y +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT61PCI=m +CONFIG_RT61PCI_RFKILL=y +CONFIG_RT73USB=m +CONFIG_RTC=y +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DEBUG is not set +# CONFIG_RTC_DRV_CMOS is not set +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_M41T80_WDT=y +CONFIG_RTC_DRV_M48T59=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_STK17TA8=m +CONFIG_RTC_DRV_TEST=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_LIB=y +CONFIG_RTL8187=m +CONFIG_RT_MUTEXES=y +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_RXKAD=m +CONFIG_S2IO=m +# CONFIG_S2IO_NAPI is not set +# CONFIG_SAMPLES is not set +CONFIG_SATA_AHCI=m +CONFIG_SATA_INIC162X=m +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIL24=m +CONFIG_SATA_SIS=m +CONFIG_SATA_SVW=m +CONFIG_SATA_SX4=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m +CONFIG_SBC8360_WDT=m +CONFIG_SBC_EPX_C3_WATCHDOG=m +CONFIG_SBNI=m +# CONFIG_SBNI_MULTILINE is not set +CONFIG_SC1200_WDT=m +CONFIG_SC520_WDT=m +CONFIG_SC92031=m +# CONFIG_SCHEDSTATS is not set +CONFIG_SCHED_DEBUG=y +CONFIG_SCHED_MC=y +CONFIG_SCSI=m +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_ADVANSYS=m +CONFIG_SCSI_AIC79XX=m +CONFIG_SCSI_AIC7XXX=m +# CONFIG_SCSI_AIC7XXX_OLD is not set +CONFIG_SCSI_AIC94XX=m +CONFIG_SCSI_ARCMSR=m +CONFIG_SCSI_ARCMSR_AER=y +CONFIG_SCSI_BUSLOGIC=m +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_DC390T=m +CONFIG_SCSI_DC395x=m +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_DMA=y +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_EATA=m +CONFIG_SCSI_EATA_LINKED_COMMANDS=y +CONFIG_SCSI_EATA_MAX_TAGS=16 +CONFIG_SCSI_EATA_TAGGED_QUEUE=y +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_FC_TGT_ATTRS=y +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_SCSI_GDTH=m +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_IMM=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_DUMP is not set +# CONFIG_SCSI_IPR_TRACE is not set +CONFIG_SCSI_IPS=m +CONFIG_SCSI_ISCSI_ATTRS=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_LOWLEVEL=y +CONFIG_SCSI_LOWLEVEL_PCMCIA=y +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_NETLINK=y +# CONFIG_SCSI_OMIT_FLASHPOINT is not set +CONFIG_SCSI_PPA=m +CONFIG_SCSI_PROC_FS=y +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_SAS_ATA=y +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_SRP=m +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_TGT=m +CONFIG_SCSI_WAIT_SCAN=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_HMAC_MD5=y +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SDIO_UART=m +CONFIG_SECCOMP=y +CONFIG_SECURITY=y +CONFIG_SECURITY_APPARMOR=y +CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 +# CONFIG_SECURITY_APPARMOR_DISABLE is not set +CONFIG_SECURITY_CAPABILITIES=y +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_DISABLE=y +# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SEMAPHORE_SLEEPERS=y +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_ABITUGURU3=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_APPLESMC=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_FSCHMD=m +CONFIG_SENSORS_FSCPOS=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_HDAPS=m +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_IBMPEX=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_K8TEMP=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_LM93=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_TSL2550=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_CS=m +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_NR_UARTS=48 +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_PNP=y +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_SERIO=y +CONFIG_SERIO_CT82C710=m +CONFIG_SERIO_I8042=y +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_PARKBD=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SERIO_RAW=m +CONFIG_SERIO_SERPORT=m +CONFIG_SGI_IOC4=m +CONFIG_SGI_PARTITION=y +CONFIG_SHAPER=m +CONFIG_SHMEM=y +CONFIG_SIGMATEL_FIR=m +CONFIG_SIGNALFD=y +CONFIG_SIS190=m +CONFIG_SIS900=m +# CONFIG_SK98LIN is not set +CONFIG_SKFP=m +CONFIG_SKGE=m +# CONFIG_SKGE_DEBUG is not set +CONFIG_SKY2=m +# CONFIG_SKY2_DEBUG is not set +# CONFIG_SLAB is not set +CONFIG_SLABINFO=y +CONFIG_SLHC=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_MODE_SLIP6=y +CONFIG_SLIP_SMART=y +# CONFIG_SLOB is not set +CONFIG_SLUB=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLUB_DEBUG_ON is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_SMC_IRCC_FIR=m +CONFIG_SMP=y +CONFIG_SMSC37B787_WDT=m +CONFIG_SMSC_PHY=m +# CONFIG_SND is not set +CONFIG_SOFT_WATCHDOG=m +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_SONYPI_COMPAT=y +CONFIG_SONY_LAPTOP=m +CONFIG_SOUND=m +# CONFIG_SOUND_PRIME is not set +# CONFIG_SPARSEMEM_MANUAL is not set +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPECIALIX=m +# CONFIG_SPECIALIX_RTSCTS is not set +CONFIG_SPI=y +CONFIG_SPI_AT25=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_LM70_LLP=m +CONFIG_SPI_MASTER=y +CONFIG_SPI_SPIDEV=m +CONFIG_SPI_TLE62X0=m +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_SSB=m +CONFIG_SSB_DEBUG=y +CONFIG_SSB_DRIVER_PCICORE=y +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +# CONFIG_SSB_PCMCIAHOST is not set +CONFIG_SSB_PCMCIAHOST_POSSIBLE=y +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB_SILENT is not set +CONFIG_SSFDC=m +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_STALDRV=y +CONFIG_STANDALONE=y +CONFIG_STOP_MACHINE=y +CONFIG_STRIP=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_SUNGEM=m +CONFIG_SUNRPC=m +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_SUNRPC_GSS=m +CONFIG_SUNRPC_XPRT_RDMA=m +CONFIG_SUN_PARTITION=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_SMP_POSSIBLE=y +CONFIG_SWAP=y +CONFIG_SWIOTLB=y +CONFIG_SX=m +CONFIG_SYNCLINK=m +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_CS=m +CONFIG_SYNCLINK_GT=m +CONFIG_SYN_COOKIES=y +CONFIG_SYSCTL=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSFS=y +# CONFIG_SYSFS_DEPRECATED is not set +CONFIG_SYSV68_PARTITION=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_SYSV_FS=m +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +CONFIG_TASKSTATS=y +# CONFIG_TASK_DELAY_ACCT is not set +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_TASK_XACCT=y +CONFIG_TCG_ATMEL=m +CONFIG_TCG_INFINEON=m +CONFIG_TCG_NSC=m +CONFIG_TCG_TIS=m +CONFIG_TCG_TPM=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_MD5SIG=y +CONFIG_TEHUTI=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TELCLOCK=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +CONFIG_THINKPAD_ACPI=m +CONFIG_THINKPAD_ACPI_BAY=y +# CONFIG_THINKPAD_ACPI_DEBUG is not set +CONFIG_TICK_ONESHOT=y +CONFIG_TIFM_7XX1=m +CONFIG_TIFM_CORE=m +CONFIG_TIGON3=m +CONFIG_TIMER_STATS=y +# CONFIG_TINY_SHMEM is not set +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +# CONFIG_TMD_HERMES is not set +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMS380TR=m +CONFIG_TMSPCI=m +# CONFIG_TOIM3232_DONGLE is not set +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_UCB1400=m +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TR=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_TULIP=m +# CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_NAPI is not set +CONFIG_TUN=m +CONFIG_TUNER_3036=m +CONFIG_TUNER_MT20XX=m +CONFIG_TUNER_SIMPLE=m +CONFIG_TUNER_TDA8290=m +CONFIG_TUNER_TEA5761=m +CONFIG_TUNER_TEA5767=m +CONFIG_TYPHOON=m +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_UFS_DEBUG is not set +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +CONFIG_UID16=y +CONFIG_UIO=m +CONFIG_UIO_CIF=m +CONFIG_ULI526X=m +CONFIG_ULTRIX_PARTITION=y +CONFIG_UNIX=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_USB=m +CONFIG_USBPCWATCHDOG=m +CONFIG_USB_ACM=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AMD5536UDC=m +CONFIG_USB_AN2720=y +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_ATM=m +CONFIG_USB_AUERSWALD=m +CONFIG_USB_BELKIN=y +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_CATC=m +CONFIG_USB_CXACRU=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_DABUSB=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +CONFIG_USB_DSBR=m +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EMI26=m +CONFIG_USB_EMI62=m +CONFIG_USB_EPSON2888=y +CONFIG_USB_ET61X251=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_EZUSB=y +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_GADGET=m +CONFIG_USB_GADGETFS=m +CONFIG_USB_GADGET_AMD5536UDC=y +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_S3C2410 is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_G_SERIAL=m +CONFIG_USB_HID=m +CONFIG_USB_HIDDEV=y +CONFIG_USB_HIDINPUT_POWERBOOK=y +CONFIG_USB_IBMCAM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_IRDA=m +CONFIG_USB_ISP116X_HCD=m +CONFIG_USB_KAWETH=m +CONFIG_USB_KBD=m +CONFIG_USB_KC2190=y +CONFIG_USB_KONICAWC=m +CONFIG_USB_LCD=m +CONFIG_USB_LD=m +CONFIG_USB_LED=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LIBUSUAL=y +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_USB_MON=y +CONFIG_USB_MOUSE=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_HCD_SSB is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OV511 is not set +CONFIG_USB_PEGASUS=m +CONFIG_USB_PERSIST=y +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_PRINTER=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_R8A66597_HCD=m +CONFIG_USB_RIO500=m +CONFIG_USB_RTL8150=m +CONFIG_USB_SE401=m +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_AIRPRIME=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IPW=m +# CONFIG_USB_SERIAL_IR is not set +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SISUSBVGA=m +# CONFIG_USB_SISUSBVGA_CON is not set +CONFIG_USB_SL811_CS=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SN9C102=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_STORAGE=m +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_DATAFAB=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STV680=m +CONFIG_USB_SUPPORT=y +CONFIG_USB_SUSPEND=y +# CONFIG_USB_TEST is not set +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_UHCI_HCD=m +CONFIG_USB_USBNET=m +CONFIG_USB_USS720=m +CONFIG_USB_VICAM=m +CONFIG_USB_W9968CF=m +CONFIG_USB_XUSBATM=m +CONFIG_USB_ZC0301=m +CONFIG_USB_ZD1201=m +CONFIG_USB_ZERO=m +CONFIG_USB_ZR364XX=m +# CONFIG_USER_NS is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VETH=m +CONFIG_VFAT_FS=m +# CONFIG_VGACON_SOFT_SCROLLBACK is not set +CONFIG_VGASTATE=m +CONFIG_VGA_CONSOLE=y +CONFIG_VIA_FIR=m +CONFIG_VIA_RHINE=m +CONFIG_VIA_RHINE_MMIO=y +CONFIG_VIA_RHINE_NAPI=y +CONFIG_VIA_VELOCITY=m +CONFIG_VIDEOBUF_DMA_SG=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CAFE_CCIC=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_CPIA_PP=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_CX23885=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_DEV=m +# CONFIG_VIDEO_DPC is not set +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_FB_IVTV=m +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_MEYE=m +CONFIG_VIDEO_MSP3400=m +# CONFIG_VIDEO_MXB is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_24XXX=y +CONFIG_VIDEO_PVRUSB2_29XXX=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA7111=m +CONFIG_VIDEO_SAA7114=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_SAA7191=m +CONFIG_VIDEO_SELECT=y +CONFIG_VIDEO_STRADIS=m +CONFIG_VIDEO_TCM825X=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TDA9875=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_TLV320AIC23B=m +CONFIG_VIDEO_TUNER=m +# CONFIG_VIDEO_TUNER_CUSTOMIZE is not set +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_VP27SMPX=m +CONFIG_VIDEO_VPX3220=m +CONFIG_VIDEO_W9966=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VIRTIO=m +CONFIG_VIRTIO_BALLOON=m +CONFIG_VIRTIO_BLK=m +CONFIG_VIRTIO_NET=m +CONFIG_VIRTIO_PCI=m +CONFIG_VIRTIO_RING=m +CONFIG_VIRTUALIZATION=y +CONFIG_VIRT_TO_BUS=y +CONFIG_VITESSE_PHY=m +CONFIG_VLAN_8021Q=m +CONFIG_VLSI_FIR=m +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VORTEX=m +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_VXFS_FS=m +CONFIG_W1=m +CONFIG_W1_CON=y +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_DS2760=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_THERM=m +CONFIG_W83627HF_WDT=m +CONFIG_W83697HF_WDT=m +CONFIG_W83877F_WDT=m +CONFIG_W83977F_WDT=m +CONFIG_WAFER_WDT=m +CONFIG_WAN=y +CONFIG_WANXL=m +CONFIG_WAN_ROUTER=m +CONFIG_WAN_ROUTER_DRIVERS=m +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_WDC_ALI15X3 is not set +CONFIG_WDTPCI=m +CONFIG_WDT_501_PCI=y +CONFIG_WINBOND_840=m +CONFIG_WINBOND_FIR=m +CONFIG_WIRELESS_EXT=y +CONFIG_WLAN_80211=y +CONFIG_WLAN_PRE80211=y +# CONFIG_WRAPPER_PRINT is not set +CONFIG_X25=m +CONFIG_X25_ASY=m +CONFIG_X86=y +# CONFIG_X86_32 is not set +CONFIG_X86_64=y +CONFIG_X86_64_ACPI_NUMA=y +CONFIG_X86_ACPI_CPUFREQ=m +# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set +# CONFIG_X86_BIGSMP is not set +CONFIG_X86_CMPXCHG=y +CONFIG_X86_CPUID=m +# CONFIG_X86_ELAN is not set +# CONFIG_X86_ES7000 is not set +# CONFIG_X86_GENERICARCH is not set +CONFIG_X86_GOOD_APIC=y +CONFIG_X86_HT=y +CONFIG_X86_INTERNODE_CACHE_BYTES=128 +CONFIG_X86_IO_APIC=y +CONFIG_X86_L1_CACHE_BYTES=128 +CONFIG_X86_L1_CACHE_SHIFT=7 +CONFIG_X86_LOCAL_APIC=y +CONFIG_X86_MCE=y +CONFIG_X86_MCE_AMD=y +CONFIG_X86_MCE_INTEL=y +CONFIG_X86_MINIMUM_CPU_FAMILY=64 +CONFIG_X86_MSR=m +# CONFIG_X86_NUMAQ is not set +# CONFIG_X86_P4_CLOCKMOD is not set +CONFIG_X86_PC=y +CONFIG_X86_PM_TIMER=y +CONFIG_X86_POWERNOW_K8=m +CONFIG_X86_POWERNOW_K8_ACPI=y +# CONFIG_X86_SPEEDSTEP_CENTRINO is not set +# CONFIG_X86_SPEEDSTEP_LIB is not set +# CONFIG_X86_SUMMIT is not set +CONFIG_X86_TSC=y +# CONFIG_X86_VISWS is not set +# CONFIG_X86_VOYAGER is not set +# CONFIG_X86_VSMP is not set +CONFIG_XFRM=y +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_XFRM_USER=m +CONFIG_XFS_FS=m +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_QUOTA=y +CONFIG_XFS_RT=y +CONFIG_XFS_SECURITY=y +CONFIG_XOR_BLOCKS=m +CONFIG_YAM=m +CONFIG_YELLOWFIN=m +CONFIG_YENTA=m +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_ZISOFS=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZONE_DMA=y +CONFIG_ZONE_DMA32=y +CONFIG_ZONE_DMA_FLAG=1 --- linux-2.6.24.orig/debian/config/amd64/config.generic +++ linux-2.6.24/debian/config/amd64/config.generic @@ -0,0 +1,20 @@ +# +# Config options for config.generic automatically generated by splitconfig.pl +# +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_EDD_OFF=y +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_NETLABEL is not set +CONFIG_NR_CPUS=8 +CONFIG_PREEMPT_BKL=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_SCHED_SMT is not set +CONFIG_VERSION_SIGNATURE="Ubuntu 2.6.24-4.6-generic" --- linux-2.6.24.orig/debian/config/amd64/config.server +++ linux-2.6.24/debian/config/amd64/config.server @@ -0,0 +1,21 @@ +# +# Config options for config.server automatically generated by splitconfig.pl +# +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_DEADLINE=y +CONFIG_DEFAULT_IOSCHED="deadline" +# CONFIG_EDD_OFF is not set +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_HZ=100 +CONFIG_HZ_100=y +# CONFIG_HZ_250 is not set +CONFIG_IPV6_MULTIPLE_TABLES=y +# CONFIG_IPV6_SUBTREES is not set +CONFIG_NETLABEL=y +CONFIG_NR_CPUS=64 +# CONFIG_PREEMPT_BKL is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_SCHED_SMT=y +CONFIG_VERSION_SIGNATURE="Ubuntu 2.6.24-4.6-server" --- linux-2.6.24.orig/debian/config/hppa/config.hppa32 +++ linux-2.6.24/debian/config/hppa/config.hppa32 @@ -0,0 +1,386 @@ +# +# Config options for config.hppa32 automatically generated by splitconfig.pl +# +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_8129=y +CONFIG_8139TOO_PIO=y +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_9P_FS=m +CONFIG_AC3200=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_ADAPTEC_STARFIRE=m +# CONFIG_ADAPTEC_STARFIRE_NAPI is not set +CONFIG_AGP=m +CONFIG_AIRO_CS=m +# CONFIG_AMD8111E_NAPI is not set +CONFIG_AMD8111_ETH=m +CONFIG_APRICOT=m +# CONFIG_ARLAN is not set +CONFIG_AT1700=m +CONFIG_ATL1=m +CONFIG_AUTOFS4_FS=m +CONFIG_AUTOFS_FS=m +CONFIG_B43_LEDS=y +CONFIG_B44=m +CONFIG_B44_PCI=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI_AUTOSELECT=y +CONFIG_BCM43XX=m +# CONFIG_BCM43XX_DEBUG is not set +CONFIG_BCM43XX_DMA=y +CONFIG_BCM43XX_DMA_AND_PIO_MODE=y +# CONFIG_BCM43XX_DMA_MODE is not set +CONFIG_BCM43XX_PIO=y +# CONFIG_BCM43XX_PIO_MODE is not set +CONFIG_BNX2=m +CONFIG_CARDMAN_4000=m +CONFIG_CARDMAN_4040=m +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T1_NAPI=y +CONFIG_CHELSIO_T3=m +CONFIG_CPUSETS=y +CONFIG_CRAMFS=y +CONFIG_CRC16=m +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_DES=y +CONFIG_CS89x0=m +# CONFIG_DE2104X is not set +CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_RWLOCK is not set +CONFIG_DEPCA=m +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_DISPLAY_SUPPORT=m +CONFIG_DL2K=m +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +CONFIG_E2100=m +CONFIG_ECRYPT_FS=m +CONFIG_EEPRO100=m +CONFIG_EEXPRESS=m +CONFIG_EEXPRESS_PRO=m +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_EPIC100=m +CONFIG_ES3210=m +CONFIG_ETH16I=m +CONFIG_EWRK3=m +CONFIG_EXT2_FS=m +CONFIG_EXT3_FS=m +CONFIG_FB=y +# CONFIG_FB_3DFX is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_DDC is not set +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_MATROX is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_PM2 is not set +CONFIG_FB_PM3=m +# CONFIG_FB_RADEON is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +CONFIG_FB_SM501=m +CONFIG_FB_STI=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +CONFIG_FB_TILEBLITTING=y +# CONFIG_FB_TRIDENT is not set +CONFIG_FB_UVESA=m +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +CONFIG_FEALNX=m +CONFIG_FIRMWARE_EDID=y +CONFIG_FLATMEM=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +CONFIG_FORCEDETH=m +# CONFIG_FORCEDETH_NAPI is not set +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FS_MBCACHE=m +CONFIG_FUSE_FS=m +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=m +CONFIG_GFS2_FS_LOCKING_NOLOCK=m +CONFIG_HAMACHI=m +CONFIG_HID=m +CONFIG_HIL_MLC=m +CONFIG_HOSTAP=m +CONFIG_HOSTAP_CS=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_PLX=m +CONFIG_HOTPLUG_CPU=y +CONFIG_HPLAN=m +CONFIG_HPLAN_PLUS=m +# CONFIG_HPUX is not set +CONFIG_HP_SDC=m +CONFIG_HP_SDC_RTC=m +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HWMON_VID=m +CONFIG_HW_RANDOM=y +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_KEYBOARD=y +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_TABLET=y +# CONFIG_INPUT_UINPUT is not set +CONFIG_INPUT_YEALINK=m +CONFIG_ISO9660_FS=m +CONFIG_IXGB=m +# CONFIG_IXGB_NAPI is not set +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_ATKBD_HP_KEYCODES is not set +CONFIG_KEYBOARD_HIL=m +CONFIG_KEYBOARD_HIL_OLD=m +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_KEYBOARD_STOWAWAY=m +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_KS0108=m +CONFIG_KS0108_DELAY=2 +CONFIG_KS0108_PORT=0x378 +# CONFIG_LBD is not set +CONFIG_LCD_LTV350QV=m +CONFIG_LEDS_CLASS=m +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=m +CONFIG_LEDS_TRIGGER_IDE_DISK=y +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_LNE390=m +CONFIG_LOCKD=y +CONFIG_LOCK_KERNEL=y +# CONFIG_LOGO is not set +CONFIG_LP486E=m +# CONFIG_LP_CONSOLE is not set +# CONFIG_LSF is not set +CONFIG_MAC80211_DEBUGFS=y +CONFIG_MAC80211_LEDS=y +CONFIG_MFD_SM501=m +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_HIL=m +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +CONFIG_MOUSE_PS2=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +CONFIG_MYRI10GE=m +CONFIG_NATSEMI=m +CONFIG_NE2000=m +CONFIG_NE2K_PCI=m +CONFIG_NE3210=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NETXEN_NIC=m +CONFIG_NET_ISA=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_NEW_LEDS=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_FS=y +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_ISO8859_15 is not set +CONFIG_NR_CPUS=32 +CONFIG_NS83820=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_FS=m +# CONFIG_NTFS_RW is not set +CONFIG_PA11=y +CONFIG_PA7000=y +# CONFIG_PA8X00 is not set +CONFIG_PCMCIA_AHA152X=m +CONFIG_PCMCIA_AXNET=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_NETWAVE=m +CONFIG_PCMCIA_NINJA_SCSI=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_WL3501=m +CONFIG_PDC_CONSOLE=y +CONFIG_PPPOE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PREEMPT_BKL=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_PRINTER=m +CONFIG_PRINTK_TIME=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_QLA3XXX=m +CONFIG_QUOTACTL=y +CONFIG_R8169=m +# CONFIG_R8169_NAPI is not set +CONFIG_R8169_VLAN=y +# CONFIG_RAW_DRIVER is not set +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_FS_XATTR is not set +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_RFKILL_LEDS=y +CONFIG_ROOT_NFS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RT2X00_LIB_DEBUGFS is not set +CONFIG_RTC_CLASS=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_M48T59=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_STK17TA8=m +CONFIG_RTC_DRV_TEST=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_LIB=m +CONFIG_S2IO=m +# CONFIG_S2IO_NAPI is not set +CONFIG_SC92031=m +# CONFIG_SCSI_AHA152X is not set +CONFIG_SCSI_DPT_I2O=m +CONFIG_SCSI_NSP32=m +CONFIG_SEEQ8005=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SERIAL_8250_ACCENT=m +CONFIG_SERIAL_8250_BOCA=m +CONFIG_SERIAL_8250_EXAR_ST16C554=m +CONFIG_SERIAL_8250_FOURPORT=m +CONFIG_SERIAL_8250_HUB6=m +CONFIG_SERIAL_8250_NR_UARTS=48 +# CONFIG_SERIAL_MUX is not set +CONFIG_SERIO=y +CONFIG_SERIO_GSCPS2=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_RAW=m +# CONFIG_SERIO_SERPORT is not set +CONFIG_SHAPER=m +CONFIG_SIS190=m +CONFIG_SIS900=m +CONFIG_SKGE=m +# CONFIG_SKGE_DEBUG is not set +CONFIG_SKY2=m +# CONFIG_SKY2_DEBUG is not set +# CONFIG_SLAB is not set +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +# CONFIG_SLIP_MODE_SLIP6 is not set +CONFIG_SLIP_SMART=y +CONFIG_SLUB=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLUB_DEBUG_ON is not set +CONFIG_SMP=y +CONFIG_SPI=y +CONFIG_SPI_AT25=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_LM70_LLP=m +CONFIG_SPI_MASTER=y +CONFIG_SPI_SPIDEV=m +CONFIG_SPI_TLE62X0=m +CONFIG_SPLIT_PTLOCK_CPUS=4096 +CONFIG_STI_CONSOLE=y +CONFIG_STOP_MACHINE=y +# CONFIG_STRIP is not set +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_SYNCLINK_CS=m +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +CONFIG_TIMER_STATS=y +CONFIG_TIME_LOW_RES=y +CONFIG_TLAN=m +CONFIG_TULIP=m +# CONFIG_TULIP_MMIO is not set +# CONFIG_UFS_FS is not set +CONFIG_ULI526X=m +CONFIG_UNUSED_SYMBOLS=y +# CONFIG_USB_STORAGE_ONETOUCH is not set +CONFIG_VIA_RHINE=m +CONFIG_VIA_RHINE_MMIO=y +CONFIG_VIA_RHINE_NAPI=y +CONFIG_VIA_VELOCITY=m +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_VXFS_FS=m +# CONFIG_WAVELAN is not set +CONFIG_WLAN_PRE80211=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_QUOTA=y +CONFIG_YELLOWFIN=m +CONFIG_ZISOFS=y +CONFIG_ZLIB_INFLATE=y --- linux-2.6.24.orig/debian/config/hppa/config +++ linux-2.6.24/debian/config/hppa/config @@ -0,0 +1,1363 @@ +# +# Common config options automatically generated by splitconfig.pl +# +CONFIG_53C700_LE_ON_BE=y +CONFIG_ACENIC=m +# CONFIG_ADFS_FS is not set +CONFIG_ADM8211=m +# CONFIG_AFFS_FS is not set +# CONFIG_AFS_FS is not set +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_ANON_INODES=y +# CONFIG_APPLICOM is not set +CONFIG_ARCH_FLATMEM_ENABLE=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_ARCNET is not set +# CONFIG_ARPD is not set +CONFIG_ASK_IP_FIB_HASH=y +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_ATA=m +# CONFIG_ATALK is not set +CONFIG_ATA_GENERIC=m +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_OVER_ETH=m +CONFIG_ATA_PIIX=m +# CONFIG_ATM is not set +# CONFIG_ATMEL is not set +CONFIG_AUDIT=y +CONFIG_AUDIT_GENERIC=y +CONFIG_AUXDISPLAY=y +CONFIG_B43=m +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_DEBUG=y +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y +CONFIG_B43LEGACY_PCI_AUTOSELECT=y +CONFIG_B43LEGACY_PIO=y +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_B43_DEBUG=y +CONFIG_B43_DMA=y +CONFIG_B43_DMA_AND_PIO_MODE=y +# CONFIG_B43_DMA_MODE is not set +CONFIG_B43_PCICORE_AUTOSELECT=y +CONFIG_B43_PCI_AUTOSELECT=y +# CONFIG_B43_PCMCIA is not set +CONFIG_B43_PIO=y +# CONFIG_B43_PIO_MODE is not set +CONFIG_B43_RFKILL=y +CONFIG_BACKLIGHT_CLASS_DEVICE=m +CONFIG_BACKLIGHT_CORGI=m +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BASE_FULL=y +CONFIG_BASE_SMALL=0 +CONFIG_BATTERY_DS2760=m +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_BITREVERSE=y +# CONFIG_BLK_CPQ_CISS_DA is not set +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +CONFIG_BLK_DEV_4DRIVES=y +# CONFIG_BLK_DEV_AEC62XX is not set +CONFIG_BLK_DEV_ALI14XX=m +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_CRYPTOLOOP=m +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_DELKIN=m +CONFIG_BLK_DEV_DM=m +CONFIG_BLK_DEV_DTC2278=m +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_BLK_DEV_HD is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_BLK_DEV_HPT366 is not set +CONFIG_BLK_DEV_HT6560B=m +CONFIG_BLK_DEV_IDE=m +CONFIG_BLK_DEV_IDECD=m +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDEDISK=m +CONFIG_BLK_DEV_IDEDMA=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEFLOPPY is not set +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_BLK_DEV_IDESCSI=m +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_JMICRON is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_MD=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_NS87415=m +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PIIX is not set +CONFIG_BLK_DEV_PLATFORM=m +CONFIG_BLK_DEV_QD65XX=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +# CONFIG_BLK_DEV_SC1200 is not set +CONFIG_BLK_DEV_SD=m +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_TC86C001=m +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_UMC8672=m +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_BLOCK=y +# CONFIG_BONDING is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +CONFIG_BRIDGE=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_NETFILTER=y +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BROADCOM_PHY=m +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_BT is not set +CONFIG_BUG=y +CONFIG_CARDBUS=y +CONFIG_CASSINI=m +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_CFG80211=m +CONFIG_CGROUPS=y +CONFIG_CGROUP_CPUACCT=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_NS=y +CONFIG_CHASSIS_LCD_LED=y +CONFIG_CHR_DEV_OSST=m +CONFIG_CHR_DEV_SCH=m +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_ST=m +CONFIG_CICADA_PHY=m +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG2 is not set +CONFIG_CIFS_EXPERIMENTAL=y +# CONFIG_CIFS_STATS is not set +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_WEAK_PW_HASH=y +# CONFIG_CIFS_XATTR is not set +CONFIG_CLS_U32_MARK=y +CONFIG_CLS_U32_PERF=y +# CONFIG_CODA_FS is not set +CONFIG_CONFIGFS_FS=m +CONFIG_CONNECTOR=m +CONFIG_CRC32=y +CONFIG_CRC7=m +CONFIG_CRC_CCITT=m +CONFIG_CRC_ITU_T=m +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ABLKCIPHER=m +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_XTS=m +CONFIG_DAB=y +CONFIG_DAVICOM_PHY=m +# CONFIG_DE4X5 is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_MUTEXES is not set +CONFIG_DEBUG_RODATA=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DECNET is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_BIC is not set +CONFIG_DEFAULT_CFQ=y +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_HTCP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_RELATIME=y +CONFIG_DEFAULT_RELATIME_VAL=1 +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_WESTWOOD is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_DEVPORT=y +# CONFIG_DEV_KMEM is not set +# CONFIG_DM9102 is not set +CONFIG_DM_CRYPT=m +# CONFIG_DM_DEBUG is not set +# CONFIG_DM_DELAY is not set +CONFIG_DM_MIRROR=m +# CONFIG_DM_MULTIPATH is not set +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_UEVENT=y +CONFIG_DM_ZERO=m +CONFIG_DNOTIFY=y +# CONFIG_DRM is not set +# CONFIG_DTLK is not set +CONFIG_DUMMY=m +CONFIG_DUMMY_CONSOLE=y +CONFIG_DUMMY_CONSOLE_COLUMNS=160 +CONFIG_DUMMY_CONSOLE_ROWS=64 +# CONFIG_DVB_CORE is not set +CONFIG_E100=m +CONFIG_E1000=m +CONFIG_E1000E=m +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +CONFIG_E1000_NAPI=y +# CONFIG_ECONET is not set +CONFIG_EEPROM_93CX6=m +# CONFIG_EFS_FS is not set +CONFIG_EISA=y +CONFIG_EISA_NAMES=y +CONFIG_EL1=m +CONFIG_EL16=m +CONFIG_EL2=m +CONFIG_EL3=m +CONFIG_ELF_CORE=y +# CONFIG_EMBEDDED is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +CONFIG_EPOLL=y +# CONFIG_EQUALIZER is not set +CONFIG_EVENTFD=y +CONFIG_EXPERIMENTAL=y +CONFIG_EXPORTFS=m +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT4DEV_FS is not set +CONFIG_FAIR_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_FAIR_USER_SCHED is not set +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_FAT_FS=m +# CONFIG_FAULT_INJECTION is not set +# CONFIG_FDDI is not set +CONFIG_FIB_RULES=y +# CONFIG_FIREWIRE is not set +CONFIG_FIXED_MII_1000_FDX=y +# CONFIG_FIXED_MII_100_FDX is not set +# CONFIG_FIXED_MII_10_FDX is not set +CONFIG_FIXED_MII_AMNT=1 +CONFIG_FIXED_PHY=m +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_FORCED_INLINING=y +CONFIG_FS_POSIX_ACL=y +CONFIG_FUSION=y +CONFIG_FUSION_CTL=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_LOGGING=y +CONFIG_FUSION_MAX_SGE=128 +CONFIG_FUSION_SAS=m +CONFIG_FUSION_SPI=m +CONFIG_FUTEX=y +CONFIG_FW_LOADER=y +CONFIG_GACT_PROB=y +# CONFIG_GAMEPORT is not set +CONFIG_GENERIC_ACL=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_TIME=y +CONFIG_GEN_RTC=y +CONFIG_GEN_RTC_X=y +CONFIG_GSC=y +CONFIG_GSC_DINO=y +CONFIG_GSC_LASI=y +CONFIG_GSC_WAX=y +# CONFIG_HAMRADIO is not set +CONFIG_HAPPYMEAL=m +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_HERMES=m +# CONFIG_HFSPLUS_FS is not set +# CONFIG_HFS_FS is not set +CONFIG_HIDRAW=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HID_FF is not set +CONFIG_HID_SUPPORT=y +# CONFIG_HIPPI is not set +CONFIG_HOTPLUG=y +# CONFIG_HOTPLUG_PCI is not set +CONFIG_HP100=m +# CONFIG_HPFS_FS is not set +CONFIG_HPPB=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_HW_CONSOLE=y +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_I2C is not set +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_BUS=m +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_PROC=m +CONFIG_I2O_SCSI=m +CONFIG_I82092=m +CONFIG_I82365=m +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +CONFIG_ICPLUS_PHY=m +CONFIG_IDE=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +CONFIG_IDEPCI_SHARE_IRQ=y +CONFIG_IDE_ARCH_OBSOLETE_INIT=y +# CONFIG_IDE_ARM is not set +CONFIG_IDE_GENERIC=m +CONFIG_IDE_PROC_FS=y +# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IEEE1394 is not set +CONFIG_IEEE80211=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_CRYPT_WEP=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_IFB=m +CONFIG_IKCONFIG=y +# CONFIG_IKCONFIG_PROC is not set +CONFIG_INET=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET_AH=m +CONFIG_INET_DCCP_DIAG=m +CONFIG_INET_DIAG=y +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_LRO=m +CONFIG_INET_TCP_DIAG=y +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_TUNNEL=m +# CONFIG_INFINIBAND is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_INPUT=y +# CONFIG_INPUT_EVBUG is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_JOYSTICK is not set +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_POLLDEV=m +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INSTRUMENTATION=y +CONFIG_IOMMU_CCIO=y +CONFIG_IOMMU_SBA=y +CONFIG_IOSAPIC=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_CFQ=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IP1000=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +# CONFIG_IPMI_HANDLER is not set +CONFIG_IPV6=m +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_IPV6_SIT=m +CONFIG_IPV6_TUNNEL=m +CONFIG_IPW2100=m +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +# CONFIG_IPW2200_DEBUG is not set +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +CONFIG_IPW2200_RADIOTAP=y +# CONFIG_IPX is not set +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_DCCP=m +CONFIG_IP_DCCP_ACKVEC=y +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_IP_DCCP_TFRC_LIB=m +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +# CONFIG_IP_MROUTE is not set +CONFIG_IP_MULTICAST=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_PNP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IP_SCTP=m +# CONFIG_IP_VS is not set +# CONFIG_IRDA is not set +CONFIG_IRQ_PER_CPU=y +CONFIG_ISA=y +CONFIG_ISCSI_TCP=m +# CONFIG_ISDN is not set +# CONFIG_IWLWIFI is not set +CONFIG_IXGBE=m +# CONFIG_JFS_DEBUG is not set +CONFIG_JFS_FS=m +# CONFIG_JFS_POSIX_ACL is not set +# CONFIG_JFS_SECURITY is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_JOLIET=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_KEYS=y +CONFIG_KMOD=y +# CONFIG_LAPB is not set +CONFIG_LASI_82596=m +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LIBCRC32C=m +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_CS=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_USB=m +CONFIG_LLC=m +# CONFIG_LLC2 is not set +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_LOCKD_V4=y +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_LXT_PHY=m +CONFIG_MAC80211=m +# CONFIG_MAC80211_DEBUG is not set +CONFIG_MAC80211_RCSIMPLE=y +CONFIG_MACVLAN=m +CONFIG_MAGIC_SYSRQ=y +# CONFIG_MARKERS is not set +CONFIG_MARVELL_PHY=m +CONFIG_MD=y +CONFIG_MDIO_BITBANG=m +CONFIG_MD_FAULTY=m +CONFIG_MD_LINEAR=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID5_RESHAPE=y +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_SAS=m +CONFIG_MII=m +# CONFIG_MINIX_FS is not set +CONFIG_MISC_DEVICES=y +# CONFIG_MLX4_CORE is not set +# CONFIG_MMC is not set +CONFIG_MMU=y +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MSDOS_FS=m +CONFIG_MSDOS_PARTITION=y +# CONFIG_MSS is not set +# CONFIG_MTD is not set +# CONFIG_NCP_FS is not set +CONFIG_NET=y +CONFIG_NETDEVICES=y +CONFIG_NETDEVICES_MULTIQUEUE=y +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +# CONFIG_NETLABEL is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NETWORK_SECMARK=y +CONFIG_NET_9P=m +# CONFIG_NET_9P_DEBUG is not set +CONFIG_NET_9P_FD=m +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_IND=y +# CONFIG_NET_CLS_POLICE is not set +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_ETHERNET=y +# CONFIG_NET_FC is not set +CONFIG_NET_IPGRE=m +# CONFIG_NET_IPGRE_BROADCAST is not set +CONFIG_NET_IPIP=m +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_NET_PCI=y +CONFIG_NET_PCMCIA=y +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_POCKET is not set +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_FIFO=y +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_RR=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_TULIP=y +CONFIG_NET_VENDOR_3COM=y +CONFIG_NET_VENDOR_RACAL=y +CONFIG_NET_VENDOR_SMC=y +CONFIG_NFSD=m +CONFIG_NFSD_TCP=y +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_ENABLED=m +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_NF_CONNTRACK_SANE is not set +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_TFTP=m +# CONFIG_NI52 is not set +# CONFIG_NIU is not set +CONFIG_NL80211=y +CONFIG_NLS=y +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=m +# CONFIG_NORTEL_HERMES is not set +# CONFIG_OCFS2_FS is not set +CONFIG_OPROFILE=m +CONFIG_P54_COMMON=m +CONFIG_P54_PCI=m +CONFIG_P54_USB=m +# CONFIG_PA7100LC is not set +# CONFIG_PA7200 is not set +# CONFIG_PA7300LC is not set +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_PARIDE is not set +CONFIG_PARISC=y +# CONFIG_PARISC_PAGE_SIZE_16KB is not set +CONFIG_PARISC_PAGE_SIZE_4KB=y +# CONFIG_PARISC_PAGE_SIZE_64KB is not set +CONFIG_PARPORT=m +# CONFIG_PARPORT_1284 is not set +CONFIG_PARPORT_AX88796=m +CONFIG_PARPORT_GSC=y +CONFIG_PARPORT_NOT_PC=y +CONFIG_PARPORT_PC=m +# CONFIG_PARPORT_PC_FIFO is not set +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_PC_SUPERIO is not set +# CONFIG_PARPORT_SERIAL is not set +# CONFIG_PARTITION_ADVANCED is not set +# CONFIG_PATA_ALI is not set +CONFIG_PATA_AMD=m +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +CONFIG_PATA_CS5520=m +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +CONFIG_PATA_EFAR=m +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +CONFIG_PATA_IT8213=m +CONFIG_PATA_IT821X=m +CONFIG_PATA_JMICRON=m +# CONFIG_PATA_LEGACY is not set +CONFIG_PATA_MARVELL=m +CONFIG_PATA_MPIIX=m +CONFIG_PATA_NETCELL=m +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_NS87415 is not set +CONFIG_PATA_OLDPIIX=m +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +CONFIG_PATA_PCMCIA=m +CONFIG_PATA_PDC2027X=m +# CONFIG_PATA_PDC_OLD is not set +CONFIG_PATA_QDI=m +# CONFIG_PATA_RADISYS is not set +CONFIG_PATA_RZ1000=m +# CONFIG_PATA_SC1200 is not set +CONFIG_PATA_SERVERWORKS=m +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +CONFIG_PATA_TRIFLEX=m +CONFIG_PATA_VIA=m +CONFIG_PATA_WINBOND=m +# CONFIG_PATA_WINBOND_VLB is not set +CONFIG_PCCARD=m +CONFIG_PCCARD_NONSTATIC=m +CONFIG_PCI=y +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_HERMES is not set +CONFIG_PCI_LBA=y +CONFIG_PCI_LEGACY=y +CONFIG_PCMCIA=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_3C589=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_HERMES=m +CONFIG_PCMCIA_IOCTL=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_RAYCS=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_SPECTRUM=m +CONFIG_PCMCIA_SYM53C500=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_PCNET32=m +# CONFIG_PCNET32_NAPI is not set +CONFIG_PD6729=m +CONFIG_PDA_POWER=m +CONFIG_PDC_ADMA=m +CONFIG_PDC_CHASSIS=y +CONFIG_PDC_CHASSIS_WARN=y +CONFIG_PDC_STABLE=y +CONFIG_PHANTOM=m +# CONFIG_PHONE is not set +CONFIG_PHYLIB=m +# CONFIG_PID_NS is not set +CONFIG_PLIP=m +CONFIG_PLIST=y +# CONFIG_PLX_HERMES is not set +# CONFIG_PNP is not set +CONFIG_POSIX_MQUEUE=y +CONFIG_POWER_SUPPLY=m +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PPDEV is not set +CONFIG_PPP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_SYNC_TTY=m +# CONFIG_PREEMPT is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_PRINTK=y +# CONFIG_PRISM54 is not set +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROFILING=y +# CONFIG_QNX4FS_FS is not set +CONFIG_QSEMI_PHY=m +# CONFIG_QUOTA is not set +# CONFIG_R3964 is not set +CONFIG_RADIO_ADAPTERS=y +# CONFIG_RADIO_AZTECH is not set +# CONFIG_RADIO_CADET is not set +# CONFIG_RADIO_GEMTEK is not set +# CONFIG_RADIO_GEMTEK_PCI is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_RTRACK is not set +# CONFIG_RADIO_RTRACK2 is not set +# CONFIG_RADIO_SF16FMI is not set +# CONFIG_RADIO_SF16FMR2 is not set +# CONFIG_RADIO_TERRATEC is not set +# CONFIG_RADIO_TRUST is not set +# CONFIG_RADIO_TYPHOON is not set +# CONFIG_RADIO_ZOLTRIX is not set +CONFIG_RAID_ATTRS=m +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RELAY=y +CONFIG_RESOURCES_64BIT=y +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +# CONFIG_ROMFS_FS is not set +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_RT2400PCI=m +CONFIG_RT2400PCI_RFKILL=y +CONFIG_RT2500PCI=m +CONFIG_RT2500PCI_RFKILL=y +CONFIG_RT2500USB=m +CONFIG_RT2X00=m +# CONFIG_RT2X00_DEBUG is not set +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_PCI=m +CONFIG_RT2X00_LIB_RFKILL=y +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT61PCI=m +CONFIG_RT61PCI_RFKILL=y +CONFIG_RT73USB=m +CONFIG_RTL8187=m +CONFIG_RT_MUTEXES=y +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_RXKAD=m +# CONFIG_SAMPLES is not set +CONFIG_SATA_AHCI=m +CONFIG_SATA_INIC162X=m +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIL24=m +CONFIG_SATA_SIS=m +CONFIG_SATA_SVW=m +CONFIG_SATA_SX4=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m +# CONFIG_SCHEDSTATS is not set +CONFIG_SCHED_DEBUG=y +CONFIG_SCSI=y +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_ACARD is not set +CONFIG_SCSI_ADVANSYS=m +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +CONFIG_SCSI_AIC94XX=m +CONFIG_SCSI_ARCMSR=m +# CONFIG_SCSI_CONSTANTS is not set +CONFIG_SCSI_DC390T=m +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DEBUG is not set +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_FC_TGT_ATTRS=y +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +CONFIG_SCSI_HPTIOP=m +# CONFIG_SCSI_IMM is not set +# CONFIG_SCSI_IN2000 is not set +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_INITIO=m +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_IPS is not set +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_LASI700=m +# CONFIG_SCSI_LOGGING is not set +CONFIG_SCSI_LOWLEVEL=y +CONFIG_SCSI_LOWLEVEL_PCMCIA=y +CONFIG_SCSI_LPFC=m +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_NCR53C406A is not set +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 +CONFIG_SCSI_NCR53C8XX_SYNC=20 +CONFIG_SCSI_NETLINK=y +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PPA is not set +CONFIG_SCSI_PROC_FS=y +# CONFIG_SCSI_PSI240I is not set +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_QLOGIC_1280=m +# CONFIG_SCSI_QLOGIC_FAS is not set +CONFIG_SCSI_SAS_ATA=y +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set +CONFIG_SCSI_SCAN_ASYNC=y +# CONFIG_SCSI_SIM710 is not set +CONFIG_SCSI_SPI_ATTRS=y +CONFIG_SCSI_SRP=m +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_STEX=m +# CONFIG_SCSI_SYM53C416 is not set +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +# CONFIG_SCSI_T128 is not set +CONFIG_SCSI_TGT=m +CONFIG_SCSI_WAIT_SCAN=m +CONFIG_SCSI_ZALON=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_HMAC_MD5=y +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SECURITY=y +CONFIG_SECURITY_APPARMOR=y +CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 +# CONFIG_SECURITY_APPARMOR_DISABLE is not set +CONFIG_SECURITY_CAPABILITIES=y +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +# CONFIG_SECURITY_SELINUX is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_CS=m +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_GSC=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_PCI=y +# CONFIG_SERIAL_8250_RSA is not set +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_SGI_IOC4=m +CONFIG_SHMEM=y +CONFIG_SIGNALFD=y +# CONFIG_SK98LIN is not set +CONFIG_SLABINFO=y +CONFIG_SLHC=m +# CONFIG_SLOB is not set +CONFIG_SMB_FS=m +CONFIG_SMB_NLS_DEFAULT=y +CONFIG_SMB_NLS_REMOTE="cp437" +CONFIG_SMC9194=m +CONFIG_SMSC_PHY=m +# CONFIG_SOUND is not set +# CONFIG_SPARSEMEM_MANUAL is not set +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SSB=m +CONFIG_SSB_DEBUG=y +CONFIG_SSB_DRIVER_PCICORE=y +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +# CONFIG_SSB_PCMCIAHOST is not set +CONFIG_SSB_PCMCIAHOST_POSSIBLE=y +CONFIG_SSB_POSSIBLE=y +CONFIG_STACK_GROWSUP=y +CONFIG_STANDALONE=y +CONFIG_SUNGEM=m +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_SUPERIO=y +CONFIG_SWAP=y +# CONFIG_SYN_COOKIES is not set +CONFIG_SYSCTL=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSFS=y +# CONFIG_SYSFS_DEPRECATED is not set +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_SYSV_FS is not set +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_TASKSTATS=y +# CONFIG_TASK_DELAY_ACCT is not set +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_TASK_XACCT=y +# CONFIG_TCG_TPM is not set +CONFIG_TCIC=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_MD5SIG=y +CONFIG_TEHUTI=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TIFM_7XX1=m +CONFIG_TIFM_CORE=m +CONFIG_TIGON3=m +# CONFIG_TINY_SHMEM is not set +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +# CONFIG_TMD_HERMES is not set +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +# CONFIG_TR is not set +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_NAPI is not set +CONFIG_TUN=m +CONFIG_TYPHOON=m +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_UIO=m +CONFIG_UIO_CIF=m +CONFIG_ULTRA=m +CONFIG_ULTRA32=m +CONFIG_UNIX=y +CONFIG_UNIX98_PTYS=y +CONFIG_USB=m +# CONFIG_USB_ACM is not set +CONFIG_USB_ADUTUX=m +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_AUERSWALD is not set +CONFIG_USB_BERRY_CHARGE=m +# CONFIG_USB_CATC is not set +CONFIG_USB_CYPRESS_CY7C63=m +# CONFIG_USB_CYTHERM is not set +CONFIG_USB_DABUSB=m +CONFIG_USB_DEBUG=y +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DSBR is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EMI26=m +CONFIG_USB_EMI62=m +# CONFIG_USB_ET61X251 is not set +CONFIG_USB_FTDI_ELAN=m +# CONFIG_USB_GADGET is not set +CONFIG_USB_HID=m +CONFIG_USB_HIDDEV=y +CONFIG_USB_HIDINPUT_POWERBOOK=y +# CONFIG_USB_IBMCAM is not set +# CONFIG_USB_IDMOUSE is not set +CONFIG_USB_IOWARRIOR=m +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_KAWETH is not set +CONFIG_USB_KBD=m +# CONFIG_USB_KONICAWC is not set +# CONFIG_USB_LCD is not set +CONFIG_USB_LD=m +# CONFIG_USB_LED is not set +# CONFIG_USB_LEGOTOWER is not set +CONFIG_USB_LIBUSUAL=y +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +CONFIG_USB_MON=y +CONFIG_USB_MOUSE=m +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_HCD_SSB is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OV511 is not set +# CONFIG_USB_PEGASUS is not set +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_PWC is not set +# CONFIG_USB_QUICKCAM_MESSENGER is not set +CONFIG_USB_R8A66597_HCD=m +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_SE401 is not set +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SISUSBVGA is not set +CONFIG_USB_SL811_CS=m +CONFIG_USB_SL811_HCD=m +# CONFIG_USB_SN9C102 is not set +CONFIG_USB_STORAGE=m +CONFIG_USB_STORAGE_ALAUDA=y +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +CONFIG_USB_STORAGE_KARMA=y +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +CONFIG_USB_STORAGE_USBAT=y +# CONFIG_USB_STV680 is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_U132_HCD=m +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_USS720 is not set +# CONFIG_USB_VICAM is not set +# CONFIG_USB_ZC0301 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_USER_NS is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VERSION_SIGNATURE="Unofficial" +CONFIG_VETH=m +CONFIG_VFAT_FS=m +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_BWQCAM is not set +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_VIDEO_CQCAM is not set +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_OUTPUT_CONTROL=m +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_STRADIS is not set +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +# CONFIG_VIDEO_VIVI is not set +CONFIG_VIRT_TO_BUS=y +CONFIG_VITESSE_PHY=m +CONFIG_VLAN_8021Q=m +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VORTEX=m +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_W1=m +CONFIG_W1_CON=y +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_DS2760=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_THERM=m +# CONFIG_WAN is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_WATCHDOG is not set +CONFIG_WD80x3=m +# CONFIG_WINBOND_840 is not set +CONFIG_WIRELESS_EXT=y +CONFIG_WLAN_80211=y +# CONFIG_X25 is not set +CONFIG_XFRM=y +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_XFRM_USER=m +CONFIG_XFS_FS=m +# CONFIG_XFS_RT is not set +# CONFIG_XFS_SECURITY is not set +CONFIG_XOR_BLOCKS=m +CONFIG_YENTA=m +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_ZLIB_DEFLATE=m +CONFIG_ZONE_DMA_FLAG=0 --- linux-2.6.24.orig/debian/config/hppa/config.hppa64 +++ linux-2.6.24/debian/config/hppa/config.hppa64 @@ -0,0 +1,173 @@ +# +# Config options for config.hppa64 automatically generated by splitconfig.pl +# +CONFIG_64BIT=y +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_9P_FS is not set +# CONFIG_AC3200 is not set +CONFIG_ACENIC_OMIT_TIGON_I=y +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AGP is not set +# CONFIG_AIRO_CS is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_APRICOT is not set +CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y +CONFIG_ARCH_DISCONTIGMEM_ENABLE=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +# CONFIG_AT1700 is not set +# CONFIG_ATL1 is not set +CONFIG_AUTOFS4_FS=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_B44 is not set +# CONFIG_BCM43XX is not set +CONFIG_BLOCK_COMPAT=y +# CONFIG_BNX2 is not set +CONFIG_BROKEN_ON_SMP=y +# CONFIG_CARDMAN_4000 is not set +# CONFIG_CARDMAN_4040 is not set +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +CONFIG_COMPAT=y +# CONFIG_CRAMFS is not set +# CONFIG_CRC16 is not set +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_DES=m +# CONFIG_CS89x0 is not set +CONFIG_DE2104X=m +# CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEPCA is not set +# CONFIG_DETECT_SOFTLOCKUP is not set +CONFIG_DISCONTIGMEM=y +CONFIG_DISCONTIGMEM_MANUAL=y +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_DL2K is not set +# CONFIG_DLM is not set +# CONFIG_ECRYPT_FS is not set +# CONFIG_EEPRO100 is not set +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_EPIC100 is not set +# CONFIG_ES3210 is not set +CONFIG_EXT2_FS=y +CONFIG_EXT3_FS=y +# CONFIG_FB is not set +# CONFIG_FEALNX is not set +# CONFIG_FLATMEM_MANUAL is not set +# CONFIG_FORCEDETH is not set +CONFIG_FS_MBCACHE=y +# CONFIG_FUSE_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_HAMACHI is not set +CONFIG_HID=y +# CONFIG_HOSTAP is not set +# CONFIG_HWMON is not set +CONFIG_HW_RANDOM=m +CONFIG_I2O_EXT_ADAPTEC_DMA64=y +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MISC is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_ISO9660_FS=y +# CONFIG_IXGB is not set +CONFIG_JBD=y +CONFIG_KEYS_DEBUG_PROC_KEYS=y +# CONFIG_KS0108 is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_LNE390 is not set +CONFIG_LOCKD=m +CONFIG_MAX_RAW_DEVS=256 +# CONFIG_MFD_SM501 is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +CONFIG_NEED_MULTIPLE_NODES=y +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_NEW_LEDS is not set +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_FS=m +# CONFIG_NI5010 is not set +CONFIG_NLS_ASCII=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NODES_SHIFT=3 +# CONFIG_NS83820 is not set +# CONFIG_NTFS_FS is not set +CONFIG_PA20=y +# CONFIG_PA7000 is not set +CONFIG_PA8X00=y +# CONFIG_PCMCIA_AXNET is not set +# CONFIG_PCMCIA_FMVJ18X is not set +# CONFIG_PCMCIA_NMCLAN is not set +# CONFIG_PCMCIA_PCNET is not set +# CONFIG_PCMCIA_WL3501 is not set +# CONFIG_PCMCIA_XIRTULIP is not set +# CONFIG_PPPOE is not set +# CONFIG_PPP_FILTER is not set +# CONFIG_PPP_MPPE is not set +# CONFIG_PPP_MULTILINK is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREFETCH=y +# CONFIG_PRINTER is not set +# CONFIG_PRINTK_TIME is not set +# CONFIG_QLA3XXX is not set +# CONFIG_R8169 is not set +CONFIG_RAW_DRIVER=y +# CONFIG_REISERFS_FS is not set +CONFIG_RPCSEC_GSS_KRB5=m +# CONFIG_RTC_CLASS is not set +# CONFIG_S2IO is not set +# CONFIG_SC92031 is not set +# CONFIG_SERIAL_8250_ACCENT is not set +# CONFIG_SERIAL_8250_BOCA is not set +# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set +# CONFIG_SERIAL_8250_FOURPORT is not set +# CONFIG_SERIAL_8250_HUB6 is not set +CONFIG_SERIAL_8250_NR_UARTS=17 +CONFIG_SERIAL_MUX=y +CONFIG_SERIAL_MUX_CONSOLE=y +# CONFIG_SERIO is not set +# CONFIG_SHAPER is not set +# CONFIG_SIS190 is not set +# CONFIG_SIS900 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +CONFIG_SLAB=y +# CONFIG_SLIP is not set +# CONFIG_SLUB is not set +# CONFIG_SMP is not set +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_STI_CONSOLE is not set +# CONFIG_SUNDANCE is not set +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +# CONFIG_SYNCLINK_CS is not set +# CONFIG_TIMER_STATS is not set +CONFIG_TULIP=y +CONFIG_TULIP_MMIO=y +# CONFIG_UFS_DEBUG is not set +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_ULI526X is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_VXFS_FS is not set +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_ZISOFS is not set +CONFIG_ZLIB_INFLATE=m --- linux-2.6.24.orig/debian/config/ia64/config +++ linux-2.6.24/debian/config/ia64/config @@ -0,0 +1,2537 @@ +# +# Common config options automatically generated by splitconfig.pl +# +CONFIG_3C359=m +CONFIG_64BIT=y +# CONFIG_6PACK is not set +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_8129=y +CONFIG_8139TOO_PIO=y +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_9P_FS=m +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_ACORN_PARTITION=y +CONFIG_ACORN_PARTITION_ADFS=y +# CONFIG_ACORN_PARTITION_CUMANA is not set +CONFIG_ACORN_PARTITION_EESOX=y +CONFIG_ACORN_PARTITION_ICS=y +CONFIG_ACORN_PARTITION_POWERTEC=y +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_ACPI=y +CONFIG_ACPI_BAY=m +CONFIG_ACPI_BLACKLIST_YEAR=0 +CONFIG_ACPI_BUTTON=m +CONFIG_ACPI_CONTAINER=m +CONFIG_ACPI_CUSTOM_DSDT_INITRD=y +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_DOCK=m +CONFIG_ACPI_EC=y +CONFIG_ACPI_FAN=m +CONFIG_ACPI_NUMA=y +CONFIG_ACPI_POWER=y +CONFIG_ACPI_PROCESSOR=m +CONFIG_ACPI_PROCFS=y +CONFIG_ACPI_PROCFS_POWER=y +CONFIG_ACPI_PROC_EVENT=y +CONFIG_ACPI_SYSFS_POWER=y +CONFIG_ACPI_SYSTEM=y +CONFIG_ACPI_THERMAL=m +CONFIG_ADAPTEC_STARFIRE=m +# CONFIG_ADAPTEC_STARFIRE_NAPI is not set +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_ADM8211=m +CONFIG_AFFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_AFS_FS=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_AGP=m +CONFIG_AGP_HP_ZX1=m +CONFIG_AGP_I460=m +# CONFIG_AGP_SGI_TIOCA is not set +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +# CONFIG_AIC79XX_DEBUG_ENABLE is not set +CONFIG_AIC79XX_DEBUG_MASK=0 +# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +CONFIG_AIC7XXX_CMDS_PER_DEVICE=253 +# CONFIG_AIC7XXX_DEBUG_ENABLE is not set +CONFIG_AIC7XXX_DEBUG_MASK=0 +# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_AIRO_CS=m +# CONFIG_AMD8111E_NAPI is not set +CONFIG_AMD8111_ETH=m +CONFIG_AMIGA_PARTITION=y +CONFIG_ANON_INODES=y +CONFIG_APPLICOM=m +CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y +CONFIG_ARCH_DISCONTIGMEM_ENABLE=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_ARCH_FLATMEM_ENABLE=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUPPORTS_MSI=y +CONFIG_ARCNET=m +CONFIG_ARCNET_1051=m +CONFIG_ARCNET_1201=m +CONFIG_ARCNET_CAP=m +CONFIG_ARCNET_COM20020=m +CONFIG_ARCNET_COM20020_CS=m +CONFIG_ARCNET_COM20020_PCI=m +# CONFIG_ARCNET_COM90xx is not set +CONFIG_ARCNET_COM90xxIO=m +CONFIG_ARCNET_RAW=m +# CONFIG_ARCNET_RIM_I is not set +# CONFIG_ARPD is not set +CONFIG_ASK_IP_FIB_HASH=y +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_ATA=m +CONFIG_ATALK=m +CONFIG_ATARI_PARTITION=y +CONFIG_ATA_ACPI=y +CONFIG_ATA_GENERIC=m +CONFIG_ATA_NONSTANDARD=y +CONFIG_ATA_OVER_ETH=m +CONFIG_ATA_PIIX=m +CONFIG_ATL1=m +# CONFIG_ATM is not set +CONFIG_ATMEL=m +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y +CONFIG_AUDIT_ARCH=y +CONFIG_AUDIT_TREE=y +CONFIG_AUTOFS4_FS=m +CONFIG_AUTOFS_FS=m +CONFIG_AUXDISPLAY=y +CONFIG_AX25=m +CONFIG_AX25_DAMA_SLAVE=y +CONFIG_B43=m +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_DEBUG=y +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y +CONFIG_B43LEGACY_PCI_AUTOSELECT=y +CONFIG_B43LEGACY_PIO=y +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_B43_DEBUG=y +CONFIG_B43_DMA=y +CONFIG_B43_DMA_AND_PIO_MODE=y +# CONFIG_B43_DMA_MODE is not set +CONFIG_B43_LEDS=y +CONFIG_B43_PCICORE_AUTOSELECT=y +CONFIG_B43_PCI_AUTOSELECT=y +# CONFIG_B43_PCMCIA is not set +CONFIG_B43_PIO=y +# CONFIG_B43_PIO_MODE is not set +CONFIG_B43_RFKILL=y +CONFIG_B44=m +CONFIG_B44_PCI=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI_AUTOSELECT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_CORGI=m +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BASE_FULL=y +CONFIG_BASE_SMALL=0 +CONFIG_BATTERY_DS2760=m +CONFIG_BAYCOM_PAR=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_BCM43XX=m +# CONFIG_BCM43XX_DEBUG is not set +CONFIG_BCM43XX_DMA=y +CONFIG_BCM43XX_DMA_AND_PIO_MODE=y +# CONFIG_BCM43XX_DMA_MODE is not set +CONFIG_BCM43XX_PIO=y +# CONFIG_BCM43XX_PIO_MODE is not set +# CONFIG_BEFS_DEBUG is not set +CONFIG_BEFS_FS=m +CONFIG_BFS_FS=m +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_BITREVERSE=y +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_DEV=y +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_BLK_DEV_AEC62XX=m +CONFIG_BLK_DEV_ALI15X3=m +CONFIG_BLK_DEV_AMD74XX=m +# CONFIG_BLK_DEV_BSG is not set +CONFIG_BLK_DEV_CMD64X=m +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_CRYPTOLOOP=m +# CONFIG_BLK_DEV_CS5520 is not set +CONFIG_BLK_DEV_CS5530=m +CONFIG_BLK_DEV_CY82C693=m +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_DELKIN=m +CONFIG_BLK_DEV_DM=m +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_HPT34X=m +CONFIG_BLK_DEV_HPT366=m +CONFIG_BLK_DEV_IDE=m +CONFIG_BLK_DEV_IDEACPI=y +CONFIG_BLK_DEV_IDECD=m +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDEDISK=m +CONFIG_BLK_DEV_IDEDMA=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_IDEFLOPPY=m +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_BLK_DEV_IDEPNP=y +CONFIG_BLK_DEV_IDESCSI=m +CONFIG_BLK_DEV_IDETAPE=m +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_JMICRON is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_MD=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_NS87415=m +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_OPTI621=m +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +CONFIG_BLK_DEV_PDC202XX_OLD=m +# CONFIG_BLK_DEV_PIIX is not set +CONFIG_BLK_DEV_PLATFORM=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_BLK_DEV_SC1200=m +CONFIG_BLK_DEV_SD=m +CONFIG_BLK_DEV_SGIIOC4=m +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +CONFIG_BLK_DEV_SR=m +CONFIG_BLK_DEV_SR_VENDOR=y +# CONFIG_BLK_DEV_SVWKS is not set +CONFIG_BLK_DEV_SX8=m +CONFIG_BLK_DEV_TC86C001=m +# CONFIG_BLK_DEV_TRIFLEX is not set +CONFIG_BLK_DEV_TRM290=m +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_UMEM=m +# CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_BLOCK=y +CONFIG_BLOCK_COMPAT=y +CONFIG_BNX2=m +CONFIG_BONDING=m +# CONFIG_BOOT_PRINTK_DELAY is not set +CONFIG_BOUNCE=y +CONFIG_BPQETHER=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_NETFILTER=y +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BROADCOM_PHY=m +CONFIG_BSD_DISKLABEL=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_BT=m +CONFIG_BT_BNEP=m +# CONFIG_BT_BNEP_MC_FILTER is not set +# CONFIG_BT_BNEP_PROTO_FILTER is not set +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIUART=m +# CONFIG_BT_HCIUART_BCSP is not set +# CONFIG_BT_HCIUART_H4 is not set +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIUSB=m +# CONFIG_BT_HCIUSB_SCO is not set +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HIDP=m +CONFIG_BT_L2CAP=m +CONFIG_BT_RFCOMM=m +# CONFIG_BT_RFCOMM_TTY is not set +CONFIG_BT_SCO=m +CONFIG_BUG=y +CONFIG_CARDBUS=y +CONFIG_CARDMAN_4000=m +CONFIG_CARDMAN_4040=m +CONFIG_CASSINI=m +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_CFG80211=m +CONFIG_CGROUPS=y +CONFIG_CGROUP_CPUACCT=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_NS=y +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T1_NAPI=y +CONFIG_CHELSIO_T3=m +CONFIG_CHR_DEV_OSST=m +CONFIG_CHR_DEV_SCH=m +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_ST=m +CONFIG_CICADA_PHY=m +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG2 is not set +CONFIG_CIFS_EXPERIMENTAL=y +# CONFIG_CIFS_STATS is not set +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_WEAK_PW_HASH=y +# CONFIG_CIFS_XATTR is not set +CONFIG_CISS_SCSI_TAPE=y +CONFIG_CLS_U32_MARK=y +# CONFIG_CLS_U32_PERF is not set +CONFIG_CODA_FS=m +CONFIG_CODA_FS_OLD_API=y +CONFIG_COMPAT=y +CONFIG_COMPAT_FOR_U64_ALIGNMENT=y +CONFIG_COMPUTONE=m +CONFIG_CONFIGFS_FS=m +CONFIG_CONNECTOR=m +CONFIG_CPUSETS=y +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEBUG is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_TABLE=m +CONFIG_CRAMFS=y +CONFIG_CRC16=m +CONFIG_CRC32=y +CONFIG_CRC7=m +CONFIG_CRC_CCITT=m +CONFIG_CRC_ITU_T=m +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ABLKCIPHER=m +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_XTS=m +# CONFIG_CYCLADES is not set +# CONFIG_CYCLADES_SYNC is not set +CONFIG_DAB=y +CONFIG_DAVICOM_PHY=m +CONFIG_DE2104X=m +CONFIG_DE4X5=m +CONFIG_DE600=m +CONFIG_DE620=m +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_DRIVER is not set +CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_MUTEXES is not set +CONFIG_DEBUG_RODATA=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_VM is not set +CONFIG_DECNET=m +CONFIG_DECNET_NF_GRABULATOR=m +# CONFIG_DECNET_ROUTER is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_BIC is not set +CONFIG_DEFAULT_CFQ=y +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_HTCP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_RELATIME=y +CONFIG_DEFAULT_RELATIME_VAL=1 +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_WESTWOOD is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_DEFXX=m +# CONFIG_DEFXX_MMIO is not set +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_DEVPORT=y +CONFIG_DEV_APPLETALK=m +# CONFIG_DEV_KMEM is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DISABLE_VHPT is not set +CONFIG_DISCONTIGMEM=y +CONFIG_DISCONTIGMEM_MANUAL=y +CONFIG_DISPLAY_SUPPORT=m +CONFIG_DL2K=m +CONFIG_DLCI=m +CONFIG_DLCI_MAX=8 +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +CONFIG_DM9102=m +CONFIG_DMI=y +CONFIG_DMIID=y +CONFIG_DM_CRYPT=m +# CONFIG_DM_DEBUG is not set +# CONFIG_DM_DELAY is not set +CONFIG_DM_MIRROR=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_EMC=m +CONFIG_DM_MULTIPATH_HP=m +CONFIG_DM_MULTIPATH_RDAC=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_UEVENT=y +CONFIG_DM_ZERO=m +CONFIG_DNOTIFY=y +# CONFIG_DONGLE is not set +CONFIG_DRM=m +CONFIG_DRM_MGA=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_SAVAGE=m +CONFIG_DRM_SIS=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_VIA=m +CONFIG_DRM_VIA_CHROME9=n +CONFIG_DS1682=m +CONFIG_DSCC4=m +# CONFIG_DSCC4_PCISYNC is not set +# CONFIG_DSCC4_PCI_RST is not set +CONFIG_DUMMY=m +CONFIG_DUMMY_CONSOLE=y +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_B2C2_FLEXCOP=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_BT8XX=m +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_PATCH=m +CONFIG_DVB_CAPTURE_DRIVERS=y +CONFIG_DVB_CINERGYT2=m +CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y +CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250 +CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100 +CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512 +CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32 +CONFIG_DVB_CINERGYT2_TUNING=y +CONFIG_DVB_CORE=m +CONFIG_DVB_CORE_ATTACH=y +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_ISL6421=m +CONFIG_DVB_L64781=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_MT312=m +CONFIG_DVB_MT352=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_PLL=m +CONFIG_DVB_PLUTO2=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TDA827X=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_TUNER_MT2060=m +CONFIG_DVB_TUNER_MT2131=m +CONFIG_DVB_TUNER_MT2266=m +CONFIG_DVB_TUNER_QT1010=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_CXUSB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_ZL10353=m +CONFIG_E100=m +CONFIG_E1000=m +CONFIG_E1000E=m +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +CONFIG_E1000_NAPI=y +# CONFIG_ECONET is not set +CONFIG_ECRYPT_FS=m +CONFIG_EEPRO100=m +CONFIG_EEPROM_93CX6=m +CONFIG_EFI=y +CONFIG_EFI_PARTITION=y +CONFIG_EFI_PCDP=y +CONFIG_EFI_RTC=y +CONFIG_EFI_VARS=m +CONFIG_EFS_FS=m +CONFIG_ELF_CORE=y +# CONFIG_EMBEDDED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +CONFIG_EPIC100=m +CONFIG_EPOLL=y +CONFIG_EQUALIZER=m +CONFIG_EVENTFD=y +CONFIG_EXPERIMENTAL=y +CONFIG_EXPORTFS=m +CONFIG_EXT2_FS=m +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT4DEV_FS is not set +CONFIG_FAIR_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_FAIR_USER_SCHED is not set +CONFIG_FARSYNC=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_FAT_FS=m +# CONFIG_FAULT_INJECTION is not set +CONFIG_FB=y +CONFIG_FB_3DFX=m +# CONFIG_FB_3DFX_ACCEL is not set +CONFIG_FB_ARK=m +CONFIG_FB_ASILIANT=y +CONFIG_FB_ATY=m +CONFIG_FB_ATY128=m +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY_BACKLIGHT=y +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +CONFIG_FB_CIRRUS=m +CONFIG_FB_CYBER2000=m +CONFIG_FB_DDC=m +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_IMSTT is not set +CONFIG_FB_KYRO=m +# CONFIG_FB_MACMODES is not set +CONFIG_FB_MATROX=m +CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MULTIHEAD=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_NEOMAGIC=m +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_BACKLIGHT=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_I2C=y +CONFIG_FB_PM2=m +# CONFIG_FB_PM2_FIFO_DISCONNECT is not set +CONFIG_FB_PM3=m +CONFIG_FB_RADEON=m +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RIVA=m +CONFIG_FB_RIVA_BACKLIGHT=y +# CONFIG_FB_RIVA_DEBUG is not set +CONFIG_FB_RIVA_I2C=y +CONFIG_FB_S1D13XXX=m +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_ACCEL=y +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SIS=m +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +CONFIG_FB_SM501=m +CONFIG_FB_SVGALIB=m +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +CONFIG_FB_TILEBLITTING=y +CONFIG_FB_TRIDENT=m +# CONFIG_FB_TRIDENT_ACCEL is not set +CONFIG_FB_UVESA=m +# CONFIG_FB_VIRTUAL is not set +CONFIG_FB_VOODOO1=m +CONFIG_FB_VT8623=m +CONFIG_FDDI=y +CONFIG_FEALNX=m +CONFIG_FIB_RULES=y +# CONFIG_FIREWIRE is not set +CONFIG_FIRMWARE_EDID=y +CONFIG_FIXED_MII_1000_FDX=y +# CONFIG_FIXED_MII_100_FDX is not set +# CONFIG_FIXED_MII_10_FDX is not set +CONFIG_FIXED_MII_AMNT=1 +CONFIG_FIXED_PHY=m +# CONFIG_FLATMEM_MANUAL is not set +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +CONFIG_FORCEDETH=m +# CONFIG_FORCEDETH_NAPI is not set +# CONFIG_FORCED_INLINING is not set +CONFIG_FORCE_MAX_ZONEORDER=17 +CONFIG_FRAMEBUFFER_CONSOLE=m +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FS_MBCACHE=m +CONFIG_FS_POSIX_ACL=y +CONFIG_FTL=m +CONFIG_FUSE_FS=m +CONFIG_FUSION=y +CONFIG_FUSION_CTL=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_LAN=m +CONFIG_FUSION_LOGGING=y +CONFIG_FUSION_MAX_SGE=40 +CONFIG_FUSION_SAS=m +CONFIG_FUSION_SPI=m +CONFIG_FUTEX=y +CONFIG_FW_LOADER=y +CONFIG_GACT_PROB=y +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GENERIC_ACL=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=m +CONFIG_GFS2_FS_LOCKING_NOLOCK=m +CONFIG_HAMACHI=m +CONFIG_HAMRADIO=y +CONFIG_HANGCHECK_TIMER=m +# CONFIG_HAPPYMEAL is not set +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y +CONFIG_HAVE_ARCH_NODEDATA_EXTENSION=y +CONFIG_HDLC=m +CONFIG_HDLC_CISCO=m +CONFIG_HDLC_FR=m +CONFIG_HDLC_PPP=m +CONFIG_HDLC_RAW=m +CONFIG_HDLC_RAW_ETH=m +# CONFIG_HEADERS_CHECK is not set +CONFIG_HERMES=m +CONFIG_HFSPLUS_FS=m +CONFIG_HFS_FS=m +CONFIG_HID=m +CONFIG_HIDRAW=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HID_FF is not set +CONFIG_HID_SUPPORT=y +# CONFIG_HIPPI is not set +CONFIG_HOLES_IN_ZONE=y +CONFIG_HOSTAP=m +CONFIG_HOSTAP_CS=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_PLX=m +CONFIG_HOTPLUG=y +# CONFIG_HOTPLUG_CPU is not set +CONFIG_HOTPLUG_PCI=m +CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +CONFIG_HOTPLUG_PCI_CPCI=y +CONFIG_HOTPLUG_PCI_FAKE=m +CONFIG_HOTPLUG_PCI_PCIE=m +# CONFIG_HOTPLUG_PCI_SGI is not set +CONFIG_HOTPLUG_PCI_SHPC=m +# CONFIG_HP100 is not set +# CONFIG_HPET is not set +CONFIG_HPFS_FS=m +# CONFIG_HPT34X_AUTODMA is not set +# CONFIG_HP_SIMETH is not set +# CONFIG_HP_SIMSERIAL is not set +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HWMON_VID=m +CONFIG_HW_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_INTEL=m +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +CONFIG_I2C=m +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCA=m +CONFIG_I2C_ALGOPCF=m +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C_DEBUG_CORE is not set +CONFIG_I2C_I801=m +CONFIG_I2C_I810=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_STUB=m +CONFIG_I2C_TAOS_EVM=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_BUS=m +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_EXT_ADAPTEC_DMA64=y +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_PROC=m +CONFIG_I2O_SCSI=m +CONFIG_I82092=m +CONFIG_IA32_SUPPORT=y +CONFIG_IA64=y +# CONFIG_IA64_ACPI_CPUFREQ is not set +# CONFIG_IA64_CYCLONE is not set +# CONFIG_IA64_DEBUG_CMPXCHG is not set +# CONFIG_IA64_DEBUG_IRQ is not set +# CONFIG_IA64_DIG is not set +# CONFIG_IA64_ESI is not set +CONFIG_IA64_GENERIC=y +CONFIG_IA64_GRANULE_16MB=y +# CONFIG_IA64_GRANULE_64MB is not set +CONFIG_IA64_HP_AML_NFW=y +# CONFIG_IA64_HP_SIM is not set +# CONFIG_IA64_HP_ZX1 is not set +# CONFIG_IA64_HP_ZX1_SWIOTLB is not set +CONFIG_IA64_MCA_RECOVERY=m +CONFIG_IA64_MC_ERR_INJECT=m +CONFIG_IA64_PAGE_SIZE_16KB=y +# CONFIG_IA64_PAGE_SIZE_4KB is not set +# CONFIG_IA64_PAGE_SIZE_64KB is not set +# CONFIG_IA64_PAGE_SIZE_8KB is not set +CONFIG_IA64_PALINFO=m +CONFIG_IA64_PRINT_HAZARDS=y +# CONFIG_IA64_SGI_SN2 is not set +CONFIG_IA64_SGI_SN_XP=m +CONFIG_IA64_UNCACHED_ALLOCATOR=y +CONFIG_IBMOL=m +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +CONFIG_ICPLUS_PHY=m +CONFIG_IDE=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +CONFIG_IDEPCI_SHARE_IRQ=y +CONFIG_IDE_ARCH_OBSOLETE_INIT=y +# CONFIG_IDE_ARM is not set +CONFIG_IDE_GENERIC=m +CONFIG_IDE_MAX_HWIFS=4 +CONFIG_IDE_PROC_FS=y +CONFIG_IDE_TASK_IOCTL=y +CONFIG_IEEE1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_OHCI1394=m +CONFIG_IEEE1394_PCILYNX=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE80211=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_CRYPT_WEP=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_IFB=m +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_INET=y +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_TUNNEL=m +# CONFIG_INET_AH is not set +CONFIG_INET_DCCP_DIAG=m +CONFIG_INET_DIAG=y +# CONFIG_INET_ESP is not set +CONFIG_INET_IPCOMP=m +CONFIG_INET_LRO=m +CONFIG_INET_TCP_DIAG=y +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_AMSO1100=m +CONFIG_INFINIBAND_AMSO1100_DEBUG=y +CONFIG_INFINIBAND_CXGB3=m +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_IPOIB_DEBUG=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set +CONFIG_INFINIBAND_ISER=m +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INFTL=m +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_INPUT=y +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_EVBUG=m +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_INPUT_KEYBOARD=y +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_TABLET=y +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_YEALINK=m +CONFIG_INSTRUMENTATION=y +CONFIG_IOSAPIC=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_CFQ=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IP1000=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_RT=m +# CONFIG_IP6_NF_QUEUE is not set +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IPDDP=m +CONFIG_IPDDP_DECAP=y +CONFIG_IPDDP_ENCAP=y +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_POWEROFF=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPV6=m +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_IPV6_SIT=m +CONFIG_IPV6_TUNNEL=m +CONFIG_IPW2100=m +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +# CONFIG_IPW2200_DEBUG is not set +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_DCCP=m +CONFIG_IP_DCCP_ACKVEC=y +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_IP_DCCP_TFRC_LIB=m +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +# CONFIG_IP_MROUTE is not set +CONFIG_IP_MULTICAST=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_ULOG=m +# CONFIG_IP_PNP is not set +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_SCTP=m +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_TAB_BITS=12 +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_WRR=m +CONFIG_IRCOMM=m +CONFIG_IRDA=m +# CONFIG_IRDA_CACHE_LAST_LSAP is not set +# CONFIG_IRDA_DEBUG is not set +# CONFIG_IRDA_FAST_RR is not set +# CONFIG_IRDA_ULTRA is not set +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRQ_PER_CPU=y +CONFIG_IRTTY_SIR=m +CONFIG_ISCSI_TCP=m +# CONFIG_ISDN is not set +# CONFIG_ISI is not set +CONFIG_ISO9660_FS=m +# CONFIG_IWLWIFI is not set +CONFIG_IXGB=m +CONFIG_IXGBE=m +# CONFIG_IXGB_NAPI is not set +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_JFFS2_CMODE_FAVOURLZO=y +# CONFIG_JFFS2_CMODE_NONE is not set +# CONFIG_JFFS2_CMODE_PRIORITY is not set +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_LZO=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFS_DEBUG=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +CONFIG_JFS_STATISTICS=y +CONFIG_JOLIET=y +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_IFORCE=m +# CONFIG_JOYSTICK_IFORCE_232 is not set +# CONFIG_JOYSTICK_IFORCE_USB is not set +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_KARMA_PARTITION=y +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_KINGSUN_DONGLE=m +CONFIG_KMOD=y +CONFIG_KPROBES=y +CONFIG_KS0108=m +CONFIG_KS0108_DELAY=2 +CONFIG_KS0108_PORT=0x378 +CONFIG_KS959_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +CONFIG_LANMEDIA=m +# CONFIG_LAPB is not set +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_LTV350QV=m +CONFIG_LDM_DEBUG=y +CONFIG_LDM_PARTITION=y +CONFIG_LEDS_CLASS=m +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_IDE_DISK=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_LIBCRC32C=m +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_CS=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_USB=m +# CONFIG_LKDTM is not set +CONFIG_LLC=y +CONFIG_LLC2=m +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_LOCK_KERNEL=y +# CONFIG_LOGO is not set +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_LP_CONSOLE is not set +CONFIG_LXT_PHY=m +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +CONFIG_MAC80211=m +# CONFIG_MAC80211_DEBUG is not set +CONFIG_MAC80211_DEBUGFS=y +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_RCSIMPLE=y +CONFIG_MACVLAN=m +CONFIG_MAC_PARTITION=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_MARKERS is not set +CONFIG_MARVELL_PHY=m +CONFIG_MAX_RAW_DEVS=256 +CONFIG_MCS_FIR=m +CONFIG_MD=y +CONFIG_MDIO_BITBANG=m +CONFIG_MD_FAULTY=m +CONFIG_MD_LINEAR=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID5_RESHAPE=y +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_SAS=m +CONFIG_MFD_SM501=m +CONFIG_MIGRATION=y +CONFIG_MII=m +CONFIG_MINIX_FS=m +CONFIG_MINIX_SUBPARTITION=y +CONFIG_MISC_DEVICES=y +# CONFIG_MKISS is not set +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_MLX4_INFINIBAND=m +# CONFIG_MMC is not set +# CONFIG_MMTIMER is not set +CONFIG_MMU=y +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_PS2=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_PS2_TRACKPOINT=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_MOXA_INTELLIO=m +# CONFIG_MOXA_SMARTIO is not set +CONFIG_MOXA_SMARTIO_NEW=m +CONFIG_MSDOS_FS=m +CONFIG_MSDOS_PARTITION=y +CONFIG_MSPEC=m +# CONFIG_MSS is not set +CONFIG_MTD=m +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTD_ABSENT=m +CONFIG_MTD_ALAUDA=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK2MTD=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_MTD_CFI=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_CHAR=m +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_CONCAT=m +CONFIG_MTD_DATAFLASH=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_DOC2000=m +CONFIG_MTD_DOC2001=m +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCECC=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCPROBE_ADDRESS=0 +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_INTEL_VR_NOR=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_M25P80=m +CONFIG_MTD_MAP_BANK_WIDTH_1=y +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +CONFIG_MTD_MTDRAM=m +CONFIG_MTD_NAND=m +CONFIG_MTD_NAND_CAFE=m +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_NANDSIM=m +CONFIG_MTD_NAND_PLATFORM=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_ONENAND=m +CONFIG_MTD_ONENAND_2X_PROGRAM=y +# CONFIG_MTD_ONENAND_OTP is not set +CONFIG_MTD_ONENAND_SIM=m +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +CONFIG_MTD_OOPS=m +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_PCI=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PHYSMAP_LEN=0x4000000 +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PLATRAM=m +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +CONFIG_MTD_RAM=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS=m +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +CONFIG_MTD_ROM=m +CONFIG_MTD_SLRAM=m +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_DEBUG is not set +CONFIG_MTD_UBI_GLUEBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MYRI10GE=m +CONFIG_NATSEMI=m +CONFIG_NCPFS_EXTRAS=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_OS2_NS=y +CONFIG_NCPFS_PACKET_SIGNING=y +CONFIG_NCPFS_SMALLDOS=y +CONFIG_NCPFS_STRONG=y +CONFIG_NCP_FS=m +CONFIG_NE2K_PCI=m +CONFIG_NEED_MULTIPLE_NODES=y +CONFIG_NET=y +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETDEVICES=y +CONFIG_NETDEVICES_MULTIQUEUE=y +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +# CONFIG_NETLABEL is not set +CONFIG_NETPOLL=y +CONFIG_NETPOLL_TRAP=y +CONFIG_NETROM=m +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NETWORK_SECMARK=y +CONFIG_NETXEN_NIC=m +CONFIG_NET_9P=m +# CONFIG_NET_9P_DEBUG is not set +CONFIG_NET_9P_FD=m +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_FW=m +# CONFIG_NET_CLS_IND is not set +# CONFIG_NET_CLS_POLICE is not set +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_DCCPPROBE=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_ETHERNET=y +CONFIG_NET_FC=y +# CONFIG_NET_IPGRE is not set +CONFIG_NET_IPIP=m +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_NET_PCI=y +CONFIG_NET_PCMCIA=y +CONFIG_NET_PKTGEN=m +CONFIG_NET_POCKET=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_NET_SB1000=m +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_FIFO=y +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_RR=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_TCPPROBE=m +CONFIG_NET_TULIP=y +CONFIG_NET_VENDOR_3COM=y +CONFIG_NEW_LEDS=y +CONFIG_NFSD=m +CONFIG_NFSD_TCP=y +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_ENABLED=m +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_NF_CONNTRACK_SANE is not set +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_TFTP=m +# CONFIG_NIU is not set +CONFIG_NL80211=y +CONFIG_NLS=y +CONFIG_NLS_ASCII=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +CONFIG_NODES_SHIFT=8 +# CONFIG_NORTEL_HERMES is not set +CONFIG_NR_CPUS=64 +CONFIG_NR_QUICK=1 +CONFIG_NS83820=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_FS=m +# CONFIG_NTFS_RW is not set +CONFIG_NUMA=y +CONFIG_N_HDLC=m +# CONFIG_OCFS2_DEBUG_FS is not set +CONFIG_OCFS2_DEBUG_MASKLOG=y +CONFIG_OCFS2_FS=m +CONFIG_OPROFILE=m +CONFIG_OSF_PARTITION=y +CONFIG_P54_COMMON=m +CONFIG_P54_PCI=m +CONFIG_P54_USB=m +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_PARIDE=m +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_EPAT=m +CONFIG_PARIDE_EPATC8=y +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PG=m +CONFIG_PARIDE_PT=m +CONFIG_PARPORT=m +CONFIG_PARPORT_1284=y +CONFIG_PARPORT_AX88796=m +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_NOT_PC=y +CONFIG_PARPORT_PC=m +# CONFIG_PARPORT_PC_FIFO is not set +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_SERIAL=m +CONFIG_PARTITION_ADVANCED=y +CONFIG_PATA_ACPI=m +# CONFIG_PATA_ALI is not set +CONFIG_PATA_AMD=m +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +CONFIG_PATA_CS5520=m +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +CONFIG_PATA_EFAR=m +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +CONFIG_PATA_IT8213=m +CONFIG_PATA_IT821X=m +CONFIG_PATA_JMICRON=m +CONFIG_PATA_MARVELL=m +CONFIG_PATA_MPIIX=m +CONFIG_PATA_NETCELL=m +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_NS87415 is not set +CONFIG_PATA_OLDPIIX=m +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +CONFIG_PATA_PCMCIA=m +CONFIG_PATA_PDC2027X=m +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +CONFIG_PATA_RZ1000=m +# CONFIG_PATA_SC1200 is not set +CONFIG_PATA_SERVERWORKS=m +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +CONFIG_PATA_TRIFLEX=m +CONFIG_PATA_VIA=m +CONFIG_PATA_WINBOND=m +CONFIG_PC300=m +# CONFIG_PC300TOO is not set +CONFIG_PC300_MLPPP=y +CONFIG_PCCARD=m +CONFIG_PCCARD_NONSTATIC=m +CONFIG_PCI=y +CONFIG_PCI200SYN=m +CONFIG_PCIEAER=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCI_ATMEL=m +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_DOMAINS=y +# CONFIG_PCI_HERMES is not set +CONFIG_PCI_LEGACY=y +# CONFIG_PCI_MSI is not set +CONFIG_PCI_SYSCALL=y +CONFIG_PCMCIA=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_PCMCIA_AXNET=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_HERMES=m +CONFIG_PCMCIA_IOCTL=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_NETWAVE=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_RAYCS=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_SPECTRUM=m +CONFIG_PCMCIA_SYM53C500=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_WL3501=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_PCNET32=m +# CONFIG_PCNET32_NAPI is not set +CONFIG_PD6729=m +CONFIG_PDA_POWER=m +# CONFIG_PDC202XX_BURST is not set +CONFIG_PDC_ADMA=m +CONFIG_PERFMON=y +CONFIG_PGTABLE_3=y +# CONFIG_PGTABLE_4 is not set +CONFIG_PHANTOM=m +CONFIG_PHONE=m +CONFIG_PHONE_IXJ=m +CONFIG_PHONE_IXJ_PCMCIA=m +CONFIG_PHYLIB=m +# CONFIG_PID_NS is not set +CONFIG_PLIP=m +CONFIG_PLIST=y +# CONFIG_PLX_HERMES is not set +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_DISABLE_CONSOLE=y +CONFIG_PM_LEGACY=y +CONFIG_PNP=y +CONFIG_PNPACPI=y +# CONFIG_PNP_DEBUG is not set +CONFIG_POSIX_MQUEUE=y +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +CONFIG_PPDEV=m +CONFIG_PPP=m +CONFIG_PPPOE=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_SYNC_TTY=m +# CONFIG_PREEMPT is not set +CONFIG_PREEMPT_BKL=y +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_PRINTER=m +CONFIG_PRINTK=y +CONFIG_PRINTK_TIME=y +CONFIG_PRINT_QUOTA_WARNING=y +# CONFIG_PRISM54 is not set +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROFILING=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_QLA3XXX=m +CONFIG_QNX4FS_FS=m +CONFIG_QSEMI_PHY=m +CONFIG_QUICKLIST=y +CONFIG_QUOTA=y +CONFIG_QUOTACTL=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +CONFIG_R3964=m +CONFIG_R8169=m +# CONFIG_R8169_NAPI is not set +CONFIG_R8169_VLAN=y +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAESTRO=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RAID_ATTRS=m +CONFIG_RAW_DRIVER=m +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_FS=m +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_REISERFS_FS_XATTR=y +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_RELAY=y +CONFIG_RESOURCES_64BIT=y +CONFIG_RFD_FTL=m +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +CONFIG_RFKILL_LEDS=y +CONFIG_RIO=m +CONFIG_RIO_OLDPCI=y +CONFIG_ROCKETPORT=m +CONFIG_ROMFS_FS=m +CONFIG_ROSE=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_RT2400PCI=m +CONFIG_RT2400PCI_RFKILL=y +CONFIG_RT2500PCI=m +CONFIG_RT2500PCI_RFKILL=y +CONFIG_RT2500USB=m +CONFIG_RT2X00=m +# CONFIG_RT2X00_DEBUG is not set +CONFIG_RT2X00_LIB=m +# CONFIG_RT2X00_LIB_DEBUGFS is not set +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_PCI=m +CONFIG_RT2X00_LIB_RFKILL=y +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT61PCI=m +CONFIG_RT61PCI_RFKILL=y +CONFIG_RT73USB=m +CONFIG_RTC_CLASS=m +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_M41T80_WDT=y +CONFIG_RTC_DRV_M48T59=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_STK17TA8=m +CONFIG_RTC_DRV_TEST=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_LIB=m +CONFIG_RTL8187=m +CONFIG_RT_MUTEXES=y +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_RXKAD=m +CONFIG_S2IO=m +# CONFIG_S2IO_NAPI is not set +# CONFIG_SAMPLES is not set +CONFIG_SATA_AHCI=m +CONFIG_SATA_INIC162X=m +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIL24=m +CONFIG_SATA_SIS=m +CONFIG_SATA_SVW=m +CONFIG_SATA_SX4=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m +CONFIG_SC92031=m +# CONFIG_SCHEDSTATS is not set +CONFIG_SCHED_DEBUG=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +# CONFIG_SCHED_SMT is not set +CONFIG_SCSI=m +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_ADVANSYS=m +CONFIG_SCSI_AIC79XX=m +CONFIG_SCSI_AIC7XXX=m +# CONFIG_SCSI_AIC7XXX_OLD is not set +CONFIG_SCSI_AIC94XX=m +CONFIG_SCSI_ARCMSR=m +CONFIG_SCSI_ARCMSR_AER=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_DC390T=m +CONFIG_SCSI_DC395x=m +# CONFIG_SCSI_DEBUG is not set +CONFIG_SCSI_DMA=y +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_FC_TGT_ATTRS=y +# CONFIG_SCSI_FUTURE_DOMAIN is not set +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_IMM=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_DUMP is not set +# CONFIG_SCSI_IPR_TRACE is not set +CONFIG_SCSI_IPS=m +CONFIG_SCSI_ISCSI_ATTRS=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_LOWLEVEL=y +CONFIG_SCSI_LOWLEVEL_PCMCIA=y +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_NETLINK=y +CONFIG_SCSI_PPA=m +CONFIG_SCSI_PROC_FS=y +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_SAS_ATA=y +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_SRP=m +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_TGT=m +CONFIG_SCSI_WAIT_SCAN=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_MD5 is not set +CONFIG_SCTP_HMAC_NONE=y +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SECURITY=y +CONFIG_SECURITY_APPARMOR=y +CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 +# CONFIG_SECURITY_APPARMOR_DISABLE is not set +CONFIG_SECURITY_CAPABILITIES=y +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_DISABLE=y +# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_IBMPEX=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_LM93=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_TSL2550=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_CS=m +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_NR_UARTS=48 +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_PNP=y +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_SERIAL_SGI_IOC3=m +CONFIG_SERIAL_SGI_IOC4=m +CONFIG_SERIAL_SGI_L1_CONSOLE=y +CONFIG_SERIO=y +CONFIG_SERIO_I8042=m +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_PARKBD=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SERIO_RAW=m +CONFIG_SERIO_SERPORT=m +CONFIG_SGI_IOC3=m +CONFIG_SGI_IOC4=m +CONFIG_SGI_MBCS=m +CONFIG_SGI_PARTITION=y +CONFIG_SGI_SN=y +CONFIG_SGI_SNSC=y +CONFIG_SGI_TIOCX=y +CONFIG_SHAPER=m +CONFIG_SHMEM=y +CONFIG_SIGMATEL_FIR=m +CONFIG_SIGNALFD=y +CONFIG_SIS190=m +CONFIG_SIS900=m +# CONFIG_SK98LIN is not set +CONFIG_SKFP=m +CONFIG_SKGE=m +# CONFIG_SKGE_DEBUG is not set +CONFIG_SKY2=m +# CONFIG_SKY2_DEBUG is not set +# CONFIG_SLAB is not set +CONFIG_SLABINFO=y +CONFIG_SLHC=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_MODE_SLIP6=y +CONFIG_SLIP_SMART=y +# CONFIG_SLOB is not set +CONFIG_SLUB=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLUB_DEBUG_ON is not set +CONFIG_SMB_FS=m +CONFIG_SMB_NLS_DEFAULT=y +CONFIG_SMB_NLS_REMOTE="cp437" +CONFIG_SMP=y +CONFIG_SMSC_PHY=m +CONFIG_SOLARIS_X86_PARTITION=y +# CONFIG_SOUND is not set +# CONFIG_SPARSEMEM_MANUAL is not set +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +# CONFIG_SPECIALIX is not set +CONFIG_SPI=y +CONFIG_SPI_AT25=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_LM70_LLP=m +CONFIG_SPI_MASTER=y +CONFIG_SPI_SPIDEV=m +CONFIG_SPI_TLE62X0=m +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_SSB=m +CONFIG_SSB_DEBUG=y +CONFIG_SSB_DRIVER_PCICORE=y +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +# CONFIG_SSB_PCMCIAHOST is not set +CONFIG_SSB_PCMCIAHOST_POSSIBLE=y +CONFIG_SSB_POSSIBLE=y +CONFIG_SSFDC=m +CONFIG_STALDRV=y +CONFIG_STANDALONE=y +CONFIG_STOP_MACHINE=y +CONFIG_STRIP=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +# CONFIG_SUNGEM is not set +CONFIG_SUNRPC=m +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_SUNRPC_GSS=m +CONFIG_SUNRPC_XPRT_RDMA=m +CONFIG_SUN_PARTITION=y +CONFIG_SWAP=y +CONFIG_SWIOTLB=y +# CONFIG_SX is not set +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_CS=m +CONFIG_SYNCLINK_GT=m +CONFIG_SYN_COOKIES=y +CONFIG_SYSCTL=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSFS=y +# CONFIG_SYSFS_DEPRECATED is not set +CONFIG_SYSV68_PARTITION=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_SYSV_FS=m +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +CONFIG_TASKSTATS=y +# CONFIG_TASK_DELAY_ACCT is not set +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_TASK_XACCT=y +CONFIG_TCG_ATMEL=m +CONFIG_TCG_INFINEON=m +CONFIG_TCG_NSC=m +CONFIG_TCG_TIS=m +CONFIG_TCG_TPM=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_MD5SIG=y +CONFIG_TEHUTI=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TIFM_7XX1=m +CONFIG_TIFM_CORE=m +CONFIG_TIGON3=m +CONFIG_TIMER_STATS=y +# CONFIG_TINY_SHMEM is not set +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +# CONFIG_TMD_HERMES is not set +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +# CONFIG_TMS380TR is not set +CONFIG_TR=y +CONFIG_TULIP=m +# CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_NAPI is not set +CONFIG_TUN=m +CONFIG_TUNER_3036=m +CONFIG_TUNER_MT20XX=m +CONFIG_TUNER_SIMPLE=m +CONFIG_TUNER_TDA8290=m +CONFIG_TUNER_TEA5761=m +CONFIG_TUNER_TEA5767=m +CONFIG_TYPHOON=m +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_UFS_DEBUG is not set +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +CONFIG_UIO=m +CONFIG_UIO_CIF=m +CONFIG_ULI526X=m +CONFIG_ULTRIX_PARTITION=y +CONFIG_UNIX=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_USB=m +CONFIG_USB_ACM=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_AUERSWALD=m +CONFIG_USB_BELKIN=y +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_CATC=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_DABUSB=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +CONFIG_USB_DSBR=m +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EMI26=m +CONFIG_USB_EMI62=m +CONFIG_USB_EPSON2888=y +CONFIG_USB_ET61X251=m +CONFIG_USB_EZUSB=y +CONFIG_USB_FTDI_ELAN=m +# CONFIG_USB_GADGET is not set +CONFIG_USB_HID=m +CONFIG_USB_HIDDEV=y +CONFIG_USB_HIDINPUT_POWERBOOK=y +CONFIG_USB_IBMCAM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_IRDA=m +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_KAWETH=m +CONFIG_USB_KBD=m +CONFIG_USB_KC2190=y +CONFIG_USB_KONICAWC=m +CONFIG_USB_LCD=m +CONFIG_USB_LD=m +CONFIG_USB_LED=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LIBUSUAL=y +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_MON=y +CONFIG_USB_MOUSE=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_HCD_SSB is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OV511 is not set +CONFIG_USB_PEGASUS=m +# CONFIG_USB_PERSIST is not set +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_PRINTER=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_R8A66597_HCD=m +CONFIG_USB_RIO500=m +CONFIG_USB_RTL8150=m +CONFIG_USB_SE401=m +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_AIRPRIME=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IPW=m +# CONFIG_USB_SERIAL_IR is not set +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SISUSBVGA=m +# CONFIG_USB_SISUSBVGA_CON is not set +CONFIG_USB_SL811_CS=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SN9C102=m +CONFIG_USB_STORAGE=m +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_DATAFAB=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STV680=m +CONFIG_USB_SUPPORT=y +CONFIG_USB_SUSPEND=y +# CONFIG_USB_TEST is not set +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_UHCI_HCD=m +CONFIG_USB_USBNET=m +CONFIG_USB_USS720=m +CONFIG_USB_VICAM=m +CONFIG_USB_W9968CF=m +CONFIG_USB_ZC0301=m +CONFIG_USB_ZD1201=m +CONFIG_USB_ZR364XX=m +# CONFIG_USER_NS is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VERSION_SIGNATURE="Unofficial" +CONFIG_VETH=m +CONFIG_VFAT_FS=m +# CONFIG_VGACON_SOFT_SCROLLBACK is not set +CONFIG_VGASTATE=m +CONFIG_VGA_CONSOLE=y +CONFIG_VIA_RHINE=m +CONFIG_VIA_RHINE_MMIO=y +CONFIG_VIA_RHINE_NAPI=y +CONFIG_VIA_VELOCITY=m +CONFIG_VIDEOBUF_DMA_SG=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CAFE_CCIC=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_CPIA_PP=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_CX23885=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_DEV=m +# CONFIG_VIDEO_DPC is not set +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_FB_IVTV=m +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_MSP3400=m +# CONFIG_VIDEO_MXB is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_24XXX=y +CONFIG_VIDEO_PVRUSB2_29XXX=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA7111=m +CONFIG_VIDEO_SAA7114=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_SAA7191=m +CONFIG_VIDEO_STRADIS=m +CONFIG_VIDEO_TCM825X=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TDA9875=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_TLV320AIC23B=m +CONFIG_VIDEO_TUNER=m +# CONFIG_VIDEO_TUNER_CUSTOMIZE is not set +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_USBVIDEO=m +# CONFIG_VIDEO_USBVISION is not set +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_VP27SMPX=m +CONFIG_VIDEO_VPX3220=m +CONFIG_VIDEO_W9966=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VIRTUAL_MEM_MAP=y +CONFIG_VIRT_TO_BUS=y +CONFIG_VITESSE_PHY=m +CONFIG_VLAN_8021Q=m +# CONFIG_VLSI_FIR is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VORTEX=m +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_VXFS_FS=m +CONFIG_W1=m +CONFIG_W1_CON=y +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_DS2760=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_THERM=m +CONFIG_WAN=y +CONFIG_WANXL=m +CONFIG_WAN_ROUTER=m +CONFIG_WAN_ROUTER_DRIVERS=m +# CONFIG_WATCHDOG is not set +CONFIG_WDC_ALI15X3=y +CONFIG_WINBOND_840=m +CONFIG_WIRELESS_EXT=y +CONFIG_WLAN_80211=y +CONFIG_WLAN_PRE80211=y +# CONFIG_X25 is not set +CONFIG_XFRM=y +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_XFRM_USER=m +CONFIG_XFS_FS=m +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_QUOTA=y +# CONFIG_XFS_RT is not set +CONFIG_XFS_SECURITY=y +CONFIG_XOR_BLOCKS=m +CONFIG_YAM=m +CONFIG_YELLOWFIN=m +CONFIG_YENTA=m +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_ZISOFS=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZONE_DMA=y +CONFIG_ZONE_DMA_FLAG=1 --- linux-2.6.24.orig/debian/config/ia64/config.mckinley +++ linux-2.6.24/debian/config/ia64/config.mckinley @@ -0,0 +1,6 @@ +# +# Config options for config.mckinley automatically generated by splitconfig.pl +# +CONFIG_IA64_L1_CACHE_SHIFT=7 +# CONFIG_ITANIUM is not set +CONFIG_MCKINLEY=y --- linux-2.6.24.orig/debian/config/ia64/config.itanium +++ linux-2.6.24/debian/config/ia64/config.itanium @@ -0,0 +1,7 @@ +# +# Config options for config.itanium automatically generated by splitconfig.pl +# +CONFIG_IA64_BRL_EMU=y +CONFIG_IA64_L1_CACHE_SHIFT=6 +CONFIG_ITANIUM=y +# CONFIG_MCKINLEY is not set --- linux-2.6.24.orig/debian/config/sparc/config.sparc64-smp +++ linux-2.6.24/debian/config/sparc/config.sparc64-smp @@ -0,0 +1,16 @@ +# +# Config options for config.sparc64-smp automatically generated by splitconfig.pl +# +CONFIG_CPUSETS=y +CONFIG_HOTPLUG_CPU=y +CONFIG_LOCK_KERNEL=y +CONFIG_NR_CPUS=256 +CONFIG_PATA_CMD640_PCI=m +# CONFIG_PREEMPT_BKL is not set +CONFIG_PROC_PID_CPUSET=y +CONFIG_RIO=m +CONFIG_RIO_OLDPCI=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_SMT=y +CONFIG_SMP=y +CONFIG_STOP_MACHINE=y --- linux-2.6.24.orig/debian/config/sparc/config +++ linux-2.6.24/debian/config/sparc/config @@ -0,0 +1,2078 @@ +# +# Common config options automatically generated by splitconfig.pl +# +CONFIG_64BIT=y +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_8129=y +CONFIG_8139TOO_PIO=y +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_9P_FS=m +CONFIG_AC97_BUS=m +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +# CONFIG_ACORN_PARTITION is not set +CONFIG_ADAPTEC_STARFIRE=m +CONFIG_ADAPTEC_STARFIRE_NAPI=y +# CONFIG_ADFS_FS is not set +CONFIG_ADM8211=m +CONFIG_AFFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_AFS_FS=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +# CONFIG_AIC79XX_DEBUG_ENABLE is not set +CONFIG_AIC79XX_DEBUG_MASK=0 +# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +# CONFIG_AIC94XX_DEBUG is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_AMIGA_PARTITION is not set +CONFIG_ANON_INODES=y +CONFIG_APPLICOM=m +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_ARCH_NO_VIRT_TO_BUS=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_ARCNET is not set +CONFIG_ARPD=y +CONFIG_ASK_IP_FIB_HASH=y +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_ATA=m +CONFIG_ATALK=m +# CONFIG_ATARI_PARTITION is not set +CONFIG_ATA_GENERIC=m +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_OVER_ETH=m +CONFIG_ATA_PIIX=m +CONFIG_ATL1=m +# CONFIG_ATM is not set +CONFIG_ATMEL=m +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y +CONFIG_AUDIT_ARCH=y +CONFIG_AUDIT_TREE=y +CONFIG_AUTOFS4_FS=m +CONFIG_AUTOFS_FS=m +CONFIG_AUXDISPLAY=y +CONFIG_B43=m +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_DEBUG=y +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y +CONFIG_B43LEGACY_PCI_AUTOSELECT=y +CONFIG_B43LEGACY_PIO=y +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_B43_DEBUG=y +CONFIG_B43_DMA=y +CONFIG_B43_DMA_AND_PIO_MODE=y +# CONFIG_B43_DMA_MODE is not set +CONFIG_B43_LEDS=y +CONFIG_B43_PCICORE_AUTOSELECT=y +CONFIG_B43_PCI_AUTOSELECT=y +CONFIG_B43_PIO=y +# CONFIG_B43_PIO_MODE is not set +CONFIG_B43_RFKILL=y +# CONFIG_B44 is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_CORGI=m +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BASE_FULL=y +CONFIG_BASE_SMALL=0 +CONFIG_BATTERY_DS2760=m +CONFIG_BBC_I2C=m +CONFIG_BCM43XX=m +# CONFIG_BCM43XX_DEBUG is not set +CONFIG_BCM43XX_DMA=y +CONFIG_BCM43XX_DMA_AND_PIO_MODE=y +# CONFIG_BCM43XX_DMA_MODE is not set +CONFIG_BCM43XX_PIO=y +# CONFIG_BCM43XX_PIO_MODE is not set +# CONFIG_BEFS_DEBUG is not set +CONFIG_BEFS_FS=m +CONFIG_BFS_FS=m +# CONFIG_BINFMT_AOUT32 is not set +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_ELF32=y +CONFIG_BINFMT_MISC=m +CONFIG_BITREVERSE=y +# CONFIG_BLK_CPQ_CISS_DA is not set +CONFIG_BLK_DEV=y +CONFIG_BLK_DEV_3W_XXXX_RAID=m +# CONFIG_BLK_DEV_AEC62XX is not set +CONFIG_BLK_DEV_ALI15X3=m +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_BLK_DEV_BSG is not set +CONFIG_BLK_DEV_CMD64X=m +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_CS5520 is not set +CONFIG_BLK_DEV_CS5530=m +CONFIG_BLK_DEV_CY82C693=m +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_DM=m +CONFIG_BLK_DEV_FD=y +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_BLK_DEV_HD is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_BLK_DEV_HPT366 is not set +CONFIG_BLK_DEV_IDE=m +CONFIG_BLK_DEV_IDECD=m +CONFIG_BLK_DEV_IDEDISK=m +CONFIG_BLK_DEV_IDEDMA=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_IDEFLOPPY=m +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_BLK_DEV_IDESCSI is not set +CONFIG_BLK_DEV_IDETAPE=m +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_JMICRON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_MD=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_NS87415=m +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +CONFIG_BLK_DEV_PDC202XX_OLD=m +# CONFIG_BLK_DEV_PIIX is not set +CONFIG_BLK_DEV_PLATFORM=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +# CONFIG_BLK_DEV_SC1200 is not set +CONFIG_BLK_DEV_SD=m +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +CONFIG_BLK_DEV_SR=m +CONFIG_BLK_DEV_SR_VENDOR=y +# CONFIG_BLK_DEV_SVWKS is not set +CONFIG_BLK_DEV_SX8=m +CONFIG_BLK_DEV_TC86C001=m +# CONFIG_BLK_DEV_TRIFLEX is not set +CONFIG_BLK_DEV_TRM290=m +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_BLOCK=y +CONFIG_BLOCK_COMPAT=y +CONFIG_BNX2=m +CONFIG_BONDING=m +# CONFIG_BOOT_PRINTK_DELAY is not set +CONFIG_BRIDGE=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_NETFILTER=y +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BROADCOM_PHY=m +# CONFIG_BSD_DISKLABEL is not set +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_BT is not set +CONFIG_BUG=y +CONFIG_CASSINI=m +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_CFG80211=m +CONFIG_CGROUPS=y +CONFIG_CGROUP_CPUACCT=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_NS=y +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T1_NAPI=y +CONFIG_CHELSIO_T3=m +CONFIG_CHR_DEV_OSST=m +# CONFIG_CHR_DEV_SCH is not set +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_ST=m +CONFIG_CICADA_PHY=m +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG2 is not set +CONFIG_CIFS_EXPERIMENTAL=y +# CONFIG_CIFS_STATS is not set +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_WEAK_PW_HASH=y +# CONFIG_CIFS_XATTR is not set +CONFIG_CLS_U32_MARK=y +# CONFIG_CLS_U32_PERF is not set +# CONFIG_CMDLINE_BOOL is not set +CONFIG_CODA_FS=m +# CONFIG_CODA_FS_OLD_API is not set +CONFIG_COMPAT=y +CONFIG_COMPUTONE=m +CONFIG_CONFIGFS_FS=m +CONFIG_CONNECTOR=m +# CONFIG_CPU_FREQ is not set +CONFIG_CRAMFS=y +CONFIG_CRC16=m +CONFIG_CRC32=y +CONFIG_CRC7=m +CONFIG_CRC_CCITT=m +CONFIG_CRC_ITU_T=m +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ABLKCIPHER=m +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TEA=m +# CONFIG_CRYPTO_TEST is not set +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_XTS=m +CONFIG_CYCLADES=m +# CONFIG_CYZ_INTR is not set +CONFIG_DAB=y +CONFIG_DAVICOM_PHY=m +# CONFIG_DE2104X is not set +# CONFIG_DE4X5 is not set +CONFIG_DE600=m +CONFIG_DE620=m +# CONFIG_DEBUG_BOOTMEM is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_DCFLUSH is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_DRIVER is not set +CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_DEBUG_MUTEXES is not set +CONFIG_DEBUG_RODATA=y +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_VM is not set +CONFIG_DECNET=m +CONFIG_DECNET_NF_GRABULATOR=m +CONFIG_DECNET_ROUTER=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_BIC is not set +CONFIG_DEFAULT_CFQ=y +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_HTCP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_RELATIME=y +CONFIG_DEFAULT_RELATIME_VAL=1 +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_WESTWOOD is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +# CONFIG_DEFXX is not set +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_DEVPORT=y +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DEV_KMEM is not set +CONFIG_DIGIEPCA=m +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_DISPLAY7SEG=m +CONFIG_DISPLAY_SUPPORT=m +CONFIG_DL2K=m +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +# CONFIG_DM9102 is not set +CONFIG_DM_CRYPT=m +# CONFIG_DM_DEBUG is not set +# CONFIG_DM_DELAY is not set +CONFIG_DM_MIRROR=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_EMC=m +CONFIG_DM_MULTIPATH_HP=m +CONFIG_DM_MULTIPATH_RDAC=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_UEVENT=y +CONFIG_DM_ZERO=m +CONFIG_DNOTIFY=y +CONFIG_DRM=y +CONFIG_DRM_MGA=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_SAVAGE=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_VIA=m +CONFIG_DRM_VIA_CHROME9=n +CONFIG_DS1682=m +CONFIG_DUMMY=m +CONFIG_DUMMY_CONSOLE=y +# CONFIG_DVB_CORE is not set +CONFIG_E100=m +CONFIG_E1000=m +CONFIG_E1000E=m +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +CONFIG_E1000_NAPI=y +# CONFIG_ECONET is not set +CONFIG_ECRYPT_FS=m +# CONFIG_EEPRO100 is not set +CONFIG_EEPROM_93CX6=m +# CONFIG_EFI_PARTITION is not set +CONFIG_EFS_FS=m +CONFIG_ELF_CORE=y +# CONFIG_EMBEDDED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +CONFIG_ENVCTRL=m +CONFIG_EPIC100=m +CONFIG_EPOLL=y +CONFIG_EQUALIZER=m +CONFIG_EVENTFD=y +CONFIG_EXPERIMENTAL=y +CONFIG_EXPORTFS=m +CONFIG_EXT2_FS=m +CONFIG_EXT2_FS_POSIX_ACL=y +# CONFIG_EXT2_FS_SECURITY is not set +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_POSIX_ACL=y +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT4DEV_FS is not set +CONFIG_FAIR_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_FAIR_USER_SCHED is not set +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_FAT_FS=m +# CONFIG_FAULT_INJECTION is not set +CONFIG_FB=y +# CONFIG_FB_3DFX is not set +CONFIG_FB_ARK=m +# CONFIG_FB_ASILIANT is not set +CONFIG_FB_ATY=y +CONFIG_FB_ATY128=y +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY_BACKLIGHT=y +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_BACKLIGHT=y +# CONFIG_FB_BW2 is not set +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_CG14 is not set +# CONFIG_FB_CG3 is not set +CONFIG_FB_CG6=y +# CONFIG_FB_CIRRUS is not set +CONFIG_FB_DDC=y +CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_FFB=y +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_LEO is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_MATROX is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_NEOMAGIC is not set +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_BACKLIGHT=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_I2C=y +# CONFIG_FB_P9100 is not set +CONFIG_FB_PM2=y +# CONFIG_FB_PM2_FIFO_DISCONNECT is not set +CONFIG_FB_PM3=m +CONFIG_FB_RADEON=y +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_RADEON_I2C=y +# CONFIG_FB_RIVA is not set +CONFIG_FB_S1D13XXX=m +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_ACCEL=y +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SBUS=y +# CONFIG_FB_SIS is not set +CONFIG_FB_SM501=m +CONFIG_FB_SVGALIB=m +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_TCX is not set +CONFIG_FB_TILEBLITTING=y +# CONFIG_FB_TRIDENT is not set +CONFIG_FB_UVESA=m +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_VOODOO1 is not set +CONFIG_FB_VT8623=m +CONFIG_FB_XVR2500=y +CONFIG_FB_XVR500=y +CONFIG_FDDI=y +CONFIG_FEALNX=m +CONFIG_FIB_RULES=y +# CONFIG_FIREWIRE is not set +CONFIG_FIRMWARE_EDID=y +CONFIG_FIXED_MII_1000_FDX=y +# CONFIG_FIXED_MII_100_FDX is not set +# CONFIG_FIXED_MII_10_FDX is not set +CONFIG_FIXED_MII_AMNT=1 +CONFIG_FIXED_PHY=m +# CONFIG_FLATMEM_MANUAL is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x16=y +# CONFIG_FONT_SUN12x22 is not set +CONFIG_FONT_SUN8x16=y +# CONFIG_FORCEDETH is not set +# CONFIG_FORCED_INLINING is not set +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FS_MBCACHE=m +CONFIG_FS_POSIX_ACL=y +CONFIG_FUSE_FS=m +CONFIG_FUSION=y +CONFIG_FUSION_CTL=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_LAN=m +CONFIG_FUSION_LOGGING=y +CONFIG_FUSION_MAX_SGE=40 +CONFIG_FUSION_SAS=m +CONFIG_FUSION_SPI=m +CONFIG_FUTEX=y +CONFIG_FW_LOADER=y +CONFIG_GACT_PROB=y +# CONFIG_GAMEPORT is not set +CONFIG_GENERIC_ACL=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_TIME=y +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=m +CONFIG_GFS2_FS_LOCKING_NOLOCK=m +# CONFIG_HAMACHI is not set +# CONFIG_HAMRADIO is not set +CONFIG_HAPPYMEAL=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAVE_MEMORY_PRESENT=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_HERMES=m +CONFIG_HFSPLUS_FS=m +CONFIG_HFS_FS=m +CONFIG_HID=m +CONFIG_HIDRAW=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HID_FF is not set +CONFIG_HID_SUPPORT=y +CONFIG_HIGH_RES_TIMERS=y +# CONFIG_HIPPI is not set +CONFIG_HOSTAP=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_PLX=m +CONFIG_HOTPLUG=y +# CONFIG_HP100 is not set +CONFIG_HPFS_FS=m +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_HUGETLB_PAGE_SIZE_4MB=y +# CONFIG_HUGETLB_PAGE_SIZE_512K is not set +# CONFIG_HUGETLB_PAGE_SIZE_64K is not set +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HWMON_VID=m +CONFIG_HW_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +CONFIG_I2C=y +CONFIG_I2C_ALGOBIT=y +CONFIG_I2C_ALGOPCA=m +CONFIG_I2C_ALGOPCF=m +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_NFORCE2 is not set +CONFIG_I2C_OCORES=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PIIX4=m +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +CONFIG_I2C_SIMTEC=m +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +CONFIG_I2C_STUB=m +CONFIG_I2C_TAOS_EVM=m +CONFIG_I2C_TINY_USB=m +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_BUS=m +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_EXT_ADAPTEC_DMA64=y +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_PROC=m +CONFIG_I2O_SCSI=m +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +CONFIG_ICPLUS_PHY=m +CONFIG_IDE=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +# CONFIG_IDEPCI_SHARE_IRQ is not set +CONFIG_IDE_ARCH_OBSOLETE_INIT=y +# CONFIG_IDE_ARM is not set +CONFIG_IDE_GENERIC=m +CONFIG_IDE_PROC_FS=y +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IEEE1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_OHCI1394=m +CONFIG_IEEE1394_PCILYNX=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE80211=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_CRYPT_WEP=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_IFB=m +# CONFIG_IKCONFIG is not set +CONFIG_INET=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET_AH=m +CONFIG_INET_DCCP_DIAG=m +CONFIG_INET_DIAG=y +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_LRO=m +CONFIG_INET_TCP_DIAG=y +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_AMSO1100=m +CONFIG_INFINIBAND_AMSO1100_DEBUG=y +CONFIG_INFINIBAND_CXGB3=m +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_IPOIB_DEBUG=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set +CONFIG_INFINIBAND_ISER=m +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_INPUT=y +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +# CONFIG_INPUT_EVBUG is not set +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_JOYSTICK is not set +CONFIG_INPUT_KEYBOARD=y +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_SPARCSPKR=y +CONFIG_INPUT_TABLET=y +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_UINPUT is not set +CONFIG_INPUT_YEALINK=m +CONFIG_INSTRUMENTATION=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_CFQ=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IP1000=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_POWEROFF is not set +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPV6=m +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_IPV6_SIT=m +CONFIG_IPV6_TUNNEL=m +CONFIG_IPW2100=m +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +# CONFIG_IPW2200_DEBUG is not set +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_DCCP=m +CONFIG_IP_DCCP_ACKVEC=y +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_IP_DCCP_TFRC_LIB=m +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +# CONFIG_IP_MROUTE is not set +CONFIG_IP_MULTICAST=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_RARP=y +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IP_SCTP=m +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_TAB_BITS=12 +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_WRR=m +# CONFIG_IRDA is not set +CONFIG_ISCSI_TCP=m +# CONFIG_ISDN is not set +# CONFIG_ISI is not set +CONFIG_ISO9660_FS=m +# CONFIG_IWLWIFI is not set +CONFIG_IXGB=m +CONFIG_IXGBE=m +CONFIG_IXGB_NAPI=y +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +# CONFIG_JFS_FS is not set +CONFIG_JOLIET=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_KARMA_PARTITION=y +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_LKKBD=m +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_KEYBOARD_SUNKBD=y +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_KMOD=y +CONFIG_KPROBES=y +CONFIG_KS0108=m +CONFIG_KS0108_DELAY=2 +CONFIG_KS0108_PORT=0x378 +# CONFIG_LAPB is not set +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_LTV350QV=m +# CONFIG_LDM_PARTITION is not set +CONFIG_LEDS_CLASS=m +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_IDE_DISK=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_LIBCRC32C=m +CONFIG_LIBERTAS=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_SDIO=m +CONFIG_LIBERTAS_USB=m +# CONFIG_LKDTM is not set +CONFIG_LLC=m +CONFIG_LLC2=m +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_LOCKD=m +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_LOCKD_V4=y +# CONFIG_LOCK_STAT is not set +# CONFIG_LOGO is not set +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_LP_CONSOLE is not set +CONFIG_LXT_PHY=m +CONFIG_MAC80211=m +# CONFIG_MAC80211_DEBUG is not set +CONFIG_MAC80211_DEBUGFS=y +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_RCSIMPLE=y +CONFIG_MACVLAN=m +# CONFIG_MAC_PARTITION is not set +CONFIG_MAGIC_SYSRQ=y +# CONFIG_MARKERS is not set +CONFIG_MARVELL_PHY=m +CONFIG_MAX_RAW_DEVS=256 +CONFIG_MD=y +CONFIG_MDIO_BITBANG=m +CONFIG_MD_FAULTY=m +CONFIG_MD_LINEAR=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID5_RESHAPE=y +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_SAS=m +CONFIG_MFD_SM501=m +CONFIG_MII=m +CONFIG_MINIX_FS=m +# CONFIG_MINIX_SUBPARTITION is not set +CONFIG_MISC_DEVICES=y +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_MLX4_INFINIBAND=m +CONFIG_MMC=m +CONFIG_MMC_BLOCK=m +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_RICOH_MMC=m +CONFIG_MMC_SDHCI=m +CONFIG_MMC_SPI=m +CONFIG_MMC_TIFM_SD=m +# CONFIG_MMC_UNSAFE_RESUME is not set +CONFIG_MMU=y +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_PS2_TRACKPOINT=y +CONFIG_MOUSE_SERIAL=y +# CONFIG_MOUSE_VSXXXAA is not set +CONFIG_MOXA_INTELLIO=m +# CONFIG_MOXA_SMARTIO is not set +CONFIG_MOXA_SMARTIO_NEW=m +CONFIG_MSDOS_FS=m +CONFIG_MSDOS_PARTITION=y +CONFIG_MSNDCLAS_INIT_FILE="/etc/sound/msndinit.bin" +CONFIG_MSNDCLAS_PERM_FILE="/etc/sound/msndperm.bin" +CONFIG_MSNDPIN_INIT_FILE="/etc/sound/pndspini.bin" +CONFIG_MSNDPIN_PERM_FILE="/etc/sound/pndsperm.bin" +# CONFIG_MSS is not set +# CONFIG_MTD is not set +CONFIG_MYRI10GE=m +CONFIG_MYRI_SBUS=m +CONFIG_NATSEMI=m +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +CONFIG_NCPFS_NFS_NS=y +# CONFIG_NCPFS_NLS is not set +CONFIG_NCPFS_OS2_NS=y +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_STRONG is not set +CONFIG_NCP_FS=m +CONFIG_NE2K_PCI=m +CONFIG_NET=y +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETDEVICES=y +CONFIG_NETDEVICES_MULTIQUEUE=y +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +# CONFIG_NETLABEL is not set +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NETWORK_SECMARK=y +CONFIG_NETXEN_NIC=m +CONFIG_NET_9P=m +# CONFIG_NET_9P_DEBUG is not set +CONFIG_NET_9P_FD=m +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_FW=m +# CONFIG_NET_CLS_IND is not set +# CONFIG_NET_CLS_POLICE is not set +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_DCCPPROBE=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_ETHERNET=y +CONFIG_NET_FC=y +# CONFIG_NET_IPGRE is not set +CONFIG_NET_IPIP=m +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_NET_PCI=y +# CONFIG_NET_PKTGEN is not set +CONFIG_NET_POCKET=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_FIFO=y +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_RR=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_TCPPROBE=m +CONFIG_NET_TULIP=y +CONFIG_NET_VENDOR_3COM=y +CONFIG_NEW_LEDS=y +CONFIG_NFSD=m +CONFIG_NFSD_TCP=y +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_ENABLED=m +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_NF_CONNTRACK_SANE is not set +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NIU=m +CONFIG_NL80211=y +CONFIG_NLS=y +CONFIG_NLS_ASCII=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +# CONFIG_NORTEL_HERMES is not set +CONFIG_NO_HZ=y +CONFIG_NR_QUICK=1 +CONFIG_NS83820=m +# CONFIG_NTFS_FS is not set +CONFIG_N_HDLC=m +CONFIG_OBP_FLASH=m +# CONFIG_OCFS2_DEBUG_FS is not set +CONFIG_OCFS2_DEBUG_MASKLOG=y +CONFIG_OCFS2_FS=m +CONFIG_OF=y +CONFIG_OF_DEVICE=y +# CONFIG_OSF_PARTITION is not set +CONFIG_P54_COMMON=m +CONFIG_P54_PCI=m +CONFIG_P54_USB=m +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_PARIDE is not set +CONFIG_PARPORT=m +CONFIG_PARPORT_1284=y +CONFIG_PARPORT_AX88796=m +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_NOT_PC=y +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_FIFO=y +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_SUNBPP=m +CONFIG_PARTITION_ADVANCED=y +# CONFIG_PATA_ALI is not set +CONFIG_PATA_AMD=m +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD64X is not set +CONFIG_PATA_CS5520=m +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +CONFIG_PATA_EFAR=m +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +CONFIG_PATA_IT8213=m +CONFIG_PATA_IT821X=m +CONFIG_PATA_JMICRON=m +CONFIG_PATA_MARVELL=m +CONFIG_PATA_MPIIX=m +CONFIG_PATA_NETCELL=m +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_NS87415 is not set +CONFIG_PATA_OLDPIIX=m +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +CONFIG_PATA_PDC2027X=m +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +CONFIG_PATA_RZ1000=m +# CONFIG_PATA_SC1200 is not set +CONFIG_PATA_SERVERWORKS=m +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +CONFIG_PATA_TRIFLEX=m +CONFIG_PATA_VIA=m +CONFIG_PATA_WINBOND=m +CONFIG_PCI=y +CONFIG_PCI_ATMEL=m +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_DOMAINS=y +# CONFIG_PCI_HERMES is not set +CONFIG_PCI_LEGACY=y +# CONFIG_PCI_MSI is not set +CONFIG_PCI_SYSCALL=y +CONFIG_PCNET32=m +# CONFIG_PCNET32_NAPI is not set +CONFIG_PDA_POWER=m +# CONFIG_PDC202XX_BURST is not set +CONFIG_PDC_ADMA=m +CONFIG_PHANTOM=m +# CONFIG_PHONE is not set +CONFIG_PHYLIB=m +# CONFIG_PID_NS is not set +CONFIG_PLIP=m +CONFIG_PLIST=y +# CONFIG_PLX_HERMES is not set +CONFIG_POSIX_MQUEUE=y +CONFIG_POWER_SUPPLY=m +# CONFIG_POWER_SUPPLY_DEBUG is not set +CONFIG_PPDEV=m +CONFIG_PPP=m +CONFIG_PPPOE=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_SYNC_TTY=m +# CONFIG_PREEMPT is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_PRINTER=m +CONFIG_PRINTK=y +CONFIG_PRINTK_TIME=y +CONFIG_PRINT_QUOTA_WARNING=y +# CONFIG_PRISM54 is not set +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +# CONFIG_PROFILING is not set +CONFIG_PROM_CONSOLE=y +# CONFIG_PROVE_LOCKING is not set +# CONFIG_QFMT_V1 is not set +CONFIG_QFMT_V2=m +CONFIG_QLA3XXX=m +# CONFIG_QNX4FS_FS is not set +CONFIG_QSEMI_PHY=m +CONFIG_QUICKLIST=y +CONFIG_QUOTA=y +CONFIG_QUOTACTL=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +CONFIG_R3964=m +# CONFIG_R8169 is not set +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAESTRO=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RAID_ATTRS=m +CONFIG_RAW_DRIVER=m +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_FS=m +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_REISERFS_FS_XATTR=y +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_RELAY=y +CONFIG_RESOURCES_64BIT=y +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +CONFIG_RFKILL_LEDS=y +CONFIG_ROCKETPORT=m +CONFIG_ROMFS_FS=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_RT2400PCI=m +CONFIG_RT2400PCI_RFKILL=y +CONFIG_RT2500PCI=m +CONFIG_RT2500PCI_RFKILL=y +CONFIG_RT2500USB=m +CONFIG_RT2X00=m +# CONFIG_RT2X00_DEBUG is not set +CONFIG_RT2X00_LIB=m +# CONFIG_RT2X00_LIB_DEBUGFS is not set +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_PCI=m +CONFIG_RT2X00_LIB_RFKILL=y +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT61PCI=m +CONFIG_RT61PCI_RFKILL=y +CONFIG_RT73USB=m +CONFIG_RTC_CLASS=m +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_M41T80_WDT=y +CONFIG_RTC_DRV_M48T59=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_STK17TA8=m +CONFIG_RTC_DRV_TEST=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_LIB=m +CONFIG_RTL8187=m +CONFIG_RT_MUTEXES=y +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_RXKAD=m +CONFIG_S2IO=m +CONFIG_S2IO_NAPI=y +# CONFIG_SAMPLES is not set +CONFIG_SATA_AHCI=m +CONFIG_SATA_INIC162X=m +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIL24=m +CONFIG_SATA_SIS=m +CONFIG_SATA_SVW=m +CONFIG_SATA_SX4=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m +CONFIG_SBUS=y +CONFIG_SBUSCHAR=y +CONFIG_SC92031=m +# CONFIG_SCHEDSTATS is not set +CONFIG_SCHED_DEBUG=y +CONFIG_SCSI=m +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AIC79XX=m +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +CONFIG_SCSI_AIC94XX=m +CONFIG_SCSI_ARCMSR=m +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_DC390T is not set +CONFIG_SCSI_DC395x=m +# CONFIG_SCSI_DEBUG is not set +CONFIG_SCSI_DMA=y +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_FC_TGT_ATTRS=y +# CONFIG_SCSI_FUTURE_DOMAIN is not set +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_IMM=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_DUMP is not set +# CONFIG_SCSI_IPR_TRACE is not set +# CONFIG_SCSI_IPS is not set +CONFIG_SCSI_ISCSI_ATTRS=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +# CONFIG_SCSI_LOGGING is not set +CONFIG_SCSI_LOWLEVEL=y +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_NETLINK=y +CONFIG_SCSI_PPA=m +CONFIG_SCSI_PROC_FS=y +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_QLOGICPTI=m +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_SAS_ATA=y +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_SRP=m +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SUNESP=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_TGT=m +CONFIG_SCSI_WAIT_SCAN=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_HMAC_MD5=y +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SDIO_UART=m +CONFIG_SECCOMP=y +CONFIG_SECURITY=y +CONFIG_SECURITY_APPARMOR=y +CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 +# CONFIG_SECURITY_APPARMOR_DISABLE is not set +CONFIG_SECURITY_CAPABILITIES=y +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +# CONFIG_SECURITY_ROOTPLUG is not set +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_DISABLE=y +# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SENSORS_AD7418=m +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +# CONFIG_SENSORS_ADM1031 is not set +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_EEPROM is not set +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +# CONFIG_SENSORS_GL518SM is not set +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_IBMPEX=m +# CONFIG_SENSORS_IT87 is not set +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +CONFIG_SENSORS_LM87=m +# CONFIG_SENSORS_LM90 is not set +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_LM93=m +# CONFIG_SENSORS_MAX1619 is not set +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCA9539=m +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_TSL2550=m +# CONFIG_SENSORS_VIA686A is not set +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83627EHF=m +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83781D is not set +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +# CONFIG_SENSORS_W83L785TS is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_SERIAL_SUNCORE=y +CONFIG_SERIAL_SUNHV=y +CONFIG_SERIAL_SUNSAB=y +CONFIG_SERIAL_SUNSAB_CONSOLE=y +CONFIG_SERIAL_SUNSU=y +CONFIG_SERIAL_SUNSU_CONSOLE=y +CONFIG_SERIAL_SUNZILOG=y +CONFIG_SERIAL_SUNZILOG_CONSOLE=y +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_PARKBD is not set +CONFIG_SERIO_PCIPS2=y +CONFIG_SERIO_RAW=m +CONFIG_SERIO_SERPORT=m +CONFIG_SGI_IOC4=m +# CONFIG_SGI_PARTITION is not set +CONFIG_SHAPER=m +CONFIG_SHMEM=y +CONFIG_SIGNALFD=y +CONFIG_SIS190=m +CONFIG_SIS900=m +# CONFIG_SK98LIN is not set +CONFIG_SKFP=m +CONFIG_SKGE=m +# CONFIG_SKGE_DEBUG is not set +CONFIG_SKY2=m +# CONFIG_SKY2_DEBUG is not set +# CONFIG_SLAB is not set +CONFIG_SLABINFO=y +CONFIG_SLHC=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +# CONFIG_SLIP_MODE_SLIP6 is not set +CONFIG_SLIP_SMART=y +# CONFIG_SLOB is not set +CONFIG_SLUB=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLUB_DEBUG_ON is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_SMSC_PHY=m +CONFIG_SND=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_AC97_POWER_SAVE=y +CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0 +CONFIG_SND_AD1889=m +CONFIG_SND_ALI5451=m +CONFIG_SND_ALS300=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +CONFIG_SND_AZT3328=m +CONFIG_SND_BT87X=m +CONFIG_SND_BT87X_OVERCLOCK=y +CONFIG_SND_CA0106=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_CS4281=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_DARLA20=m +CONFIG_SND_DARLA24=m +# CONFIG_SND_DEBUG is not set +CONFIG_SND_DUMMY=m +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_ECHO3G=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_EMU10K1X=m +CONFIG_SND_ENS1370=m +CONFIG_SND_ENS1371=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_FM801=m +CONFIG_SND_FM801_TEA575X=m +CONFIG_SND_FM801_TEA575X_BOOL=y +CONFIG_SND_GINA20=m +CONFIG_SND_GINA24=m +CONFIG_SND_HDA_CODEC_ANALOG=y +CONFIG_SND_HDA_CODEC_ATIHDMI=y +CONFIG_SND_HDA_CODEC_CMEDIA=y +CONFIG_SND_HDA_CODEC_CONEXANT=y +CONFIG_SND_HDA_CODEC_REALTEK=y +CONFIG_SND_HDA_CODEC_SI3054=y +CONFIG_SND_HDA_CODEC_SIGMATEL=y +CONFIG_SND_HDA_CODEC_VIA=y +CONFIG_SND_HDA_GENERIC=y +CONFIG_SND_HDA_HWDEP=y +CONFIG_SND_HDA_INTEL=m +CONFIG_SND_HDA_POWER_SAVE=y +CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 +CONFIG_SND_HDSP=m +CONFIG_SND_HDSPM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INDIGO=m +CONFIG_SND_INDIGODJ=m +CONFIG_SND_INDIGOIO=m +CONFIG_SND_INTEL8X0=m +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_KORG1212=m +CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL=y +CONFIG_SND_LAYLA20=m +CONFIG_SND_LAYLA24=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL=y +CONFIG_SND_MIA=m +CONFIG_SND_MIXART=m +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_MONA=m +CONFIG_SND_MPU401=m +CONFIG_SND_MPU401_UART=m +CONFIG_SND_MTPAV=m +CONFIG_SND_MTS64=m +CONFIG_SND_NM256=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_PCM=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_PCXHR=m +CONFIG_SND_PORTMAN2X4=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_RIPTIDE=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_SOC=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_SUN_AMD7930=m +CONFIG_SND_SUN_CS4231=m +CONFIG_SND_SUN_DBRI=m +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_TIMER=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_VERBOSE_PROCFS is not set +CONFIG_SND_VIA82XX=m +CONFIG_SND_VIA82XX_MODEM=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_VX222=m +CONFIG_SND_VX_LIB=m +CONFIG_SND_YMFPCI=m +CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL=y +CONFIG_SOLARIS_EMUL=m +# CONFIG_SOLARIS_X86_PARTITION is not set +CONFIG_SOUND=m +CONFIG_SOUND_MSNDCLAS=m +CONFIG_SOUND_MSNDPIN=m +CONFIG_SOUND_PRIME=m +CONFIG_SOUND_TRIDENT=m +CONFIG_SPARC=y +CONFIG_SPARC32_COMPAT=y +CONFIG_SPARC64=y +# CONFIG_SPARC64_PAGE_SIZE_4MB is not set +# CONFIG_SPARC64_PAGE_SIZE_512KB is not set +# CONFIG_SPARC64_PAGE_SIZE_64KB is not set +CONFIG_SPARC64_PAGE_SIZE_8KB=y +CONFIG_SPARSEMEM=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_MANUAL=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +# CONFIG_SPECIALIX is not set +CONFIG_SPI=y +CONFIG_SPI_AT25=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_LM70_LLP=m +CONFIG_SPI_MASTER=y +CONFIG_SPI_SPIDEV=m +CONFIG_SPI_TLE62X0=m +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_SSB=m +CONFIG_SSB_DEBUG=y +CONFIG_SSB_DRIVER_PCICORE=y +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +CONFIG_SSB_POSSIBLE=y +CONFIG_STACKTRACE_SUPPORT=y +# CONFIG_STACK_DEBUG is not set +CONFIG_STALDRV=y +CONFIG_STANDALONE=y +CONFIG_STRIP=m +CONFIG_SUNBMAC=m +CONFIG_SUNDANCE=m +CONFIG_SUNDANCE_MMIO=y +CONFIG_SUNGEM=y +CONFIG_SUNLANCE=m +CONFIG_SUNQE=m +CONFIG_SUNRPC=m +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_SUNRPC_GSS=m +CONFIG_SUNRPC_XPRT_RDMA=m +CONFIG_SUNVDC=m +CONFIG_SUNVNET=m +CONFIG_SUN_AUXIO=y +# CONFIG_SUN_BPP is not set +CONFIG_SUN_IO=y +CONFIG_SUN_LDOMS=y +CONFIG_SUN_OPENPROMFS=m +CONFIG_SUN_OPENPROMIO=y +CONFIG_SUN_PARTITION=y +CONFIG_SWAP=y +CONFIG_SX=m +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_GT=m +CONFIG_SYN_COOKIES=y +CONFIG_SYSCTL=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSFS=y +# CONFIG_SYSFS_DEPRECATED is not set +CONFIG_SYSV68_PARTITION=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_SYSV_FS=m +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +CONFIG_TASKSTATS=y +# CONFIG_TASK_DELAY_ACCT is not set +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_TASK_XACCT=y +CONFIG_TCG_ATMEL=m +CONFIG_TCG_TPM=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_MD5SIG=y +CONFIG_TEHUTI=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TICK_ONESHOT=y +CONFIG_TIFM_7XX1=m +CONFIG_TIFM_CORE=m +CONFIG_TIGON3=m +CONFIG_TIMER_STATS=y +# CONFIG_TINY_SHMEM is not set +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +# CONFIG_TMD_HERMES is not set +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +# CONFIG_TR is not set +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_TULIP=m +# CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_MWI is not set +CONFIG_TULIP_NAPI=y +CONFIG_TULIP_NAPI_HW_MITIGATION=y +CONFIG_TUN=m +# CONFIG_TUNER_3036 is not set +CONFIG_TUNER_MT20XX=m +CONFIG_TUNER_SIMPLE=m +CONFIG_TUNER_TDA8290=m +CONFIG_TUNER_TEA5761=m +CONFIG_TUNER_TEA5767=m +CONFIG_TYPHOON=m +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_UFS_DEBUG is not set +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +CONFIG_UID16=y +CONFIG_UIO=m +CONFIG_UIO_CIF=m +CONFIG_ULI526X=m +# CONFIG_ULTRIX_PARTITION is not set +CONFIG_UNIX=y +CONFIG_UNIX98_PTYS=y +# CONFIG_UNIXWARE_DISKLABEL is not set +CONFIG_UNUSED_SYMBOLS=y +CONFIG_USB=y +# CONFIG_USB_ACM is not set +CONFIG_USB_ADUTUX=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARMLINUX=y +# CONFIG_USB_AUERSWALD is not set +CONFIG_USB_BELKIN=y +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_CATC=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_DABUSB=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +CONFIG_USB_DSBR=m +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EMI26=m +CONFIG_USB_EMI62=m +CONFIG_USB_EPSON2888=y +CONFIG_USB_ET61X251=m +CONFIG_USB_FTDI_ELAN=m +# CONFIG_USB_GADGET is not set +CONFIG_USB_HID=m +# CONFIG_USB_HIDDEV is not set +CONFIG_USB_HIDINPUT_POWERBOOK=y +# CONFIG_USB_IBMCAM is not set +CONFIG_USB_IDMOUSE=m +CONFIG_USB_IOWARRIOR=m +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_KAWETH=m +CONFIG_USB_KBD=m +CONFIG_USB_KC2190=y +# CONFIG_USB_KONICAWC is not set +CONFIG_USB_LCD=m +CONFIG_USB_LD=m +CONFIG_USB_LED=m +# CONFIG_USB_LEGOTOWER is not set +CONFIG_USB_LIBUSUAL=y +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_MON=y +CONFIG_USB_MOUSE=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_HCD_SSB is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OV511 is not set +CONFIG_USB_PEGASUS=m +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +# CONFIG_USB_PHIDGETSERVO is not set +CONFIG_USB_PRINTER=m +# CONFIG_USB_PWC is not set +# CONFIG_USB_QUICKCAM_MESSENGER is not set +CONFIG_USB_R8A66597_HCD=m +CONFIG_USB_RIO500=m +CONFIG_USB_RTL8150=m +# CONFIG_USB_SE401 is not set +# CONFIG_USB_SERIAL is not set +CONFIG_USB_SISUSBVGA=m +# CONFIG_USB_SISUSBVGA_CON is not set +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SN9C102=m +CONFIG_USB_STORAGE=m +CONFIG_USB_STORAGE_ALAUDA=y +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +# CONFIG_USB_STORAGE_JUMPSHOT is not set +CONFIG_USB_STORAGE_KARMA=y +# CONFIG_USB_STORAGE_ONETOUCH is not set +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_USBAT=y +# CONFIG_USB_STV680 is not set +CONFIG_USB_SUPPORT=y +# CONFIG_USB_TEST is not set +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_UHCI_HCD=m +CONFIG_USB_USBNET=m +# CONFIG_USB_USS720 is not set +# CONFIG_USB_VICAM is not set +# CONFIG_USB_W9968CF is not set +CONFIG_USB_ZC0301=m +CONFIG_USB_ZD1201=m +CONFIG_USB_ZR364XX=m +# CONFIG_USER_NS is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VERSION_SIGNATURE="Unofficial" +CONFIG_VETH=m +CONFIG_VFAT_FS=m +CONFIG_VGASTATE=m +CONFIG_VIA_RHINE=m +CONFIG_VIA_RHINE_MMIO=y +CONFIG_VIA_RHINE_NAPI=y +CONFIG_VIA_VELOCITY=m +CONFIG_VIDEOBUF_DMA_SG=m +CONFIG_VIDEOBUF_GEN=m +# CONFIG_VIDEO_ADV7170 is not set +# CONFIG_VIDEO_ADV7175 is not set +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_BT819 is not set +# CONFIG_VIDEO_BT848 is not set +# CONFIG_VIDEO_BT856 is not set +# CONFIG_VIDEO_BT866 is not set +# CONFIG_VIDEO_BWQCAM is not set +CONFIG_VIDEO_CAFE_CCIC=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_VIDEO_CQCAM is not set +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_CX25840=m +# CONFIG_VIDEO_CX88 is not set +CONFIG_VIDEO_DEV=m +# CONFIG_VIDEO_DPC is not set +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_IR_I2C=m +# CONFIG_VIDEO_IVTV is not set +# CONFIG_VIDEO_KS0127 is not set +CONFIG_VIDEO_MSP3400=m +# CONFIG_VIDEO_MXB is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_VIDEO_OV7670=m +# CONFIG_VIDEO_OVCAMCHIP is not set +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_24XXX=y +CONFIG_VIDEO_PVRUSB2_29XXX=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_SAA5246A=m +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_VIDEO_SAA7110 is not set +# CONFIG_VIDEO_SAA7111 is not set +# CONFIG_VIDEO_SAA7114 is not set +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_ALSA=m +CONFIG_VIDEO_SAA7134_OSS=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +# CONFIG_VIDEO_SAA7185 is not set +# CONFIG_VIDEO_SAA7191 is not set +CONFIG_VIDEO_TCM825X=m +# CONFIG_VIDEO_TDA7432 is not set +CONFIG_VIDEO_TDA9840=m +# CONFIG_VIDEO_TDA9875 is not set +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_TLV320AIC23B=m +CONFIG_VIDEO_TUNER=m +# CONFIG_VIDEO_TUNER_CUSTOMIZE is not set +# CONFIG_VIDEO_TVAUDIO is not set +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_VP27SMPX=m +# CONFIG_VIDEO_VPX3220 is not set +# CONFIG_VIDEO_W9966 is not set +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_WM8775=m +CONFIG_VITESSE_PHY=m +CONFIG_VLAN_8021Q=m +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VORTEX=m +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_VXFS_FS is not set +CONFIG_W1=m +CONFIG_W1_CON=y +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_DS2760=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_THERM=m +# CONFIG_WAN is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_WATCHDOG is not set +# CONFIG_WDC_ALI15X3 is not set +CONFIG_WINBOND_840=m +CONFIG_WIRELESS_EXT=y +CONFIG_WLAN_80211=y +CONFIG_WLAN_PRE80211=y +# CONFIG_X25 is not set +CONFIG_XFRM=y +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_XFRM_USER=m +CONFIG_XFS_FS=m +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_QUOTA=y +# CONFIG_XFS_RT is not set +# CONFIG_XFS_SECURITY is not set +CONFIG_XOR_BLOCKS=m +CONFIG_YELLOWFIN=m +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +# CONFIG_ZISOFS is not set +CONFIG_ZLIB_DEFLATE=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZONE_DMA_FLAG=0 --- linux-2.6.24.orig/debian/config/sparc/config.sparc64 +++ linux-2.6.24/debian/config/sparc/config.sparc64 @@ -0,0 +1,10 @@ +# +# Config options for config.sparc64 automatically generated by splitconfig.pl +# +CONFIG_BROKEN_ON_SMP=y +CONFIG_ISTALLION=m +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_RIO is not set +CONFIG_RISCOM8=m +# CONFIG_SMP is not set +CONFIG_STALLION=m --- linux-2.6.24.orig/debian/control-scripts/postrm +++ linux-2.6.24/debian/control-scripts/postrm @@ -0,0 +1,376 @@ +#! /usr/bin/perl +# -*- Mode: Cperl -*- +# image.postrm --- +# Author : Manoj Srivastava ( srivasta@glaurung.green-gryphon.com ) +# Created On : Sat May 15 11:05:13 1999 +# Created On Node : glaurung.green-gryphon.com +# Last Modified By : Manoj Srivastava +# Last Modified On : Wed Sep 13 11:26:19 2006 +# Last Machine Used: glaurung.internal.golden-gryphon.com +# Update Count : 57 +# Status : Unknown, Use with caution! +# HISTORY : +# Description : +# +# $Id: image.postrm,v 1.31 2003/10/07 16:24:20 srivasta Exp $ +# + + +# +#use strict; #for debugging +use Cwd 'abs_path'; + +$|=1; + +# Predefined values: +my $version = "=V"; +my $link_in_boot = ""; # Should be empty, mostly +my $no_symlink = ""; # Should be empty, mostly +my $reverse_symlink = ""; # Should be empty, mostly +my $do_symlink = "Yes"; # target machine defined +my $do_boot_enable = "Yes"; # target machine defined +my $do_bootfloppy = "Yes"; # target machine defined +my $do_bootloader = "Yes"; # target machine defined +my $move_image = ''; # target machine defined +my $kimage = "=K"; # Should be empty, mostly +my $loader = "=L"; # lilo, silo, quik, palo, vmelilo, or nettrom +my $image_dir = "/boot"; # where the image is located +my $clobber_modules = ''; # target machine defined +my $initrd = "YES"; # initrd kernel +my $do_initrd = ''; # Normally, we don't +my $warn_initrd = 'YES'; # Normally we do +my $use_hard_links = ''; # hardlinks do not work across fs boundaries +my $postinst_hook = ''; #Normally we do not +my $postrm_hook = ''; #Normally we do not +my $preinst_hook = ''; #Normally we do not +my $prerm_hook = ''; #Normally we do not +my $minimal_swap = ''; # Do not swap symlinks +my $ignore_depmod_err = ''; # normally we do not +my $relink_build_link = 'YES'; # There is no harm in checking the link +my $force_build_link = ''; # we shall not create a dangling link +my $kernel_arch = "=B"; +my $ramdisk = "/usr/sbin/update-initramfs"; +my $package_name = "linux-image-$version"; + +my $Loader = "NoLOADER"; # +$Loader = "LILO" if $loader =~ /^lilo/io; +$Loader = "SILO" if $loader =~ /^silo/io; +$Loader = "QUIK" if $loader =~ /^quik/io; +$Loader = "yaboot" if $loader =~ /^yaboot/io; +$Loader = "PALO" if $loader =~ /^palo/io; +$Loader = "NETTROM" if $loader =~ /^nettrom/io; +$Loader = "VMELILO" if $loader =~ /^vmelilo/io; +$Loader = "ZIPL" if $loader =~ /^zipl/io; +$Loader = "ELILO" if $loader =~ /^elilo/io; + + +# This should not point to /tmp, because of security risks. +my $temp_file_name = "/var/log/$loader" . "_log.$$"; + +#known variables +my @boilerplate = (); +my @silotemplate = (); +my @quiktemplate = (); +my @palotemplate = (); +my @vmelilotemplate = (); +my $bootdevice = ''; +my $rootdevice = ''; +my $rootdisk = ''; +my $rootpartition = ''; +my $image_dest = "/"; +my $realimageloc = "/$image_dir/"; +my $have_conffile = ""; +my $CONF_LOC = '/etc/kernel-img.conf'; +my $relative_links = ''; +my $silent_modules = ''; +my $silent_loader = ''; +my $warn_reboot = 'Yes'; # Warn that we are installing a version of + # the kernel we are running + +chdir('/') or die "could not chdir to /:$!\n"; +# remove multiple leading slashes; make sure there is at least one. +$realimageloc =~ s|^/*|/|o; +$realimageloc =~ s|/+|/|o; + + +if (-r "$CONF_LOC" && -f "$CONF_LOC" ) { + if (open(CONF, "$CONF_LOC")) { + while () { + chomp; + s/\#.*$//g; + next if /^\s*$/; + + $do_symlink = "" if /^\s*do_symlinks\s*=\s*(no|false|0)\s*$/ig; + $no_symlink = "" if /^\s*no_symlinks\s*=\s*(no|false|0)\s*$/ig; + $reverse_symlink = "" if /^\s*reverse_symlinks\s*=\s*(no|false|0)\s*$/ig; + $link_in_boot = "" if /^\s*image_in_boot\s*=\s*(no|false|0)\s*$/ig; + $link_in_boot = "" if /^\s*link_in_boot\s*=\s*(no|false|0)\s*$/ig; + $move_image = "" if /^\s*move_image\s*=\s*(no|false|0)\s*$/ig; + $clobber_modules = '' if /^\s*clobber_modules\s*=\s*(no|false|0)\s*$/ig; + $do_boot_enable = '' if /^\s*do_boot_enable\s*=\s*(no|false|0)\s*$/ig; + $do_bootfloppy = '' if /^\s*do_bootfloppy\s*=\s*(no|false|0)\s*$/ig; + $relative_links = '' if /^\s*relative_links \s*=\s*(no|false|0)\s*$/ig; + $do_bootloader = '' if /^\s*do_bootloader\s*=\s*(no|false|0)\s*$/ig; + $do_initrd = '' if /^\s*do_initrd\s*=\s*(no|false|0)\s*$/ig; + $warn_initrd = '' if /^\s*warn_initrd\s*=\s*(no|false|0)\s*$/ig; + $use_hard_links = '' if /^\s*use_hard_links\s*=\s*(no|false|0)\s*$/ig; + $silent_modules = '' if /^\s*silent_modules\s*=\s*(no|false|0)\s*$/ig; + $silent_loader = '' if /^\s*silent_loader\s*=\s*(no|false|0)\s*$/ig; + $warn_reboot = '' if /^\s*warn_reboot\s*=\s*(no|false|0)\s*$/ig; + $minimal_swap = '' if /^\s*minimal_swap\s*=\s*(no|false|0)\s*$/ig; + $ignore_depmod_err = '' if /^\s*ignore_depmod_err\s*=\s*(no|false|0)\s*$/ig; + $relink_build_link = '' if /^\s*relink_build_link\s*=\s*(no|false|0)\s*$/ig; + $force_build_link = '' if /^\s*force_build_link\s*=\s*(no|false|0)\s*$/ig; + + $do_symlink = "Yes" if /^\s*do_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $no_symlink = "Yes" if /^\s*no_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $reverse_symlink = "Yes" if /^\s*reverse_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $link_in_boot = "Yes" if /^\s*image_in_boot\s*=\s*(yes|true|1)\s*$/ig; + $link_in_boot = "Yes" if /^\s*link_in_boot\s*=\s*(yes|true|1)\s*$/ig; + $move_image = "Yes" if /^\s*move_image\s*=\s*(yes|true|1)\s*$/ig; + $clobber_modules = "Yes" if /^\s*clobber_modules\s*=\s*(yes|true|1)\s*$/ig; + $do_boot_enable = "Yes" if /^\s*do_boot_enable\s*=\s*(yes|true|1)\s*$/ig; + $do_bootfloppy = "Yes" if /^\s*do_bootfloppy\s*=\s*(yes|true|1)\s*$/ig; + $do_bootloader = "Yes" if /^\s*do_bootloader\s*=\s*(yes|true|1)\s*$/ig; + $relative_links = "Yes" if /^\s*relative_links\s*=\s*(yes|true|1)\s*$/ig; + $do_initrd = "Yes" if /^\s*do_initrd\s*=\s*(yes|true|1)\s*$/ig; + $warn_initrd = "Yes" if /^\s*warn_initrd\s*=\s*(yes|true|1)\s*$/ig; + $use_hard_links = "Yes" if /^\s*use_hard_links\s*=\s*(yes|true|1)\s*$/ig; + $silent_modules = 'Yes' if /^\s*silent_modules\s*=\s*(yes|true|1)\s*$/ig; + $silent_loader = 'Yes' if /^\s*silent_loader\s*=\s*(yes|true|1)\s*$/ig; + $warn_reboot = 'Yes' if /^\s*warn_reboot\s*=\s*(yes|true|1)\s*$/ig; + $minimal_swap = 'Yes' if /^\s*minimal_swap\s*=\s*(yes|true|1)\s*$/ig; + $ignore_depmod_err = 'Yes' if /^\s*ignore_depmod_err\s*=\s*(yes|true|1)\s*$/ig; + $relink_build_link = 'Yes' if /^\s*relink_build_link\s*=\s*(yes|true|1)\s*$/ig; + $force_build_link = 'Yes' if /^\s*force_build_link\s*=\s*(yes|true|1)\s*$/ig; + + $image_dest = "$1" if /^\s*image_dest\s*=\s*(\S+)/ig; + $postinst_hook = "$1" if /^\s*postinst_hook\s*=\s*(\S+)/ig; + $postrm_hook = "$1" if /^\s*postrm_hook\s*=\s*(\S+)/ig; + $preinst_hook = "$1" if /^\s*preinst_hook\s*=\s*(\S+)/ig; + $prerm_hook = "$1" if /^\s*prerm_hook\s*=\s*(\S+)/ig; + $ramdisk = "$1" if /^\s*ramdisk\s*=\s*(.+)$/ig; + } + close CONF; + $have_conffile = "Yes"; + } +} + +if ($link_in_boot) { + $image_dest = "/$image_dir/"; + $image_dest =~ s|^/*|/|o; +} + +$image_dest = "$image_dest/"; +$image_dest =~ s|/+$|/|o; + +# The destdir may be gone by now. +if (-d "$image_dest") { + chdir("$image_dest") or die "could not chdir to $image_dest:$!\n"; +} + +# Paranoid check to make sure that the correct value is put in there +if (! $kimage) {$kimage = "vmlinuz"} # Hmm. empty +elsif ($kimage =~ m/^b?zImage$/o) {$kimage = "vmlinuz"} # these produce vmlinuz +elsif ($kimage =~ m/^[iI]mage$/o) { my $nop = $kimage;} +elsif ($kimage =~ m/^vmlinux$/o) { my $nop = $kimage;} +else {$kimage = "vmlinuz"} # default + +$ENV{KERNEL_ARCH}=$kernel_arch if $kernel_arch; + + +###################################################################### +###################################################################### +############ +###################################################################### +###################################################################### +sub remove_sym_link { + my $bad_image = $_[0]; + + warn "Removing symbolic link $bad_image \n"; + if ($loader =~ /lilo/i) + { + warn "Unless you used the optional flag in lilo, \n"; + } + warn " you may need to re-run your boot loader" . ($loader ? "[$loader]":"") + . "\n"; + # Remove the dangling link + unlink "$bad_image"; +} + +###################################################################### +###################################################################### +############ +###################################################################### +###################################################################### +sub CanonicalizePath { + my $path = join '/', @_; + my @work = split '/', $path; + my @out; + my $is_absolute; + + if (@work && $work[0] eq "") { $is_absolute = 1; shift @work; } + + while (@work) { + my $seg = shift @work; + if ($seg eq "." || $seg eq "") { + } elsif ($seg eq "..") { + if (@out && $out[-1] ne "..") { + pop @out; + } else { + # Leading "..", or "../..", etc. + push @out, $seg; + } + } else { + push @out, $seg; + } + } + + unshift @out, "" if $is_absolute; + return join('/', @out); +} + +###################################################################### +###################################################################### +############ +###################################################################### +###################################################################### +# This removes dangling symlinks. What do we do about hard links? Surely a +# something with the nane $image_dest . "$kimage" ought not to be left behind? +sub image_magic { + my $kimage = $_[0]; + my $image_dest = $_[1]; + + if (-l "$kimage") { + # There is a symbolic link + my $force_move = 0; + my $vmlinuz_target = readlink "$kimage"; + my $real_target = ''; + $real_target = abs_path($vmlinuz_target) if defined ($vmlinuz_target); + if (!defined($vmlinuz_target) || ! -f "$real_target") { + # what, a dangling symlink? + warn "The link " . $image_dest . "$kimage is a damaged link\n"; + # Remove the dangling link + &remove_sym_link("$kimage"); + } + else { + my $canonical_target = CanonicalizePath("$vmlinuz_target"); + if (! -e $canonical_target) { + warn "The link " . $image_dest . "$kimage is a dangling link\n"; + &remove_sym_link("$kimage"); + } + } + } +} + +# set the env var stem +$ENV{'STEM'} = "linux"; + +sub exec_script { + my $type = shift; + my $script = shift; + print STDERR "Running $type hook script $script.\n"; + system ("$script $version $realimageloc$kimage-$version") && + print STDERR "User $type hook script [$script] "; + if ($?) { + if ($? == -1) { + print STDERR "failed to execute: $!\n"; + } + elsif ($? & 127) { + printf STDERR "died with signal %d, %s coredump\n", + ($? & 127), ($? & 128) ? 'with' : 'without'; + } + else { + printf STDERR "exited with value %d\n", $? >> 8; + } + } +} +sub run_hook { + my $type = shift; + my $script = shift; + if ($script =~ m,^/,) { + # Full path provided for the hook script + if (-x "$script") { + &exec_script($type,$script); + } + else { + warn "The provided $type hook script [$script] could not be run.\n"; + } + } + else { + # Look for it in a safe path + for my $path ('/bin', '/sbin', '/usr/bin', '/usr/sbin') { + if (-x "$path/$script") { + &exec_script($type, "$path/$script"); + return 0; + } + } + # No luck + print STDERR "Could not find $type hook script [$script].\n"; + warn "Looked in: '/bin', '/sbin', '/usr/bin', '/usr/sbin'\n"; + } +} + +## Run user hook script here, if any +if ($postrm_hook) { + &run_hook("postrm", $postrm_hook); +} +if (-d "/etc/kernel/postrm.d") { + warn "Examining /etc/kernel/postrm.d .\n"; + system ("run-parts --verbose --exit-on-error --arg=$version " . + "--arg=$realimageloc$kimage-$version " . + "/etc/kernel/postrm.d") && + die "Failed to process /etc/kernel/postrm.d"; +} +if (-d "/etc/kernel/postrm.d/$version") { + warn "Examining /etc/kernel/postrm.d/$version .\n"; + system ("run-parts --verbose --exit-on-error --arg=$version " . + "--arg=$realimageloc$kimage-$version " . + "/etc/kernel/postrm.d/$version") && + die "Failed to process /etc/kernel/postrm.d/$version"; +} + +# check and remove damaged and dangling symlinks +if ($ARGV[0] !~ /upgrade/) { + system("$ramdisk -d -k " . $version . " > /dev/null 2>&1"); + if (-f $realimageloc . "initrd.img-$version.bak") { + unlink $realimageloc . "initrd.img-$version.bak"; + } + image_magic($kimage, $image_dest); + image_magic($kimage . ".old", $image_dest); + image_magic("initrd.img", $image_dest) if $initrd; + image_magic("initrd.img.old", $image_dest) if $initrd; +} + + +# Ignore all invocations except when called on to purge. +exit 0 unless $ARGV[0] =~ /purge/; + +my @files_to_remove = qw{ + modules.dep modules.isapnpmap modules.pcimap + modules.usbmap modules.parportmap + modules.generic_string modules.ieee1394map + modules.ieee1394map modules.pnpbiosmap + modules.alias modules.ccwmap modules.inputmap + modules.symbols build source modules.ofmap + }; + +foreach my $extra_file (@files_to_remove) { + if (-f "/lib/modules/$version/$extra_file") { + unlink "/lib/modules/$version/$extra_file"; + } +} + +if (-d "/lib/modules/$version" ) { + system ("rmdir", "/lib/modules/$version"); +} + +exit 0; + +__END__ + + + + + + --- linux-2.6.24.orig/debian/control-scripts/postinst +++ linux-2.6.24/debian/control-scripts/postinst @@ -0,0 +1,1087 @@ +#! /usr/bin/perl +# OriginalAuthor : Manoj Srivastava ( srivasta@pilgrim.umass.edu ) +# +# Customized for Ubuntu by: Ben Collins + +#use strict; #for debugging +use Cwd 'abs_path'; + +$|=1; + +# Predefined values: +my $version = "=V"; +my $link_in_boot = ""; # Should be empty, mostly +my $no_symlink = ""; # Should be empty, mostly +my $reverse_symlink = ""; # Should be empty, mostly +my $do_symlink = "Yes"; # target machine defined +my $do_boot_enable = "Yes"; # target machine defined +my $do_bootfloppy = "Yes"; # target machine defined +my $do_bootloader = "Yes"; # target machine defined +my $move_image = ''; # target machine defined +my $kimage = "=K"; # Should be empty, mostly +my $loader = "=L"; # lilo, silo, quik, palo, vmelilo, nettrom, arcboot or delo +my $image_dir = "/boot"; # where the image is located +my $clobber_modules = ''; # target machine defined +my $relative_links = ""; # target machine defined +my $initrd = "YES"; # initrd kernel +my $do_initrd = ''; # Normally we do not +my $use_hard_links = ''; # hardlinks do not work across fs boundaries +my $postinst_hook = ''; #Normally we do not +my $postrm_hook = ''; #Normally we do not +my $preinst_hook = ''; #Normally we do not +my $prerm_hook = ''; #Normally we do not +my $minimal_swap = ''; # Do not swap symlinks +my $ignore_depmod_err = ''; # normally we do not +my $kernel_arch = "=B"; +my $ramdisk = "/usr/sbin/update-initramfs"; # List of tools to create initial ram fs. +my $notifier = "/usr/share/update-notifier/notify-reboot-required"; +my $package_name = "linux-image-$version"; +my $explicit_do_loader = 'Yes'; + +my $Loader = "NoLOADER"; # +$Loader = "LILO" if $loader =~ /^lilo/io; +$Loader = "SILO" if $loader =~ /^silo/io; +$Loader = "QUIK" if $loader =~ /^quik/io; +$Loader = "yaboot" if $loader =~ /^yaboot/io; +$Loader = "PALO" if $loader =~ /^palo/io; +$Loader = "NETTROM" if $loader =~ /^nettrom/io; +$Loader = "VMELILO" if $loader =~ /^vmelilo/io; +$Loader = "ZIPL" if $loader =~ /^zipl/io; +$Loader = "ELILO" if $loader =~ /^elilo/io; +$Loader = "ARCBOOT" if $loader =~ /^arcboot/io; +$Loader = "DELO" if $loader =~ /^delo/io; + +# This should not point to /tmp, because of security risks. +my $temp_file_name = "/var/log/$loader" . "_log.$$"; + +#known variables +my $image_dest = "/"; +my $realimageloc = "/$image_dir/"; +my $have_conffile = ""; +my $silent_modules = ''; +my $silent_loader = ''; +my $warn_reboot = 'Yes'; # Warn that we are installing a version of + # the kernel we are running + +my $modules_base = '/lib/modules'; +my $CONF_LOC = '/etc/kernel-img.conf'; + +# Ignore all invocations except when called on to configure. +exit 0 unless $ARGV[0] =~ /configure/; + +my $DEBUG = 0; + +# Do some preliminary sanity checks here to ensure we actually have an +# valid image dir +chdir('/') or die "could not chdir to /:$!\n"; +die "Internal Error: ($image_dir) is not a directory!\n" + unless -d $image_dir; + +# remove multiple leading slashes; make sure there is at least one. +$realimageloc =~ s|^/*|/|o; +$realimageloc =~ s|/+|/|o; +die "Internal Error: ($realimageloc) is not a directory!\n" + unless -d $realimageloc; + +if (-r "$CONF_LOC" && -f "$CONF_LOC" ) { + if (open(CONF, "$CONF_LOC")) { + while () { + chomp; + s/\#.*$//g; + next if /^\s*$/; + + $do_symlink = "" if /^\s*do_symlinks\s*=\s*(no|false|0)\s*$/ig; + $no_symlink = "" if /^\s*no_symlinks\s*=\s*(no|false|0)\s*$/ig; + $reverse_symlink = "" if /^\s*reverse_symlink\s*=\s*(no|false|0)\s*$/ig; + $link_in_boot = "" if /^\s*image_in_boot\s*=\s*(no|false|0)\s*$/ig; + $link_in_boot = "" if /^\s*link_in_boot\s*=\s*(no|false|0)\s*$/ig; + $move_image = "" if /^\s*move_image\s*=\s*(no|false|0)\s*$/ig; + $clobber_modules = '' if /^\s*clobber_modules\s*=\s*(no|false|0)\s*$/ig; + $do_boot_enable = '' if /^\s*do_boot_enable\s*=\s*(no|false|0)\s*$/ig; + $do_bootfloppy = '' if /^\s*do_bootfloppy\s*=\s*(no|false|0)\s*$/ig; + $relative_links = '' if /^\s*relative_links \s*=\s*(no|false|0)\s*$/ig; + $do_bootloader = '' if /^\s*do_bootloader\s*=\s*(no|false|0)\s*$/ig; + $explicit_do_loader = '' if /^\s*do_bootloader\s*=\s*(no|false|0)\s*$/ig; + $do_initrd = '' if /^\s*do_initrd\s*=\s*(no|false|0)\s*$/ig; + $use_hard_links = '' if /^\s*use_hard_links\s*=\s*(no|false|0)\s*$/ig; + $silent_modules = '' if /^\s*silent_modules\s*=\s*(no|false|0)\s*$/ig; + $silent_loader = '' if /^\s*silent_loader\s*=\s*(no|false|0)\s*$/ig; + $warn_reboot = '' if /^\s*warn_reboot\s*=\s*(no|false|0)\s*$/ig; + $minimal_swap = '' if /^\s*minimal_swap\s*=\s*(no|false|0)\s*$/ig; + $ignore_depmod_err = '' if /^\s*ignore_depmod_err\s*=\s*(no|false|0)\s*$/ig; + + $do_symlink = "Yes" if /^\s*do_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $no_symlink = "Yes" if /^\s*no_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $reverse_symlink = "Yes" if /^\s*reverse_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $link_in_boot = "Yes" if /^\s*image_in_boot\s*=\s*(yes|true|1)\s*$/ig; + $link_in_boot = "Yes" if /^\s*link_in_boot\s*=\s*(yes|true|1)\s*$/ig; + $move_image = "Yes" if /^\s*move_image\s*=\s*(yes|true|1)\s*$/ig; + $clobber_modules = "Yes" if /^\s*clobber_modules\s*=\s*(yes|true|1)\s*$/ig; + $do_boot_enable = "Yes" if /^\s*do_boot_enable\s*=\s*(yes|true|1)\s*$/ig; + $do_bootfloppy = "Yes" if /^\s*do_bootfloppy\s*=\s*(yes|true|1)\s*$/ig; + $do_bootloader = "Yes" if /^\s*do_bootloader\s*=\s*(yes|true|1)\s*$/ig; + $explicit_do_loader = "YES" if /^\s*do_bootloader\s*=\s*(yes|true|1)\s*$/ig; + $relative_links = "Yes" if /^\s*relative_links\s*=\s*(yes|true|1)\s*$/ig; + $do_initrd = "Yes" if /^\s*do_initrd\s*=\s*(yes|true|1)\s*$/ig; + $use_hard_links = "Yes" if /^\s*use_hard_links\s*=\s*(yes|true|1)\s*$/ig; + $silent_modules = 'Yes' if /^\s*silent_modules\s*=\s*(yes|true|1)\s*$/ig; + $silent_loader = 'Yes' if /^\s*silent_loader\s*=\s*(yes|true|1)\s*$/ig; + $warn_reboot = 'Yes' if /^\s*warn_reboot\s*=\s*(yes|true|1)\s*$/ig; + $minimal_swap = 'Yes' if /^\s*minimal_swap\s*=\s*(yes|true|1)\s*$/ig; + $ignore_depmod_err = 'Yes' if /^\s*ignore_depmod_err\s*=\s*(yes|true|1)\s*$/ig; + + $image_dest = "$1" if /^\s*image_dest\s*=\s*(\S+)/ig; + $postinst_hook = "$1" if /^\s*postinst_hook\s*=\s*(\S+)/ig; + $postrm_hook = "$1" if /^\s*postrm_hook\s*=\s*(\S+)/ig; + $preinst_hook = "$1" if /^\s*preinst_hook\s*=\s*(\S+)/ig; + $prerm_hook = "$1" if /^\s*prerm_hook\s*=\s*(\S+)/ig; + $ramdisk = "$1" if /^\s*ramdisk\s*=\s*(.+)$/ig; + } + close CONF; + $have_conffile = "Yes"; + } +} + + + +# For some versions of kernel-package, we had this warning in the +# postinst, but the rules did not really interpolate the value in. +# Here is a sanity check. +my $pattern = "=" . "I"; +$initrd=~ s/^$pattern$//; + +if ($link_in_boot) { + $image_dest = "/$image_dir/"; # same as realimageloc +} + +# Tack on at least one trainling / +$image_dest = "$image_dest/"; +$image_dest =~ s|^/*|/|o; +$image_dest =~ s|/+$|/|o; + +if (! -d "$image_dest") { + die "Expected Image Destination dir ($image_dest) to be a valid directory!\n"; +} + +# sanity +if (!($do_bootfloppy || $do_bootloader)) { + $do_boot_enable = ''; +} +if ($do_symlink && $no_symlink) { + warn "Both do_symlinks and no_symlinks options enabled; disabling no_symlinks\n"; + $no_symlink = 0; +} + +# most of our work is done in $image_dest (nominally /) +chdir("$image_dest") or die "could not chdir to $image_dest:$!\n"; + +# Paranoid check to make sure that the correct value is put in there +if (! $kimage) { $kimage = "vmlinuz"; } # Hmm. empty +elsif ($kimage =~ m/^b?zImage$/o) { $kimage = "vmlinuz"; } # these produce vmlinuz +elsif ($kimage =~ m/^[iI]mage$/o) { my $nop = $kimage; } +elsif ($kimage =~ m/^vmlinux$/o) { my $nop = $kimage; } +else { $kimage = "vmlinuz"; } # Default + +$ENV{KERNEL_ARCH}=$kernel_arch if $kernel_arch; + + +die "Internal Error: Could not find image (" . $realimageloc + . "$kimage-$version)\n" unless -e $realimageloc + . "$kimage-$version"; + +# search for the boot loader in the path +my $loader_exec; +($loader_exec = $loader) =~ s|.*/||; +my ($loaderloc) = grep -x, map "$_/$loader_exec", + map { length($_) ? $_ : "." } split /:/, $ENV{PATH}; + + +###################################################################### +###################################################################### +########### Test whether a relative symlinkwould be OK ####### +###################################################################### +###################################################################### +sub test_relative { + my %params = @_; + my $cwd; + + die "Internal Error: Missing Required paramater 'Old Dir' " + unless $params{'Old Dir'}; + die "Internal Error: Missing Required paramater New Dir' " + unless $params{'New Dir'}; + + + die "Internal Error: No such dir $params{'Old Dir'} " + unless -d $params{'Old Dir'}; + die "Internal Error: No such dir $params{'New Dir'} " + unless -d $params{'New Dir'}; + + warn "Test relative: testing $params{'Old Dir'} -> $params{'New Dir'}" + if $DEBUG; + chomp($cwd = `pwd`); + chdir ($params{'New Dir'}) or die "Could not chdir to $params{'New Dir'}:$!"; + my $ok = 0; + $params{'Old Dir'} =~ s|^/*||o; + if (-d $params{'Old Dir'} ) { + if (defined $params{'Test File'}) { + if (-e $params{'Old Dir'} . $params{'Test File'}) { + $ok = 1; + } + } else { + $ok = 1; # well, backward compatibility + } + } + chdir ($cwd) or die "Could not chdir to $params{'New Dir'}:$!"; + return $ok; +} + +###################################################################### +###################################################################### +############ +###################################################################### +###################################################################### +# sub CanonicalizePath { +# my $path = join '/', @_; +# my @work = split '/', $path; +# my @out; +# my $is_absolute; + +# if (@work && $work[0] eq "") { +# $is_absolute = 1; shift @work; +# } + +# while (@work) { +# my $seg = shift @work; +# if ($seg eq "." || $seg eq "") { +# } +# elsif ($seg eq "..") { +# if (@out && $out[-1] ne "..") { +# pop @out; +# } +# else { +# # Leading "..", or "../..", etc. +# push @out, $seg; +# } +# } +# else { +# push @out, $seg; +# } +# } + +# unshift @out, "" if $is_absolute; +# return join('/', @out); +# } +###################################################################### +###################################################################### +############ +###################################################################### +###################################################################### + +sub spath { + my %params = @_; + + die "Missing Required paramater 'Old'" unless $params{'Old'}; + die "Missing Required paramater 'New'" unless $params{'New'}; + + my @olddir = split '/', `readlink -q -m $params{'Old'}`; + my @newdir = split '/', `readlink -q -m $params{'New'}`; + my @outdir = @olddir; + + my $out = ''; + my $i; + for ($i = 0; $i <= $#olddir && $i <= $#newdir; $i++) { + $out++ if ($olddir[$i] ne $newdir[$i]); + shift @outdir unless $out; + unshift @outdir, ".." if $out; + } + if ($#newdir > $#olddir) { + for ($i=0; $i < $#newdir; $i++) { + unshift @outdir, ".."; + } + } + return join ('/', @outdir); +} +###################################################################### +###################################################################### +############ +###################################################################### +###################################################################### + + +# This routine actually moves the kernel image +# From: $realimageloc/$kimage-$version (/boot/vmlinuz-2.6.12) +# To: $image_dest/$kimage-$version (/vmlinuz-2.6.12) +# Note that the image is moved to a versioned destination, but ordinary +# symlinks we create otherwise are not normally versioned +sub really_move_image { + my $src_dir = $_[0]; + my $target = $_[1]; + my $dest_dir = $_[2]; + + warn "Really move image: src_dir=$src_dir, target=$target,\n destdir=$dest_dir" + if $DEBUG; + if (-e "$target") { + # we should be in dir $dest_dir == $image_dest /, normally + rename("$target", "$target.$$") || + die "failed to move " . $dest_dir . "$target:$!"; + warn "mv $target $target.$$" if $DEBUG; + } + warn "mv -f $src_dir$target $target" if $DEBUG; + my $ret = system("mv -f " . $src_dir . "$target " . + " $target"); + if ($ret) { + die("Failed to move " . $src_dir . "$target to " + . $dest_dir . "$target.\n"); + } + # Ok, now we may clobber the previous .old files + if (-e "$target.$$") { + rename("$target.$$", "$target.old") || + die "failed to move " . $dest_dir . "$target:$!"; + warn "mv $target.$$ $target " if $DEBUG; + } +} + +# Normally called after really_move_image; and only called if we asked for +# reversed link this routine reverses the symbolic link that is notmally +# created. Since the real kernel image has been moved over to +# $image_dest/$kimage-$version. So, this routine links +# From: $image_dest/$kimage-$version (/vmlinuz-2.6.12) +# To: $realimageloc/$kimage-$version (/boot/vmlinuz-2.6.12) +sub really_reverse_link { + my $src_dir = $_[0]; + my $link_name = $_[1]; + my $dest_dir = $_[2]; + warn "Really reverse link: src_dir=$src_dir, link name=$link_name\n" . + "\tdestdir=$dest_dir" if $DEBUG; + + my $Old = $dest_dir; + if (test_relative ('Old Dir' => $Old, 'New Dir' => $src_dir, + 'Test File' => "$link_name")) { + $Old =~ s|^/*||o; + } + # Special case is they are in the same dir + my $rel_path = spath('Old' => "$Old", 'New' => "$src_dir" ); + $Old ="" if $rel_path =~ m/^\s*$/o; + + if ($use_hard_links =~ m/YES/i) { + link($Old . "$link_name", $src_dir . "$link_name") || + die("Failed to symbolic-link " . $dest_dir . "$link_name to " . $src_dir + . "$link_name .\n"); + warn "ln " . $Old . "$link_name " . $src_dir . "$link_name" if $DEBUG; + } + else { + symlink($Old . "$link_name", $src_dir . "$link_name") || + die("Failed to link " . $dest_dir . "$link_name to " . $src_dir . + "$link_name .\n"); + warn "ln -s " . $Old . "$link_name " . $src_dir . "$link_name" if $DEBUG; + } +} + +# This routine is invoked if there is a symbolic link in place +# in $image_dest/$kimage -- so a symlink exists in the destination. +# What we are trying to determine is if we need to move the symbolic link over +# to the the .old location +sub move_p { + my $kimage = $_[0]; # Name of the symbolic link + my $image_dest = $_[1]; # The directory the links goes into + my $image_name = $_[2]; + my $src_dir = $_[3]; + my $force_move = 0; + warn "Move?: kimage=$kimage, image_dest=$image_dest, \n" . + "\timage_name=$image_name, src_dir=$src_dir" if $DEBUG; + + if ($no_symlink || $reverse_symlink) { + # we do not want links, yet we have a symbolic link here! + warn "found a symbolic link in " . $image_dest . "$kimage \n" . + "even though no_symlink is defined\n" if $no_symlink; + warn "found a symbolic link in " . $image_dest . "$kimage \n" . + "even though reverse_symlink is defined\n" if $reverse_symlink; + # make sure we change this state of affairs + $force_move = 1; + return $force_move; + } + + warn "DEBUG: OK. We found symlink, and we should have a symlink here.\n" + if $DEBUG; + my $vmlinuz_target = readlink "$kimage"; + my $real_target = ''; + my $target = `readlink -q -m "${realimageloc}${kimage-$version}"`; + $real_target = abs_path($vmlinuz_target) if defined($vmlinuz_target); + + if (!defined($vmlinuz_target) || ! -f "$real_target") { + # what, a dangling symlink? + warn "The link " . $image_dest . "$kimage is a dangling link" . + "to $real_target\n"; + $force_move = 1; + return $force_move; + } + + + warn "DEBUG: The link $kimage points to ($vmlinuz_target)\n" if $DEBUG; + warn "DEBUG: ($vmlinuz_target) is really ($real_target)\n" if $DEBUG; + my $cwd; + chomp ($cwd=`pwd`); + if ($vmlinuz_target !~ m|^/|o) { + $vmlinuz_target = $cwd . "/" . $vmlinuz_target; + $vmlinuz_target =~ s|/+|/|o; + } + $vmlinuz_target = `readlink -q -m $vmlinuz_target`; + + if ("$vmlinuz_target" ne "$target") { + warn "DEBUG: We need to handle this.\n" if $DEBUG; + if ($minimal_swap) { + warn "DEBUG: Minimal swap.\n" if $DEBUG; + if (-l "$kimage.old") { + warn "DEBUG: There is an old link at $kimage.old\n" if $DEBUG; + my $old_target = readlink "$kimage.old"; + my $real_old_target = ''; + $real_old_target=abs_path($old_target) if defined ($old_target); + + if ($real_old_target && -f "$real_old_target") { + if ($old_target !~ m|^/|o) { + $old_target = $cwd . "/" . $old_target; + $old_target =~ s|/+|/|o; + } + $old_target = `readlink -q -m $old_target`; + if ("$old_target" ne "$target") { + $force_move = 1; + warn "DEBUG: Old link ($old_target) does not point to us ($target)\n" + if $DEBUG; + } + else { # The .old points to the current + warn "$kimage.old --> $target -- doing nothing"; + $force_move = 0; + } + } + else { + warn "DEBUG: Well, the old link does not exist -- so we move\n" + if $DEBUG; + $force_move = 1; + } + } + else { + warn "DEBUG: No .old link -- OK to move\n" + if $DEBUG; + $force_move = 1; + } + } + else { + warn "DEBUG: ok, minimal swap is no-- so we move.\n" + if $DEBUG; + $force_move = 1; + } + } + else { # already have proper link + warn "$kimage($vmlinuz_target) points to $target ($real_target) -- doing nothing"; + $force_move = 0; + } + return $force_move; +} + + +# This routine moves the symbolic link around (/vmlinuz -> /vmlinuz.old) +# It pays attention to whether we should the fact whether we should be using +# hard links or not. +sub really_move_link { + my $kimage = $_[0]; # Name of the symbolic link + my $image_dest = $_[1]; # The directory the links goes into + my $image_name = $_[2]; + my $src_dir = $_[3]; + warn "really_move_link: kimage=$kimage, image_dest=$image_dest\n" . + "\t image_name=$image_name, src_dir=$src_dir" if $DEBUG; + + # don't clobber $kimage.old quite yet + rename("$kimage", "$kimage.$$") || + die "failed to move " . $image_dest . "$kimage:$!"; + warn "mv $kimage $kimage.$$" if $DEBUG; + my $Old = $src_dir; + my $cwd; + + chomp($cwd=`pwd`); + if (test_relative ('Old Dir' => $Old, 'New Dir' => $cwd, + 'Test File' => "$image_name")) { + $Old =~ s|^/*||o; + } + # Special case is they are in the same dir + my $rel_path = spath('Old' => "$Old", 'New' => "$cwd" ); + $Old ="" if $rel_path =~ m/^\s*$/o; + + if ($use_hard_links =~ m/YES/i) { + warn "ln ${Old}${image_name} $kimage" if $DEBUG; + if (! link("${Old}${image_name}", "$kimage")) { + rename("$kimage.$$", "$kimage"); + die("Failed to link ${Old}${image_name} to " . + "${image_dest}${kimage}.\n"); + } + } + else { + warn "ln -s ${Old}${image_name} $kimage" if $DEBUG; + if (! symlink("${Old}${image_name}", "$kimage")) { + rename("$kimage.$$", "$kimage"); + die("Failed to symbolic-link ${Old}${image_name} to " . + "${image_dest}${kimage}.\n"); + } + } + + # Ok, now we may clobber the previous .old file + if (-l "$kimage.old" || ! -e "$kimage.old" ) { + rename("$kimage.$$", "$kimage.old"); + warn "mv $kimage.$$ $kimage.old" if $DEBUG; + } + else { + warn "$kimage.old is not a symlink, not clobbering\n"; + warn "rm $kimage.$$"; + unlink "$kimage.$$" if $DEBUG; + } +} + +# This routine handles a request to do symlinks, but there is no +# symlink file already there. Either we are supposed to use copy, or we are +# installing on a pristine system, or the user does not want symbolic links at +# all. We use a configuration file to tell the last two cases apart, creating +# a config file if needed. +sub handle_missing_link { + my $kimage = $_[0]; # Name of the symbolic link + my $image_dest = $_[1]; # The directory the links goes into + my $image_name = $_[2]; + my $src_dir = $_[3]; + warn "handle_missing_link: kimage=$kimage, image_dest=$image_dest\n" . + "\t image_name=$image_name, src_dir=$src_dir" if $DEBUG; + + if ($no_symlink) { + warn "cp -a --backup=t $realimageloc$image_name $kimage" if $DEBUG; + my $ret = system("cp -a --backup=t " . $realimageloc . + "$image_name " . " $kimage"); + if ($ret) { + die("Failed to copy " . $realimageloc . "$image_name to " + . $image_dest . "$kimage .\n"); + } + } + elsif ($reverse_symlink) { + warn "mv -f $realimageloc$image_name $kimage" if $DEBUG; + my $ret = system("mv -f " . $realimageloc . "$image_name " + . "$kimage"); + if ($ret) { + die("Failed to move " . $realimageloc . "$image_name to " + . $image_dest . "$kimage .\n"); + } + } + else { + if (! $have_conffile) { + my $ret; + my $answer=''; + $do_symlink = "Yes"; + + if (open(CONF, ">$CONF_LOC")) { + print CONF "# Kernel Image management overrides\n"; + print CONF "# See kernel-img.conf(5) for details\n"; + if ($loader =~ /palo/i) { + print CONF "link_in_boot = Yes\n"; + print CONF "do_symlinks = Yes\n"; + print CONF "relative_links = Yes\n"; + print CONF "do_bootloader = No\n"; + } else { + print CONF "do_symlinks = $do_symlink\n"; + } + close CONF; + } + $have_conffile = "Yes"; + } + } + + if (! $no_symlink && $do_symlink =~ /Yes/i) { + my $Old = $realimageloc; + my $New = $image_dest; + my $Name = "$image_name"; + my $Link_Dest = "$kimage"; + + if ($reverse_symlink) { + $Old = $image_dest; + $New = $realimageloc; + $Name = "$kimage"; + $Link_Dest = $realimageloc . "$image_name"; + } + if (test_relative ('Old Dir' => $Old, + 'New Dir' => $New, + 'Test File' => $Name)) { + $Old =~ s|^/*||o; + } + # Special case is they are in the same dir + my $rel_path = spath('Old' => "$Old", 'New' => "$New" ); + $Old ="" if $rel_path =~ m/^\s*$/o; + + symlink($Old . "$Name", "$Link_Dest") || + die("Failed to symbolic-link ${Old}$Name to $Link_Dest.\n"); + warn "ln -s ${Old}$Name $Link_Dest" if $DEBUG; + + } +} + +# This routine handles the rest of the cases, where the user has requested +# non-traditional handling, like using cp, or reverse symlinks, or hard links. +sub handle_non_symlinks { + my $kimage = $_[0]; # Name of the symbolic link + my $image_dest = $_[1]; # The directory the links goes into + my $image_name = $_[2]; + my $src_dir = $_[3]; + warn "handle_non_link: kimage=$kimage, image_dest=$image_dest\n" . + "\t image_name=$image_name, src_dir=$src_dir" if $DEBUG; + + # Save the current image. We do this in all four cases + rename("$kimage", "$kimage.$$") || + die "failed to move " . $image_dest . "$kimage:$!"; + warn "mv $kimage $kimage.$$" if $DEBUG; + + ##,#### + # case One + #`#### + if ($no_symlink) { + # Maybe /$image_dest is on a dos system? + warn "cp -a --backup=t $realimageloc$image_name $kimage" if $DEBUG; + my $ret = system("cp -a --backup=t " . $realimageloc + . "$image_name " . "$kimage"); + if ($ret) { + if (-e "$kimage.$$") { + rename("$kimage.$$", "$kimage"); + warn "mv $kimage.$$ $kimage" if $DEBUG; + } + die("Failed to copy " . $realimageloc . "$image_name to " + . $image_dest . "$kimage .\n"); + } + } + ##,#### + # case Two + #`#### + elsif ($reverse_symlink) { # Maybe /$image_dest is on a dos system? + warn "mv -f $realimageloc$image_name $kimage" if $DEBUG; + my $ret = system("mv -f " . $realimageloc . "$image_name " + . $image_dest . "$kimage"); + if ($ret) { + if (-e "$kimage.$$") { + rename("$kimage.$$", "$kimage"); + warn "mv $kimage.$$ $kimage" if $DEBUG; + } + die("Failed to move " . $realimageloc . "$image_name to " + . $image_dest . "$kimage .\n"); + } + my $Old = $image_dest; + if (test_relative ('Old Dir' => $Old, 'New Dir' => $realimageloc, + 'Test File' => "$kimage")) { + $Old =~ s|^/*||o; + } + # Special case is they are in the same dir + my $rel_path = spath('Old' => "$Old", 'New' => "$realimageloc" ); + $Old ="" if $rel_path =~ m/^\s*$/o; + + if ($use_hard_links =~ m/YES/i) { + warn "ln " . $Old . "$kimage " . $realimageloc . "$image_name" if $DEBUG; + if (! link($Old . "$kimage", $realimageloc . "$image_name")) { + warn "Could not link " . $image_dest . + "$kimage to $image_name :$!"; + } + } + else { + warn "ln -s " . $Old . "$kimage " . $realimageloc . "$image_name" if $DEBUG; + if (! symlink($Old . "$kimage", $realimageloc . "$image_name")) { + warn "Could not symlink " . $image_dest . + "$kimage to $image_name :$!"; + } + } + } + ##,#### + # case Three + #`#### + elsif ($use_hard_links =~ m/YES/i ) { + # Ok then. this ought to be a hard link, and hence fair game + # don't clobber $kimage.old quite yet + my $Old = $realimageloc; + my $cwd; + chomp($cwd=`pwd`); + if (test_relative ('Old Dir' => $Old, 'New Dir' => $cwd, + 'Test File' => "$image_name")) { + $Old =~ s|^/*||o; + } + # Special case is they are in the same dir + my $rel_path = spath('Old' => "$Old", 'New' => "$cwd" ); + $Old ="" if $rel_path =~ m/^\s*$/o; + + warn "ln " . $Old . "$image_name " . "$kimage" if $DEBUG; + if (! link($Old . "$image_name", "$kimage")) { + warn "mv $kimage.$$ $kimage" if $DEBUG; + rename("$kimage.$$", "$kimage"); + die("Failed to link " . $realimageloc . "$image_name to " + . $image_dest . "$kimage .\n"); + } + } + ##,#### + # case Four + #`#### + else { + # We just use cp + warn "cp -a --backup=t $realimageloc$image_name $kimage" if $DEBUG; + my $ret = system("cp -a --backup=t " . $realimageloc + . "$image_name " . "$kimage"); + if ($ret) { + if (-e "$kimage.$$") { + warn "mv $kimage.$$ $kimage" if $DEBUG; + rename("$kimage.$$", "$kimage"); + } + die("Failed to copy " . $realimageloc . "$image_name to " + . $image_dest . "$kimage .\n"); + } + } + # Ok, now we may clobber the previous .old file + warn "mv $kimage.$$ $kimage.old if -e $kimage.$$" if $DEBUG; + rename("$kimage.$$", "$kimage.old") if -e "$kimage.$$"; +} + +# This routine is responsible for setting up the symbolic links +# So, the actual kernel image lives in +# $realimageloc/$image_name (/boot/vmlinuz-2.6.12). +# This routine creates symbolic links in $image_dest/$kimage (/vmlinuz) +sub image_magic { + my $kimage = $_[0]; # Name of the symbolic link + my $image_dest = $_[1]; # The directory the links goes into + my $image_name = "$kimage-$version"; + my $src_dir = $realimageloc; + warn "image_magic: kimage=$kimage, image_dest=$image_dest\n" . + "\t image_name=$image_name, src_dir=$src_dir" if $DEBUG; + + # Well, in any case, if the destination (the symlink we are trying + # to create) is a directory, we should do nothing, except throw a + # diagnostic. + if (-d "$kimage" ) { + die ("Hmm. $kimage is a directory, which I did not expect. I am\n" . + "trying to create a symbolic link with that name linked to \n" . + "$image_dest . Since a directory exists here, my assumptions \n" . + "are way off, and I am aborting.\n" ); + exit (3); + } + + if ($move_image) { # Maybe $image_dest is in on dos, or something? + # source dir, link name, dest dir + really_move_image( $realimageloc, $image_name, $image_dest); + really_reverse_link($realimageloc, $image_name, $image_dest) + if $reverse_symlink; + return; + } + + if (-l "$kimage") { # There is a symbolic link + warn "DEBUG: There is a symlink for $kimage\n" if $DEBUG; + my $force_move = move_p($kimage, $image_dest, $image_name, $src_dir); + + if ($force_move) { + really_move_link($kimage, $image_dest, $image_name, $src_dir); + } + } + elsif (! -e "$kimage") { + # Hmm. Pristine system? How can that be? Installing from scratch? + # Or maybe the user does not want a symbolic link here. + # Possibly they do not want a link here. (we should be in / + # here[$image_dest, really] + handle_missing_link($kimage, $image_dest, $image_name, $src_dir); + } + elsif (-e "$kimage" ) { + # OK, $kimage exists -- but is not a link + handle_non_symlinks($kimage, $image_dest, $image_name, $src_dir); + } +} + +###################################################################### +###################################################################### +###################################################################### +###################################################################### + +# We may not have any modules installed +if ( -d "$modules_base/$version" ) { + print STDERR "Running depmod.\n"; + my $ret = system("depmod -a -F $realimageloc/System.map-$version $version"); + if ($ret) { + print STDERR "Failed to run depmod\n"; + exit(1); + } +} + + + +sub find_initrd_tool { + my $hostversion = shift; + my $version = shift; + print STDERR "Finding valid ramdisk creators.\n"; + my @ramdisks = + grep { + my $args = + "$_ " . + "--supported-host-version=$hostversion " . + "--supported-target-version=$version " . + "1>/dev/null 2>&1" + ; + system($args) == 0; + } + split (/[:,\s]+/, $ramdisk); +} + +# The initrd symlink should probably be in the same dir that the +# symlinks are in +if ($initrd) { + my $success = 0; + + # Update-initramfs is called slightly different than mkinitrd and + # mkinitramfs. XXX It should really be made compatible with this stuff + # some how. + my $upgrading = 1; + if (! defined $ARGV[1] || ! $ARGV[1] || $ARGV[1] =~ m//og) { + $upgrading = 0; + } + my $ret = system("$ramdisk " . ($upgrading ? "-u" : "-c") . " -k " . $version . " >&2"); + $success = 1 unless $ret; + die "Failed to create initrd image.\n" unless $success; + if (! defined $ARGV[1] || ! $ARGV[1] || $ARGV[1] =~ m//og) { + image_magic("initrd.img", $image_dest); + } + else { + if (! -e "initrd.img") { + handle_missing_link("initrd.img", $image_dest, "initrd.img-$version", + $realimageloc); + } + else { + print STDERR + "Not updating initrd symbolic links since we are being updated/reinstalled \n"; + print STDERR + "($ARGV[1] was configured last, according to dpkg)\n"; + } + } + + if ($initrd && -l "initrd" ) { + unlink "initrd"; + } + + if ($initrd && -l "$image_dir/initrd" && ! $link_in_boot) { + unlink "$image_dir/initrd"; + } +} +else { # Not making an initrd emage + if (-l "initrd.img") { + # Ooh, last image was an initrd image? in any case, we should move it. + my $target = readlink "initrd.img"; + my $real_target = ''; + $real_target = abs_path($target) if defined ($target); + + if (!defined($target) || ! -f "$real_target") { + # Eh. dangling link. can safely be removed. + unlink("initrd.img"); + } else { + if (-l "initrd.img.old" || ! -e "initrd.img.old" ) { + rename("initrd.img", "initrd.img.old"); + } else { + warn "initrd.img.old is not a symlink, not clobbering\n"; + unlink("initrd.img"); + } + } + } +} + +# Warn of a reboot +if (-x $notifier) { + system($notifier); +} + +# Let programs know not to hibernate if the kernel that would be used for +# resume-from-hibernate is likely to differ from the currently running kernel. +system("mountpoint -q /var/run"); +if ($? eq 0) { + system("touch /var/run/do-not-hibernate"); +} + +# Only change the symlinks if we are not being upgraded +if (! defined $ARGV[1] || ! $ARGV[1] || $ARGV[1] =~ m//og) { + image_magic($kimage, $image_dest); +} +else { + if (! -e "$kimage") { + handle_missing_link($kimage, $image_dest, "$kimage-$version", + $realimageloc); + } + else { + print STDERR + "Not updating image symbolic links since we are being updated/reinstalled \n"; + print STDERR + "($ARGV[1] was configured last, according to dpkg)\n"; + } +} + +# We used to have System.* files in / +if (-e "/System.map" || -e "/System.old") { + unlink '/System.map' if -e '/System.map'; + unlink '/System.old' if -e '/System.old'; +} + +# creating some info about kernel and initrd +if ($DEBUG) { + my $ksize=sprintf("%.0f",(stat($realimageloc . + "$kimage-$version"))[7]/1024)."kB"; + my $initrdsize=''; + if ($initrd) { + $initrdsize=sprintf("%.0f",(stat($realimageloc . + "initrd.img-$version"))[7]/1024)."kB"; + } + + print STDERR <<"EOMSG"; +A new kernel image has been installed at $realimageloc$kimage-$version + (Size: $ksize) + +Symbolic links, unless otherwise specified, can be found in $image_dest + +EOMSG + ; + + if ($initrd) { + print STDERR <<"EOMSGA"; + + Initial rootdisk image: ${realimageloc}initrd.img-$version (Size: $initrdsize) +EOMSGA + ; + } +} + +# set the env var stem +$ENV{'STEM'} = "linux"; +sub exec_script { + my $type = shift; + my $script = shift; + print STDERR "Running $type hook script $script.\n"; + system ("$script $version $realimageloc$kimage-$version") && + print STDERR "User $type hook script [$script] "; + if ($?) { + if ($? == -1) { + print STDERR "failed to execute: $!\n"; + } + elsif ($? & 127) { + printf STDERR "died with signal %d, %s coredump\n", + ($? & 127), ($? & 128) ? 'with' : 'without'; + } + else { + printf STDERR "exited with value %d\n", $? >> 8; + } + exit $? >> 8; + } +} +sub run_hook { + my $type = shift; + my $script = shift; + if ($script =~ m,^/,) { + # Full path provided for the hook script + if (-x "$script") { + &exec_script($type,$script); + } + else { + die "The provided $type hook script [$script] could not be run.\n"; + } + } + else { + # Look for it in a safe path + for my $path ('/bin', '/sbin', '/usr/bin', '/usr/sbin') { + if (-x "$path/$script") { + &exec_script($type, "$path/$script"); + return 0; + } + } + # No luck + print STDERR "Could not find $type hook script [$script].\n"; + die "Looked in: '/bin', '/sbin', '/usr/bin', '/usr/sbin'\n"; + } +} + +## Run user hook script here, if any +if ($postinst_hook) { + &run_hook("postinst", $postinst_hook); +} + +if (-d "/etc/kernel/postinst.d") { + print STDERR "Examining /etc/kernel/postinst.d.\n"; + system ("run-parts --verbose --exit-on-error --arg=$version " . + "--arg=$realimageloc$kimage-$version " . + "/etc/kernel/postinst.d") && + die "Failed to process /etc/kernel/postinst.d"; +} + +if (-d "/etc/kernel/postinst.d/$version") { + print STDERR "Examining /etc/kernel/postinst.d/$version.\n"; + system ("run-parts --verbose --exit-on-error --arg=$version " . + "--arg=$realimageloc$kimage-$version " . + "/etc/kernel/postinst.d/$version") && + die "Failed to process /etc/kernel/postinst.d/$version"; +} + +LOADER: { + last unless $do_boot_enable; # Exit if explicitly asked to + + last if $loader =~ /silo/i; # SILO does not have to be executed. + last if $loader =~ /yaboot/i; # yaboot does not have to be executed. + last if $loader =~ /milo/i; # MILO does not have to be executed. + last if $loader =~ /nettrom/i; # NETTROM does not have to be executed. + last if $loader =~ /arcboot/i; # ARCBOOT does not have to be executed. + last if $loader =~ /delo/i; # DELO does not have to be executed. + last if $loader =~ /quik/i; # maintainer asked quik invocation to be ignored + + last unless $loaderloc; + last unless -x $loaderloc; + last unless $do_bootloader; + + if (-T "/etc/$loader.conf") { + # Trust and use the existing lilo.conf. + print STDERR "You already have a $Loader configuration in /etc/$loader.conf\n"; + my $ret = &run_lilo(); + exit $ret if $ret; + } +} + + +sub run_lilo (){ + my $ret; + # Try and figure out if the user really wants lilo to be run -- + # since the default is to run the boot laoder, which is ! grub -- but + # the user may be using grub now, and not changed the default. + + # So, if the user has explicitly asked for the loader to be run, or + # if there is no postinst hook, or if there is no grub installed -- + # we are OK. Or else, we ask. + if ($explicit_do_loader || (! ($postinst_hook && -x '/usr/sbin/grub'))) { + print STDERR "Running boot loader as requested\n"; + } else { + print STDERR "Ok, not running $loader\n"; + } + if ($loader =~ /^lilo/io or $loader =~ /vmelilo/io) { + print STDERR "Testing $loader.conf ... \n"; + unlink $temp_file_name; # security + $ret = system("$loaderloc -t >$temp_file_name 2>&1"); + if ($ret) { + print STDERR "Boot loader test failed\n"; + return $ret; + } + unlink "$temp_file_name"; + print STDERR "Testing successful.\n"; + print STDERR "Installing the "; + print STDERR "partition " if $loader =~ /^lilo/io; + print STDERR "boot sector... \n"; + } + + print STDERR "Running $loaderloc ... \n"; + if ($loader =~ /^elilo/io) { + $ret = system("$loaderloc 2>&1 | tee $temp_file_name"); + } else { + $ret = system("$loaderloc >$temp_file_name 2>&1"); + } + if ($ret) { + print STDERR "Boot loader failed to run\n"; + return $ret; + } + unlink $temp_file_name; + print STDERR "Installation successful.\n"; + return 0; +} + +exit 0; + +__END__ + --- linux-2.6.24.orig/debian/control-scripts/preinst +++ linux-2.6.24/debian/control-scripts/preinst @@ -0,0 +1,299 @@ +#! /usr/bin/perl +# -*- Mode: Cperl -*- +# image.preinst --- +# Author : Manoj Srivastava ( srivasta@tiamat.datasync.com ) +# Created On : Sun Jun 14 03:38:02 1998 +# Created On Node : tiamat.datasync.com +# Last Modified By : Manoj Srivastava +# Last Modified On : Sun Sep 24 14:04:42 2006 +# Last Machine Used: glaurung.internal.golden-gryphon.com +# Update Count : 99 +# Status : Unknown, Use with caution! +# HISTORY : +# Description : +# +# + +# +#use strict; #for debugging + +use Debconf::Client::ConfModule qw(:all); +version('2.0'); +my $capb=capb("backup"); + +$|=1; + +# Predefined values: +my $version = "=V"; +my $link_in_boot = ""; # Should be empty, mostly +my $no_symlink = ""; # Should be empty, mostly +my $reverse_symlink = ""; # Should be empty, mostly +my $do_symlink = "Yes"; # target machine defined +my $do_boot_enable = "Yes"; # target machine defined +my $do_bootfloppy = "Yes"; # target machine defined +my $do_bootloader = "Yes"; # target machine defined +my $move_image = ''; # target machine defined +my $kimage = "=K"; # Should be empty, mostly +my $loader = "=L"; # lilo, silo, quik, palo, vmelilo, nettrom + # or elilo +my $image_dir = "/boot"; # where the image is located +my $initrd = "YES"; # initrd kernel +my $use_hard_links = ''; # hardlinks do not wirk across fs boundaries +my $postinst_hook = ''; #Normally we do not +my $postrm_hook = ''; #Normally we do not +my $preinst_hook = ''; #Normally we do not +my $prerm_hook = ''; #Normally we do not +my $minimal_swap = ''; # Do not swap symlinks +my $ignore_depmod_err = ''; # normally we do not +my $relink_src_link = 'YES'; # There is no harm in checking the link +my $relink_build_link = 'YES'; # There is no harm in checking the link +my $force_build_link = ''; # There is no harm in checking the link +my $kernel_arch = "=B"; +my $ramdisk = "/usr/sbin/update-initramfs"; # List of tools to create initial ram fs. +my $package_name = "linux-image-$version"; + +my $Loader = "NoLOADER"; # +$Loader = "LILO" if $loader =~ /^lilo/io; +$Loader = "SILO" if $loader =~ /^silo/io; +$Loader = "QUIK" if $loader =~ /^quik/io; +$Loader = "yaboot" if $loader =~ /^yaboot/io; +$Loader = "PALO" if $loader =~ /^palo/io; +$Loader = "NETTROM" if $loader =~ /^nettrom/io; +$Loader = "VMELILO" if $loader =~ /^vmelilo/io; +$Loader = "ZIPL" if $loader =~ /^zipl/io; +$Loader = "ELILO" if $loader =~ /^elilo/io; + + +#known variables +my @boilerplate = (); +my @silotemplate = (); +my @quiktemplate = (); +my @palotemplate = (); +my @vmelilotemplate = (); +my $bootdevice = ''; +my $rootdevice = ''; +my $rootdisk = ''; +my $rootpartition = ''; +my $image_dest = "/"; +my $realimageloc = "/$image_dir/"; +my $have_conffile = ""; +my $CONF_LOC = '/etc/kernel-img.conf'; +my $relative_links = ''; +my $silent_loader = ''; +my $warn_reboot = ''; # Warn that we are installing a version of + # the kernel we are running + +my $modules_base = '/lib/modules'; + +die "Pre inst Internal error. Aborting." unless $version; + +exit 0 if $ARGV[0] =~ /abort-upgrade/; +exit 1 unless $ARGV[0] =~ /(install|upgrade)/; + +# remove multiple leading slashes; make sure there is at least one. +$realimageloc =~ s|^/*|/|o; +$realimageloc =~ s|/+|/|o; + +if (-r "$CONF_LOC" && -f "$CONF_LOC" ) { + if (open(CONF, "$CONF_LOC")) { + while () { + chomp; + s/\#.*$//g; + next if /^\s*$/; + + $do_symlink = "" if /^\s*do_symlinks\s*=\s*(no|false|0)\s*$/ig; + $no_symlink = "" if /^\s*no_symlinks\s*=\s*(no|false|0)\s*$/ig; + $reverse_symlink = "" if /^\s*reverse_symlinks\s*=\s*(no|false|0)\s*$/ig; + $link_in_boot = "" if /^\s*image_in_boot\s*=\s*(no|false|0)\s*$/ig; + $link_in_boot = "" if /^\s*link_in_boot\s*=\s*(no|false|0)\s*$/ig; + $move_image = "" if /^\s*move_image\s*=\s*(no|false|0)\s*$/ig; + $do_boot_enable = '' if /^\s*do_boot_enable\s*=\s*(no|false|0)\s*$/ig; + $do_bootfloppy = '' if /^\s*do_bootfloppy\s*=\s*(no|false|0)\s*$/ig; + $do_bootloader = '' if /^\s*do_bootloader\s*=\s*(no|false|0)\s*$/ig; + $relative_links = '' if /^\s*relative_links \s*=\s*(no|false|0)\s*$/ig; + $use_hard_links = '' if /^\s*use_hard_links\s*=\s*(no|false|0)\s*$/ig; + $silent_loader = '' if /^\s*silent_loader\s*=\s*(no|false|0)\s*$/ig; + $warn_reboot = '' if /^\s*warn_reboot\s*=\s*(no|false|0)\s*$/ig; + $minimal_swap = '' if /^\s*minimal_swap\s*=\s*(no|false|0)\s*$/ig; + $ignore_depmod_err = '' if /^\s*ignore_depmod_err\s*=\s*(no|false|0)\s*$/ig; + $relink_src_link = '' if /^\s*relink_src_link\s*=\s*(no|false|0)\s*$/ig; + $relink_build_link = '' if /^\s*relink_build_link\s*=\s*(no|false|0)\s*$/ig; + $force_build_link = '' if /^\s*force_build_link\s*=\s*(no|false|0)\s*$/ig; + + $do_symlink = "Yes" if /^\s*do_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $no_symlink = "Yes" if /^\s*no_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $reverse_symlink = "Yes" if /^\s*reverse_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $link_in_boot = "Yes" if /^\s*image_in_boot\s*=\s*(yes|true|1)\s*$/ig; + $link_in_boot = "Yes" if /^\s*link_in_boot\s*=\s*(yes|true|1)\s*$/ig; + $move_image = "Yes" if /^\s*move_image\s*=\s*(yes|true|1)\s*$/ig; + $do_boot_enable = "Yes" if /^\s*do_boot_enable\s*=\s*(yes|true|1)\s*$/ig; + $do_bootfloppy = "Yes" if /^\s*do_bootfloppy\s*=\s*(yes|true|1)\s*$/ig; + $do_bootloader = "Yes" if /^\s*do_bootloader\s*=\s*(yes|true|1)\s*$/ig; + $relative_links = "Yes" if /^\s*relative_links\s*=\s*(yes|true|1)\s*$/ig; + $use_hard_links = "Yes" if /^\s*use_hard_links\s*=\s*(yes|true|1)\s*$/ig; + $silent_loader = 'Yes' if /^\s*silent_loader\s*=\s*(yes|true|1)\s*$/ig; + $warn_reboot = 'Yes' if /^\s*warn_reboot\s*=\s*(yes|true|1)\s*$/ig; + $minimal_swap = 'Yes' if /^\s*minimal_swap\s*=\s*(yes|true|1)\s*$/ig; + $ignore_depmod_err = 'Yes' if /^\s*ignore_depmod_err\s*=\s*(yes|true|1)\s*$/ig; + $relink_src_link = 'Yes' if /^\s*relink_src_link\s*=\s*(yes|true|1)\s*$/ig; + $relink_build_link = 'Yes' if /^\s*relink_build_link\s*=\s*(yes|true|1)\s*$/ig; + $force_build_link = 'Yes' if /^\s*force_build_link\s*=\s*(yes|true|1)\s*$/ig; + + $image_dest = "$1" if /^\s*image_dest\s*=\s*(\S+)/ig; + $postinst_hook = "$1" if /^\s*postinst_hook\s*=\s*(\S+)/ig; + $postrm_hook = "$1" if /^\s*postrm_hook\s*=\s*(\S+)/ig; + $preinst_hook = "$1" if /^\s*preinst_hook\s*=\s*(\S+)/ig; + $prerm_hook = "$1" if /^\s*prerm_hook\s*=\s*(\S+)/ig; + $ramdisk = "$1" if /^\s*ramdisk\s*=\s*(.+)$/ig; + } + close CONF; + $have_conffile = "Yes"; + $have_conffile = "Yes"; # stop perl complaining + } +} + +$ENV{KERNEL_ARCH}=$kernel_arch if $kernel_arch; + +# About to upgrade this package from version $2 TO THIS VERSION. +# "prerm upgrade" has already been called for the old version of +# this package. + +sub find_initrd_tool { + my $hostversion = shift; + my $version = shift; + my @ramdisks = + grep { + my $args = + "$_ " . + "--supported-host-version=$hostversion " . + "--supported-target-version=$version " . + "1>/dev/null 2>&1" + ; + system($args) == 0; + } + split (/[:,\s]+/, $ramdisk); +} + +sub check { + my $version = shift; + my $lib_modules="$modules_base/$version"; + my $message = ''; + + if (-d "$lib_modules") { + opendir(DIR, $lib_modules) || die "can’t opendir $lib_modules: $!"; + my @children = readdir(DIR); + if ($#children > 1) { + my @dirs = grep { -d "$lib_modules/$_" } @children; + if ($#dirs > 1) { # we have subdirs + my $dir_message=''; + for my $dir (@dirs) { + if ($dir =~/kernel$/) { + $dir_message="An older install was detected.\n"; + } + else { + $dir_message="Module sub-directories were detected.\n" + unless $dir_message; + } + } + $message += $dir_message if $dir_message; + } + + my @links = grep { -l "$lib_modules/$_" } @children; + if ($#links > -1) { + my $links_message = ''; + for my $link (@links) { + next if ($link =~ /^build$/); + next if ($link =~ /^source$/); + $links_message = "Symbolic links were detected in $modules_base/$version.\n"; + } + $message += $links_message if $links_message; + } + my @files = grep { -f "$lib_modules/$_" } @children; + $message += "Additional files also exist in $modules_base/$version.\n" + if ($#files > -1); + } + } + else { $message .= "$lib_modules does not exist. ";} + return $message; +} + +if (-d "$modules_base/$version") { + my $errors=check($version); + warn "Info:\n$errors\n" if $errors; +} + +# set the env var stem +$ENV{'STEM'} = "linux"; + +sub exec_script { + my $type = shift; + my $script = shift; + print STDERR "Running $type hook script $script.\n"; + system ("$script $version $realimageloc$kimage-$version") && + print STDERR "User $type hook script [$script] "; + if ($?) { + if ($? == -1) { + print STDERR "failed to execute: $!\n"; + } + elsif ($? & 127) { + printf STDERR "died with signal %d, %s coredump\n", + ($? & 127), ($? & 128) ? 'with' : 'without'; + } + else { + printf STDERR "exited with value %d\n", $? >> 8; + } + exit $? >> 8; + } +} +sub run_hook { + my $type = shift; + my $script = shift; + if ($script =~ m,^/,) { + # Full path provided for the hook script + if (-x "$script") { + &exec_script($type,$script); + } + else { + die "The provided $type hook script [$script] could not be run.\n"; + } + } + else { + # Look for it in a safe path + for my $path ('/bin', '/sbin', '/usr/bin', '/usr/sbin') { + if (-x "$path/$script") { + &exec_script($type, "$path/$script"); + return 0; + } + } + # No luck + print STDERR "Could not find $type hook script [$script].\n"; + die "Looked in: '/bin', '/sbin', '/usr/bin', '/usr/sbin'\n"; + } +} + + +## Run user hook script here, if any +if (-x "$preinst_hook") { + &run_hook("preinst", $preinst_hook); +} +if (-d "/etc/kernel/preinst.d") { + print STDERR "Examining /etc/kernel/preinst.d/\n"; + system ("run-parts --verbose --exit-on-error --arg=$version" . + " --arg=$realimageloc$kimage-$version" . + " /etc/kernel/preinst.d") && + die "Failed to process /etc/kernel/preinst.d"; +} +if (-d "/etc/kernel/preinst.d/$version") { + print STDERR "Examining /etc/kernel/preinst.d/$version.\n"; + system ("run-parts --verbose --exit-on-error --arg=$version" . + " --arg=$realimageloc$kimage-$version" . + " /etc/kernel/preinst.d/$version") && + die "Failed to process /etc/kernel/preinst.d/$version"; +} +print STDERR "Done.\n"; + +exit 0; + +__END__ + + --- linux-2.6.24.orig/debian/control-scripts/headers-postinst +++ linux-2.6.24/debian/control-scripts/headers-postinst @@ -0,0 +1,126 @@ +#!/usr/bin/perl +# -*- Mode: Cperl -*- +# debian.postinst --- +# Author : Manoj Srivastava ( srivasta@pilgrim.umass.edu ) +# Created On : Sat Apr 27 05:42:43 1996 +# Created On Node : melkor.pilgrim.umass.edu +# Last Modified By : Manoj Srivastava +# Last Modified On : Sat Aug 5 13:20:22 2006 +# Last Machine Used: glaurung.internal.golden-gryphon.com +# Update Count : 45 +# Status : Unknown, Use with caution! +# HISTORY : +# Description : +# +# +# +# arch-tag: 1c716174-2f0a-476d-a626-a1322e62503a +# + + +$|=1; + +# Predefined values: +my $version = "=V"; +my $kimage = "=K"; +my $package_name = "linux-image-$version"; + + +# Ignore all invocations uxcept when called on to configure. +exit 0 unless ($ARGV[0] && $ARGV[0] =~ /configure/); + +#known variables +my $image_dest = "/"; +my $realimageloc = "/boot/"; +my $silent_modules = ''; +my $modules_base = '/lib/modules'; +my $CONF_LOC = '/etc/kernel-img.conf'; +# remove multiple leading slashes; make sure there is at least one. +$realimageloc =~ s|^/*|/|o; +$realimageloc =~ s|/+|/|o; + +chdir '/usr/src' or die "Could not chdir to /usr/src:$!"; + +if (-r "$CONF_LOC" && -f "$CONF_LOC" ) { + if (open(CONF, "$CONF_LOC")) { + while () { + chomp; + s/\#.*$//g; + next if /^\s*$/; + + $header_postinst_hook = "$1" if /^\s*header_postinst_hook\s*=\s*(\S+)/ig; + } + close CONF; + } +} + +sub exec_script { + my $type = shift; + my $script = shift; + print STDERR "Running $type hook script $script.\n"; + system ("$script $version $realimageloc$kimage-$version") && + print STDERR "User $type hook script [$script] "; + if ($?) { + if ($? == -1) { + print STDERR "failed to execute: $!\n"; + } + elsif ($? & 127) { + printf STDERR "died with signal %d, %s coredump\n", + ($? & 127), ($? & 128) ? 'with' : 'without'; + } + else { + printf STDERR "exited with value %d\n", $? >> 8; + } + exit $? >> 8; + } +} +sub run_hook { + my $type = shift; + my $script = shift; + if ($script =~ m,^/,) { + # Full path provided for the hook script + if (-x "$script") { + &exec_script($type,$script); + } + else { + die "The provided $type hook script [$script] could not be run.\n"; + } + } + else { + # Look for it in a safe path + for my $path ('/bin', '/sbin', '/usr/bin', '/usr/sbin') { + if (-x "$path/$script") { + &exec_script($type, "$path/$script"); + return 0; + } + } + # No luck + print STDERR "Could not find $type hook script [$script].\n"; + die "Looked in: '/bin', '/sbin', '/usr/bin', '/usr/sbin'\n"; + } +} + +## Run user hook script here, if any +if (-x "$header_postinst_hook") { + &run_hook("postinst", $header_postinst_hook); +} + +if (-d "/etc/kernel/header_postinst.d") { + print STDERR "Examining /etc/kernel/header_postinst.d.\n"; + system ("run-parts --verbose --exit-on-error --arg=$version " . + "--arg=$realimageloc$kimage-$version " . + "/etc/kernel/header_postinst.d") && + die "Failed to process /etc/kernel/header_postinst.d"; +} + +if (-d "/etc/kernel/header_postinst.d/$version") { + print STDERR "Examining /etc/kernel/header_postinst.d/$version.\n"; + system ("run-parts --verbose --exit-on-error --arg=$version " . + "--arg=$realimageloc$kimage-$version " . + "/etc/kernel/header_postinst.d/$version") && + die "Failed to process /etc/kernel/header_postinst.d/$version"; +} + +exit 0; + +__END__ --- linux-2.6.24.orig/debian/control-scripts/prerm +++ linux-2.6.24/debian/control-scripts/prerm @@ -0,0 +1,294 @@ +#! /usr/bin/perl +# -*- Mode: Perl -*- +# image.prerm --- +# Author : root ( root@melkor.pilgrim.umass.edu ) +# Created On : Fri May 17 03:28:59 1996 +# Created On Node : melkor.pilgrim.umass.edu +# Last Modified By : Manoj Srivastava +# Last Modified On : Sat Aug 5 13:14:17 2006 +# Last Machine Used: glaurung.internal.golden-gryphon.com +# Update Count : 85 +# Status : Unknown, Use with caution! +# HISTORY : +# Description : +# +# +# $Id: image.prerm,v 1.22 2003/10/07 16:24:20 srivasta Exp $ +# +# +#use strict; + +$|=1; +# Predefined values: +my $version = "=V"; +my $link_in_boot = ""; # Should be empty, mostly +my $no_symlink = ""; # Should be empty, mostly +my $reverse_symlink = ""; # Should be empty, mostly +my $do_symlinks = "Yes"; # target machine defined +my $do_boot_enable = "Yes"; # target machine defined +my $do_bootfloppy = "Yes"; # target machine defined +my $do_bootloader = "Yes"; # target machine defined +my $move_image = ''; # target machine defined +my $kimage = "=K"; # Should be empty, mostly +my $loader = "=L"; # lilo, silo, quik, palo, vmelilo, or nettrom +my $image_dir = "/boot"; # where the image is located +my $clobber_modules = ''; # target machine defined +my $initrd = "YES"; # initrd kernel +my $use_hard_links = ''; # hardlinks do not wirk across fs boundaries +my $postinst_hook = ''; #Normally we do not +my $postrm_hook = ''; #Normally we do not +my $preinst_hook = ''; #Normally we do not +my $prerm_hook = ''; #Normally we do not +my $minimal_swap = ''; # Do not swap symlinks +my $ignore_depmod_err = ''; # normally we do not +my $relink_build_link = 'YES'; # There is no harm in checking the link +my $force_build_link = ''; # There is no harm in checking the link +my $kernel_arch = "=B"; +my $ramdisk = "/usr/sbin/update-initramfs"; +my $package_name = "linux-image-$version"; + +my $Loader = "NoLOADER"; # +$Loader = "LILO" if $loader =~ /^lilo/io; +$Loader = "SILO" if $loader =~ /^silo/io; +$Loader = "QUIK" if $loader =~ /^quik/io; +$Loader = "yaboot" if $loader =~ /^yaboot/io; +$Loader = "PALO" if $loader =~ /^palo/io; +$Loader = "NETTROM" if $loader =~ /^nettrom/io; +$Loader = "VMELILO" if $loader =~ /^vmelilo/io; +$Loader = "ZIPL" if $loader =~ /^zipl/io; +$Loader = "ELILO" if $loader =~ /^elilo/io; + + +# This should not point to /tmp, because of security risks. +my $temp_file_name = "/var/log/$loader" . "_log.$$"; + +#known variables +my $image_dest = "/"; +my $realimageloc = "/$image_dir/"; +my $have_conffile = ""; +my $CONF_LOC = '/etc/kernel-img.conf'; +my $relative_links = ''; +my $silent_loader = ''; +my $warn_reboot = 'Yes'; # Warn that we are installing a version of + # the kernel we are running + +# remove multiple leading slashes; make sure there is at least one. +$realimageloc =~ s|^/*|/|o; +$realimageloc =~ s|/+|/|o; + +my $DEBUG = 0; + +# Variables used +my $image=''; +my $ret=0; +my $seen=''; +my $answer=''; +my $running = ''; +my $WouldInvalidate = 0; + +if ($ARGV[0] && ($ARGV[0] =~ /remove/ || $ARGV[0] =~ /upgrade/)) { + if (-l "/usr/doc/linux-image-$version") { + unlink "/usr/doc/linux-image-$version"; + } +} + +# Ignore all invocations uxcept when called on to remove +exit 0 unless ($ARGV[0] && $ARGV[0] =~ /remove/) ; + +# Paranoid check to make sure that the correct value is put in there +if (! $kimage) { $kimage = "vmlinuz";} # Hmm. empty +elsif ($kimage =~ m/^b?zImage$/o) { $kimage = "vmlinuz";} # these produce vmlinuz +elsif ($kimage =~ m/^[iI]mage$/o) { my $nop = $kimage; } +elsif ($kimage =~ m/^vmlinux$/o) { my $nop = $kimage; } +else { $kimage = "vmlinuz";} # Default + +if (-r "$CONF_LOC" && -f "$CONF_LOC" ) { + if (open(CONF, "$CONF_LOC")) { + while () { + chomp; + s/\#.*$//g; + next if /^\s*$/; + + $do_symlink = "" if /^\s*do_symlinks\s*=\s*(no|false|0)\s*$/ig; + $no_symlink = "" if /^\s*no_symlinks\s*=\s*(no|false|0)\s*$/ig; + $reverse_symlink = "" if /^\s*reverse_symlinks\s*=\s*(no|false|0)\s*$/ig; + $link_in_boot = "" if /^\s*image_in_boot\s*=\s*(no|false|0)\s*$/ig; + $link_in_boot = "" if /^\s*link_in_boot\s*=\s*(no|false|0)\s*$/ig; + $move_image = "" if /^\s*move_image\s*=\s*(no|false|0)\s*$/ig; + $clobber_modules = '' if /^\s*clobber_modules\s*=\s*(no|false|0)\s*$/ig; + $do_boot_enable = '' if /^\s*do_boot_enable\s*=\s*(no|false|0)\s*$/ig; + $do_bootfloppy = '' if /^\s*do_bootfloppy\s*=\s*(no|false|0)\s*$/ig; + $relative_links = '' if /^\s*relative_links \s*=\s*(no|false|0)\s*$/ig; + $do_bootloader = '' if /^\s*do_bootloader\s*=\s*(no|false|0)\s*$/ig; + $do_initrd = '' if /^\s*do_initrd\s*=\s*(no|false|0)\s*$/ig; + $use_hard_links = '' if /^\s*use_hard_links\s*=\s*(no|false|0)\s*$/ig; + $silent_loader = '' if /^\s*silent_loader\s*=\s*(no|false|0)\s*$/ig; + $warn_reboot = '' if /^\s*warn_reboot\s*=\s*(no|false|0)\s*$/ig; + $minimal_swap = '' if /^\s*minimal_swap\s*=\s*(no|false|0)\s*$/ig; + $ignore_depmod_err = '' if /^\s*ignore_depmod_err\s*=\s*(no|false|0)\s*$/ig; + $relink_build_link = '' if /^\s*relink_build_link\s*=\s*(no|false|0)\s*$/ig; + $force_build_link = '' if /^\s*force_build_link\s*=\s*(no|false|0)\s*$/ig; + + + $do_symlink = "Yes" if /^\s*do_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $no_symlink = "Yes" if /^\s*no_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $reverse_symlink = "Yes" if /^\s*reverse_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $link_in_boot = "Yes" if /^\s*image_in_boot\s*=\s*(yes|true|1)\s*$/ig; + $link_in_boot = "Yes" if /^\s*link_in_boot\s*=\s*(yes|true|1)\s*$/ig; + $move_image = "Yes" if /^\s*move_image\s*=\s*(yes|true|1)\s*$/ig; + $clobber_modules = "Yes" if /^\s*clobber_modules\s*=\s*(yes|true|1)\s*$/ig; + $do_boot_enable = "Yes" if /^\s*do_boot_enable\s*=\s*(yes|true|1)\s*$/ig; + $do_bootfloppy = "Yes" if /^\s*do_bootfloppy\s*=\s*(yes|true|1)\s*$/ig; + $do_bootloader = "Yes" if /^\s*do_bootloader\s*=\s*(yes|true|1)\s*$/ig; + $relative_links = "Yes" if /^\s*relative_links\s*=\s*(yes|true|1)\s*$/ig; + $do_initrd = "Yes" if /^\s*do_initrd\s*=\s*(yes|true|1)\s*$/ig; + $use_hard_links = "Yes" if /^\s*use_hard_links\s*=\s*(yes|true|1)\s*$/ig; + $silent_loader = 'Yes' if /^\s*silent_loader\s*=\s*(yes|true|1)\s*$/ig; + $warn_reboot = 'Yes' if /^\s*warn_reboot\s*=\s*(yes|true|1)\s*$/ig; + $minimal_swap = 'Yes' if /^\s*minimal_swap\s*=\s*(yes|true|1)\s*$/ig; + $ignore_depmod_err = 'Yes' if /^\s*ignore_depmod_err\s*=\s*(yes|true|1)\s*$/ig; + $relink_build_link = 'Yes' if /^\s*relink_build_link\s*=\s*(yes|true|1)\s*$/ig; + $force_build_link = 'Yes' if /^\s*force_build_link\s*=\s*(yes|true|1)\s*$/ig; + + $image_dest = "$1" if /^\s*image_dest\s*=\s*(\S+)/ig; + $postinst_hook = "$1" if /^\s*postinst_hook\s*=\s*(\S+)/ig; + $postrm_hook = "$1" if /^\s*postrm_hook\s*=\s*(\S+)/ig; + $preinst_hook = "$1" if /^\s*preinst_hook\s*=\s*(\S+)/ig; + $prerm_hook = "$1" if /^\s*prerm_hook\s*=\s*(\S+)/ig; + $ramdisk = "$1" if /^\s*ramdisk\s*=\s*(.+)$/ig; + } + close CONF; + $have_conffile = "Yes"; + } +} + + +$ENV{KERNEL_ARCH}=$kernel_arch if $kernel_arch; + +#check to see if we are trying to remove a running kernel +# if so we abort right now. +chop($running=`uname -r`); +if ($running eq $version) { + print STDERR "WARN: Proceeding with removing running kernel image.\n"; +} + +#Now, they have an alternate kernel which they are currently running + +# This is just us being nice to lilo users. + +chdir("/") or die "could not chdir to /:$!\n"; + +if (-f "/etc/$loader.conf") { #I know, could be a link, but .. + open (LILO, "/etc/$loader.conf") || &success(); # this is not critical + while () { + chop; + s/\#.*//; # nix the comments + next unless /^\s*image\s*=\s(\S+)/o; + $image = $1; + if ($image && -e $image) { + while (defined($image) && -l $image) { + $image = readlink ($image); + } + if (defined($image) && -e $image) { + $WouldInvalidate |= $image =~ /$kimage-$version/; + } + else { + &success(); # invalid $loader.conf file + } + } + else { + &success(); # invalid $loader.conf file + } + } + close (LILO); + if ($WouldInvalidate) { + print STFERR "WARN: Proceeding with removing running kernel image.\n"; + &success(); + } +} + + +# set the env var stem +$ENV{'STEM'} = "linux"; + +sub exec_script { + my $type = shift; + my $script = shift; + print STDERR "Running $type hook script $script.\n"; + system ("$script $version $realimageloc$kimage-$version") && + print STDERR "User $type hook script [$script] "; + if ($?) { + if ($? == -1) { + print STDERR "failed to execute: $!\n"; + } + elsif ($? & 127) { + printf STDERR "died with signal %d, %s coredump\n", + ($? & 127), ($? & 128) ? 'with' : 'without'; + } + else { + printf STDERR "exited with value %d\n", $? >> 8; + } + exit $? >> 8; + } +} +sub run_hook { + my $type = shift; + my $script = shift; + if ($script =~ m,^/,) { + # Full path provided for the hook script + if (-x "$script") { + &exec_script($type,$script); + } + else { + die "The provided $type hook script [$script] could not be run.\n"; + } + } + else { + # Look for it in a safe path + for my $path ('/bin', '/sbin', '/usr/bin', '/usr/sbin') { + if (-x "$path/$script") { + &exec_script($type, "$path/$script"); + return 0; + } + } + # No luck + print STDERR "Could not find $type hook script [$script].\n"; + die "Looked in: '/bin', '/sbin', '/usr/bin', '/usr/sbin'\n"; + } +} + + +## Run user hook script here, if any +if (-x "$prerm_hook") { + &run_hook("prerm", $prerm_hook); +} +if (-d "/etc/kernel/prerm.d") { + print STDERR "Examining /etc/kernel/prerm.d.\n"; + system ("run-parts --verbose --exit-on-error --arg=$version " . + "--arg=$realimageloc$kimage-$version /etc/kernel/prerm.d") && + die "Failed to process /etc/kernel/prerm.d"; +} +if (-d "/etc/kernel/prerm.d/$version") { + print STDERR "Examining /etc/kernel/prerm.d/$version.\n"; + system ("run-parts --verbose --exit-on-error --arg=$version" . + " --arg=$realimageloc$kimage-$version " . + "/etc/kernel/prerm.d/$version") && + die "Failed to process /etc/kernel/prerm.d/$version"; +} + +sub success () { + -f "/lib/modules/$version/modules.dep" && + unlink "/lib/modules/$version/modules.dep"; + exit 0; +} + + + +&success(); +exit 0; +__END__ + + + + + --- linux-2.6.24.orig/debian/stamps/keep-dir +++ linux-2.6.24/debian/stamps/keep-dir @@ -0,0 +1 @@ +Place holder --- linux-2.6.24.orig/debian/control.d/vars.generic +++ linux-2.6.24/debian/control.d/vars.generic @@ -0,0 +1,7 @@ +arch="i386 amd64" +supported="Generic" +target="Geared toward desktop systems." +desc="x86/x86_64" +bootloader="lilo (>= 19.1) | grub" +provides="kvm-api-4, redhat-cluster-modules, ivtv-modules" +do_debug="Yes" --- linux-2.6.24.orig/debian/control.d/vars.sparc64-smp +++ linux-2.6.24/debian/control.d/vars.sparc64-smp @@ -0,0 +1,6 @@ +supported="64-bit UltraSPARC SMP" +target="Geared toward desktop or server systems." +desc="64-bit UltraSPARC SMP" +bootloader="silo" +provides="redhat-cluster-modules, ivtv-modules" +arch="sparc" --- linux-2.6.24.orig/debian/control.d/vars.sparc64 +++ linux-2.6.24/debian/control.d/vars.sparc64 @@ -0,0 +1,6 @@ +supported="64-bit UltraSPARC" +target="Geared toward desktop or server systems." +desc="64-bit UltraSPARC" +bootloader="silo" +provides="redhat-cluster-modules, ivtv-modules" +arch="sparc" --- linux-2.6.24.orig/debian/control.d/vars.hppa64 +++ linux-2.6.24/debian/control.d/vars.hppa64 @@ -0,0 +1,9 @@ +supported="64-bit HP PA-RISC SMP" +target="Geared toward desktop or server systems." +desc="64-bit HP PA-RISC SMP" +bootloader="palo" +provides="redhat-cluster-modules" +arch="hppa" + +# Keep in sync with debian/control.stub.in Build-Depends. +header_depends="gcc-4.1-hppa64, binutils-hppa64," --- linux-2.6.24.orig/debian/control.d/vars.server +++ linux-2.6.24/debian/control.d/vars.server @@ -0,0 +1,7 @@ +arch="i386 amd64" +supported="Server" +target="Geared toward server systems." +desc="x86/x86_64" +bootloader="lilo (>= 19.1) | grub" +provides="redhat-cluster-modules, kvm-api-4, ivtv-modules" +do_debug="Yes" --- linux-2.6.24.orig/debian/control.d/vars.hppa32 +++ linux-2.6.24/debian/control.d/vars.hppa32 @@ -0,0 +1,9 @@ +supported="32-bit HP PA-RISC SMP" +target="Geared toward desktop or server systems." +desc="32-bit HP PA-RISC SMP" +bootloader="palo" +provides="redhat-cluster-modules" +arch="hppa" + +# Keep in sync with debian/control.stub.in Build-Depends. +header_depends="gcc-4.1," --- linux-2.6.24.orig/debian/control.d/vars.powerpc +++ linux-2.6.24/debian/control.d/vars.powerpc @@ -0,0 +1,9 @@ +supported="32-bit PowerPC" +target="Geared toward desktop or server systems." +desc="32-bit PowerPC" +bootloader="yaboot" +provides="redhat-cluster-modules, ivtv-modules" +arch="powerpc" + +# Keep in sync with debian/control.stub.in Build-Depends. +header_depends="gcc-4.1," --- linux-2.6.24.orig/debian/control.d/vars.powerpc-smp +++ linux-2.6.24/debian/control.d/vars.powerpc-smp @@ -0,0 +1,9 @@ +supported="32-bit PowerPC SMP" +target="Geared toward desktop or server systems." +desc="32-bit PowerPC SMP" +bootloader="yaboot" +provides="redhat-cluster-modules, ivtv-modules" +arch="powerpc" + +# Keep in sync with debian/control.stub.in Build-Depends. +header_depends="gcc-4.1," --- linux-2.6.24.orig/debian/control.d/vars.itanium +++ linux-2.6.24/debian/control.d/vars.itanium @@ -0,0 +1,9 @@ +supported="Itanium SMP" +target="Geared toward desktop or server systems." +desc="Itanium SMP" +bootloader="elilo (>= 3.6-1)" +provides="redhat-cluster-modules, ivtv-modules" +arch="ia64" + +# Keep in sync with debian/control.stub.in Build-Depends. +header_depends="gcc-4.1," --- linux-2.6.24.orig/debian/control.d/flavour-control.stub +++ linux-2.6.24/debian/control.d/flavour-control.stub @@ -0,0 +1,52 @@ +# Items that get replaced: +# FLAVOUR +# DESC +# ARCH +# SUPPORTED +# TARGET +# BOOTLOADER +# =PROVIDES= +# =HEADER_DEPENDS= +# +# Items marked with =FOO= are optional +# +# XXX: Leave the blank line before the first package!! + +Package: linux-image-PKGVER-ABINUM-FLAVOUR +Architecture: ARCH +Section: SECTION_IMAGE +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, =PROVIDES= +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: BOOTLOADER +Suggests: fdutils, linux-doc-PKGVER | linux-source-PKGVER +Description: Linux kernel image for version PKGVER on DESC + This package contains the Linux kernel image for version PKGVER on + DESC. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports SUPPORTED processors. + . + TARGET + . + You likely do not want to install this package directly. Instead, install + the linux-FLAVOUR meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-PKGVER-ABINUM-FLAVOUR +Architecture: ARCH +Section: SECTION_HEADERS +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-PKGVER-ABINUM, =HEADER_DEPENDS= ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version PKGVER on DESC + This package provides kernel header files for version PKGVER on + DESC. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-PKGVER-ABINUM/debian.README.gz for details. --- linux-2.6.24.orig/debian/control.d/vars.virtual +++ linux-2.6.24/debian/control.d/vars.virtual @@ -0,0 +1,7 @@ +arch="i386" +supported="Virtual" +target="Geared toward virtualised hardware." +desc="x86" +bootloader="lilo (>= 19.1) | grub" +provides="kvm-api-4, redhat-cluster-modules" +do_debug="Yes" --- linux-2.6.24.orig/debian/control.d/flavour-control-debug.stub +++ linux-2.6.24/debian/control.d/flavour-control-debug.stub @@ -0,0 +1,26 @@ +# Items that get replaced: +# FLAVOUR +# DESC +# ARCH +# SUPPORTED +# TARGET +# BOOTLOADER +# =PROVIDES= +# +# Items marked with =FOO= are optional +# +# XXX: Leave the blank line before the first package!! + +Package: linux-image-debug-PKGVER-ABINUM-FLAVOUR +Architecture: ARCH +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version PKGVER on DESC + This package provides a kernel debug image for version PKGVER on + DESC. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. --- linux-2.6.24.orig/debian/control.d/vars.powerpc64-smp +++ linux-2.6.24/debian/control.d/vars.powerpc64-smp @@ -0,0 +1,9 @@ +supported="64-bit PowerPC SMP" +target="Geared toward desktop or server systems." +desc="64-bit PowerPC SMP" +bootloader="yaboot" +provides="redhat-cluster-modules, ivtv-modules" +arch="powerpc" + +# Keep in sync with debian/control.stub.in Build-Depends. +header_depends="gcc-4.1," --- linux-2.6.24.orig/debian/control.d/vars.mckinley +++ linux-2.6.24/debian/control.d/vars.mckinley @@ -0,0 +1,9 @@ +supported="Itanium II SMP" +target="Geared toward desktop or server systems." +desc="Itanium II SMP" +bootloader="elilo (>= 3.6-1)" +provides="redhat-cluster-modules, ivtv-modules" +arch="ia64" + +# Keep in sync with debian/control.stub.in Build-Depends. +header_depends="gcc-4.1," --- linux-2.6.24.orig/debian/control.d/vars.386 +++ linux-2.6.24/debian/control.d/vars.386 @@ -0,0 +1,7 @@ +supported="Alternate x86 (486 and better)" +target="Geared toward desktop systems." +desc="i386" +bootloader="lilo (>= 19.1) | grub" +provides="kvm-api-4, ivtv-modules" +arch=i386 +do_debug="Yes" --- linux-2.6.24.orig/debian/binary-custom.d/README +++ linux-2.6.24/debian/binary-custom.d/README @@ -0,0 +1,46 @@ +Welcome to the answer to all your requests. + +The binary-custom target for the kernel allows easy building of special +kernels that would otherwise not be allowed in our tree. The way this is +achieved is to disaccociate the normal build process and patches required +for these kernels. + +In this directory, you will need to create 4 files for your custom +kernel. All files are placed in a subdirectory. This subdirectory is the +name of your flavour (IOW, what will be appended to 2.6.X-ABI- to get the +package name). So the subdirectory name should be package name safe (e.g., +no underscores). There are currently at least three files and one directory +required in each subdirectory: + + FLAV/config.ARCH : The kernel .config used to build the kernel + (one for each architecture this flavour will + build on). + + FLAV/patchset : The directory containing the patchset for this + flavour, to be applied with -p1. + + FLAV/rules : A make file snippet for any target overrides + (usually empty). See below for what can be here. + + FLAV/vars : Template for control file generation. + +The rules file can contain overrides for some variables used during the +build. Here is a list of what can be defined in this make file snippet: + + build_image_FLAV : The image make target (e.g. bzImage). + + kernel_file_FLAV : The resulting kernel image from the build. + +The patchset directory contains a series of patches, named using a convention +such as -.patch. e.g. 0001-foo.patch, 0002-bar.patch. The +patches will then be applied in increasing order by number. + +To add your custom kernel to the normal build, add it to the +custom_flavours var for each architecture it will build on in the +debian/rules.d/ARCH.mk file. + +Once done, you can specifically build the custom image using: + + fakeroot debian/rules custom-binary-FLAV + +That's it! --- linux-2.6.24.orig/debian/binary-custom.d/rt/rules +++ linux-2.6.24/debian/binary-custom.d/rt/rules @@ -0,0 +1 @@ +# Nothing special here --- linux-2.6.24.orig/debian/binary-custom.d/rt/config.amd64 +++ linux-2.6.24/debian/binary-custom.d/rt/config.amd64 @@ -0,0 +1,3677 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.24.7 +# Fri Nov 21 17:16:54 2008 +# +CONFIG_64BIT=y +# CONFIG_X86_32 is not set +CONFIG_X86_64=y +CONFIG_X86=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_SEMAPHORE_SLEEPERS=y +CONFIG_MMU=y +CONFIG_ZONE_DMA=y +# CONFIG_QUICKLIST is not set +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_DMI=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_ASM_SEMAPHORES=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_ZONE_DMA32=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_AUDIT_ARCH=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_X86_HT=y +# CONFIG_KTIME_SCALAR is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_VERSION_SIGNATURE="Ubuntu 2.6.24-4.6-generic" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +# CONFIG_TASK_DELAY_ACCT is not set +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y +CONFIG_AUDIT_TREE=y +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_CGROUPS=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_NS=y +CONFIG_CPUSETS=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_FAIR_USER_SCHED is not set +CONFIG_FAIR_CGROUP_SCHED=y +CONFIG_CGROUP_CPUACCT=y +# CONFIG_SYSFS_DEPRECATED is not set +CONFIG_PROC_PID_CPUSET=y +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_RADIX_TREE_CONCURRENT=y +CONFIG_RADIX_TREE_OPTIMISTIC=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y +CONFIG_STOP_MACHINE=y +CONFIG_BLOCK=y +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_BLK_DEV_BSG is not set +CONFIG_BLOCK_COMPAT=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_PREEMPT_NOTIFIERS=y + +# +# Processor type and features +# +CONFIG_TICK_ONESHOT=y +# CONFIG_NO_HZ is not set +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_SMP=y +CONFIG_X86_PC=y +# CONFIG_X86_ELAN is not set +# CONFIG_X86_VOYAGER is not set +# CONFIG_X86_NUMAQ is not set +# CONFIG_X86_SUMMIT is not set +# CONFIG_X86_BIGSMP is not set +# CONFIG_X86_VISWS is not set +# CONFIG_X86_GENERICARCH is not set +# CONFIG_X86_ES7000 is not set +# CONFIG_X86_VSMP is not set +# CONFIG_M386 is not set +# CONFIG_M486 is not set +# CONFIG_M586 is not set +# CONFIG_M586TSC is not set +# CONFIG_M586MMX is not set +# CONFIG_M686 is not set +# CONFIG_MPENTIUMII is not set +# CONFIG_MPENTIUMIII is not set +# CONFIG_MPENTIUMM is not set +# CONFIG_MPENTIUM4 is not set +# CONFIG_MK6 is not set +# CONFIG_MK7 is not set +# CONFIG_MK8 is not set +# CONFIG_MCRUSOE is not set +# CONFIG_MEFFICEON is not set +# CONFIG_MWINCHIPC6 is not set +# CONFIG_MWINCHIP2 is not set +# CONFIG_MWINCHIP3D is not set +# CONFIG_MGEODEGX1 is not set +# CONFIG_MGEODE_LX is not set +# CONFIG_MCYRIXIII is not set +# CONFIG_MVIAC3_2 is not set +# CONFIG_MVIAC7 is not set +# CONFIG_MPSC is not set +# CONFIG_MCORE2 is not set +CONFIG_GENERIC_CPU=y +CONFIG_X86_L1_CACHE_BYTES=128 +CONFIG_X86_INTERNODE_CACHE_BYTES=128 +CONFIG_X86_CMPXCHG=y +CONFIG_X86_L1_CACHE_SHIFT=7 +CONFIG_X86_GOOD_APIC=y +CONFIG_X86_TSC=y +CONFIG_X86_MINIMUM_CPU_FAMILY=64 +CONFIG_HPET_TIMER=y +CONFIG_HPET_EMULATE_RTC=y +CONFIG_GART_IOMMU=y +CONFIG_CALGARY_IOMMU=y +CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT=y +CONFIG_SWIOTLB=y +CONFIG_NR_CPUS=8 +# CONFIG_SCHED_SMT is not set +CONFIG_SCHED_MC=y +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT_DESKTOP is not set +CONFIG_PREEMPT_RT=y +CONFIG_PREEMPT=y +CONFIG_PREEMPT_SOFTIRQS=y +CONFIG_PREEMPT_HARDIRQS=y +CONFIG_PREEMPT_BKL=y +# CONFIG_CLASSIC_RCU is not set +CONFIG_PREEMPT_RCU=y +CONFIG_PREEMPT_RCU_BOOST=y +CONFIG_RCU_TRACE=m +CONFIG_X86_LOCAL_APIC=y +CONFIG_X86_IO_APIC=y +CONFIG_X86_MCE=y +CONFIG_X86_MCE_INTEL=y +CONFIG_X86_MCE_AMD=y +CONFIG_MICROCODE=m +CONFIG_MICROCODE_OLD_INTERFACE=y +CONFIG_X86_MSR=m +CONFIG_X86_CPUID=m +CONFIG_NUMA=y +CONFIG_K8_NUMA=y +CONFIG_X86_64_ACPI_NUMA=y +# CONFIG_NUMA_EMU is not set +CONFIG_NODES_SHIFT=6 +CONFIG_ARCH_DISCONTIGMEM_ENABLE=y +CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_SELECT_MEMORY_MODEL=y +# CONFIG_FLATMEM_MANUAL is not set +CONFIG_DISCONTIGMEM_MANUAL=y +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_DISCONTIGMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_NEED_MULTIPLE_NODES=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_MIGRATION=y +CONFIG_RESOURCES_64BIT=y +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_MTRR=y +CONFIG_SECCOMP=y +CONFIG_CC_STACKPROTECTOR=y +# CONFIG_CC_STACKPROTECTOR_ALL is not set +# CONFIG_HZ_100 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_300 is not set +CONFIG_HZ_1000=y +CONFIG_HZ=1000 +CONFIG_KEXEC=y +CONFIG_CRASH_DUMP=y +CONFIG_PHYSICAL_START=0x200000 +CONFIG_RELOCATABLE=y +CONFIG_PHYSICAL_ALIGN=0x200000 +CONFIG_HOTPLUG_CPU=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y +CONFIG_OUT_OF_LINE_PFN_TO_PAGE=y +CONFIG_HARDIRQS_SW_RESEND=y + +# +# Power management options +# +CONFIG_ARCH_HIBERNATION_HEADER=y +CONFIG_PM=y +CONFIG_PM_LEGACY=y +CONFIG_PM_DEBUG=y +# CONFIG_PM_VERBOSE is not set +CONFIG_PM_TRACE=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND_SMP_POSSIBLE=y +CONFIG_SUSPEND=y +CONFIG_PM_DISABLE_CONSOLE=y +CONFIG_HIBERNATION_SMP_POSSIBLE=y +CONFIG_HIBERNATION=y +CONFIG_PM_STD_PARTITION="" +CONFIG_ACPI=y +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_PROCFS=y +CONFIG_ACPI_PROCFS_POWER=y +CONFIG_ACPI_SYSFS_POWER=y +CONFIG_ACPI_PROC_EVENT=y +CONFIG_ACPI_AC=m +CONFIG_ACPI_BATTERY=m +CONFIG_ACPI_BUTTON=m +CONFIG_ACPI_VIDEO=m +CONFIG_ACPI_FAN=m +CONFIG_ACPI_DOCK=m +CONFIG_ACPI_BAY=m +CONFIG_ACPI_PROCESSOR=m +CONFIG_ACPI_HOTPLUG_CPU=y +CONFIG_ACPI_THERMAL=m +CONFIG_ACPI_NUMA=y +CONFIG_ACPI_ASUS=m +CONFIG_ACPI_TOSHIBA=m +CONFIG_ACPI_CUSTOM_DSDT_INITRD=y +CONFIG_ACPI_BLACKLIST_YEAR=0 +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_EC=y +CONFIG_ACPI_POWER=y +CONFIG_ACPI_SYSTEM=y +CONFIG_X86_PM_TIMER=y +CONFIG_ACPI_CONTAINER=m +CONFIG_ACPI_SBS=m + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=m +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m + +# +# CPUFreq processor drivers +# +CONFIG_X86_ACPI_CPUFREQ=m +CONFIG_X86_POWERNOW_K8=m +CONFIG_X86_POWERNOW_K8_ACPI=y +# CONFIG_X86_SPEEDSTEP_CENTRINO is not set +# CONFIG_X86_P4_CLOCKMOD is not set + +# +# shared options +# +# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set +# CONFIG_X86_SPEEDSTEP_LIB is not set +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y + +# +# Bus options (PCI etc.) +# +CONFIG_PCI=y +CONFIG_PCI_DIRECT=y +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_DOMAINS=y +# CONFIG_DMAR is not set +CONFIG_PCIEPORTBUS=y +CONFIG_HOTPLUG_PCI_PCIE=m +CONFIG_PCIEAER=y +CONFIG_ARCH_SUPPORTS_MSI=y +CONFIG_PCI_MSI=y +CONFIG_PCI_LEGACY=y +# CONFIG_PCI_DEBUG is not set +CONFIG_HT_IRQ=y +CONFIG_ISA_DMA_API=y +CONFIG_K8_NB=y +CONFIG_PCCARD=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=m +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_IOCTL=y +CONFIG_CARDBUS=y + +# +# PC-card bridges +# +CONFIG_YENTA=m +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_PD6729=m +CONFIG_I82092=m +CONFIG_PCCARD_NONSTATIC=m +CONFIG_HOTPLUG_PCI=m +CONFIG_HOTPLUG_PCI_FAKE=m +CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +CONFIG_HOTPLUG_PCI_CPCI=y +CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m +CONFIG_HOTPLUG_PCI_CPCI_GENERIC=m +CONFIG_HOTPLUG_PCI_SHPC=m + +# +# Executable file formats / Emulations +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_IA32_EMULATION=y +# CONFIG_IA32_AOUT is not set +CONFIG_COMPAT=y +CONFIG_COMPAT_FOR_U64_ALIGNMENT=y +CONFIG_SYSVIPC_COMPAT=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=m +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_LRO=m +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=m +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +# CONFIG_DEFAULT_BIC is not set +# CONFIG_DEFAULT_CUBIC is not set +# CONFIG_DEFAULT_HTCP is not set +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_WESTWOOD is not set +CONFIG_DEFAULT_RENO=y +CONFIG_DEFAULT_TCP_CONG="reno" +CONFIG_TCP_MD5SIG=y +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m +CONFIG_IPV6=m +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +# CONFIG_IPV6_MIP6 is not set +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_TUNNEL=m +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_NETLABEL is not set +CONFIG_NETWORK_SECMARK=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK_ENABLED=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +# CONFIG_NF_CONNTRACK_SANE is not set +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m + +# +# IP: Netfilter Configuration +# +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration (EXPERIMENTAL) +# +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_RAW=m + +# +# DECnet: Netfilter Configuration +# +CONFIG_DECNET_NF_GRABULATOR=m + +# +# Bridge: Netfilter Configuration +# +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_IP_DCCP=m +CONFIG_INET_DCCP_DIAG=m +CONFIG_IP_DCCP_ACKVEC=y + +# +# DCCP CCIDs Configuration (EXPERIMENTAL) +# +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +CONFIG_IP_DCCP_TFRC_LIB=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 + +# +# DCCP Kernel Hacking +# +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_NET_DCCPPROBE=m +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +CONFIG_ATM=y +CONFIG_ATM_CLIP=y +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +CONFIG_DECNET=m +# CONFIG_DECNET_ROUTER is not set +CONFIG_LLC=y +CONFIG_LLC2=m +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_ATALK=m +CONFIG_DEV_APPLETALK=m +CONFIG_IPDDP=m +CONFIG_IPDDP_ENCAP=y +CONFIG_IPDDP_DECAP=y +CONFIG_X25=m +CONFIG_LAPB=m +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +CONFIG_WAN_ROUTER=m +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RR=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_INGRESS=m + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +# CONFIG_CLS_U32_PERF is not set +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m +# CONFIG_NET_CLS_POLICE is not set +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_SCH_FIFO=y + +# +# Network testing +# +CONFIG_NET_PKTGEN=m +CONFIG_NET_TCPPROBE=m +CONFIG_HAMRADIO=y + +# +# Packet Radio protocols +# +CONFIG_AX25=m +CONFIG_AX25_DAMA_SLAVE=y +CONFIG_NETROM=m +CONFIG_ROSE=m + +# +# AX.25 network device drivers +# +CONFIG_MKISS=m +CONFIG_6PACK=m +CONFIG_BPQETHER=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_BAYCOM_PAR=m +CONFIG_YAM=m +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +CONFIG_IRDA_ULTRA=y + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_DEBUG=y + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m + +# +# Dongle support +# +CONFIG_DONGLE=y +CONFIG_ESI_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_TEKRAM_DONGLE=m +# CONFIG_TOIM3232_DONGLE is not set +CONFIG_LITELINK_DONGLE=m +CONFIG_MA600_DONGLE=m +CONFIG_GIRBIL_DONGLE=m +CONFIG_MCP2120_DONGLE=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_ACT200L_DONGLE=m +CONFIG_KINGSUN_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +CONFIG_KS959_DONGLE=m + +# +# Old SIR device drivers +# + +# +# Old Serial dongle support +# + +# +# FIR device drivers +# +CONFIG_USB_IRDA=m +CONFIG_SIGMATEL_FIR=m +CONFIG_NSC_FIR=m +CONFIG_WINBOND_FIR=m +CONFIG_SMC_IRCC_FIR=m +CONFIG_ALI_FIR=m +CONFIG_VLSI_FIR=m +CONFIG_VIA_FIR=m +CONFIG_MCS_FIR=m +CONFIG_BT=m +CONFIG_BT_L2CAP=m +CONFIG_BT_SCO=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_CMTP=m +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIVHCI=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_RXKAD=m +CONFIG_FIB_RULES=y + +# +# Wireless +# +CONFIG_CFG80211=m +CONFIG_NL80211=y +CONFIG_WIRELESS_EXT=y +CONFIG_MAC80211=m +CONFIG_MAC80211_RCSIMPLE=y +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_DEBUGFS=y +# CONFIG_MAC80211_DEBUG is not set +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT_WEP=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +CONFIG_RFKILL_LEDS=y +CONFIG_NET_9P=m +CONFIG_NET_9P_FD=m +CONFIG_NET_9P_VIRTIO=m +# CONFIG_NET_9P_DEBUG is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_CONNECTOR=m +CONFIG_MTD=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=m +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_FTL=m +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_INFTL=m +CONFIG_RFD_FTL=m +CONFIG_SSFDC=m +CONFIG_MTD_OOPS=m + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_RAM=m +CONFIG_MTD_ROM=m +CONFIG_MTD_ABSENT=m + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PHYSMAP_LEN=0x4000000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PNC2000=m +CONFIG_MTD_SC520CDP=m +CONFIG_MTD_NETSC520=m +CONFIG_MTD_TS5500=m +CONFIG_MTD_SBC_GXX=m +CONFIG_MTD_AMD76XROM=m +CONFIG_MTD_ICHXROM=m +CONFIG_MTD_ESB2ROM=m +CONFIG_MTD_CK804XROM=m +CONFIG_MTD_SCB2_FLASH=m +CONFIG_MTD_NETtel=m +CONFIG_MTD_DILNETPC=m +CONFIG_MTD_DILNETPC_BOOTSIZE=0x80000 +CONFIG_MTD_L440GX=m +CONFIG_MTD_PCI=m +CONFIG_MTD_INTEL_VR_NOR=m +CONFIG_MTD_PLATRAM=m + +# +# Self-contained MTD device drivers +# +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +CONFIG_MTD_DATAFLASH=m +CONFIG_MTD_M25P80=m +CONFIG_MTD_SLRAM=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_MTDRAM=m +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTD_BLOCK2MTD=m + +# +# Disk-On-Chip Device Drivers +# +CONFIG_MTD_DOC2000=m +CONFIG_MTD_DOC2001=m +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCECC=m +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_DOCPROBE_ADDRESS=0 +CONFIG_MTD_NAND=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=m +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set +CONFIG_MTD_NAND_CAFE=m +CONFIG_MTD_NAND_NANDSIM=m +CONFIG_MTD_NAND_PLATFORM=m +CONFIG_MTD_ALAUDA=m +CONFIG_MTD_ONENAND=m +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +# CONFIG_MTD_ONENAND_OTP is not set +CONFIG_MTD_ONENAND_2X_PROGRAM=y +CONFIG_MTD_ONENAND_SIM=m + +# +# UBI - Unsorted block images +# +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_RESERVE=1 +CONFIG_MTD_UBI_GLUEBI=y + +# +# UBI debugging options +# +# CONFIG_MTD_UBI_DEBUG is not set +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_SERIAL=m +CONFIG_PARPORT_PC_FIFO=y +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_AX88796=m +CONFIG_PARPORT_1284=y +CONFIG_PARPORT_NOT_PC=y +CONFIG_PNP=y +# CONFIG_PNP_DEBUG is not set + +# +# Protocols +# +CONFIG_PNPACPI=y +CONFIG_BLK_DEV=y +CONFIG_BLK_DEV_FD=m +CONFIG_PARIDE=m + +# +# Parallel IDE high-level drivers +# +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PT=m +CONFIG_PARIDE_PG=m + +# +# Parallel IDE protocol modules +# +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_EPAT=m +# CONFIG_PARIDE_EPATC8 is not set +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_CISS_SCSI_TAPE=y +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_UMEM=m +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_SX8=m +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_ATA_OVER_ETH=m +CONFIG_VIRTIO_BLK=m +CONFIG_MISC_DEVICES=y +CONFIG_IBM_ASM=m +CONFIG_PHANTOM=m +CONFIG_EEPROM_93CX6=m +CONFIG_SGI_IOC4=m +CONFIG_TIFM_CORE=m +CONFIG_TIFM_7XX1=m +CONFIG_ASUS_LAPTOP=m +CONFIG_FUJITSU_LAPTOP=m +CONFIG_MSI_LAPTOP=m +CONFIG_SONY_LAPTOP=m +CONFIG_SONYPI_COMPAT=y +CONFIG_THINKPAD_ACPI=m +# CONFIG_THINKPAD_ACPI_DEBUG is not set +CONFIG_THINKPAD_ACPI_BAY=y +CONFIG_IDE=y +CONFIG_IDE_MAX_HWIFS=4 +CONFIG_BLK_DEV_IDE=m + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +# CONFIG_BLK_DEV_HD_IDE is not set +CONFIG_BLK_DEV_IDEDISK=m +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_DELKIN=m +CONFIG_BLK_DEV_IDECD=m +CONFIG_BLK_DEV_IDETAPE=m +CONFIG_BLK_DEV_IDEFLOPPY=m +CONFIG_BLK_DEV_IDESCSI=m +CONFIG_BLK_DEV_IDEACPI=y +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_PROC_FS=y + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=m +CONFIG_BLK_DEV_PLATFORM=m +CONFIG_BLK_DEV_CMD640=y +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +CONFIG_BLK_DEV_IDEPNP=y + +# +# PCI IDE chipsets support +# +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_GENERIC is not set +CONFIG_BLK_DEV_OPTI621=m +# CONFIG_BLK_DEV_RZ1000 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_AEC62XX=m +CONFIG_BLK_DEV_ALI15X3=m +# CONFIG_WDC_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +CONFIG_BLK_DEV_ATIIXP=m +CONFIG_BLK_DEV_CMD64X=m +# CONFIG_BLK_DEV_TRIFLEX is not set +CONFIG_BLK_DEV_CY82C693=m +# CONFIG_BLK_DEV_CS5520 is not set +CONFIG_BLK_DEV_CS5530=m +CONFIG_BLK_DEV_HPT34X=m +# CONFIG_HPT34X_AUTODMA is not set +CONFIG_BLK_DEV_HPT366=m +# CONFIG_BLK_DEV_JMICRON is not set +CONFIG_BLK_DEV_SC1200=m +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +CONFIG_BLK_DEV_NS87415=m +CONFIG_BLK_DEV_PDC202XX_OLD=m +CONFIG_PDC202XX_BURST=y +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +CONFIG_BLK_DEV_TRM290=m +# CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_BLK_DEV_TC86C001=m +# CONFIG_IDE_ARM is not set +CONFIG_BLK_DEV_IDEDMA=y +CONFIG_IDE_ARCH_OBSOLETE_INIT=y +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +CONFIG_RAID_ATTRS=m +CONFIG_SCSI=m +CONFIG_SCSI_DMA=y +CONFIG_SCSI_TGT=m +CONFIG_SCSI_NETLINK=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_SCH=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_FC_TGT_ATTRS=y +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +CONFIG_SCSI_SAS_ATA=y +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ISCSI_TCP=m +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +CONFIG_AIC7XXX_DEBUG_ENABLE=y +CONFIG_AIC7XXX_DEBUG_MASK=0 +CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +# CONFIG_SCSI_AIC7XXX_OLD is not set +CONFIG_SCSI_AIC79XX=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +CONFIG_AIC79XX_DEBUG_ENABLE=y +CONFIG_AIC79XX_DEBUG_MASK=0 +CONFIG_AIC79XX_REG_PRETTY_PRINT=y +CONFIG_SCSI_AIC94XX=m +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_SCSI_ADVANSYS=m +CONFIG_SCSI_ARCMSR=m +CONFIG_SCSI_ARCMSR_AER=y +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_SAS=m +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_BUSLOGIC=m +# CONFIG_SCSI_OMIT_FLASHPOINT is not set +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_EATA=m +CONFIG_SCSI_EATA_TAGGED_QUEUE=y +CONFIG_SCSI_EATA_LINKED_COMMANDS=y +CONFIG_SCSI_EATA_MAX_TAGS=16 +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_SCSI_GDTH=m +CONFIG_SCSI_IPS=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_PPA=m +CONFIG_SCSI_IMM=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_TRACE is not set +# CONFIG_SCSI_IPR_DUMP is not set +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_DC395x=m +CONFIG_SCSI_DC390T=m +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_SRP=m +CONFIG_SCSI_LOWLEVEL_PCMCIA=y +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_SYM53C500=m +CONFIG_ATA=m +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_ACPI=y +CONFIG_SATA_AHCI=m +CONFIG_SATA_SVW=m +CONFIG_ATA_PIIX=m +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_PDC_ADMA=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_SX4=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIL24=m +CONFIG_SATA_SIS=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m +CONFIG_SATA_INIC162X=m +CONFIG_PATA_ACPI=m +# CONFIG_PATA_ALI is not set +CONFIG_PATA_AMD=m +CONFIG_PATA_ARTOP=m +CONFIG_PATA_ATIIXP=m +# CONFIG_PATA_CMD640_PCI is not set +CONFIG_PATA_CMD64X=m +CONFIG_PATA_CS5520=m +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +CONFIG_PATA_EFAR=m +CONFIG_ATA_GENERIC=m +CONFIG_PATA_HPT366=m +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +CONFIG_PATA_HPT3X3=m +# CONFIG_PATA_HPT3X3_DMA is not set +CONFIG_PATA_IT821X=m +CONFIG_PATA_IT8213=m +CONFIG_PATA_JMICRON=m +CONFIG_PATA_TRIFLEX=m +CONFIG_PATA_MARVELL=m +CONFIG_PATA_MPIIX=m +CONFIG_PATA_OLDPIIX=m +CONFIG_PATA_NETCELL=m +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_NS87415 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +CONFIG_PATA_PCMCIA=m +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +CONFIG_PATA_RZ1000=m +# CONFIG_PATA_SC1200 is not set +CONFIG_PATA_SERVERWORKS=m +CONFIG_PATA_PDC2027X=m +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +CONFIG_PATA_VIA=m +CONFIG_PATA_WINBOND=m +CONFIG_PATA_PLATFORM=m +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID5_RESHAPE=y +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m +CONFIG_BLK_DEV_DM=m +# CONFIG_DM_DEBUG is not set +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_EMC=m +CONFIG_DM_MULTIPATH_RDAC=m +CONFIG_DM_MULTIPATH_HP=m +# CONFIG_DM_DELAY is not set +CONFIG_DM_UEVENT=y +CONFIG_FUSION=y +CONFIG_FUSION_SPI=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_SAS=m +CONFIG_FUSION_MAX_SGE=128 +CONFIG_FUSION_CTL=m +CONFIG_FUSION_LAN=m +CONFIG_FUSION_LOGGING=y + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_FIREWIRE is not set +CONFIG_IEEE1394=m + +# +# Subsystem Options +# +# CONFIG_IEEE1394_VERBOSEDEBUG is not set + +# +# Controllers +# +CONFIG_IEEE1394_PCILYNX=m +CONFIG_IEEE1394_OHCI1394=m + +# +# Protocols +# +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_I2O=m +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_EXT_ADAPTEC_DMA64=y +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_I2O_BUS=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_SCSI=m +CONFIG_I2O_PROC=m +CONFIG_MACINTOSH_DRIVERS=y +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_NETDEVICES=y +CONFIG_NETDEVICES_MULTIQUEUE=y +CONFIG_IFB=m +CONFIG_DUMMY=m +CONFIG_BONDING=m +CONFIG_MACVLAN=m +CONFIG_EQUALIZER=m +CONFIG_TUN=m +CONFIG_VETH=m +CONFIG_NET_SB1000=m +CONFIG_ARCNET=m +CONFIG_ARCNET_1201=m +CONFIG_ARCNET_1051=m +CONFIG_ARCNET_RAW=m +CONFIG_ARCNET_CAP=m +CONFIG_ARCNET_COM90xx=m +CONFIG_ARCNET_COM90xxIO=m +CONFIG_ARCNET_RIM_I=m +CONFIG_ARCNET_COM20020=m +CONFIG_ARCNET_COM20020_PCI=m +CONFIG_PHYLIB=m + +# +# MII PHY device drivers +# +CONFIG_MARVELL_PHY=m +CONFIG_DAVICOM_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_LXT_PHY=m +CONFIG_CICADA_PHY=m +CONFIG_VITESSE_PHY=m +CONFIG_SMSC_PHY=m +CONFIG_BROADCOM_PHY=m +CONFIG_ICPLUS_PHY=m +CONFIG_FIXED_PHY=m +# CONFIG_FIXED_MII_10_FDX is not set +# CONFIG_FIXED_MII_100_FDX is not set +CONFIG_FIXED_MII_1000_FDX=y +CONFIG_FIXED_MII_AMNT=1 +CONFIG_MDIO_BITBANG=m +CONFIG_NET_ETHERNET=y +CONFIG_MII=m +CONFIG_HAPPYMEAL=m +CONFIG_SUNGEM=m +CONFIG_CASSINI=m +CONFIG_NET_VENDOR_3COM=y +CONFIG_VORTEX=m +CONFIG_TYPHOON=m +CONFIG_NET_TULIP=y +CONFIG_DE2104X=m +CONFIG_TULIP=m +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_NAPI is not set +CONFIG_DE4X5=m +CONFIG_WINBOND_840=m +CONFIG_DM9102=m +CONFIG_ULI526X=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_HP100=m +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +CONFIG_NET_PCI=y +CONFIG_PCNET32=m +# CONFIG_PCNET32_NAPI is not set +CONFIG_AMD8111_ETH=m +# CONFIG_AMD8111E_NAPI is not set +CONFIG_ADAPTEC_STARFIRE=m +# CONFIG_ADAPTEC_STARFIRE_NAPI is not set +CONFIG_B44=m +CONFIG_B44_PCI_AUTOSELECT=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI=y +CONFIG_FORCEDETH=m +# CONFIG_FORCEDETH_NAPI is not set +CONFIG_EEPRO100=m +CONFIG_E100=m +CONFIG_FEALNX=m +CONFIG_NATSEMI=m +CONFIG_NE2K_PCI=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_PIO=y +# CONFIG_8139TOO_TUNE_TWISTER is not set +CONFIG_8139TOO_8129=y +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_SIS900=m +CONFIG_EPIC100=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_VIA_RHINE=m +CONFIG_VIA_RHINE_MMIO=y +CONFIG_VIA_RHINE_NAPI=y +CONFIG_SC92031=m +CONFIG_NET_POCKET=y +CONFIG_ATP=m +CONFIG_DE600=m +CONFIG_DE620=m +CONFIG_NETDEV_1000=y +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_DL2K=m +CONFIG_E1000=m +CONFIG_E1000_NAPI=y +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +CONFIG_E1000E=m +CONFIG_IP1000=m +CONFIG_NS83820=m +CONFIG_HAMACHI=m +CONFIG_YELLOWFIN=m +CONFIG_R8169=m +# CONFIG_R8169_NAPI is not set +CONFIG_R8169_VLAN=y +CONFIG_SIS190=m +CONFIG_SKGE=m +# CONFIG_SKGE_DEBUG is not set +CONFIG_SKY2=m +# CONFIG_SKY2_DEBUG is not set +# CONFIG_SK98LIN is not set +CONFIG_VIA_VELOCITY=m +CONFIG_TIGON3=m +CONFIG_BNX2=m +CONFIG_QLA3XXX=m +CONFIG_ATL1=m +CONFIG_NETDEV_10000=y +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T1_NAPI=y +CONFIG_CHELSIO_T3=m +CONFIG_IXGBE=m +CONFIG_IXGB=m +# CONFIG_IXGB_NAPI is not set +CONFIG_S2IO=m +# CONFIG_S2IO_NAPI is not set +CONFIG_MYRI10GE=m +CONFIG_NETXEN_NIC=m +CONFIG_NIU=m +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_TEHUTI=m +CONFIG_TR=y +CONFIG_IBMOL=m +CONFIG_3C359=m +CONFIG_TMS380TR=m +CONFIG_TMSPCI=m +CONFIG_ABYSS=m + +# +# Wireless LAN +# +CONFIG_WLAN_PRE80211=y +CONFIG_STRIP=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_NETWAVE=m +CONFIG_WLAN_80211=y +CONFIG_PCMCIA_RAYCS=m +CONFIG_IPW2100=m +CONFIG_IPW2100_MONITOR=y +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2200=m +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +# CONFIG_IPW2200_DEBUG is not set +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIBERTAS_CS=m +CONFIG_LIBERTAS_SDIO=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_AIRO=m +CONFIG_HERMES=m +# CONFIG_PLX_HERMES is not set +# CONFIG_TMD_HERMES is not set +# CONFIG_NORTEL_HERMES is not set +# CONFIG_PCI_HERMES is not set +CONFIG_PCMCIA_HERMES=m +CONFIG_PCMCIA_SPECTRUM=m +CONFIG_ATMEL=m +CONFIG_PCI_ATMEL=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_AIRO_CS=m +CONFIG_PCMCIA_WL3501=m +CONFIG_PRISM54=m +CONFIG_USB_ZD1201=m +CONFIG_RTL8187=m +CONFIG_ADM8211=m +CONFIG_P54_COMMON=m +CONFIG_P54_USB=m +CONFIG_P54_PCI=m +# CONFIG_IWLWIFI is not set +CONFIG_HOSTAP=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_PLX=m +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_CS=m +CONFIG_BCM43XX=m +# CONFIG_BCM43XX_DEBUG is not set +CONFIG_BCM43XX_DMA=y +CONFIG_BCM43XX_PIO=y +CONFIG_BCM43XX_DMA_AND_PIO_MODE=y +# CONFIG_BCM43XX_DMA_MODE is not set +# CONFIG_BCM43XX_PIO_MODE is not set +CONFIG_B43=m +CONFIG_B43_PCI_AUTOSELECT=y +CONFIG_B43_PCICORE_AUTOSELECT=y +# CONFIG_B43_PCMCIA is not set +CONFIG_B43_LEDS=y +CONFIG_B43_RFKILL=y +CONFIG_B43_DEBUG=y +CONFIG_B43_DMA=y +CONFIG_B43_PIO=y +CONFIG_B43_DMA_AND_PIO_MODE=y +# CONFIG_B43_DMA_MODE is not set +# CONFIG_B43_PIO_MODE is not set +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_PCI_AUTOSELECT=y +CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y +CONFIG_B43LEGACY_DEBUG=y +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_PIO=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_RT2X00=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_PCI=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_RFKILL=y +CONFIG_RT2400PCI=m +CONFIG_RT2400PCI_RFKILL=y +CONFIG_RT2500PCI=m +CONFIG_RT2500PCI_RFKILL=y +CONFIG_RT61PCI=m +CONFIG_RT61PCI_RFKILL=y +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +# CONFIG_RT2X00_LIB_DEBUGFS is not set +# CONFIG_RT2X00_DEBUG is not set + +# +# USB Network Adapters +# +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_KC2190=y +# CONFIG_USB_NET_ZAURUS is not set +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_AXNET=m +CONFIG_ARCNET_COM20020_CS=m +CONFIG_WAN=y +CONFIG_LANMEDIA=m +CONFIG_HDLC=m +CONFIG_HDLC_RAW=m +CONFIG_HDLC_RAW_ETH=m +CONFIG_HDLC_CISCO=m +CONFIG_HDLC_FR=m +CONFIG_HDLC_PPP=m +CONFIG_HDLC_X25=m +CONFIG_PCI200SYN=m +CONFIG_WANXL=m +CONFIG_PC300=m +CONFIG_PC300_MLPPP=y + +# +# Cyclades-PC300 MLPPP support is disabled. +# + +# +# Refer to the file README.mlppp, provided by PC300 package. +# +# CONFIG_PC300TOO is not set +CONFIG_FARSYNC=m +CONFIG_DSCC4=m +CONFIG_DSCC4_PCISYNC=y +CONFIG_DSCC4_PCI_RST=y +CONFIG_DLCI=m +CONFIG_DLCI_MAX=8 +CONFIG_WAN_ROUTER_DRIVERS=m +CONFIG_CYCLADES_SYNC=m +CONFIG_CYCLOMX_X25=y +CONFIG_LAPBETHER=m +CONFIG_X25_ASY=m +CONFIG_SBNI=m +# CONFIG_SBNI_MULTILINE is not set +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +CONFIG_ATM_TCP=m +CONFIG_ATM_LANAI=m +CONFIG_ATM_ENI=m +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +CONFIG_ATM_FIRESTREAM=m +CONFIG_ATM_ZATM=m +# CONFIG_ATM_ZATM_DEBUG is not set +CONFIG_ATM_IDT77252=m +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +CONFIG_ATM_IDT77252_USE_SUNI=y +CONFIG_ATM_AMBASSADOR=m +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +CONFIG_ATM_HORIZON=m +# CONFIG_ATM_HORIZON_DEBUG is not set +CONFIG_ATM_FORE200E_MAYBE=m +CONFIG_ATM_FORE200E_PCA=y +CONFIG_ATM_FORE200E_PCA_DEFAULT_FW=y +# CONFIG_ATM_FORE200E_USE_TASKLET is not set +CONFIG_ATM_FORE200E_TX_RETRY=16 +CONFIG_ATM_FORE200E_DEBUG=0 +CONFIG_ATM_FORE200E=m +CONFIG_ATM_HE=m +CONFIG_ATM_HE_USE_SUNI=y +CONFIG_FDDI=y +CONFIG_DEFXX=m +# CONFIG_DEFXX_MMIO is not set +CONFIG_SKFP=m +CONFIG_HIPPI=y +CONFIG_ROADRUNNER=m +# CONFIG_ROADRUNNER_LARGE_RINGS is not set +CONFIG_PLIP=m +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +CONFIG_PPPOATM=m +CONFIG_PPPOL2TP=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLHC=m +CONFIG_SLIP_SMART=y +CONFIG_SLIP_MODE_SLIP6=y +CONFIG_NET_FC=y +CONFIG_SHAPER=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_VIRTIO_NET=m +CONFIG_ISDN=m +CONFIG_ISDN_I4L=m +CONFIG_ISDN_PPP=y +CONFIG_ISDN_PPP_VJ=y +CONFIG_ISDN_MPP=y +CONFIG_IPPP_FILTER=y +CONFIG_ISDN_PPP_BSDCOMP=m +CONFIG_ISDN_AUDIO=y +CONFIG_ISDN_TTY_FAX=y +CONFIG_ISDN_X25=y + +# +# ISDN feature submodules +# +CONFIG_ISDN_DIVERSION=m + +# +# ISDN4Linux hardware drivers +# + +# +# Passive cards +# +CONFIG_ISDN_DRV_HISAX=m + +# +# D-channel protocol features +# +CONFIG_HISAX_EURO=y +CONFIG_DE_AOC=y +# CONFIG_HISAX_NO_SENDCOMPLETE is not set +# CONFIG_HISAX_NO_LLC is not set +# CONFIG_HISAX_NO_KEYPAD is not set +CONFIG_HISAX_1TR6=y +CONFIG_HISAX_NI1=y +CONFIG_HISAX_MAX_CARDS=8 + +# +# HiSax supported cards +# +CONFIG_HISAX_16_3=y +CONFIG_HISAX_TELESPCI=y +CONFIG_HISAX_S0BOX=y +CONFIG_HISAX_FRITZPCI=y +CONFIG_HISAX_AVM_A1_PCMCIA=y +CONFIG_HISAX_ELSA=y +CONFIG_HISAX_DIEHLDIVA=y +CONFIG_HISAX_SEDLBAUER=y +CONFIG_HISAX_NETJET=y +CONFIG_HISAX_NETJET_U=y +CONFIG_HISAX_NICCY=y +CONFIG_HISAX_BKM_A4T=y +CONFIG_HISAX_SCT_QUADRO=y +CONFIG_HISAX_GAZEL=y +CONFIG_HISAX_HFC_PCI=y +CONFIG_HISAX_W6692=y +CONFIG_HISAX_HFC_SX=y +CONFIG_HISAX_ENTERNOW_PCI=y +# CONFIG_HISAX_DEBUG is not set + +# +# HiSax PCMCIA card service modules +# +CONFIG_HISAX_SEDLBAUER_CS=m +CONFIG_HISAX_ELSA_CS=m +CONFIG_HISAX_AVM_A1_CS=m +CONFIG_HISAX_TELES_CS=m + +# +# HiSax sub driver modules +# +CONFIG_HISAX_ST5481=m +CONFIG_HISAX_HFCUSB=m +CONFIG_HISAX_HFC4S8S=m +CONFIG_HISAX_FRITZ_PCIPNP=m +CONFIG_HISAX_HDLC=y + +# +# Active cards +# +CONFIG_ISDN_DRV_GIGASET=m +CONFIG_GIGASET_BASE=m +CONFIG_GIGASET_M105=m +CONFIG_GIGASET_M101=m +# CONFIG_GIGASET_DEBUG is not set +# CONFIG_GIGASET_UNDOCREQ is not set +CONFIG_ISDN_CAPI=m +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y +CONFIG_CAPI_TRACE=y +CONFIG_ISDN_CAPI_MIDDLEWARE=y +CONFIG_ISDN_CAPI_CAPI20=m +CONFIG_ISDN_CAPI_CAPIFS_BOOL=y +CONFIG_ISDN_CAPI_CAPIFS=m +CONFIG_ISDN_CAPI_CAPIDRV=m + +# +# CAPI hardware drivers +# +CONFIG_CAPI_AVM=y +CONFIG_ISDN_DRV_AVMB1_B1PCI=m +CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m +CONFIG_ISDN_DRV_AVMB1_AVM_CS=m +CONFIG_ISDN_DRV_AVMB1_T1PCI=m +CONFIG_ISDN_DRV_AVMB1_C4=m +CONFIG_CAPI_EICON=y +CONFIG_ISDN_DIVAS=m +CONFIG_ISDN_DIVAS_BRIPCI=y +CONFIG_ISDN_DIVAS_PRIPCI=y +CONFIG_ISDN_DIVAS_DIVACAPI=m +CONFIG_ISDN_DIVAS_USERIDI=m +CONFIG_ISDN_DIVAS_MAINT=m +CONFIG_PHONE=m +CONFIG_PHONE_IXJ=m +CONFIG_PHONE_IXJ_PCMCIA=m + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_POLLDEV=m + +# +# 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=m +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_EVBUG=m + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_IFORCE_232=y +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_INPUT_TABLET=y +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_UCB1400=m +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_PCSPKR=m +CONFIG_INPUT_ATLAS_BTNS=m +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_YEALINK=m +CONFIG_INPUT_UINPUT=m + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=m +CONFIG_SERIO_CT82C710=m +CONFIG_SERIO_PARKBD=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_RAW=m +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_DEV_KMEM is not set +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_COMPUTONE=m +CONFIG_ROCKETPORT=m +CONFIG_CYCLADES=m +# CONFIG_CYZ_INTR is not set +CONFIG_DIGIEPCA=m +CONFIG_MOXA_INTELLIO=m +# CONFIG_MOXA_SMARTIO is not set +CONFIG_MOXA_SMARTIO_NEW=m +# CONFIG_ISI is not set +CONFIG_SYNCLINK=m +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_GT=m +CONFIG_N_HDLC=m +CONFIG_SPECIALIX=m +# CONFIG_SPECIALIX_RTSCTS is not set +CONFIG_SX=m +CONFIG_RIO=m +# CONFIG_RIO_OLDPCI is not set +CONFIG_STALDRV=y + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_PNP=y +CONFIG_SERIAL_8250_CS=m +CONFIG_SERIAL_8250_NR_UARTS=48 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_RSA=y + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_JSM=m +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_PRINTER=m +# CONFIG_LP_CONSOLE is not set +CONFIG_PPDEV=m +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_POWEROFF=m +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_INTEL=m +CONFIG_HW_RANDOM_AMD=m +CONFIG_NVRAM=m +CONFIG_RTC=y +# CONFIG_RTC_HISTOGRAM is not set +CONFIG_BLOCKER=m +CONFIG_LPPTEST=m +CONFIG_R3964=m +CONFIG_APPLICOM=m + +# +# PCMCIA character devices +# +CONFIG_SYNCLINK_CS=m +CONFIG_CARDMAN_4000=m +CONFIG_CARDMAN_4040=m +CONFIG_MWAVE=m +CONFIG_PC8736x_GPIO=m +CONFIG_NSC_GPIO=m +CONFIG_RAW_DRIVER=m +CONFIG_MAX_RAW_DEVS=256 +CONFIG_HPET=y +# CONFIG_HPET_RTC_IRQ is not set +CONFIG_HPET_MMAP=y +CONFIG_HANGCHECK_TIMER=m +CONFIG_TCG_TPM=m +CONFIG_TCG_TIS=m +CONFIG_TCG_NSC=m +CONFIG_TCG_ATMEL=m +CONFIG_TCG_INFINEON=m +CONFIG_TELCLOCK=m +CONFIG_RMEM=m +CONFIG_ALLOC_RTSJ_MEM=m +CONFIG_DEVPORT=y +CONFIG_I2C=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCF=m +CONFIG_I2C_ALGOPCA=m + +# +# I2C Hardware Bus support +# +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_I801=m +CONFIG_I2C_I810=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_TAOS_EVM=m +CONFIG_I2C_STUB=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m + +# +# Miscellaneous I2C Chip support +# +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m +CONFIG_DS1682=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_TSL2550=m +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +CONFIG_SPI_LM70_LLP=m + +# +# SPI Protocol Masters +# +CONFIG_SPI_AT25=m +CONFIG_SPI_SPIDEV=m +CONFIG_SPI_TLE62X0=m +CONFIG_W1=m +CONFIG_W1_CON=y + +# +# 1-wire Bus Masters +# +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_DS2482=m + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_DS2760=m +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +CONFIG_PDA_POWER=m +CONFIG_BATTERY_DS2760=m +CONFIG_HWMON=y +CONFIG_HWMON_VID=m +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_ABITUGURU3=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_K8TEMP=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_FSCPOS=m +CONFIG_SENSORS_FSCHMD=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_IBMPEX=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_LM93=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_HDAPS=m +CONFIG_SENSORS_APPLESMC=m +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=m +CONFIG_ACQUIRE_WDT=m +CONFIG_ADVANTECH_WDT=m +CONFIG_ALIM1535_WDT=m +CONFIG_ALIM7101_WDT=m +CONFIG_SC520_WDT=m +CONFIG_EUROTECH_WDT=m +CONFIG_IB700_WDT=m +CONFIG_IBMASR=m +CONFIG_WAFER_WDT=m +CONFIG_I6300ESB_WDT=m +CONFIG_ITCO_WDT=m +CONFIG_ITCO_VENDOR_SUPPORT=y +CONFIG_IT8712F_WDT=m +CONFIG_SC1200_WDT=m +CONFIG_PC87413_WDT=m +CONFIG_60XX_WDT=m +CONFIG_SBC8360_WDT=m +CONFIG_CPU5_WDT=m +CONFIG_SMSC37B787_WDT=m +CONFIG_W83627HF_WDT=m +CONFIG_W83697HF_WDT=m +CONFIG_W83877F_WDT=m +CONFIG_W83977F_WDT=m +CONFIG_MACHZ_WDT=m +CONFIG_SBC_EPX_C3_WATCHDOG=m + +# +# PCI-based Watchdog Cards +# +CONFIG_PCIPCWATCHDOG=m +CONFIG_WDTPCI=m +CONFIG_WDT_501_PCI=y + +# +# USB-based Watchdog Cards +# +CONFIG_USBPCWATCHDOG=m + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +CONFIG_SSB=m +CONFIG_SSB_PCIHOST_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_PCMCIAHOST_POSSIBLE=y +# CONFIG_SSB_PCMCIAHOST is not set +# CONFIG_SSB_SILENT is not set +CONFIG_SSB_DEBUG=y +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_DRIVER_PCICORE=y + +# +# Multifunction device drivers +# +CONFIG_MFD_SM501=m + +# +# Multimedia devices +# +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set + +# +# Encoders/decoders and other helper chips +# + +# +# Audio decoders +# +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TDA9875=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_TLV320AIC23B=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_VP27SMPX=m + +# +# Video decoders +# +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_TCM825X=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA7111=m +CONFIG_VIDEO_SAA7114=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7191=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_VPX3220=m + +# +# Video and audio decoders +# +CONFIG_VIDEO_CX25840=m + +# +# MPEG video encoders +# +CONFIG_VIDEO_CX2341X=m + +# +# Video encoders +# +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m + +# +# Video improvement chips +# +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_W9966=m +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA_PP=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_TUNER_3036=m +CONFIG_VIDEO_STRADIS=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_MEYE=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_DVB=m +# CONFIG_VIDEO_MXB is not set +# CONFIG_VIDEO_DPC is not set +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_CX23885=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_FB_IVTV=m +CONFIG_VIDEO_CAFE_CCIC=m +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_29XXX=y +CONFIG_VIDEO_PVRUSB2_24XXX=y +CONFIG_VIDEO_PVRUSB2_SYSFS=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_USB_VICAM=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_ET61X251=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_USB_W9968CF=m +# CONFIG_USB_OV511 is not set +CONFIG_USB_SE401=m +CONFIG_USB_SN9C102=m +CONFIG_USB_STV680=m +CONFIG_USB_ZC0301=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_ZR364XX=m +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RADIO_MAESTRO=m +CONFIG_USB_DSBR=m +CONFIG_DVB_CORE=m +CONFIG_DVB_CORE_ATTACH=y +CONFIG_DVB_CAPTURE_DRIVERS=y + +# +# Supported SAA7146 based PCI Adapters +# +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_PATCH=m + +# +# Supported USB Adapters +# +CONFIG_DVB_USB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_CINERGYT2=m +CONFIG_DVB_CINERGYT2_TUNING=y +CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32 +CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512 +CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250 +CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y +CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100 + +# +# Supported FlexCopII (B2C2) Adapters +# +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set + +# +# Supported BT878 Adapters +# +CONFIG_DVB_BT8XX=m + +# +# Supported Pluto2 Adapters +# +CONFIG_DVB_PLUTO2=m + +# +# Supported DVB Frontends +# + +# +# Customise DVB Frontends +# +# CONFIG_DVB_FE_CUSTOMISE is not set + +# +# DVB-S (satellite) frontends +# +CONFIG_DVB_STV0299=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_MT312=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_TDA10086=m + +# +# DVB-T (terrestrial) frontends +# +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_L64781=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_MT352=m +CONFIG_DVB_ZL10353=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m + +# +# DVB-C (cable) frontends +# +CONFIG_DVB_VES1820=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_STV0297=m + +# +# ATSC (North American/Korean Terrestrial/Cable DTV) frontends +# +CONFIG_DVB_NXT200X=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_S5H1409=m + +# +# Tuners/PLL support +# +CONFIG_DVB_PLL=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TDA827X=m +CONFIG_DVB_TUNER_QT1010=m +CONFIG_DVB_TUNER_MT2060=m +CONFIG_DVB_TUNER_MT2266=m +CONFIG_DVB_TUNER_MT2131=m +CONFIG_DVB_TUNER_DIB0070=m + +# +# Miscellaneous devices +# +CONFIG_DVB_LNBP21=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_TUA6100=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_TUNER=m +# CONFIG_VIDEO_TUNER_CUSTOMIZE is not set +CONFIG_TUNER_MT20XX=m +CONFIG_TUNER_TDA8290=m +CONFIG_TUNER_TEA5761=m +CONFIG_TUNER_TEA5767=m +CONFIG_TUNER_SIMPLE=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_DMA_SG=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_DAB=y +CONFIG_USB_DABUSB=m + +# +# Graphics support +# +CONFIG_AGP=y +CONFIG_AGP_AMD64=y +CONFIG_AGP_INTEL=m +CONFIG_AGP_SIS=m +CONFIG_AGP_VIA=m +CONFIG_DRM=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_I810=m +CONFIG_DRM_I830=m +CONFIG_DRM_I915=m +CONFIG_DRM_MGA=m +CONFIG_DRM_SIS=m +CONFIG_DRM_VIA=m +CONFIG_DRM_VIA_CHROME9=m +CONFIG_DRM_SAVAGE=m +CONFIG_VGASTATE=m +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +CONFIG_FB_DDC=m +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +CONFIG_FB_SYS_FILLRECT=m +CONFIG_FB_SYS_COPYAREA=m +CONFIG_FB_SYS_IMAGEBLIT=m +CONFIG_FB_SYS_FOPS=m +CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_SVGALIB=m +# CONFIG_FB_MACMODES is not set +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y + +# +# Frame buffer hardware drivers +# +CONFIG_FB_CIRRUS=m +CONFIG_FB_PM2=m +CONFIG_FB_PM2_FIFO_DISCONNECT=y +CONFIG_FB_CYBER2000=m +CONFIG_FB_ARC=m +CONFIG_FB_ASILIANT=y +CONFIG_FB_IMSTT=y +CONFIG_FB_VGA16=m +CONFIG_FB_UVESA=m +CONFIG_FB_VESA=m +CONFIG_FB_EFI=y +CONFIG_FB_HECUBA=m +CONFIG_FB_HGA=m +# CONFIG_FB_HGA_ACCEL is not set +CONFIG_FB_S1D13XXX=m +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_I2C=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_BACKLIGHT=y +CONFIG_FB_RIVA=m +CONFIG_FB_RIVA_I2C=y +# CONFIG_FB_RIVA_DEBUG is not set +CONFIG_FB_RIVA_BACKLIGHT=y +CONFIG_FB_LE80578=m +CONFIG_FB_CARILLO_RANCH=m +CONFIG_FB_INTEL=m +# CONFIG_FB_INTEL_DEBUG is not set +CONFIG_FB_INTEL_I2C=y +CONFIG_FB_MATROX=m +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MULTIHEAD=y +CONFIG_FB_RADEON=m +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_ATY128=m +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY=m +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_ATY_BACKLIGHT=y +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SAVAGE_ACCEL=y +CONFIG_FB_SIS=m +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +CONFIG_FB_NEOMAGIC=m +CONFIG_FB_KYRO=m +CONFIG_FB_3DFX=m +# CONFIG_FB_3DFX_ACCEL is not set +CONFIG_FB_VOODOO1=m +CONFIG_FB_VT8623=m +CONFIG_FB_TRIDENT=m +# CONFIG_FB_TRIDENT_ACCEL is not set +CONFIG_FB_ARK=m +CONFIG_FB_PM3=m +CONFIG_FB_GEODE=y +CONFIG_FB_GEODE_LX=m +CONFIG_FB_GEODE_GX=m +# CONFIG_FB_GEODE_GX_SET_FBSIZE is not set +CONFIG_FB_GEODE_GX1=m +CONFIG_FB_SM501=m +# CONFIG_FB_VIRTUAL is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_LTV350QV=m +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_CORGI=m +CONFIG_BACKLIGHT_PROGEAR=m +CONFIG_BACKLIGHT_CARILLO_RANCH=m + +# +# Display device support +# +CONFIG_DISPLAY_SUPPORT=m + +# +# Display hardware drivers +# + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +# CONFIG_VGACON_SOFT_SCROLLBACK is not set +CONFIG_VIDEO_SELECT=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=m +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_LOGO is not set + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HID=m +# CONFIG_HID_DEBUG is not set +CONFIG_HIDRAW=y + +# +# USB Input Devices +# +CONFIG_USB_HID=m +CONFIG_USB_HIDINPUT_POWERBOOK=y +# CONFIG_HID_FF is not set +CONFIG_USB_HIDDEV=y + +# +# USB HID Boot Protocol drivers +# +CONFIG_USB_KBD=m +CONFIG_USB_MOUSE=m +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=m +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_SUSPEND=y +CONFIG_USB_PERSIST=y +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_ISP116X_HCD=m +CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_HCD_SSB is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_UHCI_HCD=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SL811_CS=m +CONFIG_USB_R8A66597_HCD=m + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_LIBUSUAL=y + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_MON=y + +# +# USB port drivers +# +CONFIG_USB_USS720=m + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_AIRPRIME=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +# CONFIG_USB_SERIAL_IR is not set +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_EZUSB=y + +# +# USB Miscellaneous drivers +# +CONFIG_USB_EMI62=m +CONFIG_USB_EMI26=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_AUERSWALD=m +CONFIG_USB_RIO500=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LCD=m +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_LED=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_SISUSBVGA=m +# CONFIG_USB_SISUSBVGA_CON is not set +CONFIG_USB_LD=m +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_IOWARRIOR=m +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_CXACRU=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_XUSBATM=m + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=m +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_GADGET_AMD5536UDC=y +CONFIG_USB_AMD5536UDC=m +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +CONFIG_USB_ZERO=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_GADGETFS=m +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_G_SERIAL=m +# CONFIG_USB_MIDI_GADGET is not set + +# +# MMC/SD/SDIO support, can only select one arch from MMC and MSS +# +CONFIG_MMC=m +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD Card Drivers +# +CONFIG_MMC_BLOCK=m +CONFIG_MMC_BLOCK_BOUNCE=y +CONFIG_SDIO_UART=m + +# +# MMC/SD Host Controller Drivers +# +CONFIG_MMC_SDHCI=m +CONFIG_MMC_RICOH_MMC=m +CONFIG_MMC_WBSD=m +CONFIG_MMC_TIFM_SD=m +CONFIG_MMC_SPI=m +# CONFIG_MSS is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=m + +# +# LED drivers +# + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_TRIGGER_IDE_DISK=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=m +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y +CONFIG_INFINIBAND_IPATH=m +CONFIG_INFINIBAND_AMSO1100=m +CONFIG_INFINIBAND_AMSO1100_DEBUG=y +CONFIG_INFINIBAND_CXGB3=m +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set +CONFIG_MLX4_INFINIBAND=m +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_IPOIB_DEBUG=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_ISER=m +CONFIG_EDAC=y + +# +# Reporting subsystems +# +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC_E752X=m +CONFIG_EDAC_I82975X=m +CONFIG_EDAC_I5000=m +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_DRV_TEST=m + +# +# I2C RTC drivers +# +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_M41T80_WDT=y + +# +# SPI RTC drivers +# +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_MAX6902=m + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_STK17TA8=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_M48T59=m +CONFIG_RTC_DRV_V3020=m + +# +# on-CPU RTC drivers +# +CONFIG_DMADEVICES=y + +# +# DMA Devices +# +CONFIG_INTEL_IOATDMA=m +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +CONFIG_NET_DMA=y +CONFIG_DCA=m +CONFIG_AUXDISPLAY=y +CONFIG_KS0108=m +CONFIG_KS0108_PORT=0x378 +CONFIG_KS0108_DELAY=2 +CONFIG_CFAG12864B=m +CONFIG_CFAG12864B_RATE=20 + +# +# Userspace I/O +# +CONFIG_UIO=m +CONFIG_UIO_CIF=m + +# +# Firmware Drivers +# +CONFIG_EDD=y +CONFIG_EDD_OFF=y +CONFIG_DELL_RBU=m +CONFIG_DCDBAS=m +CONFIG_DMIID=y + +# +# File systems +# +CONFIG_EXT2_FS=m +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=m +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +# CONFIG_JFS_DEBUG is not set +CONFIG_JFS_STATISTICS=y +CONFIG_FS_POSIX_ACL=y +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +CONFIG_XFS_SECURITY=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_RT=y +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_NOLOCK=m +CONFIG_GFS2_FS_LOCKING_DLM=m +CONFIG_OCFS2_FS=m +CONFIG_OCFS2_DEBUG_MASKLOG=y +# CONFIG_OCFS2_DEBUG_FS is not set +CONFIG_MINIX_FS=m +CONFIG_ROMFS_FS=m +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_QUOTACTL=y +CONFIG_DNOTIFY=y +CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=m +CONFIG_GENERIC_ACL=y + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +# CONFIG_NTFS_RW is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_VMCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=m + +# +# Miscellaneous filesystems +# +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_AFFS_FS=m +CONFIG_ECRYPT_FS=m +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +CONFIG_BEFS_FS=m +# CONFIG_BEFS_DEBUG is not set +CONFIG_BFS_FS=m +CONFIG_EFS_FS=m +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_LZO=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_CMODE_NONE is not set +# CONFIG_JFFS2_CMODE_PRIORITY is not set +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_CMODE_FAVOURLZO=y +CONFIG_CRAMFS=y +CONFIG_VXFS_FS=m +CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_UFS_DEBUG is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_TCP=y +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +CONFIG_SUNRPC_XPRT_RDMA=m +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +CONFIG_CIFS_WEAK_PW_HASH=y +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +CONFIG_CIFS_EXPERIMENTAL=y +CONFIG_CIFS_UPCALL=y +CONFIG_NCP_FS=m +CONFIG_NCPFS_PACKET_SIGNING=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_STRONG=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_OS2_NS=y +# CONFIG_NCPFS_SMALLDOS is not set +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_EXTRAS=y +CONFIG_CODA_FS=m +# CONFIG_CODA_FS_OLD_API is not set +CONFIG_AFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_9P_FS=m +CONFIG_DEFAULT_RELATIME=y +CONFIG_DEFAULT_RELATIME_VAL=1 + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +CONFIG_ACORN_PARTITION=y +# CONFIG_ACORN_PARTITION_CUMANA is not set +# CONFIG_ACORN_PARTITION_EESOX is not set +CONFIG_ACORN_PARTITION_ICS=y +# CONFIG_ACORN_PARTITION_ADFS is not set +# CONFIG_ACORN_PARTITION_POWERTEC is not set +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_OSF_PARTITION=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_LDM_PARTITION=y +# CONFIG_LDM_DEBUG is not set +CONFIG_SGI_PARTITION=y +CONFIG_ULTRIX_PARTITION=y +CONFIG_SUN_PARTITION=y +CONFIG_KARMA_PARTITION=y +CONFIG_EFI_PARTITION=y +CONFIG_SYSV68_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +CONFIG_INSTRUMENTATION=y +CONFIG_PROFILING=y +CONFIG_OPROFILE=m +CONFIG_PROFILE_NMI=y +CONFIG_KPROBES=y +CONFIG_MARKERS=y + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_PRINTK_TIME=y +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +CONFIG_TIMER_STATS=y +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RTMUTEX_CHECK is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_RWLOCK_TORTURE_TEST is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_FRAME_POINTER is not set +# CONFIG_FORCED_INLINING is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_LKDTM is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_HAVE_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +# CONFIG_FTRACE is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_WAKEUP_LATENCY_HIST is not set +# CONFIG_PREEMPT_TRACE is not set +# CONFIG_SAMPLES is not set +CONFIG_NONPROMISC_DEVMEM=y +CONFIG_EARLY_PRINTK=y +# CONFIG_WRAPPER_PRINT is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_DEBUG_RODATA=y +# CONFIG_IOMMU_DEBUG is not set +CONFIG_IO_DELAY_TYPE_0X80=0 +CONFIG_IO_DELAY_TYPE_0XED=1 +CONFIG_IO_DELAY_TYPE_UDELAY=2 +CONFIG_IO_DELAY_TYPE_NONE=3 +# CONFIG_IO_DELAY_0X80 is not set +CONFIG_IO_DELAY_0XED=y +# CONFIG_IO_DELAY_UDELAY is not set +# CONFIG_IO_DELAY_NONE is not set +CONFIG_DEFAULT_IO_DELAY_TYPE=1 + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +CONFIG_SECURITY_CAPABILITIES=y +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_DISABLE=y +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +CONFIG_SECURITY_APPARMOR=y +CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 +# CONFIG_SECURITY_APPARMOR_DISABLE is not set +CONFIG_XOR_BLOCKS=m +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ABLKCIPHER=m +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_XTS=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_TWOFISH_X86_64=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_AES_X86_64=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_HW=y +CONFIG_HAVE_KVM=y +CONFIG_VIRTUALIZATION=y +CONFIG_KVM=m +CONFIG_KVM_INTEL=m +CONFIG_KVM_AMD=m +CONFIG_VIRTIO=m +CONFIG_VIRTIO_RING=m +CONFIG_VIRTIO_PCI=m +CONFIG_VIRTIO_BALLOON=m + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_CRC_CCITT=m +CONFIG_CRC16=m +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +CONFIG_CRC7=m +CONFIG_LIBCRC32C=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_CHECK_SIGNATURE=y --- linux-2.6.24.orig/debian/binary-custom.d/rt/vars +++ linux-2.6.24/debian/binary-custom.d/rt/vars @@ -0,0 +1,7 @@ +arch="i386 amd64" +supported="Generic" +target="RT kernel" +desc="Ingo Molnar's full real time preemption patch (2.6.24.7-rt21)" +bootloader="lilo (>= 19.1) | grub" +provides="kvm-api-4, redhat-cluster-modules" +section_image="universe/base" --- linux-2.6.24.orig/debian/binary-custom.d/rt/config.i386 +++ linux-2.6.24/debian/binary-custom.d/rt/config.i386 @@ -0,0 +1,3954 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.24.7 +# Fri Nov 21 17:16:40 2008 +# +# CONFIG_64BIT is not set +CONFIG_X86_32=y +# CONFIG_X86_64 is not set +CONFIG_X86=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_SEMAPHORE_SLEEPERS=y +CONFIG_MMU=y +CONFIG_ZONE_DMA=y +CONFIG_QUICKLIST=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_DMI=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_ASM_SEMAPHORES=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_CALIBRATE_DELAY=y +# CONFIG_GENERIC_TIME_VSYSCALL is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +# CONFIG_ZONE_DMA32 is not set +CONFIG_ARCH_POPULATES_NODE_MAP=y +# CONFIG_AUDIT_ARCH is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_X86_SMP=y +CONFIG_X86_HT=y +CONFIG_X86_BIOS_REBOOT=y +CONFIG_X86_TRAMPOLINE=y +CONFIG_KTIME_SCALAR=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_VERSION_SIGNATURE="Ubuntu 2.6.24-4.6-generic" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +# CONFIG_TASK_DELAY_ACCT is not set +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y +CONFIG_AUDIT_TREE=y +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_CGROUPS=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_NS=y +CONFIG_CPUSETS=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_FAIR_USER_SCHED is not set +CONFIG_FAIR_CGROUP_SCHED=y +CONFIG_CGROUP_CPUACCT=y +# CONFIG_SYSFS_DEPRECATED is not set +CONFIG_PROC_PID_CPUSET=y +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_RADIX_TREE_CONCURRENT=y +CONFIG_RADIX_TREE_OPTIMISTIC=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y +CONFIG_STOP_MACHINE=y +CONFIG_BLOCK=y +CONFIG_LBD=y +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_PREEMPT_NOTIFIERS=y + +# +# Processor type and features +# +CONFIG_TICK_ONESHOT=y +# CONFIG_NO_HZ is not set +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_SMP=y +CONFIG_X86_PC=y +# CONFIG_X86_ELAN is not set +# CONFIG_X86_VOYAGER is not set +# CONFIG_X86_NUMAQ is not set +# CONFIG_X86_SUMMIT is not set +# CONFIG_X86_BIGSMP is not set +# CONFIG_X86_VISWS is not set +# CONFIG_X86_GENERICARCH is not set +# CONFIG_X86_ES7000 is not set +# CONFIG_X86_VSMP is not set +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_PARAVIRT=y +CONFIG_PARAVIRT_GUEST=y +CONFIG_VMI=y +# CONFIG_LGUEST_GUEST is not set +# CONFIG_M386 is not set +# CONFIG_M486 is not set +CONFIG_M586=y +# CONFIG_M586TSC is not set +# CONFIG_M586MMX is not set +# CONFIG_M686 is not set +# CONFIG_MPENTIUMII is not set +# CONFIG_MPENTIUMIII is not set +# CONFIG_MPENTIUMM is not set +# CONFIG_MPENTIUM4 is not set +# CONFIG_MK6 is not set +# CONFIG_MK7 is not set +# CONFIG_MK8 is not set +# CONFIG_MCRUSOE is not set +# CONFIG_MEFFICEON is not set +# CONFIG_MWINCHIPC6 is not set +# CONFIG_MWINCHIP2 is not set +# CONFIG_MWINCHIP3D is not set +# CONFIG_MGEODEGX1 is not set +# CONFIG_MGEODE_LX is not set +# CONFIG_MCYRIXIII is not set +# CONFIG_MVIAC3_2 is not set +# CONFIG_MVIAC7 is not set +# CONFIG_MPSC is not set +# CONFIG_MCORE2 is not set +# CONFIG_GENERIC_CPU is not set +CONFIG_X86_GENERIC=y +CONFIG_X86_CMPXCHG=y +CONFIG_X86_L1_CACHE_SHIFT=7 +CONFIG_X86_XADD=y +CONFIG_X86_PPRO_FENCE=y +CONFIG_X86_F00F_BUG=y +CONFIG_X86_WP_WORKS_OK=y +CONFIG_X86_INVLPG=y +CONFIG_X86_BSWAP=y +CONFIG_X86_POPAD_OK=y +CONFIG_X86_ALIGNMENT_16=y +CONFIG_X86_INTEL_USERCOPY=y +CONFIG_X86_MINIMUM_CPU_FAMILY=4 +CONFIG_HPET_TIMER=y +CONFIG_HPET_EMULATE_RTC=y +CONFIG_NR_CPUS=8 +CONFIG_SCHED_SMT=y +CONFIG_SCHED_MC=y +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT_DESKTOP is not set +CONFIG_PREEMPT_RT=y +CONFIG_PREEMPT=y +CONFIG_PREEMPT_SOFTIRQS=y +CONFIG_PREEMPT_HARDIRQS=y +CONFIG_PREEMPT_BKL=y +# CONFIG_CLASSIC_RCU is not set +CONFIG_PREEMPT_RCU=y +CONFIG_PREEMPT_RCU_BOOST=y +CONFIG_RCU_TRACE=m +CONFIG_X86_LOCAL_APIC=y +CONFIG_X86_IO_APIC=y +# CONFIG_X86_MCE is not set +CONFIG_VM86=y +CONFIG_TOSHIBA=m +CONFIG_I8K=m +CONFIG_X86_REBOOTFIXUPS=y +CONFIG_MICROCODE=m +CONFIG_MICROCODE_OLD_INTERFACE=y +CONFIG_X86_MSR=m +CONFIG_X86_CPUID=m +# CONFIG_NOHIGHMEM is not set +CONFIG_HIGHMEM4G=y +# CONFIG_HIGHMEM64G is not set +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_3G_OPT is not set +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_2G_OPT is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_SPARSEMEM_STATIC=y +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_NR_QUICK=1 +CONFIG_VIRT_TO_BUS=y +CONFIG_HIGHPTE=y +# CONFIG_MATH_EMULATION is not set +CONFIG_MTRR=y +CONFIG_EFI=y +# CONFIG_IRQBALANCE is not set +CONFIG_BOOT_IOREMAP=y +CONFIG_SECCOMP=y +# CONFIG_HZ_100 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_300 is not set +CONFIG_HZ_1000=y +CONFIG_HZ=1000 +CONFIG_KEXEC=y +CONFIG_CRASH_DUMP=y +CONFIG_PHYSICAL_START=0x100000 +CONFIG_RELOCATABLE=y +CONFIG_PHYSICAL_ALIGN=0x100000 +CONFIG_HOTPLUG_CPU=y +# CONFIG_COMPAT_VDSO is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_HARDIRQS_SW_RESEND=y + +# +# Power management options +# +CONFIG_PM=y +CONFIG_PM_LEGACY=y +CONFIG_PM_DEBUG=y +# CONFIG_PM_VERBOSE is not set +CONFIG_PM_TRACE=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND_SMP_POSSIBLE=y +CONFIG_SUSPEND=y +CONFIG_PM_DISABLE_CONSOLE=y +CONFIG_HIBERNATION_SMP_POSSIBLE=y +CONFIG_HIBERNATION=y +CONFIG_PM_STD_PARTITION="" +CONFIG_ACPI=y +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_PROCFS=y +CONFIG_ACPI_PROCFS_POWER=y +CONFIG_ACPI_SYSFS_POWER=y +CONFIG_ACPI_PROC_EVENT=y +CONFIG_ACPI_AC=m +CONFIG_ACPI_BATTERY=m +CONFIG_ACPI_BUTTON=m +CONFIG_ACPI_VIDEO=m +CONFIG_ACPI_FAN=m +CONFIG_ACPI_DOCK=m +CONFIG_ACPI_BAY=m +CONFIG_ACPI_PROCESSOR=m +CONFIG_ACPI_HOTPLUG_CPU=y +CONFIG_ACPI_THERMAL=m +CONFIG_ACPI_ASUS=m +CONFIG_ACPI_TOSHIBA=m +CONFIG_ACPI_CUSTOM_DSDT_INITRD=y +CONFIG_ACPI_BLACKLIST_YEAR=2000 +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_EC=y +CONFIG_ACPI_POWER=y +CONFIG_ACPI_SYSTEM=y +CONFIG_X86_PM_TIMER=y +CONFIG_ACPI_CONTAINER=m +CONFIG_ACPI_SBS=m +CONFIG_APM=m +# CONFIG_APM_IGNORE_USER_SUSPEND is not set +# CONFIG_APM_DO_ENABLE is not set +# CONFIG_APM_CPU_IDLE is not set +# CONFIG_APM_DISPLAY_BLANK is not set +# CONFIG_APM_ALLOW_INTS is not set +# CONFIG_APM_REAL_MODE_POWER_OFF is not set + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=m +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m + +# +# CPUFreq processor drivers +# +CONFIG_X86_ACPI_CPUFREQ=m +CONFIG_X86_POWERNOW_K6=m +CONFIG_X86_POWERNOW_K7=m +CONFIG_X86_POWERNOW_K7_ACPI=y +CONFIG_X86_POWERNOW_K8=m +CONFIG_X86_POWERNOW_K8_ACPI=y +CONFIG_X86_GX_SUSPMOD=m +CONFIG_X86_SPEEDSTEP_CENTRINO=m +CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y +CONFIG_X86_SPEEDSTEP_ICH=m +CONFIG_X86_SPEEDSTEP_SMI=m +CONFIG_X86_P4_CLOCKMOD=m +CONFIG_X86_CPUFREQ_NFORCE2=m +CONFIG_X86_LONGRUN=m +CONFIG_X86_LONGHAUL=m +# CONFIG_X86_E_POWERSAVER is not set + +# +# shared options +# +# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set +CONFIG_X86_SPEEDSTEP_LIB=m +CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK=y +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y + +# +# Bus options (PCI etc.) +# +CONFIG_PCI=y +# CONFIG_PCI_GOBIOS is not set +# CONFIG_PCI_GOMMCONFIG is not set +# CONFIG_PCI_GODIRECT is not set +CONFIG_PCI_GOANY=y +CONFIG_PCI_BIOS=y +CONFIG_PCI_DIRECT=y +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCIEPORTBUS=y +CONFIG_HOTPLUG_PCI_PCIE=m +CONFIG_PCIEAER=y +CONFIG_ARCH_SUPPORTS_MSI=y +CONFIG_PCI_MSI=y +CONFIG_PCI_LEGACY=y +# CONFIG_PCI_DEBUG is not set +CONFIG_HT_IRQ=y +CONFIG_ISA_DMA_API=y +CONFIG_ISA=y +CONFIG_EISA=y +CONFIG_EISA_VLB_PRIMING=y +CONFIG_EISA_PCI_EISA=y +CONFIG_EISA_VIRTUAL_ROOT=y +CONFIG_EISA_NAMES=y +CONFIG_MCA=y +CONFIG_MCA_LEGACY=y +# CONFIG_MCA_PROC_FS is not set +CONFIG_SCx200=m +CONFIG_SCx200HR_TIMER=m +CONFIG_K8_NB=y +CONFIG_PCCARD=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=m +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_IOCTL=y +CONFIG_CARDBUS=y + +# +# PC-card bridges +# +CONFIG_YENTA=m +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_PD6729=m +CONFIG_I82092=m +CONFIG_I82365=m +CONFIG_TCIC=m +CONFIG_PCMCIA_PROBE=y +CONFIG_PCCARD_NONSTATIC=m +CONFIG_HOTPLUG_PCI=m +CONFIG_HOTPLUG_PCI_FAKE=m +CONFIG_HOTPLUG_PCI_COMPAQ=m +CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM=y +CONFIG_HOTPLUG_PCI_IBM=m +CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +CONFIG_HOTPLUG_PCI_CPCI=y +CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m +CONFIG_HOTPLUG_PCI_CPCI_GENERIC=m +CONFIG_HOTPLUG_PCI_SHPC=m + +# +# Executable file formats / Emulations +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=m +CONFIG_BINFMT_MISC=m + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=m +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_LRO=m +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=m +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +# CONFIG_DEFAULT_BIC is not set +# CONFIG_DEFAULT_CUBIC is not set +# CONFIG_DEFAULT_HTCP is not set +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_WESTWOOD is not set +CONFIG_DEFAULT_RENO=y +CONFIG_DEFAULT_TCP_CONG="reno" +CONFIG_TCP_MD5SIG=y +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m +CONFIG_IPV6=m +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +# CONFIG_IPV6_MIP6 is not set +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_TUNNEL=m +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_NETLABEL is not set +CONFIG_NETWORK_SECMARK=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK_ENABLED=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +# CONFIG_NF_CONNTRACK_SANE is not set +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m + +# +# IP: Netfilter Configuration +# +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration (EXPERIMENTAL) +# +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_RAW=m + +# +# DECnet: Netfilter Configuration +# +CONFIG_DECNET_NF_GRABULATOR=m + +# +# Bridge: Netfilter Configuration +# +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_IP_DCCP=m +CONFIG_INET_DCCP_DIAG=m +CONFIG_IP_DCCP_ACKVEC=y + +# +# DCCP CCIDs Configuration (EXPERIMENTAL) +# +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +CONFIG_IP_DCCP_TFRC_LIB=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 + +# +# DCCP Kernel Hacking +# +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_NET_DCCPPROBE=m +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +CONFIG_ATM=y +CONFIG_ATM_CLIP=y +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +CONFIG_DECNET=m +# CONFIG_DECNET_ROUTER is not set +CONFIG_LLC=y +CONFIG_LLC2=m +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_ATALK=m +CONFIG_DEV_APPLETALK=m +CONFIG_LTPC=m +CONFIG_COPS=m +CONFIG_COPS_DAYNA=y +CONFIG_COPS_TANGENT=y +CONFIG_IPDDP=m +CONFIG_IPDDP_ENCAP=y +CONFIG_IPDDP_DECAP=y +CONFIG_X25=m +CONFIG_LAPB=m +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +CONFIG_WAN_ROUTER=m +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RR=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_INGRESS=m + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +# CONFIG_CLS_U32_PERF is not set +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m +# CONFIG_NET_CLS_POLICE is not set +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_SCH_FIFO=y + +# +# Network testing +# +CONFIG_NET_PKTGEN=m +CONFIG_NET_TCPPROBE=m +CONFIG_HAMRADIO=y + +# +# Packet Radio protocols +# +CONFIG_AX25=m +CONFIG_AX25_DAMA_SLAVE=y +CONFIG_NETROM=m +CONFIG_ROSE=m + +# +# AX.25 network device drivers +# +CONFIG_MKISS=m +CONFIG_6PACK=m +CONFIG_BPQETHER=m +CONFIG_SCC=m +# CONFIG_SCC_DELAY is not set +# CONFIG_SCC_TRXECHO is not set +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_BAYCOM_PAR=m +CONFIG_BAYCOM_EPP=m +CONFIG_YAM=m +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +CONFIG_IRDA_ULTRA=y + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_DEBUG=y + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m + +# +# Dongle support +# +CONFIG_DONGLE=y +CONFIG_ESI_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_TEKRAM_DONGLE=m +# CONFIG_TOIM3232_DONGLE is not set +CONFIG_LITELINK_DONGLE=m +CONFIG_MA600_DONGLE=m +CONFIG_GIRBIL_DONGLE=m +CONFIG_MCP2120_DONGLE=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_ACT200L_DONGLE=m +CONFIG_KINGSUN_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +CONFIG_KS959_DONGLE=m + +# +# Old SIR device drivers +# + +# +# Old Serial dongle support +# + +# +# FIR device drivers +# +CONFIG_USB_IRDA=m +CONFIG_SIGMATEL_FIR=m +CONFIG_NSC_FIR=m +CONFIG_WINBOND_FIR=m +CONFIG_TOSHIBA_FIR=m +CONFIG_SMC_IRCC_FIR=m +CONFIG_ALI_FIR=m +CONFIG_VLSI_FIR=m +CONFIG_VIA_FIR=m +CONFIG_MCS_FIR=m +CONFIG_BT=m +CONFIG_BT_L2CAP=m +CONFIG_BT_SCO=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_CMTP=m +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIVHCI=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_RXKAD=m +CONFIG_FIB_RULES=y + +# +# Wireless +# +CONFIG_CFG80211=m +CONFIG_NL80211=y +CONFIG_WIRELESS_EXT=y +CONFIG_MAC80211=m +CONFIG_MAC80211_RCSIMPLE=y +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_DEBUGFS=y +# CONFIG_MAC80211_DEBUG is not set +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT_WEP=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +CONFIG_RFKILL_LEDS=y +CONFIG_NET_9P=m +CONFIG_NET_9P_FD=m +CONFIG_NET_9P_VIRTIO=m +# CONFIG_NET_9P_DEBUG is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_CONNECTOR=m +CONFIG_MTD=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=m +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_FTL=m +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_INFTL=m +CONFIG_RFD_FTL=m +CONFIG_SSFDC=m +CONFIG_MTD_OOPS=m + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_RAM=m +CONFIG_MTD_ROM=m +CONFIG_MTD_ABSENT=m + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PHYSMAP_LEN=0x4000000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PNC2000=m +CONFIG_MTD_SC520CDP=m +CONFIG_MTD_NETSC520=m +CONFIG_MTD_TS5500=m +CONFIG_MTD_SBC_GXX=m +CONFIG_MTD_SCx200_DOCFLASH=m +CONFIG_MTD_AMD76XROM=m +CONFIG_MTD_ICHXROM=m +CONFIG_MTD_ESB2ROM=m +CONFIG_MTD_CK804XROM=m +CONFIG_MTD_SCB2_FLASH=m +CONFIG_MTD_NETtel=m +CONFIG_MTD_DILNETPC=m +CONFIG_MTD_DILNETPC_BOOTSIZE=0x80000 +CONFIG_MTD_L440GX=m +CONFIG_MTD_PCI=m +CONFIG_MTD_INTEL_VR_NOR=m +CONFIG_MTD_PLATRAM=m + +# +# Self-contained MTD device drivers +# +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +CONFIG_MTD_DATAFLASH=m +CONFIG_MTD_M25P80=m +CONFIG_MTD_SLRAM=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_MTDRAM=m +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTD_BLOCK2MTD=m + +# +# Disk-On-Chip Device Drivers +# +CONFIG_MTD_DOC2000=m +CONFIG_MTD_DOC2001=m +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCECC=m +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_DOCPROBE_ADDRESS=0 +CONFIG_MTD_NAND=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=m +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set +CONFIG_MTD_NAND_CAFE=m +CONFIG_MTD_NAND_CS553X=m +CONFIG_MTD_NAND_NANDSIM=m +CONFIG_MTD_NAND_PLATFORM=m +CONFIG_MTD_ALAUDA=m +CONFIG_MTD_ONENAND=m +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +# CONFIG_MTD_ONENAND_OTP is not set +CONFIG_MTD_ONENAND_2X_PROGRAM=y +CONFIG_MTD_ONENAND_SIM=m + +# +# UBI - Unsorted block images +# +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_RESERVE=1 +CONFIG_MTD_UBI_GLUEBI=y + +# +# UBI debugging options +# +# CONFIG_MTD_UBI_DEBUG is not set +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_SERIAL=m +CONFIG_PARPORT_PC_FIFO=y +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_AX88796=m +CONFIG_PARPORT_1284=y +CONFIG_PARPORT_NOT_PC=y +CONFIG_PNP=y +# CONFIG_PNP_DEBUG is not set + +# +# Protocols +# +CONFIG_ISAPNP=y +CONFIG_PNPBIOS=y +CONFIG_PNPBIOS_PROC_FS=y +CONFIG_PNPACPI=y +CONFIG_BLK_DEV=y +CONFIG_BLK_DEV_FD=m +CONFIG_BLK_DEV_XD=m +CONFIG_PARIDE=m + +# +# Parallel IDE high-level drivers +# +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PT=m +CONFIG_PARIDE_PG=m + +# +# Parallel IDE protocol modules +# +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +CONFIG_PARIDE_BPCK6=m +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_EPAT=m +# CONFIG_PARIDE_EPATC8 is not set +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_CISS_SCSI_TAPE=y +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_UMEM=m +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_SX8=m +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_ATA_OVER_ETH=m +CONFIG_VIRTIO_BLK=m +CONFIG_MISC_DEVICES=y +CONFIG_IBM_ASM=m +CONFIG_PHANTOM=m +CONFIG_EEPROM_93CX6=m +CONFIG_SGI_IOC4=m +CONFIG_TIFM_CORE=m +CONFIG_TIFM_7XX1=m +CONFIG_ASUS_LAPTOP=m +CONFIG_FUJITSU_LAPTOP=m +CONFIG_MSI_LAPTOP=m +CONFIG_SONY_LAPTOP=m +CONFIG_SONYPI_COMPAT=y +CONFIG_THINKPAD_ACPI=m +# CONFIG_THINKPAD_ACPI_DEBUG is not set +CONFIG_THINKPAD_ACPI_BAY=y +CONFIG_IDE=y +CONFIG_IDE_MAX_HWIFS=4 +CONFIG_BLK_DEV_IDE=m + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +# CONFIG_BLK_DEV_HD_IDE is not set +CONFIG_BLK_DEV_IDEDISK=m +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_DELKIN=m +CONFIG_BLK_DEV_IDECD=m +CONFIG_BLK_DEV_IDETAPE=m +CONFIG_BLK_DEV_IDEFLOPPY=m +CONFIG_BLK_DEV_IDESCSI=m +CONFIG_BLK_DEV_IDEACPI=y +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_PROC_FS=y + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=m +CONFIG_BLK_DEV_PLATFORM=m +CONFIG_BLK_DEV_CMD640=y +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +CONFIG_BLK_DEV_IDEPNP=y + +# +# PCI IDE chipsets support +# +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_GENERIC is not set +CONFIG_BLK_DEV_OPTI621=m +# CONFIG_BLK_DEV_RZ1000 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_AEC62XX=m +CONFIG_BLK_DEV_ALI15X3=m +# CONFIG_WDC_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +CONFIG_BLK_DEV_ATIIXP=m +CONFIG_BLK_DEV_CMD64X=m +# CONFIG_BLK_DEV_TRIFLEX is not set +CONFIG_BLK_DEV_CY82C693=m +# CONFIG_BLK_DEV_CS5520 is not set +CONFIG_BLK_DEV_CS5530=m +CONFIG_BLK_DEV_CS5535=m +CONFIG_BLK_DEV_HPT34X=m +# CONFIG_HPT34X_AUTODMA is not set +CONFIG_BLK_DEV_HPT366=m +# CONFIG_BLK_DEV_JMICRON is not set +CONFIG_BLK_DEV_SC1200=m +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +CONFIG_BLK_DEV_NS87415=m +CONFIG_BLK_DEV_PDC202XX_OLD=m +CONFIG_PDC202XX_BURST=y +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +CONFIG_BLK_DEV_TRM290=m +# CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_BLK_DEV_TC86C001=m +# CONFIG_IDE_ARM is not set + +# +# Other IDE chipsets support +# + +# +# Note: most of these also require special kernel boot parameters +# +CONFIG_BLK_DEV_4DRIVES=y +CONFIG_BLK_DEV_ALI14XX=m +CONFIG_BLK_DEV_DTC2278=m +CONFIG_BLK_DEV_HT6560B=m +CONFIG_BLK_DEV_QD65XX=m +CONFIG_BLK_DEV_UMC8672=m +CONFIG_BLK_DEV_IDEDMA=y +CONFIG_IDE_ARCH_OBSOLETE_INIT=y +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +CONFIG_RAID_ATTRS=m +CONFIG_SCSI=m +CONFIG_SCSI_DMA=y +CONFIG_SCSI_TGT=m +CONFIG_SCSI_NETLINK=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_SCH=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_FC_TGT_ATTRS=y +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +CONFIG_SCSI_SAS_ATA=y +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ISCSI_TCP=m +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_7000FASST=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AHA152X=m +CONFIG_SCSI_AHA1542=m +CONFIG_SCSI_AHA1740=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +CONFIG_AIC7XXX_DEBUG_ENABLE=y +CONFIG_AIC7XXX_DEBUG_MASK=0 +CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +# CONFIG_SCSI_AIC7XXX_OLD is not set +CONFIG_SCSI_AIC79XX=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +CONFIG_AIC79XX_DEBUG_ENABLE=y +CONFIG_AIC79XX_DEBUG_MASK=0 +CONFIG_AIC79XX_REG_PRETTY_PRINT=y +CONFIG_SCSI_AIC94XX=m +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_SCSI_DPT_I2O=m +CONFIG_SCSI_ADVANSYS=m +CONFIG_SCSI_IN2000=m +CONFIG_SCSI_ARCMSR=m +CONFIG_SCSI_ARCMSR_AER=y +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_SAS=m +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_BUSLOGIC=m +# CONFIG_SCSI_OMIT_FLASHPOINT is not set +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_DTC3280=m +CONFIG_SCSI_EATA=m +CONFIG_SCSI_EATA_TAGGED_QUEUE=y +CONFIG_SCSI_EATA_LINKED_COMMANDS=y +CONFIG_SCSI_EATA_MAX_TAGS=16 +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_SCSI_FD_MCS=m +CONFIG_SCSI_GDTH=m +CONFIG_SCSI_GENERIC_NCR5380=m +CONFIG_SCSI_GENERIC_NCR5380_MMIO=m +CONFIG_SCSI_GENERIC_NCR53C400=y +CONFIG_SCSI_IBMMCA=m +CONFIG_IBMMCA_SCSI_ORDER_STANDARD=y +# CONFIG_IBMMCA_SCSI_DEV_RESET is not set +CONFIG_SCSI_IPS=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_PPA=m +CONFIG_SCSI_IMM=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +CONFIG_SCSI_NCR53C406A=m +CONFIG_SCSI_NCR_D700=m +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_TRACE is not set +# CONFIG_SCSI_IPR_DUMP is not set +CONFIG_SCSI_NCR_Q720=m +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=4 +CONFIG_SCSI_NCR53C8XX_SYNC=5 +CONFIG_SCSI_PAS16=m +CONFIG_SCSI_PSI240I=m +CONFIG_SCSI_QLOGIC_FAS=m +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_SEAGATE=m +CONFIG_SCSI_SIM710=m +CONFIG_SCSI_SYM53C416=m +CONFIG_SCSI_DC395x=m +CONFIG_SCSI_DC390T=m +CONFIG_SCSI_T128=m +CONFIG_SCSI_U14_34F=m +CONFIG_SCSI_U14_34F_TAGGED_QUEUE=y +CONFIG_SCSI_U14_34F_LINKED_COMMANDS=y +CONFIG_SCSI_U14_34F_MAX_TAGS=8 +CONFIG_SCSI_ULTRASTOR=m +CONFIG_SCSI_NSP32=m +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_SRP=m +CONFIG_SCSI_LOWLEVEL_PCMCIA=y +CONFIG_PCMCIA_AHA152X=m +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_NINJA_SCSI=m +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_SYM53C500=m +CONFIG_ATA=m +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_ACPI=y +CONFIG_SATA_AHCI=m +CONFIG_SATA_SVW=m +CONFIG_ATA_PIIX=m +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_PDC_ADMA=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_SX4=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIL24=m +CONFIG_SATA_SIS=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m +CONFIG_SATA_INIC162X=m +CONFIG_PATA_ACPI=m +# CONFIG_PATA_ALI is not set +CONFIG_PATA_AMD=m +CONFIG_PATA_ARTOP=m +CONFIG_PATA_ATIIXP=m +# CONFIG_PATA_CMD640_PCI is not set +CONFIG_PATA_CMD64X=m +CONFIG_PATA_CS5520=m +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CS5535 is not set +CONFIG_PATA_CS5536=m +# CONFIG_PATA_CYPRESS is not set +CONFIG_PATA_EFAR=m +CONFIG_ATA_GENERIC=m +CONFIG_PATA_HPT366=m +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +CONFIG_PATA_HPT3X3=m +# CONFIG_PATA_HPT3X3_DMA is not set +# CONFIG_PATA_ISAPNP is not set +CONFIG_PATA_IT821X=m +CONFIG_PATA_IT8213=m +CONFIG_PATA_JMICRON=m +# CONFIG_PATA_LEGACY is not set +CONFIG_PATA_TRIFLEX=m +CONFIG_PATA_MARVELL=m +CONFIG_PATA_MPIIX=m +CONFIG_PATA_OLDPIIX=m +CONFIG_PATA_NETCELL=m +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_NS87415 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +CONFIG_PATA_PCMCIA=m +# CONFIG_PATA_PDC_OLD is not set +CONFIG_PATA_QDI=m +# CONFIG_PATA_RADISYS is not set +CONFIG_PATA_RZ1000=m +# CONFIG_PATA_SC1200 is not set +CONFIG_PATA_SERVERWORKS=m +CONFIG_PATA_PDC2027X=m +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +CONFIG_PATA_VIA=m +CONFIG_PATA_WINBOND=m +# CONFIG_PATA_WINBOND_VLB is not set +CONFIG_PATA_PLATFORM=m +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID5_RESHAPE=y +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m +CONFIG_BLK_DEV_DM=m +# CONFIG_DM_DEBUG is not set +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_EMC=m +CONFIG_DM_MULTIPATH_RDAC=m +CONFIG_DM_MULTIPATH_HP=m +# CONFIG_DM_DELAY is not set +CONFIG_DM_UEVENT=y +CONFIG_FUSION=y +CONFIG_FUSION_SPI=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_SAS=m +CONFIG_FUSION_MAX_SGE=128 +CONFIG_FUSION_CTL=m +CONFIG_FUSION_LAN=m +CONFIG_FUSION_LOGGING=y + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_FIREWIRE is not set +CONFIG_IEEE1394=m + +# +# Subsystem Options +# +# CONFIG_IEEE1394_VERBOSEDEBUG is not set + +# +# Controllers +# +CONFIG_IEEE1394_PCILYNX=m +CONFIG_IEEE1394_OHCI1394=m + +# +# Protocols +# +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_I2O=m +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_I2O_BUS=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_SCSI=m +CONFIG_I2O_PROC=m +CONFIG_MACINTOSH_DRIVERS=y +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_NETDEVICES=y +CONFIG_NETDEVICES_MULTIQUEUE=y +CONFIG_IFB=m +CONFIG_DUMMY=m +CONFIG_BONDING=m +CONFIG_MACVLAN=m +CONFIG_EQUALIZER=m +CONFIG_TUN=m +CONFIG_VETH=m +CONFIG_NET_SB1000=m +CONFIG_ARCNET=m +CONFIG_ARCNET_1201=m +CONFIG_ARCNET_1051=m +CONFIG_ARCNET_RAW=m +CONFIG_ARCNET_CAP=m +CONFIG_ARCNET_COM90xx=m +CONFIG_ARCNET_COM90xxIO=m +CONFIG_ARCNET_RIM_I=m +CONFIG_ARCNET_COM20020=m +CONFIG_ARCNET_COM20020_ISA=m +CONFIG_ARCNET_COM20020_PCI=m +CONFIG_PHYLIB=m + +# +# MII PHY device drivers +# +CONFIG_MARVELL_PHY=m +CONFIG_DAVICOM_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_LXT_PHY=m +CONFIG_CICADA_PHY=m +CONFIG_VITESSE_PHY=m +CONFIG_SMSC_PHY=m +CONFIG_BROADCOM_PHY=m +CONFIG_ICPLUS_PHY=m +CONFIG_FIXED_PHY=m +# CONFIG_FIXED_MII_10_FDX is not set +# CONFIG_FIXED_MII_100_FDX is not set +CONFIG_FIXED_MII_1000_FDX=y +CONFIG_FIXED_MII_AMNT=1 +CONFIG_MDIO_BITBANG=m +CONFIG_NET_ETHERNET=y +CONFIG_MII=m +CONFIG_HAPPYMEAL=m +CONFIG_SUNGEM=m +CONFIG_CASSINI=m +CONFIG_NET_VENDOR_3COM=y +CONFIG_EL1=m +CONFIG_EL2=m +CONFIG_ELPLUS=m +CONFIG_EL16=m +CONFIG_EL3=m +CONFIG_3C515=m +CONFIG_ELMC=m +CONFIG_ELMC_II=m +CONFIG_VORTEX=m +CONFIG_TYPHOON=m +CONFIG_LANCE=m +CONFIG_NET_VENDOR_SMC=y +CONFIG_WD80x3=m +CONFIG_ULTRAMCA=m +CONFIG_ULTRA=m +CONFIG_ULTRA32=m +CONFIG_SMC9194=m +CONFIG_NET_VENDOR_RACAL=y +CONFIG_NI52=m +CONFIG_NI65=m +CONFIG_NET_TULIP=y +CONFIG_DE2104X=m +CONFIG_TULIP=m +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_NAPI is not set +CONFIG_DE4X5=m +CONFIG_WINBOND_840=m +CONFIG_DM9102=m +CONFIG_ULI526X=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_AT1700=m +CONFIG_DEPCA=m +CONFIG_HP100=m +CONFIG_NET_ISA=y +CONFIG_E2100=m +CONFIG_EWRK3=m +CONFIG_EEXPRESS=m +CONFIG_EEXPRESS_PRO=m +CONFIG_HPLAN_PLUS=m +CONFIG_HPLAN=m +CONFIG_LP486E=m +CONFIG_ETH16I=m +CONFIG_NE2000=m +CONFIG_ZNET=m +CONFIG_SEEQ8005=m +CONFIG_NE2_MCA=m +CONFIG_IBMLANA=m +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +CONFIG_NET_PCI=y +CONFIG_PCNET32=m +# CONFIG_PCNET32_NAPI is not set +CONFIG_AMD8111_ETH=m +# CONFIG_AMD8111E_NAPI is not set +CONFIG_ADAPTEC_STARFIRE=m +# CONFIG_ADAPTEC_STARFIRE_NAPI is not set +CONFIG_AC3200=m +CONFIG_APRICOT=m +CONFIG_B44=m +CONFIG_B44_PCI_AUTOSELECT=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI=y +CONFIG_FORCEDETH=m +# CONFIG_FORCEDETH_NAPI is not set +CONFIG_CS89x0=m +CONFIG_EEPRO100=m +CONFIG_E100=m +CONFIG_LNE390=m +CONFIG_FEALNX=m +CONFIG_NATSEMI=m +CONFIG_NE2K_PCI=m +CONFIG_NE3210=m +CONFIG_ES3210=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_PIO=y +# CONFIG_8139TOO_TUNE_TWISTER is not set +CONFIG_8139TOO_8129=y +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_SIS900=m +CONFIG_EPIC100=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_TLAN=m +CONFIG_VIA_RHINE=m +CONFIG_VIA_RHINE_MMIO=y +CONFIG_VIA_RHINE_NAPI=y +CONFIG_SC92031=m +CONFIG_NET_POCKET=y +CONFIG_ATP=m +CONFIG_DE600=m +CONFIG_DE620=m +CONFIG_NETDEV_1000=y +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_DL2K=m +CONFIG_E1000=m +CONFIG_E1000_NAPI=y +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +CONFIG_E1000E=m +CONFIG_IP1000=m +CONFIG_NS83820=m +CONFIG_HAMACHI=m +CONFIG_YELLOWFIN=m +CONFIG_R8169=m +# CONFIG_R8169_NAPI is not set +CONFIG_R8169_VLAN=y +CONFIG_SIS190=m +CONFIG_SKGE=m +# CONFIG_SKGE_DEBUG is not set +CONFIG_SKY2=m +# CONFIG_SKY2_DEBUG is not set +# CONFIG_SK98LIN is not set +CONFIG_VIA_VELOCITY=m +CONFIG_TIGON3=m +CONFIG_BNX2=m +CONFIG_QLA3XXX=m +CONFIG_ATL1=m +CONFIG_NETDEV_10000=y +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T1_NAPI=y +CONFIG_CHELSIO_T3=m +CONFIG_IXGBE=m +CONFIG_IXGB=m +# CONFIG_IXGB_NAPI is not set +CONFIG_S2IO=m +# CONFIG_S2IO_NAPI is not set +CONFIG_MYRI10GE=m +CONFIG_NETXEN_NIC=m +CONFIG_NIU=m +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_TEHUTI=m +CONFIG_TR=y +CONFIG_IBMTR=m +CONFIG_IBMOL=m +CONFIG_IBMLS=m +CONFIG_3C359=m +CONFIG_TMS380TR=m +CONFIG_TMSPCI=m +CONFIG_SKISA=m +CONFIG_PROTEON=m +CONFIG_ABYSS=m +CONFIG_MADGEMC=m +CONFIG_SMCTR=m + +# +# Wireless LAN +# +CONFIG_WLAN_PRE80211=y +CONFIG_STRIP=m +CONFIG_ARLAN=m +CONFIG_WAVELAN=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_NETWAVE=m +CONFIG_WLAN_80211=y +CONFIG_PCMCIA_RAYCS=m +CONFIG_IPW2100=m +CONFIG_IPW2100_MONITOR=y +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2200=m +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +# CONFIG_IPW2200_DEBUG is not set +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIBERTAS_CS=m +CONFIG_LIBERTAS_SDIO=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_AIRO=m +CONFIG_HERMES=m +# CONFIG_PLX_HERMES is not set +# CONFIG_TMD_HERMES is not set +# CONFIG_NORTEL_HERMES is not set +# CONFIG_PCI_HERMES is not set +CONFIG_PCMCIA_HERMES=m +CONFIG_PCMCIA_SPECTRUM=m +CONFIG_ATMEL=m +CONFIG_PCI_ATMEL=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_AIRO_CS=m +CONFIG_PCMCIA_WL3501=m +CONFIG_PRISM54=m +CONFIG_USB_ZD1201=m +CONFIG_RTL8187=m +CONFIG_ADM8211=m +CONFIG_P54_COMMON=m +CONFIG_P54_USB=m +CONFIG_P54_PCI=m +# CONFIG_IWLWIFI is not set +CONFIG_HOSTAP=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_PLX=m +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_CS=m +CONFIG_BCM43XX=m +# CONFIG_BCM43XX_DEBUG is not set +CONFIG_BCM43XX_DMA=y +CONFIG_BCM43XX_PIO=y +CONFIG_BCM43XX_DMA_AND_PIO_MODE=y +# CONFIG_BCM43XX_DMA_MODE is not set +# CONFIG_BCM43XX_PIO_MODE is not set +CONFIG_B43=m +CONFIG_B43_PCI_AUTOSELECT=y +CONFIG_B43_PCICORE_AUTOSELECT=y +# CONFIG_B43_PCMCIA is not set +CONFIG_B43_LEDS=y +CONFIG_B43_RFKILL=y +CONFIG_B43_DEBUG=y +CONFIG_B43_DMA=y +CONFIG_B43_PIO=y +CONFIG_B43_DMA_AND_PIO_MODE=y +# CONFIG_B43_DMA_MODE is not set +# CONFIG_B43_PIO_MODE is not set +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_PCI_AUTOSELECT=y +CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y +CONFIG_B43LEGACY_DEBUG=y +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_PIO=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_RT2X00=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_PCI=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_RFKILL=y +CONFIG_RT2400PCI=m +CONFIG_RT2400PCI_RFKILL=y +CONFIG_RT2500PCI=m +CONFIG_RT2500PCI_RFKILL=y +CONFIG_RT61PCI=m +CONFIG_RT61PCI_RFKILL=y +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +# CONFIG_RT2X00_LIB_DEBUGFS is not set +# CONFIG_RT2X00_DEBUG is not set + +# +# USB Network Adapters +# +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_KC2190=y +# CONFIG_USB_NET_ZAURUS is not set +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_AXNET=m +CONFIG_ARCNET_COM20020_CS=m +CONFIG_PCMCIA_IBMTR=m +CONFIG_WAN=y +CONFIG_HOSTESS_SV11=m +CONFIG_COSA=m +CONFIG_LANMEDIA=m +CONFIG_SEALEVEL_4021=m +CONFIG_HDLC=m +CONFIG_HDLC_RAW=m +CONFIG_HDLC_RAW_ETH=m +CONFIG_HDLC_CISCO=m +CONFIG_HDLC_FR=m +CONFIG_HDLC_PPP=m +CONFIG_HDLC_X25=m +CONFIG_PCI200SYN=m +CONFIG_WANXL=m +CONFIG_PC300=m +CONFIG_PC300_MLPPP=y + +# +# Cyclades-PC300 MLPPP support is disabled. +# + +# +# Refer to the file README.mlppp, provided by PC300 package. +# +# CONFIG_PC300TOO is not set +CONFIG_N2=m +CONFIG_C101=m +CONFIG_FARSYNC=m +CONFIG_DSCC4=m +CONFIG_DSCC4_PCISYNC=y +CONFIG_DSCC4_PCI_RST=y +CONFIG_DLCI=m +CONFIG_DLCI_MAX=8 +CONFIG_SDLA=m +CONFIG_WAN_ROUTER_DRIVERS=m +CONFIG_CYCLADES_SYNC=m +CONFIG_CYCLOMX_X25=y +CONFIG_LAPBETHER=m +CONFIG_X25_ASY=m +CONFIG_SBNI=m +# CONFIG_SBNI_MULTILINE is not set +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +CONFIG_ATM_TCP=m +CONFIG_ATM_LANAI=m +CONFIG_ATM_ENI=m +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +CONFIG_ATM_FIRESTREAM=m +CONFIG_ATM_ZATM=m +# CONFIG_ATM_ZATM_DEBUG is not set +CONFIG_ATM_NICSTAR=m +# CONFIG_ATM_NICSTAR_USE_SUNI is not set +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set +CONFIG_ATM_IDT77252=m +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +CONFIG_ATM_IDT77252_USE_SUNI=y +CONFIG_ATM_AMBASSADOR=m +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +CONFIG_ATM_HORIZON=m +# CONFIG_ATM_HORIZON_DEBUG is not set +CONFIG_ATM_IA=m +# CONFIG_ATM_IA_DEBUG is not set +CONFIG_ATM_FORE200E_MAYBE=m +CONFIG_ATM_FORE200E_PCA=y +CONFIG_ATM_FORE200E_PCA_DEFAULT_FW=y +# CONFIG_ATM_FORE200E_USE_TASKLET is not set +CONFIG_ATM_FORE200E_TX_RETRY=16 +CONFIG_ATM_FORE200E_DEBUG=0 +CONFIG_ATM_FORE200E=m +CONFIG_ATM_HE=m +CONFIG_ATM_HE_USE_SUNI=y +CONFIG_FDDI=y +CONFIG_DEFXX=m +# CONFIG_DEFXX_MMIO is not set +CONFIG_SKFP=m +CONFIG_HIPPI=y +CONFIG_ROADRUNNER=m +# CONFIG_ROADRUNNER_LARGE_RINGS is not set +CONFIG_PLIP=m +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +CONFIG_PPPOATM=m +CONFIG_PPPOL2TP=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLHC=m +CONFIG_SLIP_SMART=y +CONFIG_SLIP_MODE_SLIP6=y +CONFIG_NET_FC=y +CONFIG_SHAPER=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_VIRTIO_NET=m +CONFIG_ISDN=m +CONFIG_ISDN_I4L=m +CONFIG_ISDN_PPP=y +CONFIG_ISDN_PPP_VJ=y +CONFIG_ISDN_MPP=y +CONFIG_IPPP_FILTER=y +CONFIG_ISDN_PPP_BSDCOMP=m +CONFIG_ISDN_AUDIO=y +CONFIG_ISDN_TTY_FAX=y +CONFIG_ISDN_X25=y + +# +# ISDN feature submodules +# +CONFIG_ISDN_DIVERSION=m + +# +# ISDN4Linux hardware drivers +# + +# +# Passive cards +# +CONFIG_ISDN_DRV_HISAX=m + +# +# D-channel protocol features +# +CONFIG_HISAX_EURO=y +CONFIG_DE_AOC=y +# CONFIG_HISAX_NO_SENDCOMPLETE is not set +# CONFIG_HISAX_NO_LLC is not set +# CONFIG_HISAX_NO_KEYPAD is not set +CONFIG_HISAX_1TR6=y +CONFIG_HISAX_NI1=y +CONFIG_HISAX_MAX_CARDS=8 + +# +# HiSax supported cards +# +CONFIG_HISAX_16_0=y +CONFIG_HISAX_16_3=y +CONFIG_HISAX_TELESPCI=y +CONFIG_HISAX_S0BOX=y +CONFIG_HISAX_AVM_A1=y +CONFIG_HISAX_FRITZPCI=y +CONFIG_HISAX_AVM_A1_PCMCIA=y +CONFIG_HISAX_ELSA=y +CONFIG_HISAX_IX1MICROR2=y +CONFIG_HISAX_DIEHLDIVA=y +CONFIG_HISAX_ASUSCOM=y +CONFIG_HISAX_TELEINT=y +CONFIG_HISAX_HFCS=y +CONFIG_HISAX_SEDLBAUER=y +CONFIG_HISAX_SPORTSTER=y +CONFIG_HISAX_MIC=y +CONFIG_HISAX_NETJET=y +CONFIG_HISAX_NETJET_U=y +CONFIG_HISAX_NICCY=y +CONFIG_HISAX_ISURF=y +CONFIG_HISAX_HSTSAPHIR=y +CONFIG_HISAX_BKM_A4T=y +CONFIG_HISAX_SCT_QUADRO=y +CONFIG_HISAX_GAZEL=y +CONFIG_HISAX_HFC_PCI=y +CONFIG_HISAX_W6692=y +CONFIG_HISAX_HFC_SX=y +CONFIG_HISAX_ENTERNOW_PCI=y +# CONFIG_HISAX_DEBUG is not set + +# +# HiSax PCMCIA card service modules +# +CONFIG_HISAX_SEDLBAUER_CS=m +CONFIG_HISAX_ELSA_CS=m +CONFIG_HISAX_AVM_A1_CS=m +CONFIG_HISAX_TELES_CS=m + +# +# HiSax sub driver modules +# +CONFIG_HISAX_ST5481=m +CONFIG_HISAX_HFCUSB=m +CONFIG_HISAX_HFC4S8S=m +CONFIG_HISAX_FRITZ_PCIPNP=m +CONFIG_HISAX_HDLC=y + +# +# Active cards +# +CONFIG_ISDN_DRV_ICN=m +CONFIG_ISDN_DRV_PCBIT=m +CONFIG_ISDN_DRV_SC=m +CONFIG_ISDN_DRV_ACT2000=m +CONFIG_ISDN_DRV_GIGASET=m +CONFIG_GIGASET_BASE=m +CONFIG_GIGASET_M105=m +CONFIG_GIGASET_M101=m +# CONFIG_GIGASET_DEBUG is not set +# CONFIG_GIGASET_UNDOCREQ is not set +CONFIG_ISDN_CAPI=m +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y +CONFIG_CAPI_TRACE=y +CONFIG_ISDN_CAPI_MIDDLEWARE=y +CONFIG_ISDN_CAPI_CAPI20=m +CONFIG_ISDN_CAPI_CAPIFS_BOOL=y +CONFIG_ISDN_CAPI_CAPIFS=m +CONFIG_ISDN_CAPI_CAPIDRV=m + +# +# CAPI hardware drivers +# +CONFIG_CAPI_AVM=y +CONFIG_ISDN_DRV_AVMB1_B1ISA=m +CONFIG_ISDN_DRV_AVMB1_B1PCI=m +CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y +CONFIG_ISDN_DRV_AVMB1_T1ISA=m +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m +CONFIG_ISDN_DRV_AVMB1_AVM_CS=m +CONFIG_ISDN_DRV_AVMB1_T1PCI=m +CONFIG_ISDN_DRV_AVMB1_C4=m +CONFIG_CAPI_EICON=y +CONFIG_ISDN_DIVAS=m +CONFIG_ISDN_DIVAS_BRIPCI=y +CONFIG_ISDN_DIVAS_PRIPCI=y +CONFIG_ISDN_DIVAS_DIVACAPI=m +CONFIG_ISDN_DIVAS_USERIDI=m +CONFIG_ISDN_DIVAS_MAINT=m +CONFIG_PHONE=m +CONFIG_PHONE_IXJ=m +CONFIG_PHONE_IXJ_PCMCIA=m + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_POLLDEV=m + +# +# 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=m +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_EVBUG=m + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_INPORT=m +# CONFIG_MOUSE_ATIXL is not set +CONFIG_MOUSE_LOGIBM=m +CONFIG_MOUSE_PC110PAD=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_IFORCE_232=y +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_INPUT_TABLET=y +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_UCB1400=m +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_PCSPKR=m +CONFIG_INPUT_WISTRON_BTNS=m +CONFIG_INPUT_ATLAS_BTNS=m +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_YEALINK=m +CONFIG_INPUT_UINPUT=m + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=m +CONFIG_SERIO_CT82C710=m +CONFIG_SERIO_PARKBD=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_RAW=m +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_DEV_KMEM is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +CONFIG_ROCKETPORT=m +CONFIG_CYCLADES=m +# CONFIG_CYZ_INTR is not set +CONFIG_DIGIEPCA=m +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +CONFIG_MOXA_SMARTIO_NEW=m +# CONFIG_ISI is not set +CONFIG_SYNCLINK=m +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_GT=m +CONFIG_N_HDLC=m +CONFIG_SPECIALIX=m +# CONFIG_SPECIALIX_RTSCTS is not set +CONFIG_SX=m +# CONFIG_RIO is not set +CONFIG_STALDRV=y + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_PNP=y +CONFIG_SERIAL_8250_CS=m +CONFIG_SERIAL_8250_NR_UARTS=48 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_FOURPORT=m +CONFIG_SERIAL_8250_ACCENT=m +CONFIG_SERIAL_8250_BOCA=m +CONFIG_SERIAL_8250_EXAR_ST16C554=m +CONFIG_SERIAL_8250_HUB6=m +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_MCA=m + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_JSM=m +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_PRINTER=m +# CONFIG_LP_CONSOLE is not set +CONFIG_PPDEV=m +CONFIG_HVC_DRIVER=y +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_POWEROFF=m +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_INTEL=m +CONFIG_HW_RANDOM_AMD=m +CONFIG_HW_RANDOM_GEODE=m +CONFIG_HW_RANDOM_VIA=m +CONFIG_NVRAM=m +CONFIG_RTC=y +# CONFIG_RTC_HISTOGRAM is not set +CONFIG_BLOCKER=m +CONFIG_LPPTEST=m +CONFIG_DTLK=m +CONFIG_R3964=m +CONFIG_APPLICOM=m +CONFIG_SONYPI=m + +# +# PCMCIA character devices +# +CONFIG_SYNCLINK_CS=m +CONFIG_CARDMAN_4000=m +CONFIG_CARDMAN_4040=m +CONFIG_MWAVE=m +CONFIG_SCx200_GPIO=m +CONFIG_PC8736x_GPIO=m +CONFIG_NSC_GPIO=m +CONFIG_CS5535_GPIO=m +CONFIG_RAW_DRIVER=m +CONFIG_MAX_RAW_DEVS=256 +CONFIG_HPET=y +# CONFIG_HPET_RTC_IRQ is not set +CONFIG_HPET_MMAP=y +CONFIG_HANGCHECK_TIMER=m +CONFIG_TCG_TPM=m +CONFIG_TCG_TIS=m +CONFIG_TCG_NSC=m +CONFIG_TCG_ATMEL=m +CONFIG_TCG_INFINEON=m +CONFIG_TELCLOCK=m +CONFIG_RMEM=m +CONFIG_ALLOC_RTSJ_MEM=m +CONFIG_DEVPORT=y +CONFIG_I2C=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCF=m +CONFIG_I2C_ALGOPCA=m + +# +# I2C Hardware Bus support +# +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_I801=m +CONFIG_I2C_I810=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +CONFIG_I2C_SIMTEC=m +CONFIG_SCx200_I2C=m +CONFIG_SCx200_I2C_SCL=12 +CONFIG_SCx200_I2C_SDA=13 +CONFIG_SCx200_ACB=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_TAOS_EVM=m +CONFIG_I2C_STUB=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +CONFIG_I2C_PCA_ISA=m + +# +# Miscellaneous I2C Chip support +# +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m +CONFIG_DS1682=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_TSL2550=m +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +CONFIG_SPI_LM70_LLP=m + +# +# SPI Protocol Masters +# +CONFIG_SPI_AT25=m +CONFIG_SPI_SPIDEV=m +CONFIG_SPI_TLE62X0=m +CONFIG_W1=m +CONFIG_W1_CON=y + +# +# 1-wire Bus Masters +# +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_DS2482=m + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_DS2760=m +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +CONFIG_PDA_POWER=m +CONFIG_BATTERY_DS2760=m +CONFIG_HWMON=y +CONFIG_HWMON_VID=m +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_ABITUGURU3=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_K8TEMP=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_FSCPOS=m +CONFIG_SENSORS_FSCHMD=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_IBMPEX=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_LM93=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_HDAPS=m +CONFIG_SENSORS_APPLESMC=m +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=m +CONFIG_ACQUIRE_WDT=m +CONFIG_ADVANTECH_WDT=m +CONFIG_ALIM1535_WDT=m +CONFIG_ALIM7101_WDT=m +CONFIG_SC520_WDT=m +CONFIG_EUROTECH_WDT=m +CONFIG_IB700_WDT=m +CONFIG_IBMASR=m +CONFIG_WAFER_WDT=m +CONFIG_I6300ESB_WDT=m +CONFIG_ITCO_WDT=m +CONFIG_ITCO_VENDOR_SUPPORT=y +CONFIG_IT8712F_WDT=m +CONFIG_SC1200_WDT=m +CONFIG_SCx200_WDT=m +CONFIG_PC87413_WDT=m +CONFIG_60XX_WDT=m +CONFIG_SBC8360_WDT=m +CONFIG_SBC7240_WDT=m +CONFIG_CPU5_WDT=m +CONFIG_SMSC37B787_WDT=m +CONFIG_W83627HF_WDT=m +CONFIG_W83697HF_WDT=m +CONFIG_W83877F_WDT=m +CONFIG_W83977F_WDT=m +CONFIG_MACHZ_WDT=m +CONFIG_SBC_EPX_C3_WATCHDOG=m + +# +# ISA-based Watchdog Cards +# +CONFIG_PCWATCHDOG=m +CONFIG_MIXCOMWD=m +CONFIG_WDT=m +CONFIG_WDT_501=y + +# +# PCI-based Watchdog Cards +# +CONFIG_PCIPCWATCHDOG=m +CONFIG_WDTPCI=m +CONFIG_WDT_501_PCI=y + +# +# USB-based Watchdog Cards +# +CONFIG_USBPCWATCHDOG=m + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +CONFIG_SSB=m +CONFIG_SSB_PCIHOST_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_PCMCIAHOST_POSSIBLE=y +# CONFIG_SSB_PCMCIAHOST is not set +# CONFIG_SSB_SILENT is not set +CONFIG_SSB_DEBUG=y +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_DRIVER_PCICORE=y + +# +# Multifunction device drivers +# +CONFIG_MFD_SM501=m + +# +# Multimedia devices +# +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set + +# +# Encoders/decoders and other helper chips +# + +# +# Audio decoders +# +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TDA9875=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_TLV320AIC23B=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_VP27SMPX=m + +# +# Video decoders +# +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_TCM825X=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA7111=m +CONFIG_VIDEO_SAA7114=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7191=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_VPX3220=m + +# +# Video and audio decoders +# +CONFIG_VIDEO_CX25840=m + +# +# MPEG video encoders +# +CONFIG_VIDEO_CX2341X=m + +# +# Video encoders +# +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m + +# +# Video improvement chips +# +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_PMS=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_W9966=m +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA_PP=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_TUNER_3036=m +CONFIG_VIDEO_STRADIS=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_MEYE=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_DVB=m +# CONFIG_VIDEO_MXB is not set +# CONFIG_VIDEO_DPC is not set +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_CX23885=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_FB_IVTV=m +CONFIG_VIDEO_CAFE_CCIC=m +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_29XXX=y +CONFIG_VIDEO_PVRUSB2_24XXX=y +CONFIG_VIDEO_PVRUSB2_SYSFS=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_USB_VICAM=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_ET61X251=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_USB_W9968CF=m +# CONFIG_USB_OV511 is not set +CONFIG_USB_SE401=m +CONFIG_USB_SN9C102=m +CONFIG_USB_STV680=m +CONFIG_USB_ZC0301=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_ZR364XX=m +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_CADET=m +CONFIG_RADIO_RTRACK=m +CONFIG_RADIO_RTRACK2=m +CONFIG_RADIO_AZTECH=m +CONFIG_RADIO_GEMTEK=m +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RADIO_MAESTRO=m +CONFIG_RADIO_SF16FMI=m +CONFIG_RADIO_SF16FMR2=m +CONFIG_RADIO_TERRATEC=m +CONFIG_RADIO_TRUST=m +CONFIG_RADIO_TYPHOON=m +# CONFIG_RADIO_TYPHOON_PROC_FS is not set +CONFIG_RADIO_ZOLTRIX=m +CONFIG_USB_DSBR=m +CONFIG_DVB_CORE=m +CONFIG_DVB_CORE_ATTACH=y +CONFIG_DVB_CAPTURE_DRIVERS=y + +# +# Supported SAA7146 based PCI Adapters +# +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_PATCH=m + +# +# Supported USB Adapters +# +CONFIG_DVB_USB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_CINERGYT2=m +CONFIG_DVB_CINERGYT2_TUNING=y +CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32 +CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512 +CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250 +CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y +CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100 + +# +# Supported FlexCopII (B2C2) Adapters +# +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set + +# +# Supported BT878 Adapters +# +CONFIG_DVB_BT8XX=m + +# +# Supported Pluto2 Adapters +# +CONFIG_DVB_PLUTO2=m + +# +# Supported DVB Frontends +# + +# +# Customise DVB Frontends +# +# CONFIG_DVB_FE_CUSTOMISE is not set + +# +# DVB-S (satellite) frontends +# +CONFIG_DVB_STV0299=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_MT312=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_TDA10086=m + +# +# DVB-T (terrestrial) frontends +# +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_L64781=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_MT352=m +CONFIG_DVB_ZL10353=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m + +# +# DVB-C (cable) frontends +# +CONFIG_DVB_VES1820=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_STV0297=m + +# +# ATSC (North American/Korean Terrestrial/Cable DTV) frontends +# +CONFIG_DVB_NXT200X=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_S5H1409=m + +# +# Tuners/PLL support +# +CONFIG_DVB_PLL=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TDA827X=m +CONFIG_DVB_TUNER_QT1010=m +CONFIG_DVB_TUNER_MT2060=m +CONFIG_DVB_TUNER_MT2266=m +CONFIG_DVB_TUNER_MT2131=m +CONFIG_DVB_TUNER_DIB0070=m + +# +# Miscellaneous devices +# +CONFIG_DVB_LNBP21=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_TUA6100=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_TUNER=m +# CONFIG_VIDEO_TUNER_CUSTOMIZE is not set +CONFIG_TUNER_MT20XX=m +CONFIG_TUNER_TDA8290=m +CONFIG_TUNER_TEA5761=m +CONFIG_TUNER_TEA5767=m +CONFIG_TUNER_SIMPLE=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_DMA_SG=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_DAB=y +CONFIG_USB_DABUSB=m + +# +# Graphics support +# +CONFIG_AGP=m +CONFIG_AGP_ALI=m +CONFIG_AGP_ATI=m +CONFIG_AGP_AMD=m +CONFIG_AGP_AMD64=m +CONFIG_AGP_INTEL=m +CONFIG_AGP_NVIDIA=m +CONFIG_AGP_SIS=m +CONFIG_AGP_SWORKS=m +CONFIG_AGP_VIA=m +CONFIG_AGP_EFFICEON=m +CONFIG_DRM=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_I810=m +CONFIG_DRM_I830=m +CONFIG_DRM_I915=m +CONFIG_DRM_MGA=m +CONFIG_DRM_SIS=m +CONFIG_DRM_VIA=m +CONFIG_DRM_VIA_CHROME9=m +CONFIG_DRM_SAVAGE=m +CONFIG_VGASTATE=m +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +CONFIG_FB_DDC=m +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +CONFIG_FB_SYS_FILLRECT=m +CONFIG_FB_SYS_COPYAREA=m +CONFIG_FB_SYS_IMAGEBLIT=m +CONFIG_FB_SYS_FOPS=m +CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_SVGALIB=m +# CONFIG_FB_MACMODES is not set +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y + +# +# Frame buffer hardware drivers +# +CONFIG_FB_CIRRUS=m +CONFIG_FB_PM2=m +CONFIG_FB_PM2_FIFO_DISCONNECT=y +CONFIG_FB_CYBER2000=m +CONFIG_FB_ARC=m +CONFIG_FB_ASILIANT=y +CONFIG_FB_IMSTT=y +CONFIG_FB_VGA16=m +CONFIG_FB_UVESA=m +CONFIG_FB_VESA=m +CONFIG_FB_EFI=y +CONFIG_FB_IMAC=y +CONFIG_FB_HECUBA=m +CONFIG_FB_HGA=m +# CONFIG_FB_HGA_ACCEL is not set +CONFIG_FB_S1D13XXX=m +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_I2C=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_BACKLIGHT=y +CONFIG_FB_RIVA=m +CONFIG_FB_RIVA_I2C=y +# CONFIG_FB_RIVA_DEBUG is not set +CONFIG_FB_RIVA_BACKLIGHT=y +CONFIG_FB_I810=m +# CONFIG_FB_I810_GTF is not set +CONFIG_FB_LE80578=m +CONFIG_FB_CARILLO_RANCH=m +CONFIG_FB_INTEL=m +# CONFIG_FB_INTEL_DEBUG is not set +CONFIG_FB_INTEL_I2C=y +CONFIG_FB_MATROX=m +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MULTIHEAD=y +CONFIG_FB_RADEON=m +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_ATY128=m +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY=m +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_ATY_BACKLIGHT=y +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SAVAGE_ACCEL=y +CONFIG_FB_SIS=m +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +CONFIG_FB_NEOMAGIC=m +CONFIG_FB_KYRO=m +CONFIG_FB_3DFX=m +# CONFIG_FB_3DFX_ACCEL is not set +CONFIG_FB_VOODOO1=m +CONFIG_FB_VT8623=m +CONFIG_FB_CYBLA=m +CONFIG_FB_TRIDENT=m +# CONFIG_FB_TRIDENT_ACCEL is not set +CONFIG_FB_ARK=m +CONFIG_FB_PM3=m +CONFIG_FB_GEODE=y +CONFIG_FB_GEODE_LX=m +CONFIG_FB_GEODE_GX=m +# CONFIG_FB_GEODE_GX_SET_FBSIZE is not set +CONFIG_FB_GEODE_GX1=m +CONFIG_FB_SM501=m +# CONFIG_FB_VIRTUAL is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_LTV350QV=m +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_CORGI=m +CONFIG_BACKLIGHT_PROGEAR=m +CONFIG_BACKLIGHT_CARILLO_RANCH=m + +# +# Display device support +# +CONFIG_DISPLAY_SUPPORT=m + +# +# Display hardware drivers +# + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +# CONFIG_VGACON_SOFT_SCROLLBACK is not set +CONFIG_VIDEO_SELECT=y +CONFIG_MDA_CONSOLE=m +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=m +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_LOGO is not set + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HID=m +# CONFIG_HID_DEBUG is not set +CONFIG_HIDRAW=y + +# +# USB Input Devices +# +CONFIG_USB_HID=m +CONFIG_USB_HIDINPUT_POWERBOOK=y +# CONFIG_HID_FF is not set +CONFIG_USB_HIDDEV=y + +# +# USB HID Boot Protocol drivers +# +CONFIG_USB_KBD=m +CONFIG_USB_MOUSE=m +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=m +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_SUSPEND=y +CONFIG_USB_PERSIST=y +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_ISP116X_HCD=m +CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_HCD_SSB is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_UHCI_HCD=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SL811_CS=m +CONFIG_USB_R8A66597_HCD=m + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_LIBUSUAL=y + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_MON=y + +# +# USB port drivers +# +CONFIG_USB_USS720=m + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_AIRPRIME=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +# CONFIG_USB_SERIAL_IR is not set +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_EZUSB=y + +# +# USB Miscellaneous drivers +# +CONFIG_USB_EMI62=m +CONFIG_USB_EMI26=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_AUERSWALD=m +CONFIG_USB_RIO500=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LCD=m +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_LED=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_SISUSBVGA=m +# CONFIG_USB_SISUSBVGA_CON is not set +CONFIG_USB_LD=m +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_IOWARRIOR=m +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_CXACRU=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_XUSBATM=m + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=m +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +CONFIG_USB_GADGET_NET2280=y +CONFIG_USB_NET2280=m +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +CONFIG_USB_ZERO=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_GADGETFS=m +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_G_SERIAL=m +# CONFIG_USB_MIDI_GADGET is not set + +# +# MMC/SD/SDIO support, can only select one arch from MMC and MSS +# +CONFIG_MMC=m +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD Card Drivers +# +CONFIG_MMC_BLOCK=m +CONFIG_MMC_BLOCK_BOUNCE=y +CONFIG_SDIO_UART=m + +# +# MMC/SD Host Controller Drivers +# +CONFIG_MMC_SDHCI=m +CONFIG_MMC_RICOH_MMC=m +CONFIG_MMC_WBSD=m +CONFIG_MMC_TIFM_SD=m +# CONFIG_MSS is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=m + +# +# LED drivers +# +CONFIG_LEDS_NET48XX=m +CONFIG_LEDS_WRAP=m + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_TRIGGER_IDE_DISK=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=m +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y +CONFIG_INFINIBAND_AMSO1100=m +CONFIG_INFINIBAND_AMSO1100_DEBUG=y +CONFIG_INFINIBAND_CXGB3=m +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set +CONFIG_MLX4_INFINIBAND=m +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_IPOIB_DEBUG=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_ISER=m +CONFIG_EDAC=y + +# +# Reporting subsystems +# +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_MM_EDAC=m +# CONFIG_EDAC_AMD76X is not set +CONFIG_EDAC_E7XXX=m +CONFIG_EDAC_E752X=m +CONFIG_EDAC_I82875P=m +CONFIG_EDAC_I82975X=m +CONFIG_EDAC_I3000=m +CONFIG_EDAC_I82860=m +CONFIG_EDAC_R82600=m +CONFIG_EDAC_I5000=m +CONFIG_RTC_LIB=m +CONFIG_RTC_CLASS=m + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_DRV_TEST=m + +# +# I2C RTC drivers +# +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_M41T80_WDT=y + +# +# SPI RTC drivers +# +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_MAX6902=m + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_STK17TA8=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_M48T59=m +CONFIG_RTC_DRV_V3020=m + +# +# on-CPU RTC drivers +# +CONFIG_DMADEVICES=y + +# +# DMA Devices +# +CONFIG_INTEL_IOATDMA=m +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +CONFIG_NET_DMA=y +CONFIG_DCA=m +CONFIG_AUXDISPLAY=y +CONFIG_KS0108=m +CONFIG_KS0108_PORT=0x378 +CONFIG_KS0108_DELAY=2 +CONFIG_CFAG12864B=m +CONFIG_CFAG12864B_RATE=20 + +# +# Userspace I/O +# +CONFIG_UIO=m +CONFIG_UIO_CIF=m + +# +# Firmware Drivers +# +CONFIG_EDD=y +CONFIG_EDD_OFF=y +CONFIG_EFI_VARS=y +CONFIG_DELL_RBU=m +CONFIG_DCDBAS=m +CONFIG_DMIID=y + +# +# File systems +# +CONFIG_EXT2_FS=m +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=m +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +# CONFIG_JFS_DEBUG is not set +CONFIG_JFS_STATISTICS=y +CONFIG_FS_POSIX_ACL=y +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +CONFIG_XFS_SECURITY=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_RT=y +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_NOLOCK=m +CONFIG_GFS2_FS_LOCKING_DLM=m +CONFIG_OCFS2_FS=m +CONFIG_OCFS2_DEBUG_MASKLOG=y +# CONFIG_OCFS2_DEBUG_FS is not set +CONFIG_MINIX_FS=m +CONFIG_ROMFS_FS=m +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_QUOTACTL=y +CONFIG_DNOTIFY=y +CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=m +CONFIG_GENERIC_ACL=y + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +# CONFIG_NTFS_RW is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_VMCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=m + +# +# Miscellaneous filesystems +# +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_AFFS_FS=m +CONFIG_ECRYPT_FS=m +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +CONFIG_BEFS_FS=m +# CONFIG_BEFS_DEBUG is not set +CONFIG_BFS_FS=m +CONFIG_EFS_FS=m +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_LZO=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_CMODE_NONE is not set +# CONFIG_JFFS2_CMODE_PRIORITY is not set +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_CMODE_FAVOURLZO=y +CONFIG_CRAMFS=y +CONFIG_VXFS_FS=m +CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_UFS_DEBUG is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_TCP=y +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +CONFIG_SUNRPC_XPRT_RDMA=m +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +CONFIG_CIFS_WEAK_PW_HASH=y +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +CONFIG_CIFS_EXPERIMENTAL=y +CONFIG_CIFS_UPCALL=y +CONFIG_NCP_FS=m +CONFIG_NCPFS_PACKET_SIGNING=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_STRONG=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_OS2_NS=y +# CONFIG_NCPFS_SMALLDOS is not set +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_EXTRAS=y +CONFIG_CODA_FS=m +# CONFIG_CODA_FS_OLD_API is not set +CONFIG_AFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_9P_FS=m +CONFIG_DEFAULT_RELATIME=y +CONFIG_DEFAULT_RELATIME_VAL=1 + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +CONFIG_ACORN_PARTITION=y +# CONFIG_ACORN_PARTITION_CUMANA is not set +# CONFIG_ACORN_PARTITION_EESOX is not set +CONFIG_ACORN_PARTITION_ICS=y +# CONFIG_ACORN_PARTITION_ADFS is not set +# CONFIG_ACORN_PARTITION_POWERTEC is not set +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_OSF_PARTITION=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_LDM_PARTITION=y +# CONFIG_LDM_DEBUG is not set +CONFIG_SGI_PARTITION=y +CONFIG_ULTRIX_PARTITION=y +CONFIG_SUN_PARTITION=y +CONFIG_KARMA_PARTITION=y +CONFIG_EFI_PARTITION=y +CONFIG_SYSV68_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +CONFIG_INSTRUMENTATION=y +CONFIG_PROFILING=y +CONFIG_OPROFILE=m +CONFIG_PROFILE_NMI=y +CONFIG_KPROBES=y +CONFIG_MARKERS=y + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_PRINTK_TIME=y +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +CONFIG_TIMER_STATS=y +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RTMUTEX_CHECK is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_RWLOCK_TORTURE_TEST is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_HIGHMEM is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_FRAME_POINTER is not set +# CONFIG_FORCED_INLINING is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_LKDTM is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_HAVE_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +# CONFIG_FTRACE is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_WAKEUP_LATENCY_HIST is not set +# CONFIG_PREEMPT_TRACE is not set +# CONFIG_SAMPLES is not set +CONFIG_NONPROMISC_DEVMEM=y +CONFIG_EARLY_PRINTK=y +# CONFIG_WRAPPER_PRINT is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set + +# +# Page alloc debug is incompatible with Software Suspend on i386 +# +CONFIG_DEBUG_RODATA=y +# CONFIG_4KSTACKS is not set +CONFIG_X86_FIND_SMP_CONFIG=y +CONFIG_X86_MPPARSE=y +CONFIG_DOUBLEFAULT=y +CONFIG_IO_DELAY_TYPE_0X80=0 +CONFIG_IO_DELAY_TYPE_0XED=1 +CONFIG_IO_DELAY_TYPE_UDELAY=2 +CONFIG_IO_DELAY_TYPE_NONE=3 +# CONFIG_IO_DELAY_0X80 is not set +CONFIG_IO_DELAY_0XED=y +# CONFIG_IO_DELAY_UDELAY is not set +# CONFIG_IO_DELAY_NONE is not set +CONFIG_DEFAULT_IO_DELAY_TYPE=1 + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +CONFIG_SECURITY_CAPABILITIES=y +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_DISABLE=y +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +CONFIG_SECURITY_APPARMOR=y +CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 +# CONFIG_SECURITY_APPARMOR_DISABLE is not set +CONFIG_XOR_BLOCKS=m +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ABLKCIPHER=m +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_XTS=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_TWOFISH_586=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_AES_586=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_DEV_PADLOCK=y +CONFIG_CRYPTO_DEV_PADLOCK_AES=m +CONFIG_CRYPTO_DEV_PADLOCK_SHA=m +CONFIG_CRYPTO_DEV_GEODE=m +CONFIG_HAVE_KVM=y +CONFIG_VIRTUALIZATION=y +CONFIG_KVM=m +CONFIG_KVM_INTEL=m +CONFIG_KVM_AMD=m +CONFIG_LGUEST=m +CONFIG_VIRTIO=m +CONFIG_VIRTIO_RING=m +CONFIG_VIRTIO_PCI=m +CONFIG_VIRTIO_BALLOON=m + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_CRC_CCITT=m +CONFIG_CRC16=m +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +CONFIG_CRC7=m +CONFIG_LIBCRC32C=m +CONFIG_AUDIT_GENERIC=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_CHECK_SIGNATURE=y --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0231-preempt-realtime-i386.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0231-preempt-realtime-i386.patch @@ -0,0 +1,828 @@ +--- + arch/x86/Kconfig.debug | 2 + + arch/x86/kernel/cpu/mtrr/generic.c | 2 - + arch/x86/kernel/head_32.S | 1 + arch/x86/kernel/i8253.c | 2 - + arch/x86/kernel/i8259_32.c | 2 - + arch/x86/kernel/io_apic_32.c | 4 +-- + arch/x86/kernel/irq_32.c | 4 ++- + arch/x86/kernel/microcode.c | 2 - + arch/x86/kernel/nmi_32.c | 5 +++ + arch/x86/kernel/process_32.c | 19 ++++++++++---- + arch/x86/kernel/signal_32.c | 14 ++++++++++ + arch/x86/kernel/smp_32.c | 19 ++++++++++---- + arch/x86/kernel/traps_32.c | 18 +++++++++++--- + arch/x86/kernel/vm86_32.c | 1 + arch/x86/mm/fault_32.c | 1 + arch/x86/mm/highmem_32.c | 37 ++++++++++++++++++++++------- + arch/x86/mm/pgtable_32.c | 2 - + arch/x86/pci/common.c | 2 - + arch/x86/pci/direct.c | 29 ++++++++++++++-------- + arch/x86/pci/pci.h | 2 - + include/asm-x86/acpi_32.h | 4 +-- + include/asm-x86/dma_32.h | 2 - + include/asm-x86/highmem.h | 27 +++++++++++++++++++++ + include/asm-x86/i8253.h | 2 - + include/asm-x86/i8259.h | 2 - + include/asm-x86/mach-default/irq_vectors.h | 2 - + include/asm-x86/mc146818rtc_32.h | 2 - + include/asm-x86/pgtable_32.h | 2 - + include/asm-x86/tlbflush_32.h | 26 ++++++++++++++++++++ + include/asm-x86/xor_32.h | 21 ++++++++++++++-- + kernel/Kconfig.instrumentation | 5 +++ + 31 files changed, 211 insertions(+), 52 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/x86/Kconfig.debug +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/Kconfig.debug 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/Kconfig.debug 2008-10-08 22:23:56.000000000 -0400 +@@ -50,6 +50,7 @@ config DEBUG_PAGEALLOC + config DEBUG_RODATA + bool "Write protect kernel read-only data structures" + depends on DEBUG_KERNEL ++ default y + help + Mark the kernel read-only data as write-protected in the pagetables, + in order to catch accidental (and incorrect) writes to such const +@@ -61,6 +62,7 @@ config 4KSTACKS + bool "Use 4Kb for kernel stacks instead of 8Kb" + depends on DEBUG_KERNEL + depends on X86_32 ++ default y + help + If you say Y here the kernel will use a 4Kb stacksize for the + kernel stack attached to each process/thread. This facilitates +Index: linux-2.6.24.7-rt21/arch/x86/kernel/cpu/mtrr/generic.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/cpu/mtrr/generic.c 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/cpu/mtrr/generic.c 2008-10-08 22:23:56.000000000 -0400 +@@ -330,7 +330,7 @@ static unsigned long set_mtrr_state(void + + + static unsigned long cr4 = 0; +-static DEFINE_SPINLOCK(set_atomicity_lock); ++static DEFINE_RAW_SPINLOCK(set_atomicity_lock); + + /* + * Since we are disabling the cache don't allow any interrupts - they +Index: linux-2.6.24.7-rt21/arch/x86/kernel/head_32.S +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/head_32.S 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/head_32.S 2008-10-08 22:23:56.000000000 -0400 +@@ -533,6 +533,7 @@ ignore_int: + call printk + #endif + addl $(5*4),%esp ++ call dump_stack + popl %ds + popl %es + popl %edx +Index: linux-2.6.24.7-rt21/arch/x86/kernel/i8253.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/i8253.c 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/i8253.c 2008-10-08 22:23:56.000000000 -0400 +@@ -14,7 +14,7 @@ + #include + #include + +-DEFINE_SPINLOCK(i8253_lock); ++DEFINE_RAW_SPINLOCK(i8253_lock); + EXPORT_SYMBOL(i8253_lock); + + /* +Index: linux-2.6.24.7-rt21/arch/x86/kernel/i8259_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/i8259_32.c 2008-10-08 22:23:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/i8259_32.c 2008-10-08 22:23:56.000000000 -0400 +@@ -33,7 +33,7 @@ + */ + + static int i8259A_auto_eoi; +-DEFINE_SPINLOCK(i8259A_lock); ++DEFINE_RAW_SPINLOCK(i8259A_lock); + static void mask_and_ack_8259A(unsigned int); + + static struct irq_chip i8259A_chip = { +Index: linux-2.6.24.7-rt21/arch/x86/kernel/io_apic_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/io_apic_32.c 2008-10-08 22:23:32.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/io_apic_32.c 2008-10-08 22:23:56.000000000 -0400 +@@ -56,8 +56,8 @@ atomic_t irq_mis_count; + /* Where if anywhere is the i8259 connect in external int mode */ + static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; + +-static DEFINE_SPINLOCK(ioapic_lock); +-static DEFINE_SPINLOCK(vector_lock); ++static DEFINE_RAW_SPINLOCK(ioapic_lock); ++static DEFINE_RAW_SPINLOCK(vector_lock); + + int timer_over_8254 __initdata = 1; + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/irq_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/irq_32.c 2008-10-08 22:23:08.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/irq_32.c 2008-10-08 22:23:56.000000000 -0400 +@@ -79,6 +79,8 @@ fastcall unsigned int do_IRQ(struct pt_r + u32 *isp; + #endif + ++ irq_show_regs_callback(smp_processor_id(), regs); ++ + if (unlikely((unsigned)irq >= NR_IRQS)) { + printk(KERN_EMERG "%s: cannot handle IRQ %d\n", + __FUNCTION__, irq); +@@ -96,7 +98,7 @@ fastcall unsigned int do_IRQ(struct pt_r + __asm__ __volatile__("andl %%esp,%0" : + "=r" (esp) : "0" (THREAD_SIZE - 1)); + if (unlikely(esp < (sizeof(struct thread_info) + STACK_WARN))) { +- printk("do_IRQ: stack overflow: %ld\n", ++ printk("BUG: do_IRQ: stack overflow: %ld\n", + esp - sizeof(struct thread_info)); + dump_stack(); + } +Index: linux-2.6.24.7-rt21/arch/x86/kernel/microcode.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/microcode.c 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/microcode.c 2008-10-08 22:23:56.000000000 -0400 +@@ -117,7 +117,7 @@ MODULE_LICENSE("GPL"); + #define exttable_size(et) ((et)->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE) + + /* serialize access to the physical write to MSR 0x79 */ +-static DEFINE_SPINLOCK(microcode_update_lock); ++static DEFINE_RAW_SPINLOCK(microcode_update_lock); + + /* no concurrent ->write()s are allowed on /dev/cpu/microcode */ + static DEFINE_MUTEX(microcode_mutex); +Index: linux-2.6.24.7-rt21/arch/x86/kernel/nmi_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/nmi_32.c 2008-10-08 22:23:22.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/nmi_32.c 2008-10-08 22:23:56.000000000 -0400 +@@ -59,7 +59,12 @@ static int endflag __initdata = 0; + static __init void nmi_cpu_busy(void *data) + { + #ifdef CONFIG_SMP ++ /* ++ * avoid a warning, on PREEMPT_RT this wont run in hardirq context: ++ */ ++#ifndef CONFIG_PREEMPT_RT + local_irq_enable_in_hardirq(); ++#endif + /* Intentionally don't use cpu_relax here. This is + to make sure that the performance counter really ticks, + even if there is a simulator or similar that catches the +Index: linux-2.6.24.7-rt21/arch/x86/kernel/process_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/process_32.c 2008-10-08 22:23:38.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/process_32.c 2008-10-08 22:23:56.000000000 -0400 +@@ -342,9 +342,10 @@ void __show_registers(struct pt_regs *re + regs->eax, regs->ebx, regs->ecx, regs->edx); + printk("ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n", + regs->esi, regs->edi, regs->ebp, esp); +- printk(" DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n", ++ printk(" DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x" ++ " preempt:%08x\n", + regs->xds & 0xffff, regs->xes & 0xffff, +- regs->xfs & 0xffff, gs, ss); ++ regs->xfs & 0xffff, gs, ss, preempt_count()); + + if (!all) + return; +@@ -416,15 +417,23 @@ void exit_thread(void) + if (unlikely(test_thread_flag(TIF_IO_BITMAP))) { + struct task_struct *tsk = current; + struct thread_struct *t = &tsk->thread; +- int cpu = get_cpu(); +- struct tss_struct *tss = &per_cpu(init_tss, cpu); ++ void *io_bitmap_ptr = t->io_bitmap_ptr; ++ int cpu; ++ struct tss_struct *tss; + +- kfree(t->io_bitmap_ptr); ++ /* ++ * On PREEMPT_RT we must not call kfree() with ++ * preemption disabled, so we first zap the pointer: ++ */ + t->io_bitmap_ptr = NULL; ++ kfree(io_bitmap_ptr); ++ + clear_thread_flag(TIF_IO_BITMAP); + /* + * Careful, clear this in the TSS too: + */ ++ cpu = get_cpu(); ++ tss = &per_cpu(init_tss, cpu); + memset(tss->io_bitmap, 0xff, tss->io_bitmap_max); + t->io_bitmap_max = 0; + tss->io_bitmap_owner = NULL; +Index: linux-2.6.24.7-rt21/arch/x86/kernel/signal_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/signal_32.c 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/signal_32.c 2008-10-08 22:23:56.000000000 -0400 +@@ -536,6 +536,13 @@ handle_signal(unsigned long sig, siginfo + } + } + ++#ifdef CONFIG_PREEMPT_RT ++ /* ++ * Fully-preemptible kernel does not need interrupts disabled: ++ */ ++ local_irq_enable(); ++ preempt_check_resched(); ++#endif + /* + * If TF is set due to a debugger (PT_DTRACE), clear the TF flag so + * that register information in the sigcontext is correct. +@@ -576,6 +583,13 @@ static void fastcall do_signal(struct pt + struct k_sigaction ka; + sigset_t *oldset; + ++#ifdef CONFIG_PREEMPT_RT ++ /* ++ * Fully-preemptible kernel does not need interrupts disabled: ++ */ ++ local_irq_enable(); ++ preempt_check_resched(); ++#endif + /* + * We want the common case to go fast, which + * is why we may in certain cases get here from +Index: linux-2.6.24.7-rt21/arch/x86/kernel/smp_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/smp_32.c 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/smp_32.c 2008-10-08 22:23:56.000000000 -0400 +@@ -247,7 +247,7 @@ void send_IPI_mask_sequence(cpumask_t ma + static cpumask_t flush_cpumask; + static struct mm_struct * flush_mm; + static unsigned long flush_va; +-static DEFINE_SPINLOCK(tlbstate_lock); ++static DEFINE_RAW_SPINLOCK(tlbstate_lock); + + /* + * We cannot call mmdrop() because we are in interrupt context, +@@ -476,10 +476,20 @@ static void native_smp_send_reschedule(i + } + + /* ++ * this function sends a 'reschedule' IPI to all other CPUs. ++ * This is used when RT tasks are starving and other CPUs ++ * might be able to run them: ++ */ ++void smp_send_reschedule_allbutself(void) ++{ ++ send_IPI_allbutself(RESCHEDULE_VECTOR); ++} ++ ++/* + * Structure and data for smp_call_function(). This is designed to minimise + * static memory requirements. It also looks cleaner. + */ +-static DEFINE_SPINLOCK(call_lock); ++static DEFINE_RAW_SPINLOCK(call_lock); + + struct call_data_struct { + void (*func) (void *info); +@@ -634,9 +644,8 @@ static void native_smp_send_stop(void) + } + + /* +- * Reschedule call back. Nothing to do, +- * all the work is done automatically when +- * we return from the interrupt. ++ * Reschedule call back. Trigger a reschedule pass so that ++ * RT-overload balancing can pass tasks around. + */ + fastcall void smp_reschedule_interrupt(struct pt_regs *regs) + { +Index: linux-2.6.24.7-rt21/arch/x86/kernel/traps_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/traps_32.c 2008-10-08 22:23:24.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/traps_32.c 2008-10-08 22:23:56.000000000 -0400 +@@ -297,6 +297,12 @@ void dump_stack(void) + + EXPORT_SYMBOL(dump_stack); + ++#if defined(CONFIG_DEBUG_STACKOVERFLOW) && defined(CONFIG_EVENT_TRACE) ++extern unsigned long worst_stack_left; ++#else ++# define worst_stack_left -1L ++#endif ++ + void show_registers(struct pt_regs *regs) + { + int i; +@@ -366,7 +372,7 @@ void die(const char * str, struct pt_reg + u32 lock_owner; + int lock_owner_depth; + } die = { +- .lock = __RAW_SPIN_LOCK_UNLOCKED, ++ .lock = RAW_SPIN_LOCK_UNLOCKED(die.lock), + .lock_owner = -1, + .lock_owner_depth = 0 + }; +@@ -378,7 +384,7 @@ void die(const char * str, struct pt_reg + if (die.lock_owner != raw_smp_processor_id()) { + console_verbose(); + raw_local_irq_save(flags); +- __raw_spin_lock(&die.lock); ++ spin_lock(&die.lock); + die.lock_owner = smp_processor_id(); + die.lock_owner_depth = 0; + bust_spinlocks(1); +@@ -427,7 +433,7 @@ void die(const char * str, struct pt_reg + bust_spinlocks(0); + die.lock_owner = -1; + add_taint(TAINT_DIE); +- __raw_spin_unlock(&die.lock); ++ spin_unlock(&die.lock); + raw_local_irq_restore(flags); + + if (!regs) +@@ -467,6 +473,11 @@ static void __kprobes do_trap(int trapnr + if (!user_mode(regs)) + goto kernel_trap; + ++#ifdef CONFIG_PREEMPT_RT ++ local_irq_enable(); ++ preempt_check_resched(); ++#endif ++ + trap_signal: { + /* + * We want error_code and trap_no set for userspace faults and +@@ -724,6 +735,7 @@ void __kprobes die_nmi(struct pt_regs *r + crash_kexec(regs); + } + ++ nmi_exit(); + do_exit(SIGSEGV); + } + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/vm86_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/vm86_32.c 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/vm86_32.c 2008-10-08 22:23:56.000000000 -0400 +@@ -135,6 +135,7 @@ struct pt_regs * fastcall save_v86_state + local_irq_enable(); + + if (!current->thread.vm86_info) { ++ local_irq_disable(); + printk("no vm86_info: BAD\n"); + do_exit(SIGSEGV); + } +Index: linux-2.6.24.7-rt21/arch/x86/mm/fault_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/mm/fault_32.c 2008-10-08 22:23:08.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/mm/fault_32.c 2008-10-08 22:23:56.000000000 -0400 +@@ -502,6 +502,7 @@ bad_area_nosemaphore: + nr = (address - idt_descr.address) >> 3; + + if (nr == 6) { ++ zap_rt_locks(); + do_invalid_op(regs, 0); + return; + } +Index: linux-2.6.24.7-rt21/arch/x86/mm/highmem_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/mm/highmem_32.c 2008-10-08 22:23:18.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/mm/highmem_32.c 2008-10-08 22:23:56.000000000 -0400 +@@ -18,6 +18,26 @@ void kunmap(struct page *page) + kunmap_high(page); + } + ++void kunmap_virt(void *ptr) ++{ ++ struct page *page; ++ ++ if ((unsigned long)ptr < PKMAP_ADDR(0)) ++ return; ++ page = pte_page(pkmap_page_table[PKMAP_NR((unsigned long)ptr)]); ++ kunmap(page); ++} ++ ++struct page *kmap_to_page(void *ptr) ++{ ++ struct page *page; ++ ++ if ((unsigned long)ptr < PKMAP_ADDR(0)) ++ return virt_to_page(ptr); ++ page = pte_page(pkmap_page_table[PKMAP_NR((unsigned long)ptr)]); ++ return page; ++} ++ + /* + * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because + * no global lock is needed and because the kmap code must perform a global TLB +@@ -26,7 +46,7 @@ void kunmap(struct page *page) + * However when holding an atomic kmap is is not legal to sleep, so atomic + * kmaps are appropriate for short, tight code paths only. + */ +-void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) ++void *__kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) + { + enum fixed_addresses idx; + unsigned long vaddr; +@@ -46,12 +66,12 @@ void *kmap_atomic_prot(struct page *page + return (void *)vaddr; + } + +-void *kmap_atomic(struct page *page, enum km_type type) ++void *__kmap_atomic(struct page *page, enum km_type type) + { + return kmap_atomic_prot(page, type, kmap_prot); + } + +-void kunmap_atomic(void *kvaddr, enum km_type type) ++void __kunmap_atomic(void *kvaddr, enum km_type type) + { + unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; + enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); +@@ -78,7 +98,7 @@ void kunmap_atomic(void *kvaddr, enum km + /* This is the same as kmap_atomic() but can map memory that doesn't + * have a struct page associated with it. + */ +-void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) ++void *__kmap_atomic_pfn(unsigned long pfn, enum km_type type) + { + enum fixed_addresses idx; + unsigned long vaddr; +@@ -93,7 +113,7 @@ void *kmap_atomic_pfn(unsigned long pfn, + return (void*) vaddr; + } + +-struct page *kmap_atomic_to_page(void *ptr) ++struct page *__kmap_atomic_to_page(void *ptr) + { + unsigned long idx, vaddr = (unsigned long)ptr; + pte_t *pte; +@@ -108,6 +128,7 @@ struct page *kmap_atomic_to_page(void *p + + EXPORT_SYMBOL(kmap); + EXPORT_SYMBOL(kunmap); +-EXPORT_SYMBOL(kmap_atomic); +-EXPORT_SYMBOL(kunmap_atomic); +-EXPORT_SYMBOL(kmap_atomic_to_page); ++EXPORT_SYMBOL(kunmap_virt); ++EXPORT_SYMBOL(__kmap_atomic); ++EXPORT_SYMBOL(__kunmap_atomic); ++EXPORT_SYMBOL(__kmap_atomic_to_page); +Index: linux-2.6.24.7-rt21/arch/x86/mm/pgtable_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/mm/pgtable_32.c 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/mm/pgtable_32.c 2008-10-08 22:23:56.000000000 -0400 +@@ -210,7 +210,7 @@ void pmd_ctor(struct kmem_cache *cache, + * vmalloc faults work because attached pagetables are never freed. + * -- wli + */ +-DEFINE_SPINLOCK(pgd_lock); ++DEFINE_RAW_SPINLOCK(pgd_lock); + struct page *pgd_list; + + static inline void pgd_list_add(pgd_t *pgd) +Index: linux-2.6.24.7-rt21/arch/x86/pci/common.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/pci/common.c 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/pci/common.c 2008-10-08 22:23:56.000000000 -0400 +@@ -54,7 +54,7 @@ int pcibios_scanned; + * This interrupt-safe spinlock protects all accesses to PCI + * configuration space. + */ +-DEFINE_SPINLOCK(pci_config_lock); ++DEFINE_RAW_SPINLOCK(pci_config_lock); + + /* + * Several buggy motherboards address only 16 devices and mirror +Index: linux-2.6.24.7-rt21/arch/x86/pci/direct.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/pci/direct.c 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/pci/direct.c 2008-10-08 22:23:56.000000000 -0400 +@@ -220,16 +220,23 @@ static int __init pci_check_type1(void) + unsigned int tmp; + int works = 0; + +- local_irq_save(flags); ++ spin_lock_irqsave(&pci_config_lock, flags); + + outb(0x01, 0xCFB); + tmp = inl(0xCF8); + outl(0x80000000, 0xCF8); +- if (inl(0xCF8) == 0x80000000 && pci_sanity_check(&pci_direct_conf1)) { +- works = 1; ++ ++ if (inl(0xCF8) == 0x80000000) { ++ spin_unlock_irqrestore(&pci_config_lock, flags); ++ ++ if (pci_sanity_check(&pci_direct_conf1)) ++ works = 1; ++ ++ spin_lock_irqsave(&pci_config_lock, flags); + } + outl(tmp, 0xCF8); +- local_irq_restore(flags); ++ ++ spin_unlock_irqrestore(&pci_config_lock, flags); + + return works; + } +@@ -239,17 +246,19 @@ static int __init pci_check_type2(void) + unsigned long flags; + int works = 0; + +- local_irq_save(flags); ++ spin_lock_irqsave(&pci_config_lock, flags); + + outb(0x00, 0xCFB); + outb(0x00, 0xCF8); + outb(0x00, 0xCFA); +- if (inb(0xCF8) == 0x00 && inb(0xCFA) == 0x00 && +- pci_sanity_check(&pci_direct_conf2)) { +- works = 1; +- } + +- local_irq_restore(flags); ++ if (inb(0xCF8) == 0x00 && inb(0xCFA) == 0x00) { ++ spin_unlock_irqrestore(&pci_config_lock, flags); ++ ++ if (pci_sanity_check(&pci_direct_conf2)) ++ works = 1; ++ } else ++ spin_unlock_irqrestore(&pci_config_lock, flags); + + return works; + } +Index: linux-2.6.24.7-rt21/arch/x86/pci/pci.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/pci/pci.h 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/pci/pci.h 2008-10-08 22:23:56.000000000 -0400 +@@ -80,7 +80,7 @@ struct irq_routing_table { + extern unsigned int pcibios_irq_mask; + + extern int pcibios_scanned; +-extern spinlock_t pci_config_lock; ++extern raw_spinlock_t pci_config_lock; + + extern int (*pcibios_enable_irq)(struct pci_dev *dev); + extern void (*pcibios_disable_irq)(struct pci_dev *dev); +Index: linux-2.6.24.7-rt21/include/asm-x86/acpi_32.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/acpi_32.h 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/acpi_32.h 2008-10-08 22:23:56.000000000 -0400 +@@ -52,8 +52,8 @@ + + #define ACPI_ASM_MACROS + #define BREAKPOINT3 +-#define ACPI_DISABLE_IRQS() local_irq_disable() +-#define ACPI_ENABLE_IRQS() local_irq_enable() ++#define ACPI_DISABLE_IRQS() local_irq_disable_nort() ++#define ACPI_ENABLE_IRQS() local_irq_enable_nort() + #define ACPI_FLUSH_CPU_CACHE() wbinvd() + + int __acpi_acquire_global_lock(unsigned int *lock); +Index: linux-2.6.24.7-rt21/include/asm-x86/dma_32.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/dma_32.h 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/dma_32.h 2008-10-08 22:23:56.000000000 -0400 +@@ -134,7 +134,7 @@ + #define DMA_AUTOINIT 0x10 + + +-extern spinlock_t dma_spin_lock; ++extern spinlock_t dma_spin_lock; + + static __inline__ unsigned long claim_dma_lock(void) + { +Index: linux-2.6.24.7-rt21/include/asm-x86/highmem.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/highmem.h 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/highmem.h 2008-10-08 22:23:56.000000000 -0400 +@@ -67,6 +67,16 @@ extern void * FASTCALL(kmap_high(struct + extern void FASTCALL(kunmap_high(struct page *page)); + + void *kmap(struct page *page); ++extern void kunmap_virt(void *ptr); ++extern struct page *kmap_to_page(void *ptr); ++void kunmap(struct page *page); ++ ++void *__kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot); ++void *__kmap_atomic(struct page *page, enum km_type type); ++void __kunmap_atomic(void *kvaddr, enum km_type type); ++void *__kmap_atomic_pfn(unsigned long pfn, enum km_type type); ++struct page *__kmap_atomic_to_page(void *ptr); ++ + void kunmap(struct page *page); + void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot); + void *kmap_atomic(struct page *page, enum km_type type); +@@ -80,6 +90,23 @@ struct page *kmap_atomic_to_page(void *p + + #define flush_cache_kmaps() do { } while (0) + ++/* ++ * on PREEMPT_RT kmap_atomic() is a wrapper that uses kmap(): ++ */ ++#ifdef CONFIG_PREEMPT_RT ++# define kmap_atomic_prot(page, type, prot) kmap(page) ++# define kmap_atomic(page, type) kmap(page) ++# define kmap_atomic_pfn(pfn, type) kmap(pfn_to_page(pfn)) ++# define kunmap_atomic(kvaddr, type) kunmap_virt(kvaddr) ++# define kmap_atomic_to_page(kvaddr) kmap_to_page(kvaddr) ++#else ++# define kmap_atomic_prot(page, type, prot) __kmap_atomic_prot(page, type, prot) ++# define kmap_atomic(page, type) __kmap_atomic(page, type) ++# define kmap_atomic_pfn(pfn, type) __kmap_atomic_pfn(pfn, type) ++# define kunmap_atomic(kvaddr, type) __kunmap_atomic(kvaddr, type) ++# define kmap_atomic_to_page(kvaddr) __kmap_atomic_to_page(kvaddr) ++#endif ++ + #endif /* __KERNEL__ */ + + #endif /* _ASM_HIGHMEM_H */ +Index: linux-2.6.24.7-rt21/include/asm-x86/i8253.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/i8253.h 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/i8253.h 2008-10-08 22:23:56.000000000 -0400 +@@ -6,7 +6,7 @@ + #define PIT_CH0 0x40 + #define PIT_CH2 0x42 + +-extern spinlock_t i8253_lock; ++extern raw_spinlock_t i8253_lock; + + extern struct clock_event_device *global_clock_event; + +Index: linux-2.6.24.7-rt21/include/asm-x86/i8259.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/i8259.h 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/i8259.h 2008-10-08 22:23:56.000000000 -0400 +@@ -7,7 +7,7 @@ extern unsigned int cached_irq_mask; + #define cached_master_mask (__byte(0, cached_irq_mask)) + #define cached_slave_mask (__byte(1, cached_irq_mask)) + +-extern spinlock_t i8259A_lock; ++extern raw_spinlock_t i8259A_lock; + + extern void init_8259A(int auto_eoi); + extern void enable_8259A_irq(unsigned int irq); +Index: linux-2.6.24.7-rt21/include/asm-x86/mach-default/irq_vectors.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/mach-default/irq_vectors.h 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/mach-default/irq_vectors.h 2008-10-08 22:23:56.000000000 -0400 +@@ -63,7 +63,7 @@ + * levels. (0x80 is the syscall vector) + */ + #define FIRST_DEVICE_VECTOR 0x31 +-#define FIRST_SYSTEM_VECTOR 0xef ++#define FIRST_SYSTEM_VECTOR 0xee + + #define TIMER_IRQ 0 + +Index: linux-2.6.24.7-rt21/include/asm-x86/mc146818rtc_32.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/mc146818rtc_32.h 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/mc146818rtc_32.h 2008-10-08 22:23:56.000000000 -0400 +@@ -72,7 +72,7 @@ static inline unsigned char current_lock + lock_cmos(reg) + #define lock_cmos_suffix(reg) \ + unlock_cmos(); \ +- local_irq_restore(cmos_flags); \ ++ local_irq_restore(cmos_flags); \ + } while (0) + #else + #define lock_cmos_prefix(reg) do {} while (0) +Index: linux-2.6.24.7-rt21/include/asm-x86/pgtable_32.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/pgtable_32.h 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/pgtable_32.h 2008-10-08 22:23:56.000000000 -0400 +@@ -33,7 +33,7 @@ struct vm_area_struct; + extern unsigned long empty_zero_page[1024]; + extern pgd_t swapper_pg_dir[1024]; + extern struct kmem_cache *pmd_cache; +-extern spinlock_t pgd_lock; ++extern raw_spinlock_t pgd_lock; + extern struct page *pgd_list; + void check_pgt_cache(void); + +Index: linux-2.6.24.7-rt21/include/asm-x86/tlbflush_32.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/tlbflush_32.h 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/tlbflush_32.h 2008-10-08 22:23:56.000000000 -0400 +@@ -4,6 +4,21 @@ + #include + #include + ++/* ++ * TLB-flush needs to be nonpreemptible on PREEMPT_RT due to the ++ * following complex race scenario: ++ * ++ * if the current task is lazy-TLB and does a TLB flush and ++ * gets preempted after the movl %%r3, %0 but before the ++ * movl %0, %%cr3 then its ->active_mm might change and it will ++ * install the wrong cr3 when it switches back. This is not a ++ * problem for the lazy-TLB task itself, but if the next task it ++ * switches to has an ->mm that is also the lazy-TLB task's ++ * new ->active_mm, then the scheduler will assume that cr3 is ++ * the new one, while we overwrote it with the old one. The result ++ * is the wrong cr3 in the new (non-lazy-TLB) task, which typically ++ * causes an infinite pagefault upon the next userspace access. ++ */ + #ifdef CONFIG_PARAVIRT + #include + #else +@@ -16,11 +31,13 @@ + do { \ + unsigned int tmpreg; \ + \ ++ preempt_disable(); \ + __asm__ __volatile__( \ + "movl %%cr3, %0; \n" \ + "movl %0, %%cr3; # flush TLB \n" \ + : "=r" (tmpreg) \ + :: "memory"); \ ++ preempt_enable(); \ + } while (0) + + /* +@@ -31,6 +48,7 @@ + do { \ + unsigned int tmpreg, cr4, cr4_orig; \ + \ ++ preempt_disable(); \ + __asm__ __volatile__( \ + "movl %%cr4, %2; # turn off PGE \n" \ + "movl %2, %1; \n" \ +@@ -42,6 +60,7 @@ + : "=&r" (tmpreg), "=&r" (cr4), "=&r" (cr4_orig) \ + : "i" (~X86_CR4_PGE) \ + : "memory"); \ ++ preempt_enable(); \ + } while (0) + + #define __native_flush_tlb_single(addr) \ +@@ -97,6 +116,13 @@ + + static inline void flush_tlb_mm(struct mm_struct *mm) + { ++ /* ++ * This is safe on PREEMPT_RT because if we preempt ++ * right after the check but before the __flush_tlb(), ++ * and if ->active_mm changes, then we might miss a ++ * TLB flush, but that TLB flush happened already when ++ * ->active_mm was changed: ++ */ + if (mm == current->active_mm) + __flush_tlb(); + } +Index: linux-2.6.24.7-rt21/include/asm-x86/xor_32.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/xor_32.h 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/xor_32.h 2008-10-08 22:23:56.000000000 -0400 +@@ -862,7 +862,21 @@ static struct xor_block_template xor_blo + #include + + #undef XOR_TRY_TEMPLATES +-#define XOR_TRY_TEMPLATES \ ++/* ++ * MMX/SSE ops disable preemption for long periods of time, ++ * so on PREEMPT_RT use the register-based ops only: ++ */ ++#ifdef CONFIG_PREEMPT_RT ++# define XOR_TRY_TEMPLATES \ ++ do { \ ++ xor_speed(&xor_block_8regs); \ ++ xor_speed(&xor_block_8regs_p); \ ++ xor_speed(&xor_block_32regs); \ ++ xor_speed(&xor_block_32regs_p); \ ++ } while (0) ++# define XOR_SELECT_TEMPLATE(FASTEST) (FASTEST) ++#else ++# define XOR_TRY_TEMPLATES \ + do { \ + xor_speed(&xor_block_8regs); \ + xor_speed(&xor_block_8regs_p); \ +@@ -875,9 +889,10 @@ static struct xor_block_template xor_blo + xor_speed(&xor_block_p5_mmx); \ + } \ + } while (0) +- + /* We force the use of the SSE xor block because it can write around L2. + We may also be able to load into the L1 only depending on how the cpu + deals with a load to a line that is being prefetched. */ +-#define XOR_SELECT_TEMPLATE(FASTEST) \ ++# define XOR_SELECT_TEMPLATE(FASTEST) \ + (cpu_has_xmm ? &xor_block_pIII_sse : FASTEST) ++#endif ++ +Index: linux-2.6.24.7-rt21/kernel/Kconfig.instrumentation +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/Kconfig.instrumentation 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/Kconfig.instrumentation 2008-10-08 22:23:56.000000000 -0400 +@@ -29,6 +29,11 @@ config OPROFILE + + If unsure, say N. + ++config PROFILE_NMI ++ bool ++ depends on OPROFILE ++ default y ++ + config KPROBES + bool "Kprobes" + depends on KALLSYMS && MODULES && !UML --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0248-preempt-realtime-init-show-enabled-debugs.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0248-preempt-realtime-init-show-enabled-debugs.patch @@ -0,0 +1,104 @@ +--- + init/main.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 54 insertions(+) + +Index: linux-2.6.24.7-rt21/init/main.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/init/main.c 2008-10-08 22:23:57.000000000 -0400 ++++ linux-2.6.24.7-rt21/init/main.c 2008-10-08 22:24:01.000000000 -0400 +@@ -437,6 +437,8 @@ static void noinline __init_refok rest_i + { + int pid; + ++ system_state = SYSTEM_BOOTING_SCHEDULER_OK; ++ + kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); + numa_default_policy(); + pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); +@@ -649,6 +651,9 @@ asmlinkage void __init start_kernel(void + + acpi_early_init(); /* before LAPIC and SMP init */ + ++#ifdef CONFIG_PREEMPT_RT ++ WARN_ON(irqs_disabled()); ++#endif + /* Do the rest non-__init'ed, we're now alive */ + rest_init(); + } +@@ -753,12 +758,14 @@ __setup("nosoftlockup", nosoftlockup_set + static void __init do_pre_smp_initcalls(void) + { + extern int spawn_ksoftirqd(void); ++ extern int spawn_desched_task(void); + + migration_init(); + posix_cpu_thread_init(); + spawn_ksoftirqd(); + if (!nosoftlockup) + spawn_softlockup_task(); ++ spawn_desched_task(); + } + + static void run_init_process(char *init_filename) +@@ -792,6 +799,9 @@ static int noinline init_post(void) + printk(KERN_WARNING "Failed to execute %s\n", + ramdisk_execute_command); + } ++#ifdef CONFIG_PREEMPT_RT ++ WARN_ON(irqs_disabled()); ++#endif + + /* + * We try each of these until one succeeds. +@@ -857,7 +867,51 @@ static int __init kernel_init(void * unu + ramdisk_execute_command = NULL; + prepare_namespace(); + } ++#ifdef CONFIG_PREEMPT_RT ++ WARN_ON(irqs_disabled()); ++#endif + ++#define DEBUG_COUNT (defined(CONFIG_DEBUG_RT_MUTEXES) + defined(CONFIG_CRITICAL_PREEMPT_TIMING) + defined(CONFIG_CRITICAL_IRQSOFF_TIMING) + defined(CONFIG_FUNCTION_TRACE) + defined(CONFIG_DEBUG_SLAB) + defined(CONFIG_DEBUG_PAGEALLOC) + defined(CONFIG_LOCKDEP)) ++ ++#if DEBUG_COUNT > 0 ++ printk(KERN_ERR "*****************************************************************************\n"); ++ printk(KERN_ERR "* *\n"); ++#if DEBUG_COUNT == 1 ++ printk(KERN_ERR "* REMINDER, the following debugging option is turned on in your .config: *\n"); ++#else ++ printk(KERN_ERR "* REMINDER, the following debugging options are turned on in your .config: *\n"); ++#endif ++ printk(KERN_ERR "* *\n"); ++#ifdef CONFIG_DEBUG_RT_MUTEXES ++ printk(KERN_ERR "* CONFIG_DEBUG_RT_MUTEXES *\n"); ++#endif ++#ifdef CONFIG_CRITICAL_PREEMPT_TIMING ++ printk(KERN_ERR "* CONFIG_CRITICAL_PREEMPT_TIMING *\n"); ++#endif ++#ifdef CONFIG_CRITICAL_IRQSOFF_TIMING ++ printk(KERN_ERR "* CONFIG_CRITICAL_IRQSOFF_TIMING *\n"); ++#endif ++#ifdef CONFIG_FUNCTION_TRACE ++ printk(KERN_ERR "* CONFIG_FUNCTION_TRACE *\n"); ++#endif ++#ifdef CONFIG_DEBUG_SLAB ++ printk(KERN_ERR "* CONFIG_DEBUG_SLAB *\n"); ++#endif ++#ifdef CONFIG_DEBUG_PAGEALLOC ++ printk(KERN_ERR "* CONFIG_DEBUG_PAGEALLOC *\n"); ++#endif ++#ifdef CONFIG_LOCKDEP ++ printk(KERN_ERR "* CONFIG_LOCKDEP *\n"); ++#endif ++ printk(KERN_ERR "* *\n"); ++#if DEBUG_COUNT == 1 ++ printk(KERN_ERR "* it may increase runtime overhead and latencies. *\n"); ++#else ++ printk(KERN_ERR "* they may increase runtime overhead and latencies. *\n"); ++#endif ++ printk(KERN_ERR "* *\n"); ++ printk(KERN_ERR "*****************************************************************************\n"); ++#endif + /* + * Ok, we have completed the initial bootup, and + * we're essentially up and running. Get rid of the --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0523-ftrace-preempt-trace-check.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0523-ftrace-preempt-trace-check.patch @@ -0,0 +1,38 @@ +Subject: ftrace: only trace preempt off with preempt tracer +From: Steven Rostedt + +When PREEMPT_TRACER and IRQSOFF_TRACER are both configured and irqsoff +tracer is running, the preempt_off sections might also be traced. + +Thanks to Andrew Morton for pointing out my mistake of spin_lock disabling +interrupts while he was reviewing ftrace.txt. Seems that my example I used +actually hit this bug. + +Signed-off-by: Steven Rostedt +--- + + kernel/trace/trace_irqsoff.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/trace/trace_irqsoff.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/trace_irqsoff.c 2008-10-08 22:25:04.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/trace_irqsoff.c 2008-10-08 22:25:09.000000000 -0400 +@@ -358,13 +358,15 @@ EXPORT_SYMBOL(trace_hardirqs_off_caller) + void trace_preempt_on(unsigned long a0, unsigned long a1) + { + tracing_hist_preempt_stop(0); +- stop_critical_timing(a0, a1); ++ if (preempt_trace()) ++ stop_critical_timing(a0, a1); + } + + void trace_preempt_off(unsigned long a0, unsigned long a1) + { + start_critical_timing(a0, a1); +- tracing_hist_preempt_start(); ++ if (preempt_trace()) ++ tracing_hist_preempt_start(); + } + #endif /* CONFIG_PREEMPT_TRACER */ + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0479-x86-disable-spinlock-preempt.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0479-x86-disable-spinlock-preempt.patch @@ -0,0 +1,34 @@ +x86: disable spinlock preempt feature since we have ticketlocks + +From: Gregory Haskins + +The spinlock preempt feature utilizes spin_trylock() to implement +preemptible waiters. However, doing so circumvents the benefit of +using a FIFO/ticket lock, so we disable the feature when ticketlocks +are enabled. + +Signed-off-by: Gregory Haskins +CC: Nick Piggin +--- + + kernel/spinlock.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/kernel/spinlock.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/spinlock.c 2008-10-08 22:24:47.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/spinlock.c 2008-10-08 22:24:59.000000000 -0400 +@@ -115,9 +115,12 @@ EXPORT_SYMBOL(__write_trylock_irqsave); + * If lockdep is enabled then we use the non-preemption spin-ops + * even on CONFIG_PREEMPT, because lockdep assumes that interrupts are + * not re-enabled during lock-acquire (which the preempt-spin-ops do): ++ * ++ * We also disable them on x86 because we now have ticket/fifo locks, ++ * which are defeated using a preemptible spinlock + */ + #if !defined(CONFIG_PREEMPT) || !defined(CONFIG_SMP) || \ +- defined(CONFIG_DEBUG_LOCK_ALLOC) ++ defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_X86) + + void __lockfunc __read_lock(raw_rwlock_t *lock) + { --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0469-ftrace-print-missing-cmdline.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0469-ftrace-print-missing-cmdline.patch @@ -0,0 +1,46 @@ +From: Steven Rostedt +Subject: ftrace: fix the command line printing + +Only half of the command line recording was implemented. The reverse +map back from command line array to pid to verify that the command line +did indeed belong to the pid, was missing. + +Signed-off-by: Steven Rostedt +--- + kernel/trace/trace.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +Index: linux-2.6.24.7-rt21/kernel/trace/trace.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/trace.c 2008-10-08 22:24:56.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/trace.c 2008-10-08 22:24:56.000000000 -0400 +@@ -685,14 +685,19 @@ static void trace_save_cmdline(struct ta + if (!spin_trylock(&trace_cmdline_lock)) + return; + ++ /* from the pid, find the index of the cmdline array */ + idx = map_pid_to_cmdline[tsk->pid]; ++ + if (idx >= SAVED_CMDLINES) { ++ /* this is new */ + idx = (cmdline_idx + 1) % SAVED_CMDLINES; + ++ /* check the reverse map and reset it if needed */ + map = map_cmdline_to_pid[idx]; + if (map <= PID_MAX_DEFAULT) + map_pid_to_cmdline[map] = (unsigned)-1; + ++ map_cmdline_to_pid[idx] = tsk->pid; + map_pid_to_cmdline[tsk->pid] = idx; + + cmdline_idx = idx; +@@ -718,6 +723,9 @@ static char *trace_find_cmdline(int pid) + if (map >= SAVED_CMDLINES) + goto out; + ++ if (map_cmdline_to_pid[map] != pid) ++ goto out; ++ + cmdline = saved_cmdlines[map]; + + out: --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0164-rt-mutex-preempt-debugging.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0164-rt-mutex-preempt-debugging.patch @@ -0,0 +1,201 @@ +--- + include/linux/preempt.h | 18 +++++++++++++++--- + include/linux/smp.h | 2 +- + init/main.c | 2 +- + kernel/sched.c | 24 ++++++++++++++++++++++-- + kernel/softirq.c | 6 +++--- + kernel/stop_machine.c | 2 +- + 6 files changed, 43 insertions(+), 11 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/preempt.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/preempt.h 2008-10-08 22:23:09.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/preempt.h 2008-10-08 22:23:36.000000000 -0400 +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + + #if defined(CONFIG_DEBUG_PREEMPT) || defined(CONFIG_PREEMPT_TRACER) || \ + defined(CONFIG_PREEMPT_TRACE) +@@ -22,11 +23,12 @@ + #define inc_preempt_count() add_preempt_count(1) + #define dec_preempt_count() sub_preempt_count(1) + +-#define preempt_count() (current_thread_info()->preempt_count) ++#define preempt_count() (current_thread_info()->preempt_count) + + #ifdef CONFIG_PREEMPT + + asmlinkage void preempt_schedule(void); ++asmlinkage void preempt_schedule_irq(void); + + #define preempt_disable() \ + do { \ +@@ -34,12 +36,19 @@ do { \ + barrier(); \ + } while (0) + +-#define preempt_enable_no_resched() \ ++#define __preempt_enable_no_resched() \ + do { \ + barrier(); \ + dec_preempt_count(); \ + } while (0) + ++ ++#ifdef CONFIG_DEBUG_PREEMPT ++extern void notrace preempt_enable_no_resched(void); ++#else ++# define preempt_enable_no_resched() __preempt_enable_no_resched() ++#endif ++ + #define preempt_check_resched() \ + do { \ + if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \ +@@ -48,7 +57,7 @@ do { \ + + #define preempt_enable() \ + do { \ +- preempt_enable_no_resched(); \ ++ __preempt_enable_no_resched(); \ + barrier(); \ + preempt_check_resched(); \ + } while (0) +@@ -85,6 +94,7 @@ do { \ + + #define preempt_disable() do { } while (0) + #define preempt_enable_no_resched() do { } while (0) ++#define __preempt_enable_no_resched() do { } while (0) + #define preempt_enable() do { } while (0) + #define preempt_check_resched() do { } while (0) + +@@ -92,6 +102,8 @@ do { \ + #define preempt_enable_no_resched_notrace() do { } while (0) + #define preempt_enable_notrace() do { } while (0) + ++#define preempt_schedule_irq() do { } while (0) ++ + #endif + + #ifdef CONFIG_PREEMPT_NOTIFIERS +Index: linux-2.6.24.7-rt21/include/linux/smp.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/smp.h 2008-10-08 22:22:36.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/smp.h 2008-10-08 22:23:36.000000000 -0400 +@@ -137,7 +137,7 @@ static inline void smp_send_reschedule(i + + #define get_cpu() ({ preempt_disable(); smp_processor_id(); }) + #define put_cpu() preempt_enable() +-#define put_cpu_no_resched() preempt_enable_no_resched() ++#define put_cpu_no_resched() __preempt_enable_no_resched() + + void smp_setup_processor_id(void); + +Index: linux-2.6.24.7-rt21/init/main.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/init/main.c 2008-10-08 22:23:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/init/main.c 2008-10-08 22:23:36.000000000 -0400 +@@ -446,7 +446,7 @@ static void noinline __init_refok rest_i + * at least once to get things moving: + */ + init_idle_bootup_task(current); +- preempt_enable_no_resched(); ++ __preempt_enable_no_resched(); + schedule(); + preempt_disable(); + +Index: linux-2.6.24.7-rt21/kernel/sched.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched.c 2008-10-08 22:23:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched.c 2008-10-08 22:23:36.000000000 -0400 +@@ -1859,6 +1859,26 @@ fire_sched_out_preempt_notifiers(struct + + #endif + ++#ifdef CONFIG_DEBUG_PREEMPT ++void notrace preempt_enable_no_resched(void) ++{ ++ static int once = 1; ++ ++ barrier(); ++ dec_preempt_count(); ++ ++ if (once && !preempt_count()) { ++ once = 0; ++ printk(KERN_ERR "BUG: %s:%d task might have lost a preemption check!\n", ++ current->comm, current->pid); ++ dump_stack(); ++ } ++} ++ ++EXPORT_SYMBOL(preempt_enable_no_resched); ++#endif ++ ++ + /** + * prepare_task_switch - prepare to switch tasks + * @rq: the runqueue preparing to switch +@@ -3753,7 +3773,7 @@ need_resched_nonpreemptible: + rq = cpu_rq(cpu); + goto need_resched_nonpreemptible; + } +- preempt_enable_no_resched(); ++ __preempt_enable_no_resched(); + if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) + goto need_resched; + } +@@ -7051,7 +7071,7 @@ void __init sched_init(void) + current->sched_class = &fair_sched_class; + } + +-#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP ++#if defined(CONFIG_DEBUG_SPINLOCK_SLEEP) || defined(CONFIG_DEBUG_PREEMPT) + void __might_sleep(char *file, int line) + { + #ifdef in_atomic +Index: linux-2.6.24.7-rt21/kernel/softirq.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/softirq.c 2008-10-08 22:23:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/softirq.c 2008-10-08 22:23:36.000000000 -0400 +@@ -413,7 +413,7 @@ void irq_exit(void) + tick_nohz_stop_sched_tick(); + rcu_irq_exit(); + #endif +- preempt_enable_no_resched(); ++ __preempt_enable_no_resched(); + } + + /* +@@ -599,7 +599,7 @@ static int ksoftirqd(void * __data) + while (!kthread_should_stop()) { + preempt_disable(); + if (!(local_softirq_pending() & mask)) { +- preempt_enable_no_resched(); ++ __preempt_enable_no_resched(); + schedule(); + preempt_disable(); + } +@@ -618,7 +618,7 @@ static int ksoftirqd(void * __data) + goto wait_to_die; + + local_irq_disable(); +- preempt_enable_no_resched(); ++ __preempt_enable_no_resched(); + set_softirq_pending(local_softirq_pending() & ~mask); + local_bh_disable(); + local_irq_enable(); +Index: linux-2.6.24.7-rt21/kernel/stop_machine.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/stop_machine.c 2008-10-08 22:22:36.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/stop_machine.c 2008-10-08 22:23:36.000000000 -0400 +@@ -133,7 +133,7 @@ static void restart_machine(void) + { + stopmachine_set_state(STOPMACHINE_EXIT); + local_irq_enable(); +- preempt_enable_no_resched(); ++ __preempt_enable_no_resched(); + } + + struct stop_machine_data --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0183-percpu-locked-mm.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0183-percpu-locked-mm.patch @@ -0,0 +1,454 @@ + arch/ppc/mm/init.c | 2 - + arch/x86/mm/init_32.c | 2 - + arch/x86/mm/init_64.c | 2 - + include/asm-generic/percpu.h | 24 ++++++++++++ + include/asm-generic/tlb.h | 9 +++- + include/asm-x86/percpu_32.h | 19 +++++++++ + include/asm-x86/percpu_64.h | 25 ++++++++++++ + include/linux/percpu.h | 23 +++++++++++ + mm/swap.c | 85 ++++++++++++++++++++++++++++++++++++------- + 9 files changed, 173 insertions(+), 18 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/ppc/mm/init.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ppc/mm/init.c 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ppc/mm/init.c 2008-10-08 22:23:42.000000000 -0400 +@@ -55,7 +55,7 @@ + #endif + #define MAX_LOW_MEM CONFIG_LOWMEM_SIZE + +-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); ++DEFINE_PER_CPU_LOCKED(struct mmu_gather, mmu_gathers); + + unsigned long total_memory; + unsigned long total_lowmem; +Index: linux-2.6.24.7-rt21/arch/x86/mm/init_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/mm/init_32.c 2008-10-08 22:23:06.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/mm/init_32.c 2008-10-08 22:23:42.000000000 -0400 +@@ -47,7 +47,7 @@ + + unsigned int __VMALLOC_RESERVE = 128 << 20; + +-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); ++DEFINE_PER_CPU_LOCKED(struct mmu_gather, mmu_gathers); + unsigned long highstart_pfn, highend_pfn; + + static int noinline do_test_wp_bit(void); +Index: linux-2.6.24.7-rt21/arch/x86/mm/init_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/mm/init_64.c 2008-10-08 22:23:06.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/mm/init_64.c 2008-10-08 22:23:42.000000000 -0400 +@@ -53,7 +53,7 @@ EXPORT_SYMBOL(dma_ops); + + static unsigned long dma_reserve __initdata; + +-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); ++DEFINE_PER_CPU_LOCKED(struct mmu_gather, mmu_gathers); + + /* + * NOTE: pagetable_init alloc all the fixmap pagetables contiguous on the +Index: linux-2.6.24.7-rt21/include/asm-generic/percpu.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-generic/percpu.h 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-generic/percpu.h 2008-10-08 22:23:42.000000000 -0400 +@@ -19,6 +19,10 @@ extern unsigned long __per_cpu_offset[NR + __typeof__(type) per_cpu__##name \ + ____cacheline_aligned_in_smp + ++#define DEFINE_PER_CPU_LOCKED(type, name) \ ++ __attribute__((__section__(".data.percpu"))) __DEFINE_SPINLOCK(per_cpu_lock__##name##_locked); \ ++ __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name##_locked ++ + /* var is in discarded region: offset to particular copy we want */ + #define per_cpu(var, cpu) (*({ \ + extern int simple_identifier_##var(void); \ +@@ -26,6 +30,15 @@ extern unsigned long __per_cpu_offset[NR + #define __get_cpu_var(var) per_cpu(var, smp_processor_id()) + #define __raw_get_cpu_var(var) per_cpu(var, raw_smp_processor_id()) + ++#define per_cpu_lock(var, cpu) \ ++ (*RELOC_HIDE(&per_cpu_lock__##var##_locked, __per_cpu_offset[cpu])) ++#define per_cpu_var_locked(var, cpu) \ ++ (*RELOC_HIDE(&per_cpu__##var##_locked, __per_cpu_offset[cpu])) ++#define __get_cpu_lock(var, cpu) \ ++ per_cpu_lock(var, cpu) ++#define __get_cpu_var_locked(var, cpu) \ ++ per_cpu_var_locked(var, cpu) ++ + /* A macro to avoid #include hell... */ + #define percpu_modcopy(pcpudst, src, size) \ + do { \ +@@ -38,19 +51,30 @@ do { \ + + #define DEFINE_PER_CPU(type, name) \ + __typeof__(type) per_cpu__##name ++#define DEFINE_PER_CPU_LOCKED(type, name) \ ++ __DEFINE_SPINLOCK(per_cpu_lock__##name##_locked); \ ++ __typeof__(type) per_cpu__##name##_locked + + #define DEFINE_PER_CPU_SHARED_ALIGNED(type, name) \ + DEFINE_PER_CPU(type, name) + + #define per_cpu(var, cpu) (*((void)(cpu), &per_cpu__##var)) ++#define per_cpu_var_locked(var, cpu) (*((void)(cpu), &per_cpu__##var##_locked)) + #define __get_cpu_var(var) per_cpu__##var + #define __raw_get_cpu_var(var) per_cpu__##var ++#define __get_cpu_lock(var, cpu) per_cpu_lock__##var##_locked ++#define __get_cpu_var_locked(var, cpu) per_cpu__##var##_locked + + #endif /* SMP */ + + #define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name ++#define DECLARE_PER_CPU_LOCKED(type, name) \ ++ extern spinlock_t per_cpu_lock__##name##_locked; \ ++ extern __typeof__(type) per_cpu__##name##_locked + + #define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var) + #define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var) ++#define EXPORT_PER_CPU_LOCKED_SYMBOL(var) EXPORT_SYMBOL(per_cpu_lock__##var##_locked); EXPORT_SYMBOL(per_cpu__##var##_locked) ++#define EXPORT_PER_CPU_LOCKED_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu_lock__##var##_locked); EXPORT_SYMBOL_GPL(per_cpu__##var##_locked) + + #endif /* _ASM_GENERIC_PERCPU_H_ */ +Index: linux-2.6.24.7-rt21/include/asm-generic/tlb.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-generic/tlb.h 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-generic/tlb.h 2008-10-08 22:23:42.000000000 -0400 +@@ -42,11 +42,12 @@ struct mmu_gather { + unsigned int nr; /* set to ~0U means fast mode */ + unsigned int need_flush;/* Really unmapped some ptes? */ + unsigned int fullmm; /* non-zero means full mm flush */ ++ int cpu; + struct page * pages[FREE_PTE_NR]; + }; + + /* Users of the generic TLB shootdown code must declare this storage space. */ +-DECLARE_PER_CPU(struct mmu_gather, mmu_gathers); ++DECLARE_PER_CPU_LOCKED(struct mmu_gather, mmu_gathers); + + /* tlb_gather_mmu + * Return a pointer to an initialized struct mmu_gather. +@@ -54,8 +55,10 @@ DECLARE_PER_CPU(struct mmu_gather, mmu_g + static inline struct mmu_gather * + tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush) + { +- struct mmu_gather *tlb = &get_cpu_var(mmu_gathers); ++ int cpu; ++ struct mmu_gather *tlb = &get_cpu_var_locked(mmu_gathers, &cpu); + ++ tlb->cpu = cpu; + tlb->mm = mm; + + /* Use fast mode if only one CPU is online */ +@@ -91,7 +94,7 @@ tlb_finish_mmu(struct mmu_gather *tlb, u + /* keep the page table cache within bounds */ + check_pgt_cache(); + +- put_cpu_var(mmu_gathers); ++ put_cpu_var_locked(mmu_gathers, tlb->cpu); + } + + /* tlb_remove_page +Index: linux-2.6.24.7-rt21/include/asm-x86/percpu_32.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/percpu_32.h 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/percpu_32.h 2008-10-08 22:23:42.000000000 -0400 +@@ -51,6 +51,10 @@ extern unsigned long __per_cpu_offset[]; + + /* Separate out the type, so (int[3], foo) works. */ + #define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name ++#define DECLARE_PER_CPU_LOCKED(type, name) \ ++ extern spinlock_t per_cpu_lock__##name##_locked; \ ++ extern __typeof__(type) per_cpu__##name##_locked ++ + #define DEFINE_PER_CPU(type, name) \ + __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name + +@@ -59,6 +63,10 @@ extern unsigned long __per_cpu_offset[]; + __typeof__(type) per_cpu__##name \ + ____cacheline_aligned_in_smp + ++#define DEFINE_PER_CPU_LOCKED(type, name) \ ++ __attribute__((__section__(".data.percpu"))) __DEFINE_SPINLOCK(per_cpu_lock__##name##_locked); \ ++ __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name##_locked ++ + /* We can use this directly for local CPU (faster). */ + DECLARE_PER_CPU(unsigned long, this_cpu_off); + +@@ -74,6 +82,15 @@ DECLARE_PER_CPU(unsigned long, this_cpu_ + + #define __get_cpu_var(var) __raw_get_cpu_var(var) + ++#define per_cpu_lock(var, cpu) \ ++ (*RELOC_HIDE(&per_cpu_lock__##var##_locked, __per_cpu_offset[cpu])) ++#define per_cpu_var_locked(var, cpu) \ ++ (*RELOC_HIDE(&per_cpu__##var##_locked, __per_cpu_offset[cpu])) ++#define __get_cpu_lock(var, cpu) \ ++ per_cpu_lock(var, cpu) ++#define __get_cpu_var_locked(var, cpu) \ ++ per_cpu_var_locked(var, cpu) ++ + /* A macro to avoid #include hell... */ + #define percpu_modcopy(pcpudst, src, size) \ + do { \ +@@ -85,6 +102,8 @@ do { \ + + #define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var) + #define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var) ++#define EXPORT_PER_CPU_LOCKED_SYMBOL(var) EXPORT_SYMBOL(per_cpu_lock__##var##_locked); EXPORT_SYMBOL(per_cpu__##var##_locked) ++#define EXPORT_PER_CPU_LOCKED_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu_lock__##var##_locked); EXPORT_SYMBOL_GPL(per_cpu__##var##_locked) + + /* fs segment starts at (positive) offset == __per_cpu_offset[cpu] */ + #define __percpu_seg "%%fs:" +Index: linux-2.6.24.7-rt21/include/asm-x86/percpu_64.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/percpu_64.h 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/percpu_64.h 2008-10-08 22:23:42.000000000 -0400 +@@ -19,6 +19,9 @@ + /* Separate out the type, so (int[3], foo) works. */ + #define DEFINE_PER_CPU(type, name) \ + __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name ++#define DEFINE_PER_CPU_LOCKED(type, name) \ ++ __attribute__((__section__(".data.percpu"))) __DEFINE_SPINLOCK(per_cpu_lock__##name##_locked); \ ++ __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name##_locked + + #define DEFINE_PER_CPU_SHARED_ALIGNED(type, name) \ + __attribute__((__section__(".data.percpu.shared_aligned"))) \ +@@ -36,6 +39,15 @@ + extern int simple_identifier_##var(void); \ + RELOC_HIDE(&per_cpu__##var, __my_cpu_offset()); })) + ++#define per_cpu_lock(var, cpu) \ ++ (*RELOC_HIDE(&per_cpu_lock__##var##_locked, __per_cpu_offset(cpu))) ++#define per_cpu_var_locked(var, cpu) \ ++ (*RELOC_HIDE(&per_cpu__##var##_locked, __per_cpu_offset(cpu))) ++#define __get_cpu_lock(var, cpu) \ ++ per_cpu_lock(var, cpu) ++#define __get_cpu_var_locked(var, cpu) \ ++ per_cpu_var_locked(var, cpu) ++ + /* A macro to avoid #include hell... */ + #define percpu_modcopy(pcpudst, src, size) \ + do { \ +@@ -54,15 +66,28 @@ extern void setup_per_cpu_areas(void); + #define DEFINE_PER_CPU_SHARED_ALIGNED(type, name) \ + DEFINE_PER_CPU(type, name) + ++#define DEFINE_PER_CPU_LOCKED(type, name) \ ++ spinlock_t per_cpu_lock__##name##_locked = SPIN_LOCK_UNLOCKED; \ ++ __typeof__(type) per_cpu__##name##_locked ++ + #define per_cpu(var, cpu) (*((void)(cpu), &per_cpu__##var)) ++#define per_cpu_var_locked(var, cpu) (*((void)(cpu), &per_cpu__##var##_locked)) + #define __get_cpu_var(var) per_cpu__##var + #define __raw_get_cpu_var(var) per_cpu__##var ++#define __get_cpu_lock(var, cpu) per_cpu_lock__##var##_locked ++#define __get_cpu_var_locked(var, cpu) per_cpu__##var##_locked + + #endif /* SMP */ + + #define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name + ++#define DECLARE_PER_CPU_LOCKED(type, name) \ ++ extern spinlock_t per_cpu_lock__##name##_locked; \ ++ extern __typeof__(type) per_cpu__##name##_locked ++ + #define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var) + #define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var) ++#define EXPORT_PER_CPU_LOCKED_SYMBOL(var) EXPORT_SYMBOL(per_cpu_lock__##var##_locked); EXPORT_SYMBOL(per_cpu__##var##_locked) ++#define EXPORT_PER_CPU_LOCKED_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu_lock__##var##_locked); EXPORT_SYMBOL_GPL(per_cpu__##var##_locked) + + #endif /* _ASM_X8664_PERCPU_H_ */ +Index: linux-2.6.24.7-rt21/include/linux/percpu.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/percpu.h 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/percpu.h 2008-10-08 22:23:42.000000000 -0400 +@@ -31,6 +31,29 @@ + &__get_cpu_var(var); })) + #define put_cpu_var(var) preempt_enable() + ++/* ++ * Per-CPU data structures with an additional lock - useful for ++ * PREEMPT_RT code that wants to reschedule but also wants ++ * per-CPU data structures. ++ * ++ * 'cpu' gets updated with the CPU the task is currently executing on. ++ * ++ * NOTE: on normal !PREEMPT_RT kernels these per-CPU variables ++ * are the same as the normal per-CPU variables, so there no ++ * runtime overhead. ++ */ ++#define get_cpu_var_locked(var, cpuptr) \ ++(*({ \ ++ int __cpu = raw_smp_processor_id(); \ ++ \ ++ *(cpuptr) = __cpu; \ ++ spin_lock(&__get_cpu_lock(var, __cpu)); \ ++ &__get_cpu_var_locked(var, __cpu); \ ++})) ++ ++#define put_cpu_var_locked(var, cpu) \ ++ do { (void)cpu; spin_unlock(&__get_cpu_lock(var, cpu)); } while (0) ++ + #ifdef CONFIG_SMP + + struct percpu_data { +Index: linux-2.6.24.7-rt21/mm/swap.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/mm/swap.c 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/mm/swap.c 2008-10-08 22:23:42.000000000 -0400 +@@ -33,10 +33,64 @@ + /* How many pages do we try to swap or page in/out together? */ + int page_cluster; + ++/* ++ * On PREEMPT_RT we don't want to disable preemption for cpu variables. ++ * We grab a cpu and then use that cpu to lock the variables accordingly. ++ */ ++#ifdef CONFIG_PREEMPT_RT ++static DEFINE_PER_CPU_LOCKED(struct pagevec, lru_add_pvecs) = { 0, }; ++static DEFINE_PER_CPU_LOCKED(struct pagevec, lru_add_active_pvecs) = { 0, }; ++static DEFINE_PER_CPU_LOCKED(struct pagevec, lru_rotate_pvecs) = { 0, }; ++ ++#define swap_get_cpu_var_irq_save(var, flags, cpu) \ ++ ({ \ ++ (void)flags; \ ++ &get_cpu_var_locked(var, &cpu); \ ++ }) ++#define swap_put_cpu_var_irq_restore(var, flags, cpu) \ ++ put_cpu_var_locked(var, cpu) ++#define swap_get_cpu_var(var, cpu) \ ++ &get_cpu_var_locked(var, &cpu) ++#define swap_put_cpu_var(var, cpu) \ ++ put_cpu_var_locked(var, cpu) ++#define swap_per_cpu_lock(var, cpu) \ ++ ({ \ ++ spin_lock(&__get_cpu_lock(var, cpu)); \ ++ &__get_cpu_var_locked(var, cpu); \ ++ }) ++#define swap_per_cpu_unlock(var, cpu) \ ++ spin_unlock(&__get_cpu_lock(var, cpu)); ++#define swap_get_cpu() raw_smp_processor_id(); ++#define swap_put_cpu() ++#else + static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, }; + static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, }; + static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs) = { 0, }; + ++#define swap_get_cpu_var_irq_save(var, flags, cpu) \ ++ ({ \ ++ (void)cpu; \ ++ local_irq_save(flags); \ ++ &__get_cpu_var(var); \ ++ }) ++#define swap_put_cpu_var_irq_restore(var, flags, cpu) \ ++ local_irq_restore(flags) ++#define swap_get_cpu_var(var, cpu) \ ++ ({ (void)cpu; &get_cpu_var(var); }) ++#define swap_put_cpu_var(var, cpu) \ ++ do { \ ++ (void)cpu; \ ++ put_cpu_var(var); \ ++ } while(0) ++#define swap_per_cpu_lock(var, cpu) \ ++ &per_cpu(lru_add_pvecs, cpu) ++#define swap_per_cpu_unlock(var, cpu) \ ++ do { } while(0) ++#define swap_get_cpu() get_cpu() ++#define swap_put_cpu() put_cpu(); ++ ++#endif /* CONFIG_PREEMPT_RT */ ++ + /* + * This path almost never happens for VM activity - pages are normally + * freed via pagevecs. But it gets used by networking. +@@ -139,6 +193,7 @@ int rotate_reclaimable_page(struct page + { + struct pagevec *pvec; + unsigned long flags; ++ int cpu; + + if (PageLocked(page)) + return 1; +@@ -150,11 +205,10 @@ int rotate_reclaimable_page(struct page + return 1; + + page_cache_get(page); +- local_irq_save(flags); +- pvec = &__get_cpu_var(lru_rotate_pvecs); ++ pvec = swap_get_cpu_var_irq_save(lru_rotate_pvecs, flags, cpu); + if (!pagevec_add(pvec, page)) + pagevec_move_tail(pvec); +- local_irq_restore(flags); ++ swap_put_cpu_var_irq_restore(lru_rotate_pvecs, flags, cpu); + + if (!test_clear_page_writeback(page)) + BUG(); +@@ -204,22 +258,24 @@ EXPORT_SYMBOL(mark_page_accessed); + */ + void fastcall lru_cache_add(struct page *page) + { +- struct pagevec *pvec = &get_cpu_var(lru_add_pvecs); ++ int cpu; ++ struct pagevec *pvec = swap_get_cpu_var(lru_add_pvecs, cpu); + + page_cache_get(page); + if (!pagevec_add(pvec, page)) + __pagevec_lru_add(pvec); +- put_cpu_var(lru_add_pvecs); ++ swap_put_cpu_var(lru_add_pvecs, cpu); + } + + void fastcall lru_cache_add_active(struct page *page) + { +- struct pagevec *pvec = &get_cpu_var(lru_add_active_pvecs); ++ int cpu; ++ struct pagevec *pvec = swap_get_cpu_var(lru_add_active_pvecs, cpu); + + page_cache_get(page); + if (!pagevec_add(pvec, page)) + __pagevec_lru_add_active(pvec); +- put_cpu_var(lru_add_active_pvecs); ++ swap_put_cpu_var(lru_add_active_pvecs, cpu); + } + + /* +@@ -231,15 +287,17 @@ static void drain_cpu_pagevecs(int cpu) + { + struct pagevec *pvec; + +- pvec = &per_cpu(lru_add_pvecs, cpu); ++ pvec = swap_per_cpu_lock(lru_add_pvecs, cpu); + if (pagevec_count(pvec)) + __pagevec_lru_add(pvec); ++ swap_per_cpu_unlock(lru_add_pvecs, cpu); + +- pvec = &per_cpu(lru_add_active_pvecs, cpu); ++ pvec = swap_per_cpu_lock(lru_add_active_pvecs, cpu); + if (pagevec_count(pvec)) + __pagevec_lru_add_active(pvec); ++ swap_per_cpu_unlock(lru_add_active_pvecs, cpu); + +- pvec = &per_cpu(lru_rotate_pvecs, cpu); ++ pvec = swap_per_cpu_lock(lru_rotate_pvecs, cpu); + if (pagevec_count(pvec)) { + unsigned long flags; + +@@ -248,12 +306,15 @@ static void drain_cpu_pagevecs(int cpu) + pagevec_move_tail(pvec); + local_irq_restore(flags); + } ++ swap_per_cpu_unlock(lru_rotate_pvecs, cpu); + } + + void lru_add_drain(void) + { +- drain_cpu_pagevecs(get_cpu()); +- put_cpu(); ++ int cpu; ++ cpu = swap_get_cpu(); ++ drain_cpu_pagevecs(cpu); ++ swap_put_cpu(); + } + + #ifdef CONFIG_NUMA --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0216-preempt-realtime-x86_64.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0216-preempt-realtime-x86_64.patch @@ -0,0 +1,403 @@ + arch/x86/kernel/early_printk.c | 2 +- + arch/x86/kernel/head64.c | 6 +++++- + arch/x86/kernel/i8259_64.c | 2 +- + arch/x86/kernel/io_apic_64.c | 13 +++++++------ + arch/x86/kernel/nmi_64.c | 2 ++ + arch/x86/kernel/process_64.c | 21 ++++++++++++--------- + arch/x86/kernel/signal_64.c | 7 +++++++ + arch/x86/kernel/smp_64.c | 14 ++++++++++++-- + arch/x86/kernel/traps_64.c | 13 ++++++------- + include/asm-x86/acpi_64.h | 4 ++-- + include/asm-x86/hw_irq_64.h | 2 +- + include/asm-x86/io_apic_64.h | 2 +- + include/asm-x86/spinlock_64.h | 6 +++--- + include/asm-x86/tlbflush_64.h | 8 +++++++- + include/asm-x86/vgtod.h | 2 +- + 15 files changed, 68 insertions(+), 36 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/early_printk.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/early_printk.c 2008-10-08 22:22:32.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/early_printk.c 2008-10-08 22:23:51.000000000 -0400 +@@ -198,7 +198,7 @@ static int early_console_initialized = 0 + + void early_printk(const char *fmt, ...) + { +- char buf[512]; ++ static char buf[512]; + int n; + va_list ap; + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/head64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/head64.c 2008-10-08 22:22:32.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/head64.c 2008-10-08 22:23:51.000000000 -0400 +@@ -24,7 +24,11 @@ static void __init zap_identity_mappings + { + pgd_t *pgd = pgd_offset_k(0UL); + pgd_clear(pgd); +- __flush_tlb(); ++ /* ++ * preempt_disable/enable does not work this early in the ++ * bootup yet: ++ */ ++ write_cr3(read_cr3()); + } + + /* Don't add a printk in there. printk relies on the PDA which is not initialized +Index: linux-2.6.24.7-rt21/arch/x86/kernel/i8259_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/i8259_64.c 2008-10-08 22:23:32.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/i8259_64.c 2008-10-08 22:23:51.000000000 -0400 +@@ -96,8 +96,8 @@ static void (*interrupt[NR_VECTORS - FIR + */ + + static int i8259A_auto_eoi; +-DEFINE_SPINLOCK(i8259A_lock); + static void mask_and_ack_8259A(unsigned int); ++DEFINE_RAW_SPINLOCK(i8259A_lock); + + static struct irq_chip i8259A_chip = { + .name = "XT-PIC", +Index: linux-2.6.24.7-rt21/arch/x86/kernel/io_apic_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/io_apic_64.c 2008-10-08 22:23:32.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/io_apic_64.c 2008-10-08 22:23:51.000000000 -0400 +@@ -91,8 +91,8 @@ int timer_over_8254 __initdata = 1; + /* Where if anywhere is the i8259 connect in external int mode */ + static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; + +-static DEFINE_SPINLOCK(ioapic_lock); +-DEFINE_SPINLOCK(vector_lock); ++static DEFINE_RAW_SPINLOCK(ioapic_lock); ++DEFINE_RAW_SPINLOCK(vector_lock); + + /* + * # of IRQ routing registers +@@ -205,6 +205,9 @@ static inline void io_apic_sync(unsigned + reg ACTION; \ + io_apic_modify(entry->apic, reg); \ + FINAL; \ ++ /* Force POST flush by reading: */ \ ++ reg = io_apic_read(entry->apic, 0x10 + R + pin*2); \ ++ \ + if (!entry->next) \ + break; \ + entry = irq_2_pin + entry->next; \ +@@ -349,10 +352,8 @@ static void add_pin_to_irq(unsigned int + static void name##_IO_APIC_irq (unsigned int irq) \ + __DO_ACTION(R, ACTION, FINAL) + +-DO_ACTION( __mask, 0, |= 0x00010000, io_apic_sync(entry->apic) ) +- /* mask = 1 */ +-DO_ACTION( __unmask, 0, &= 0xfffeffff, ) +- /* mask = 0 */ ++DO_ACTION( __mask, 0, |= 0x00010000, ) /* mask = 1 */ ++DO_ACTION( __unmask, 0, &= 0xfffeffff, ) /* mask = 0 */ + + DO_ACTION( __pcix_mask, 0, &= 0xffff7fff, ) /* edge */ + DO_ACTION( __pcix_unmask, 0, = (reg & 0xfffeffff) | 0x00008000, ) /* level */ +Index: linux-2.6.24.7-rt21/arch/x86/kernel/nmi_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/nmi_64.c 2008-10-08 22:23:22.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/nmi_64.c 2008-10-08 22:23:51.000000000 -0400 +@@ -68,7 +68,9 @@ static int endflag __initdata = 0; + */ + static __init void nmi_cpu_busy(void *data) + { ++#ifndef CONFIG_PREEMPT_RT + local_irq_enable_in_hardirq(); ++#endif + /* Intentionally don't use cpu_relax here. This is + to make sure that the performance counter really ticks, + even if there is a simulator or similar that catches the +Index: linux-2.6.24.7-rt21/arch/x86/kernel/process_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/process_64.c 2008-10-08 22:23:06.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/process_64.c 2008-10-08 22:23:51.000000000 -0400 +@@ -115,7 +115,7 @@ static void default_idle(void) + */ + smp_mb(); + local_irq_disable(); +- if (!need_resched()) { ++ if (!need_resched() && !need_resched_delayed()) { + /* Enables interrupts one instruction before HLT. + x86 special cases this so there is no race. */ + safe_halt(); +@@ -213,7 +213,7 @@ void cpu_idle (void) + /* endless idle loop with no priority at all */ + while (1) { + tick_nohz_stop_sched_tick(); +- while (!need_resched()) { ++ while (!need_resched() && !need_resched_delayed()) { + void (*idle)(void); + + if (__get_cpu_var(cpu_idle_state)) +@@ -243,9 +243,11 @@ void cpu_idle (void) + } + + tick_nohz_restart_sched_tick(); +- preempt_enable_no_resched(); +- schedule(); ++ local_irq_disable(); ++ __preempt_enable_no_resched(); ++ __schedule(); + preempt_disable(); ++ local_irq_enable(); + } + } + +@@ -261,10 +263,10 @@ void cpu_idle (void) + */ + void mwait_idle_with_hints(unsigned long eax, unsigned long ecx) + { +- if (!need_resched()) { ++ if (!need_resched() && !need_resched_delayed()) { + __monitor((void *)¤t_thread_info()->flags, 0, 0); + smp_mb(); +- if (!need_resched()) ++ if (!need_resched() && !need_resched_delayed()) + __mwait(eax, ecx); + } + } +@@ -272,10 +274,10 @@ void mwait_idle_with_hints(unsigned long + /* Default MONITOR/MWAIT with no hints, used for default C1 state */ + static void mwait_idle(void) + { +- if (!need_resched()) { ++ if (!need_resched() && !need_resched_delayed()) { + __monitor((void *)¤t_thread_info()->flags, 0, 0); + smp_mb(); +- if (!need_resched()) ++ if (!need_resched() && !need_resched_delayed()) + __sti_mwait(0, 0); + else + local_irq_enable(); +@@ -393,7 +395,7 @@ void exit_thread(void) + struct thread_struct *t = &me->thread; + + if (me->thread.io_bitmap_ptr) { +- struct tss_struct *tss = &per_cpu(init_tss, get_cpu()); ++ struct tss_struct *tss; + + kfree(t->io_bitmap_ptr); + t->io_bitmap_ptr = NULL; +@@ -401,6 +403,7 @@ void exit_thread(void) + /* + * Careful, clear this in the TSS too: + */ ++ tss = &per_cpu(init_tss, get_cpu()); + memset(tss->io_bitmap, 0xff, t->io_bitmap_max); + t->io_bitmap_max = 0; + put_cpu(); +Index: linux-2.6.24.7-rt21/arch/x86/kernel/signal_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/signal_64.c 2008-10-08 22:22:54.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/signal_64.c 2008-10-08 22:23:51.000000000 -0400 +@@ -423,6 +423,13 @@ static void do_signal(struct pt_regs *re + int signr; + sigset_t *oldset; + ++#ifdef CONFIG_PREEMPT_RT ++ /* ++ * Fully-preemptible kernel does not need interrupts disabled: ++ */ ++ local_irq_enable(); ++ preempt_check_resched(); ++#endif + /* + * We want the common case to go fast, which + * is why we may in certain cases get here from +Index: linux-2.6.24.7-rt21/arch/x86/kernel/smp_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/smp_64.c 2008-10-08 22:22:32.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/smp_64.c 2008-10-08 22:23:51.000000000 -0400 +@@ -56,7 +56,7 @@ union smp_flush_state { + struct mm_struct *flush_mm; + unsigned long flush_va; + #define FLUSH_ALL -1ULL +- spinlock_t tlbstate_lock; ++ raw_spinlock_t tlbstate_lock; + }; + char pad[SMP_CACHE_BYTES]; + } ____cacheline_aligned; +@@ -296,10 +296,20 @@ void smp_send_reschedule(int cpu) + } + + /* ++ * this function sends a 'reschedule' IPI to all other CPUs. ++ * This is used when RT tasks are starving and other CPUs ++ * might be able to run them: ++ */ ++void smp_send_reschedule_allbutself(void) ++{ ++ send_IPI_allbutself(RESCHEDULE_VECTOR); ++} ++ ++/* + * Structure and data for smp_call_function(). This is designed to minimise + * static memory requirements. It also looks cleaner. + */ +-static DEFINE_SPINLOCK(call_lock); ++static DEFINE_RAW_SPINLOCK(call_lock); + + struct call_data_struct { + void (*func) (void *info); +Index: linux-2.6.24.7-rt21/arch/x86/kernel/traps_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/traps_64.c 2008-10-08 22:23:24.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/traps_64.c 2008-10-08 22:23:51.000000000 -0400 +@@ -220,7 +220,7 @@ void dump_trace(struct task_struct *tsk, + unsigned long *stack, + const struct stacktrace_ops *ops, void *data) + { +- const unsigned cpu = get_cpu(); ++ const unsigned cpu = raw_smp_processor_id(); + unsigned long *irqstack_end = (unsigned long*)cpu_pda(cpu)->irqstackptr; + unsigned used = 0; + struct thread_info *tinfo; +@@ -311,7 +311,6 @@ void dump_trace(struct task_struct *tsk, + tinfo = task_thread_info(tsk); + HANDLE_STACK (valid_stack_ptr(tinfo, stack)); + #undef HANDLE_STACK +- put_cpu(); + } + EXPORT_SYMBOL(dump_trace); + +@@ -361,7 +360,7 @@ _show_stack(struct task_struct *tsk, str + { + unsigned long *stack; + int i; +- const int cpu = smp_processor_id(); ++ const int cpu = raw_smp_processor_id(); + unsigned long *irqstack_end = (unsigned long *) (cpu_pda(cpu)->irqstackptr); + unsigned long *irqstack = (unsigned long *) (cpu_pda(cpu)->irqstackptr - IRQSTACKSIZE); + +@@ -473,7 +472,7 @@ void out_of_line_bug(void) + EXPORT_SYMBOL(out_of_line_bug); + #endif + +-static raw_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED; ++static raw_spinlock_t die_lock = RAW_SPIN_LOCK_UNLOCKED(die_lock); + static int die_owner = -1; + static unsigned int die_nest_count; + +@@ -487,11 +486,11 @@ unsigned __kprobes long oops_begin(void) + /* racy, but better than risking deadlock. */ + raw_local_irq_save(flags); + cpu = smp_processor_id(); +- if (!__raw_spin_trylock(&die_lock)) { ++ if (!spin_trylock(&die_lock)) { + if (cpu == die_owner) + /* nested oops. should stop eventually */; + else +- __raw_spin_lock(&die_lock); ++ spin_lock(&die_lock); + } + die_nest_count++; + die_owner = cpu; +@@ -507,7 +506,7 @@ void __kprobes oops_end(unsigned long fl + die_nest_count--; + if (!die_nest_count) + /* Nest count reaches zero, release the lock. */ +- __raw_spin_unlock(&die_lock); ++ spin_unlock(&die_lock); + raw_local_irq_restore(flags); + if (panic_on_oops) + panic("Fatal exception"); +Index: linux-2.6.24.7-rt21/include/asm-x86/acpi_64.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/acpi_64.h 2008-10-08 22:22:32.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/acpi_64.h 2008-10-08 22:23:51.000000000 -0400 +@@ -51,8 +51,8 @@ + + #define ACPI_ASM_MACROS + #define BREAKPOINT3 +-#define ACPI_DISABLE_IRQS() local_irq_disable() +-#define ACPI_ENABLE_IRQS() local_irq_enable() ++#define ACPI_DISABLE_IRQS() local_irq_disable_nort() ++#define ACPI_ENABLE_IRQS() local_irq_enable_nort() + #define ACPI_FLUSH_CPU_CACHE() wbinvd() + + int __acpi_acquire_global_lock(unsigned int *lock); +Index: linux-2.6.24.7-rt21/include/asm-x86/hw_irq_64.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/hw_irq_64.h 2008-10-08 22:22:32.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/hw_irq_64.h 2008-10-08 22:23:51.000000000 -0400 +@@ -118,7 +118,7 @@ void i8254_timer_resume(void); + typedef int vector_irq_t[NR_VECTORS]; + DECLARE_PER_CPU(vector_irq_t, vector_irq); + extern void __setup_vector_irq(int cpu); +-extern spinlock_t vector_lock; ++extern raw_spinlock_t vector_lock; + + /* + * Various low-level irq details needed by irq.c, process.c, +Index: linux-2.6.24.7-rt21/include/asm-x86/io_apic_64.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/io_apic_64.h 2008-10-08 22:22:32.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/io_apic_64.h 2008-10-08 22:23:51.000000000 -0400 +@@ -131,7 +131,7 @@ extern int sis_apic_bug; /* dummy */ + + void enable_NMI_through_LVT0(void); + +-extern spinlock_t i8259A_lock; ++extern raw_spinlock_t i8259A_lock; + + extern int timer_over_8254; + +Index: linux-2.6.24.7-rt21/include/asm-x86/spinlock_64.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/spinlock_64.h 2008-10-08 22:23:40.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/spinlock_64.h 2008-10-08 22:23:51.000000000 -0400 +@@ -160,8 +160,8 @@ static inline void __raw_write_unlock(__ + : "=m" (rw->lock) : : "memory"); + } + +-#define _raw_spin_relax(lock) cpu_relax() +-#define _raw_read_relax(lock) cpu_relax() +-#define _raw_write_relax(lock) cpu_relax() ++#define __raw_spin_relax(lock) cpu_relax() ++#define __raw_read_relax(lock) cpu_relax() ++#define __raw_write_relax(lock) cpu_relax() + + #endif /* __ASM_SPINLOCK_H */ +Index: linux-2.6.24.7-rt21/include/asm-x86/tlbflush_64.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/tlbflush_64.h 2008-10-08 22:22:32.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/tlbflush_64.h 2008-10-08 22:23:51.000000000 -0400 +@@ -8,14 +8,20 @@ + + static inline void __flush_tlb(void) + { ++ preempt_disable(); + write_cr3(read_cr3()); ++ preempt_enable(); + } + + static inline void __flush_tlb_all(void) + { +- unsigned long cr4 = read_cr4(); ++ unsigned long cr4; ++ ++ preempt_disable(); ++ cr4 = read_cr4(); + write_cr4(cr4 & ~X86_CR4_PGE); /* clear PGE */ + write_cr4(cr4); /* write old PGE again and flush TLBs */ ++ preempt_enable(); + } + + #define __flush_tlb_one(addr) \ +Index: linux-2.6.24.7-rt21/include/asm-x86/vgtod.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/vgtod.h 2008-10-08 22:22:32.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/vgtod.h 2008-10-08 22:23:51.000000000 -0400 +@@ -5,7 +5,7 @@ + #include + + struct vsyscall_gtod_data { +- seqlock_t lock; ++ raw_seqlock_t lock; + + /* open coded 'struct timespec' */ + time_t wall_time_sec; --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0073-trace-add-event-markers-arm.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0073-trace-add-event-markers-arm.patch @@ -0,0 +1,26 @@ +--- + arch/arm/kernel/irq.c | 4 ++++ + 1 file changed, 4 insertions(+) + +Index: linux-2.6.24.7-rt21/arch/arm/kernel/irq.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/arm/kernel/irq.c 2008-10-08 22:22:43.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/arm/kernel/irq.c 2008-10-08 22:23:10.000000000 -0400 +@@ -37,6 +37,8 @@ + #include + #include + ++#include ++ + #include + #include + +@@ -113,6 +115,8 @@ asmlinkage void __exception asm_do_IRQ(u + struct pt_regs *old_regs = set_irq_regs(regs); + struct irq_desc *desc = irq_desc + irq; + ++ ftrace_event_irq(irq, user_mode(regs), instruction_pointer(regs)); ++ + /* + * Some hardware gives randomly wrong interrupts. Rather + * than crashing, do something sensible. --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0379-rt-plist-mods.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0379-rt-plist-mods.patch @@ -0,0 +1,113 @@ +Subject: rt: plist_head_splice + +merge-sort two plists together + +Signed-off-by: Peter Zijlstra +--- + include/linux/plist.h | 2 + + lib/plist.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++-- + 2 files changed, 68 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/plist.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/plist.h 2008-10-08 22:23:37.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/plist.h 2008-10-08 22:24:35.000000000 -0400 +@@ -148,6 +148,8 @@ static inline void plist_node_init(struc + extern void plist_add(struct plist_node *node, struct plist_head *head); + extern void plist_del(struct plist_node *node, struct plist_head *head); + ++extern void plist_head_splice(struct plist_head *src, struct plist_head *dst); ++ + /** + * plist_for_each - iterate over the plist + * @pos: the type * to use as a loop counter +Index: linux-2.6.24.7-rt21/lib/plist.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/lib/plist.c 2008-10-08 22:23:37.000000000 -0400 ++++ linux-2.6.24.7-rt21/lib/plist.c 2008-10-08 22:24:35.000000000 -0400 +@@ -66,6 +66,30 @@ static void plist_check_head(struct plis + # define plist_check_head(h) do { } while (0) + #endif + ++static inline struct plist_node *prev_node(struct plist_node *iter) ++{ ++ return list_entry(iter->plist.node_list.prev, struct plist_node, ++ plist.node_list); ++} ++ ++static inline struct plist_node *next_node(struct plist_node *iter) ++{ ++ return list_entry(iter->plist.node_list.next, struct plist_node, ++ plist.node_list); ++} ++ ++static inline struct plist_node *prev_prio(struct plist_node *iter) ++{ ++ return list_entry(iter->plist.prio_list.prev, struct plist_node, ++ plist.prio_list); ++} ++ ++static inline struct plist_node *next_prio(struct plist_node *iter) ++{ ++ return list_entry(iter->plist.prio_list.next, struct plist_node, ++ plist.prio_list); ++} ++ + /** + * plist_add - add @node to @head + * +@@ -83,8 +107,7 @@ void plist_add(struct plist_node *node, + if (node->prio < iter->prio) + goto lt_prio; + else if (node->prio == iter->prio) { +- iter = list_entry(iter->plist.prio_list.next, +- struct plist_node, plist.prio_list); ++ iter = next_prio(iter); + goto eq_prio; + } + } +@@ -118,3 +141,44 @@ void plist_del(struct plist_node *node, + + plist_check_head(head); + } ++ ++void plist_head_splice(struct plist_head *src, struct plist_head *dst) ++{ ++ struct plist_node *src_iter_first, *src_iter_last, *dst_iter; ++ struct plist_node *tail = container_of(dst, struct plist_node, plist); ++ ++ dst_iter = next_prio(tail); ++ ++ while (!plist_head_empty(src) && dst_iter != tail) { ++ src_iter_first = plist_first(src); ++ ++ src_iter_last = next_prio(src_iter_first); ++ src_iter_last = prev_node(src_iter_last); ++ ++ WARN_ON(src_iter_first->prio != src_iter_last->prio); ++ WARN_ON(list_empty(&src_iter_first->plist.prio_list)); ++ ++ while (src_iter_first->prio > dst_iter->prio) { ++ dst_iter = next_prio(dst_iter); ++ if (dst_iter == tail) ++ goto tail; ++ } ++ ++ list_del_init(&src_iter_first->plist.prio_list); ++ ++ if (src_iter_first->prio < dst_iter->prio) { ++ list_add_tail(&src_iter_first->plist.prio_list, ++ &dst_iter->plist.prio_list); ++ } else if (src_iter_first->prio == dst_iter->prio) { ++ dst_iter = next_prio(dst_iter); ++ } else BUG(); ++ ++ list_splice2_tail(&src_iter_first->plist.node_list, ++ &src_iter_last->plist.node_list, ++ &dst_iter->plist.node_list); ++ } ++ ++tail: ++ list_splice_tail_init(&src->prio_list, &dst->prio_list); ++ list_splice_tail_init(&src->node_list, &dst->node_list); ++} --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0224-preempt-realtime-powerpc-b3.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0224-preempt-realtime-powerpc-b3.patch @@ -0,0 +1,47 @@ + + To fix the following runtime warning. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +BUG: using smp_processor_id() in preemptible [00000000] code: init/371 +caller is .pgtable_free_tlb+0x2c/0x14c +Call Trace: +[C00000000FF6B770] [C00000000000FAAC] .show_stack+0x68/0x1b0 (unreliable) +[C00000000FF6B810] [C0000000001F7190] .debug_smp_processor_id+0xc8/0xf8 +[C00000000FF6B8A0] [C00000000002C52C] .pgtable_free_tlb+0x2c/0x14c +[C00000000FF6B940] [C0000000000B6528] .free_pgd_range+0x234/0x3bc +[C00000000FF6BA40] [C0000000000B6AB8] .free_pgtables+0x224/0x260 +[C00000000FF6BB00] [C0000000000B7FE8] .exit_mmap+0x100/0x208 +[C00000000FF6BBC0] [C000000000055FB0] .mmput+0x70/0x12c +[C00000000FF6BC50] [C00000000005B728] .exit_mm+0x150/0x170 +[C00000000FF6BCE0] [C00000000005D80C] .do_exit+0x28c/0x9bc +[C00000000FF6BDA0] [C00000000005DFF0] .sys_exit_group+0x0/0x8 +[C00000000FF6BE30] [C000000000008634] syscall_exit+0x0/0x40 +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + Would it be better to just use raw_smp_processor_id() rather than tlb->cpu? + +Signed-off-by: Tsutomu Owa +-- owa + +--- + arch/powerpc/mm/tlb_64.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/powerpc/mm/tlb_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/mm/tlb_64.c 2008-10-08 22:23:42.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/mm/tlb_64.c 2008-10-08 22:23:54.000000000 -0400 +@@ -91,8 +91,11 @@ static void pte_free_submit(struct pte_f + + void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf) + { +- /* This is safe since tlb_gather_mmu has disabled preemption */ +- cpumask_t local_cpumask = cpumask_of_cpu(smp_processor_id()); ++ /* ++ * This is safe since tlb_gather_mmu has disabled preemption. ++ * tlb->cpu is set by tlb_gather_mmu as well. ++ */ ++ cpumask_t local_cpumask = cpumask_of_cpu(tlb->cpu); + struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur); + + if (atomic_read(&tlb->mm->mm_users) < 2 || --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0238-preempt-realtime-sched-i386.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0238-preempt-realtime-sched-i386.patch @@ -0,0 +1,62 @@ +--- + arch/x86/kernel/entry_32.S | 11 +++++++---- + arch/x86/kernel/process_32.c | 4 +++- + 2 files changed, 10 insertions(+), 5 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/entry_32.S +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/entry_32.S 2008-10-08 22:23:38.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/entry_32.S 2008-10-08 22:23:58.000000000 -0400 +@@ -265,14 +265,18 @@ END(ret_from_exception) + #ifdef CONFIG_PREEMPT + ENTRY(resume_kernel) + DISABLE_INTERRUPTS(CLBR_ANY) ++ cmpl $0, kernel_preemption ++ jz restore_nocheck + cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ? + jnz restore_nocheck + need_resched: + movl TI_flags(%ebp), %ecx # need_resched set ? + testb $_TIF_NEED_RESCHED, %cl +- jz restore_all ++ jz restore_nocheck + testl $IF_MASK,PT_EFLAGS(%esp) # interrupts off (exception path) ? +- jz restore_all ++ jz restore_nocheck ++ DISABLE_INTERRUPTS(CLBR_ANY) ++ + call preempt_schedule_irq + jmp need_resched + END(resume_kernel) +@@ -484,12 +488,11 @@ work_pending: + testl $(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED), %ecx + jz work_notifysig + work_resched: +- call schedule + LOCKDEP_SYS_EXIT + DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt ++ call __schedule + # setting need_resched or sigpending + # between sampling and the iret +- TRACE_IRQS_OFF + movl TI_flags(%ebp), %ecx + andl $_TIF_WORK_MASK, %ecx # is there any work to be done other + # than syscall tracing? +Index: linux-2.6.24.7-rt21/arch/x86/kernel/process_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/process_32.c 2008-10-08 22:23:57.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/process_32.c 2008-10-08 22:23:58.000000000 -0400 +@@ -201,10 +201,12 @@ void cpu_idle(void) + idle(); + start_critical_timings(); + } ++ local_irq_disable(); + tick_nohz_restart_sched_tick(); + __preempt_enable_no_resched(); +- schedule(); ++ __schedule(); + preempt_disable(); ++ local_irq_enable(); + } + } + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0520-cpu-hotplug-cpu-down-vs-preempt-rt_fix.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0520-cpu-hotplug-cpu-down-vs-preempt-rt_fix.patch @@ -0,0 +1,17 @@ +--- + kernel/rcupreempt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/kernel/rcupreempt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rcupreempt.c 2008-10-08 22:25:07.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rcupreempt.c 2008-10-08 22:25:09.000000000 -0400 +@@ -860,7 +860,7 @@ void __devinit rcu_online_cpu_rt(int cpu + + #else /* #ifdef CONFIG_HOTPLUG_CPU */ + +-void rcu_offline_cpu(int cpu) ++void rcu_offline_cpu_rt(int cpu) + { + } + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0364-seqlocks-use-PICK_FUNCTION.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0364-seqlocks-use-PICK_FUNCTION.patch @@ -0,0 +1,316 @@ +From dwalker@mvista.com Wed Sep 26 22:16:38 2007 +Date: Tue, 28 Aug 2007 14:37:51 -0700 +From: Daniel Walker +To: mingo@elte.hu +Cc: mingo@redhat.com, linux-kernel@vger.kernel.org, + linux-rt-users@vger.kernel.org +Subject: [PATCH -rt 3/8] seqlocks: use PICK_FUNCTION + +Replace the old PICK_OP style macros with PICK_FUNCTION. Although, +seqlocks has some alien code, which I also replaced as can be seen +from the line count below. + +Signed-off-by: Daniel Walker + +--- + include/linux/pickop.h | 4 + include/linux/seqlock.h | 235 +++++++++++++++++++++++++++--------------------- + 2 files changed, 135 insertions(+), 104 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/pickop.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/pickop.h 2008-10-08 22:24:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/pickop.h 2008-10-08 22:24:31.000000000 -0400 +@@ -1,10 +1,6 @@ + #ifndef _LINUX_PICKOP_H + #define _LINUX_PICKOP_H + +-#undef TYPE_EQUAL +-#define TYPE_EQUAL(var, type) \ +- __builtin_types_compatible_p(typeof(var), type *) +- + #undef PICK_TYPE_EQUAL + #define PICK_TYPE_EQUAL(var, type) \ + __builtin_types_compatible_p(typeof(var), type) +Index: linux-2.6.24.7-rt21/include/linux/seqlock.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/seqlock.h 2008-10-08 22:23:37.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/seqlock.h 2008-10-08 22:24:31.000000000 -0400 +@@ -90,6 +90,12 @@ static inline void __write_seqlock(seqlo + smp_wmb(); + } + ++static __always_inline unsigned long __write_seqlock_irqsave(seqlock_t *sl) ++{ ++ __write_seqlock(sl); ++ return 0; ++} ++ + static inline void __write_sequnlock(seqlock_t *sl) + { + smp_wmb(); +@@ -97,6 +103,8 @@ static inline void __write_sequnlock(seq + spin_unlock(&sl->lock); + } + ++#define __write_sequnlock_irqrestore(sl, flags) __write_sequnlock(sl) ++ + static inline int __write_tryseqlock(seqlock_t *sl) + { + int ret = spin_trylock(&sl->lock); +@@ -149,6 +157,28 @@ static __always_inline void __write_seql + smp_wmb(); + } + ++static __always_inline unsigned long ++__write_seqlock_irqsave_raw(raw_seqlock_t *sl) ++{ ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ __write_seqlock_raw(sl); ++ return flags; ++} ++ ++static __always_inline void __write_seqlock_irq_raw(raw_seqlock_t *sl) ++{ ++ local_irq_disable(); ++ __write_seqlock_raw(sl); ++} ++ ++static __always_inline void __write_seqlock_bh_raw(raw_seqlock_t *sl) ++{ ++ local_bh_disable(); ++ __write_seqlock_raw(sl); ++} ++ + static __always_inline void __write_sequnlock_raw(raw_seqlock_t *sl) + { + smp_wmb(); +@@ -156,6 +186,27 @@ static __always_inline void __write_sequ + spin_unlock(&sl->lock); + } + ++static __always_inline void ++__write_sequnlock_irqrestore_raw(raw_seqlock_t *sl, unsigned long flags) ++{ ++ __write_sequnlock_raw(sl); ++ local_irq_restore(flags); ++ preempt_check_resched(); ++} ++ ++static __always_inline void __write_sequnlock_irq_raw(raw_seqlock_t *sl) ++{ ++ __write_sequnlock_raw(sl); ++ local_irq_enable(); ++ preempt_check_resched(); ++} ++ ++static __always_inline void __write_sequnlock_bh_raw(raw_seqlock_t *sl) ++{ ++ __write_sequnlock_raw(sl); ++ local_bh_enable(); ++} ++ + static __always_inline int __write_tryseqlock_raw(raw_seqlock_t *sl) + { + int ret = spin_trylock(&sl->lock); +@@ -182,60 +233,93 @@ static __always_inline int __read_seqret + + extern int __bad_seqlock_type(void); + +-#define PICK_SEQOP(op, lock) \ ++/* ++ * PICK_SEQ_OP() is a small redirector to allow less typing of the lock ++ * types raw_seqlock_t, seqlock_t, at the front of the PICK_FUNCTION ++ * macro. ++ */ ++#define PICK_SEQ_OP(...) \ ++ PICK_FUNCTION(raw_seqlock_t *, seqlock_t *, ##__VA_ARGS__) ++#define PICK_SEQ_OP_RET(...) \ ++ PICK_FUNCTION_RET(raw_seqlock_t *, seqlock_t *, ##__VA_ARGS__) ++ ++#define write_seqlock(sl) PICK_SEQ_OP(__write_seqlock_raw, __write_seqlock, sl) ++ ++#define write_sequnlock(sl) \ ++ PICK_SEQ_OP(__write_sequnlock_raw, __write_sequnlock, sl) ++ ++#define write_tryseqlock(sl) \ ++ PICK_SEQ_OP_RET(__write_tryseqlock_raw, __write_tryseqlock, sl) ++ ++#define read_seqbegin(sl) \ ++ PICK_SEQ_OP_RET(__read_seqbegin_raw, __read_seqbegin, sl) ++ ++#define read_seqretry(sl, iv) \ ++ PICK_SEQ_OP_RET(__read_seqretry_raw, __read_seqretry, sl, iv) ++ ++#define write_seqlock_irqsave(lock, flags) \ + do { \ +- if (TYPE_EQUAL((lock), raw_seqlock_t)) \ +- op##_raw((raw_seqlock_t *)(lock)); \ +- else if (TYPE_EQUAL((lock), seqlock_t)) \ +- op((seqlock_t *)(lock)); \ +- else __bad_seqlock_type(); \ ++ flags = PICK_SEQ_OP_RET(__write_seqlock_irqsave_raw, \ ++ __write_seqlock_irqsave, lock); \ + } while (0) + +-#define PICK_SEQOP_RET(op, lock) \ +-({ \ +- unsigned long __ret; \ +- \ +- if (TYPE_EQUAL((lock), raw_seqlock_t)) \ +- __ret = op##_raw((raw_seqlock_t *)(lock)); \ +- else if (TYPE_EQUAL((lock), seqlock_t)) \ +- __ret = op((seqlock_t *)(lock)); \ +- else __ret = __bad_seqlock_type(); \ +- \ +- __ret; \ +-}) +- +-#define PICK_SEQOP_CONST_RET(op, lock) \ +-({ \ +- unsigned long __ret; \ +- \ +- if (TYPE_EQUAL((lock), raw_seqlock_t)) \ +- __ret = op##_raw((const raw_seqlock_t *)(lock));\ +- else if (TYPE_EQUAL((lock), seqlock_t)) \ +- __ret = op((seqlock_t *)(lock)); \ +- else __ret = __bad_seqlock_type(); \ +- \ +- __ret; \ +-}) +- +-#define PICK_SEQOP2_CONST_RET(op, lock, arg) \ +- ({ \ +- unsigned long __ret; \ +- \ +- if (TYPE_EQUAL((lock), raw_seqlock_t)) \ +- __ret = op##_raw((const raw_seqlock_t *)(lock), (arg)); \ +- else if (TYPE_EQUAL((lock), seqlock_t)) \ +- __ret = op((seqlock_t *)(lock), (arg)); \ +- else __ret = __bad_seqlock_type(); \ +- \ +- __ret; \ +-}) +- +- +-#define write_seqlock(sl) PICK_SEQOP(__write_seqlock, sl) +-#define write_sequnlock(sl) PICK_SEQOP(__write_sequnlock, sl) +-#define write_tryseqlock(sl) PICK_SEQOP_RET(__write_tryseqlock, sl) +-#define read_seqbegin(sl) PICK_SEQOP_CONST_RET(__read_seqbegin, sl) +-#define read_seqretry(sl, iv) PICK_SEQOP2_CONST_RET(__read_seqretry, sl, iv) ++#define write_seqlock_irq(lock) \ ++ PICK_SEQ_OP(__write_seqlock_irq_raw, __write_seqlock, lock) ++ ++#define write_seqlock_bh(lock) \ ++ PICK_SEQ_OP(__write_seqlock_bh_raw, __write_seqlock, lock) ++ ++#define write_sequnlock_irqrestore(lock, flags) \ ++ PICK_SEQ_OP(__write_sequnlock_irqrestore_raw, \ ++ __write_sequnlock_irqrestore, lock, flags) ++ ++#define write_sequnlock_bh(lock) \ ++ PICK_SEQ_OP(__write_sequnlock_bh_raw, __write_sequnlock, lock) ++ ++#define write_sequnlock_irq(lock) \ ++ PICK_SEQ_OP(__write_sequnlock_irq_raw, __write_sequnlock, lock) ++ ++static __always_inline ++unsigned long __read_seqbegin_irqsave_raw(raw_seqlock_t *sl) ++{ ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ __read_seqbegin_raw(sl); ++ return flags; ++} ++ ++static __always_inline unsigned long __read_seqbegin_irqsave(seqlock_t *sl) ++{ ++ __read_seqbegin(sl); ++ return 0; ++} ++ ++#define read_seqbegin_irqsave(lock, flags) \ ++do { \ ++ flags = PICK_SEQ_OP_RET(__read_seqbegin_irqsave_raw, \ ++ __read_seqbegin_irqsave, lock); \ ++} while (0) ++ ++static __always_inline int ++__read_seqretry_irqrestore(seqlock_t *sl, unsigned iv, unsigned long flags) ++{ ++ return __read_seqretry(sl, iv); ++} ++ ++static __always_inline int ++__read_seqretry_irqrestore_raw(raw_seqlock_t *sl, unsigned iv, ++ unsigned long flags) ++{ ++ int ret = read_seqretry(sl, iv); ++ local_irq_restore(flags); ++ preempt_check_resched(); ++ return ret; ++} ++ ++#define read_seqretry_irqrestore(lock, iv, flags) \ ++ PICK_SEQ_OP_RET(__read_seqretry_irqrestore_raw, \ ++ __read_seqretry_irqrestore, lock, iv, flags) + + /* + * Version using sequence counter only. +@@ -286,53 +370,4 @@ static inline void write_seqcount_end(se + smp_wmb(); + s->sequence++; + } +- +-#define PICK_IRQOP(op, lock) \ +-do { \ +- if (TYPE_EQUAL((lock), raw_seqlock_t)) \ +- op(); \ +- else if (TYPE_EQUAL((lock), seqlock_t)) \ +- { /* nothing */ } \ +- else __bad_seqlock_type(); \ +-} while (0) +- +-#define PICK_IRQOP2(op, arg, lock) \ +-do { \ +- if (TYPE_EQUAL((lock), raw_seqlock_t)) \ +- op(arg); \ +- else if (TYPE_EQUAL(lock, seqlock_t)) \ +- { /* nothing */ } \ +- else __bad_seqlock_type(); \ +-} while (0) +- +- +- +-/* +- * Possible sw/hw IRQ protected versions of the interfaces. +- */ +-#define write_seqlock_irqsave(lock, flags) \ +- do { PICK_IRQOP2(local_irq_save, flags, lock); write_seqlock(lock); } while (0) +-#define write_seqlock_irq(lock) \ +- do { PICK_IRQOP(local_irq_disable, lock); write_seqlock(lock); } while (0) +-#define write_seqlock_bh(lock) \ +- do { PICK_IRQOP(local_bh_disable, lock); write_seqlock(lock); } while (0) +- +-#define write_sequnlock_irqrestore(lock, flags) \ +- do { write_sequnlock(lock); PICK_IRQOP2(local_irq_restore, flags, lock); preempt_check_resched(); } while(0) +-#define write_sequnlock_irq(lock) \ +- do { write_sequnlock(lock); PICK_IRQOP(local_irq_enable, lock); preempt_check_resched(); } while(0) +-#define write_sequnlock_bh(lock) \ +- do { write_sequnlock(lock); PICK_IRQOP(local_bh_enable, lock); } while(0) +- +-#define read_seqbegin_irqsave(lock, flags) \ +- ({ PICK_IRQOP2(local_irq_save, flags, lock); read_seqbegin(lock); }) +- +-#define read_seqretry_irqrestore(lock, iv, flags) \ +- ({ \ +- int ret = read_seqretry(lock, iv); \ +- PICK_IRQOP2(local_irq_restore, flags, lock); \ +- preempt_check_resched(); \ +- ret; \ +- }) +- + #endif /* __LINUX_SEQLOCK_H */ --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0293-radix-tree-concurrent.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0293-radix-tree-concurrent.patch @@ -0,0 +1,699 @@ +Subject: radix-tree: concurrent write side support + +Provide support for concurrent write side operations without changing the API +for all current uses. + +Concurrency is realized by means of two locking models; the simple one is +ladder locking, the more complex one is path locking. + +Ladder locking is like walking down a ladder, you place your foot on a spoke +below the one your other foot finds support etc.. There is no walking with both +feet in the air. Likewise with walking a tree, you lock a node below the +current node before releasing it. + +This allows other modifying operations to start as soon as you release the +lock on the root node and even complete before you if they walk another path +downward. + +The modifying operations: insert, lookup_slot and set_tag, use this simple +method. + +The more complex path locking method is needed for operations that need to +walk upwards again after they walked down, those are: tag_clear and delete. + +These lock their whole path downwards and release whole sections at points +where it can be determined the walk upwards will stop, thus also allowing +concurrency. + +Finding the conditions for the terminated walk upwards while doing the downward +walk is the 'interesting' part of this approach. + +The remaining - unmodified - operations will have exclusive locking (since +they're unmodified, they never move the lock downwards from the root node). + +The API for this looks like: + + DEFINE_RADIX_TREE_CONTEXT(ctx, &mapping->page_tree) + + radix_tree_lock(&ctx) + ... do _1_ modifying operation ... + radix_tree_unlock(&ctx) + +Note that before the radix operation the root node is held and will provide +exclusive locking, after the operation the held lock might only be enough to +protect a single item. + +Signed-off-by: Peter Zijlstra +--- + include/linux/radix-tree.h | 77 +++++++++++- + init/Kconfig | 4 + lib/radix-tree.c | 283 ++++++++++++++++++++++++++++++++++++--------- + 3 files changed, 302 insertions(+), 62 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/radix-tree.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/radix-tree.h 2008-10-08 22:24:12.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/radix-tree.h 2008-10-08 22:24:14.000000000 -0400 +@@ -62,23 +62,65 @@ struct radix_tree_root { + unsigned int height; + gfp_t gfp_mask; + struct radix_tree_node *rnode; ++ spinlock_t lock; + }; + + #define RADIX_TREE_INIT(mask) { \ + .height = 0, \ + .gfp_mask = (mask), \ + .rnode = NULL, \ ++ .lock = __SPIN_LOCK_UNLOCKED(radix_tree_root.lock), \ + } + + #define RADIX_TREE(name, mask) \ + struct radix_tree_root name = RADIX_TREE_INIT(mask) + +-#define INIT_RADIX_TREE(root, mask) \ +-do { \ +- (root)->height = 0; \ +- (root)->gfp_mask = (mask); \ +- (root)->rnode = NULL; \ +-} while (0) ++static inline void INIT_RADIX_TREE(struct radix_tree_root *root, gfp_t gfp_mask) ++{ ++ root->height = 0; ++ root->gfp_mask = gfp_mask; ++ root->rnode = NULL; ++ spin_lock_init(&root->lock); ++} ++ ++struct radix_tree_context { ++ struct radix_tree_root *tree; ++ struct radix_tree_root *root; ++#ifdef CONFIG_RADIX_TREE_CONCURRENT ++ spinlock_t *locked; ++#endif ++}; ++ ++#ifdef CONFIG_RADIX_TREE_CONCURRENT ++#define RADIX_CONTEXT_ROOT(context) \ ++ ((struct radix_tree_root *)(((unsigned long)context) + 1)) ++ ++#define __RADIX_TREE_CONTEXT_INIT(context, _tree) \ ++ .tree = RADIX_CONTEXT_ROOT(&context), \ ++ .locked = NULL, ++#else ++#define __RADIX_TREE_CONTEXT_INIT(context, _tree) \ ++ .tree = (_tree), ++#endif ++ ++#define DEFINE_RADIX_TREE_CONTEXT(context, _tree) \ ++ struct radix_tree_context context = { \ ++ .root = (_tree), \ ++ __RADIX_TREE_CONTEXT_INIT(context, _tree) \ ++ } ++ ++static inline void ++init_radix_tree_context(struct radix_tree_context *ctx, ++ struct radix_tree_root *root) ++{ ++ ctx->root = root; ++#ifdef CONFIG_RADIX_TREE_CONCURRENT ++ ctx->tree = RADIX_CONTEXT_ROOT(ctx); ++ ctx->locked = NULL; ++#else ++ ctx->tree = root; ++#endif ++} + + /** + * Radix-tree synchronization +@@ -155,6 +197,29 @@ static inline void radix_tree_replace_sl + rcu_assign_pointer(*pslot, item); + } + ++static inline void radix_tree_lock(struct radix_tree_context *context) ++{ ++ struct radix_tree_root *root = context->root; ++ rcu_read_lock(); ++ spin_lock(&root->lock); ++#ifdef CONFIG_RADIX_TREE_CONCURRENT ++ BUG_ON(context->locked); ++ context->locked = &root->lock; ++#endif ++} ++ ++static inline void radix_tree_unlock(struct radix_tree_context *context) ++{ ++#ifdef CONFIG_RADIX_TREE_CONCURRENT ++ BUG_ON(!context->locked); ++ spin_unlock(context->locked); ++ context->locked = NULL; ++#else ++ spin_unlock(&context->root->lock); ++#endif ++ rcu_read_unlock(); ++} ++ + int radix_tree_insert(struct radix_tree_root *, unsigned long, void *); + void *radix_tree_lookup(struct radix_tree_root *, unsigned long); + void **radix_tree_lookup_slot(struct radix_tree_root *, unsigned long); +Index: linux-2.6.24.7-rt21/init/Kconfig +=================================================================== +--- linux-2.6.24.7-rt21.orig/init/Kconfig 2008-10-08 22:22:25.000000000 -0400 ++++ linux-2.6.24.7-rt21/init/Kconfig 2008-10-08 22:24:14.000000000 -0400 +@@ -435,6 +435,10 @@ config CC_OPTIMIZE_FOR_SIZE + config SYSCTL + bool + ++config RADIX_TREE_CONCURRENT ++ bool "Enable concurrent radix tree operations (EXPERIMENTAL)" ++ default y if SMP ++ + menuconfig EMBEDDED + bool "Configure standard kernel features (for small systems)" + help +Index: linux-2.6.24.7-rt21/lib/radix-tree.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/lib/radix-tree.c 2008-10-08 22:24:12.000000000 -0400 ++++ linux-2.6.24.7-rt21/lib/radix-tree.c 2008-10-08 22:24:14.000000000 -0400 +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + + + #ifdef __KERNEL__ +@@ -52,11 +53,17 @@ struct radix_tree_node { + struct rcu_head rcu_head; + void *slots[RADIX_TREE_MAP_SIZE]; + unsigned long tags[RADIX_TREE_MAX_TAGS][RADIX_TREE_TAG_LONGS]; ++#ifdef CONFIG_RADIX_TREE_CONCURRENT ++ spinlock_t lock; ++#endif + }; + + struct radix_tree_path { + struct radix_tree_node *node; + int offset; ++#ifdef CONFIG_RADIX_TREE_CONCURRENT ++ spinlock_t *locked; ++#endif + }; + + #define RADIX_TREE_INDEX_BITS (8 /* CHAR_BIT */ * sizeof(unsigned long)) +@@ -69,6 +76,10 @@ struct radix_tree_path { + */ + static unsigned long height_to_maxindex[RADIX_TREE_MAX_PATH + 1] __read_mostly; + ++#ifdef CONFIG_RADIX_TREE_CONCURRENT ++static struct lock_class_key radix_node_class[RADIX_TREE_MAX_PATH]; ++#endif ++ + /* + * Radix tree node cache. + */ +@@ -93,7 +104,7 @@ static inline gfp_t root_gfp_mask(struct + * that the caller has pinned this thread of control to the current CPU. + */ + static struct radix_tree_node * +-radix_tree_node_alloc(struct radix_tree_root *root) ++radix_tree_node_alloc(struct radix_tree_root *root, int height) + { + struct radix_tree_node *ret; + gfp_t gfp_mask = root_gfp_mask(root); +@@ -112,6 +123,11 @@ radix_tree_node_alloc(struct radix_tree_ + put_cpu_var(radix_tree_preloads); + } + BUG_ON(radix_tree_is_indirect_ptr(ret)); ++#ifdef CONFIG_RADIX_TREE_CONCURRENT ++ spin_lock_init(&ret->lock); ++ lockdep_set_class(&ret->lock, &radix_node_class[height]); ++#endif ++ ret->height = height; + return ret; + } + +@@ -218,6 +234,22 @@ static inline int any_tag_set(struct rad + return 0; + } + ++static inline int any_tag_set_but(struct radix_tree_node *node, ++ unsigned int tag, int offset) ++{ ++ int idx; ++ int offset_idx = offset / BITS_PER_LONG; ++ unsigned long offset_mask = ~(1UL << (offset % BITS_PER_LONG)); ++ for (idx = 0; idx < RADIX_TREE_TAG_LONGS; idx++) { ++ unsigned long mask = ~0UL; ++ if (idx == offset_idx) ++ mask = offset_mask; ++ if (node->tags[tag][idx] & mask) ++ return 1; ++ } ++ return 0; ++} ++ + /* + * Return the maximum key which can be store into a + * radix tree with height HEIGHT. +@@ -247,8 +279,8 @@ static int radix_tree_extend(struct radi + } + + do { +- unsigned int newheight; +- if (!(node = radix_tree_node_alloc(root))) ++ unsigned int newheight = root->height + 1; ++ if (!(node = radix_tree_node_alloc(root, newheight))) + return -ENOMEM; + + /* Increase the height. */ +@@ -260,8 +292,6 @@ static int radix_tree_extend(struct radi + tag_set(node, tag, 0); + } + +- newheight = root->height+1; +- node->height = newheight; + node->count = 1; + node = radix_tree_ptr_to_indirect(node); + rcu_assign_pointer(root->rnode, node); +@@ -271,6 +301,80 @@ out: + return 0; + } + ++#ifdef CONFIG_RADIX_TREE_CONCURRENT ++static inline struct radix_tree_context * ++radix_tree_get_context(struct radix_tree_root **rootp) ++{ ++ struct radix_tree_context *context = NULL; ++ unsigned long addr = (unsigned long)*rootp; ++ ++ if (addr & 1) { ++ context = (struct radix_tree_context *)(addr - 1); ++ *rootp = context->root; ++ } ++ ++ return context; ++} ++ ++#define RADIX_TREE_CONTEXT(context, root) \ ++ struct radix_tree_context *context = \ ++ radix_tree_get_context(&root) ++ ++static inline spinlock_t *radix_node_lock(struct radix_tree_root *root, ++ struct radix_tree_node *node) ++{ ++ spinlock_t *locked = &node->lock; ++ spin_lock(locked); ++ return locked; ++} ++ ++static inline void radix_ladder_lock(struct radix_tree_context *context, ++ struct radix_tree_node *node) ++{ ++ if (context) { ++ struct radix_tree_root *root = context->root; ++ spinlock_t *locked = radix_node_lock(root, node); ++ if (locked) { ++ spin_unlock(context->locked); ++ context->locked = locked; ++ } ++ } ++} ++ ++static inline void radix_path_init(struct radix_tree_context *context, ++ struct radix_tree_path *pathp) ++{ ++ pathp->locked = context ? context->locked : NULL; ++} ++ ++static inline void radix_path_lock(struct radix_tree_context *context, ++ struct radix_tree_path *pathp, struct radix_tree_node *node) ++{ ++ if (context) { ++ struct radix_tree_root *root = context->root; ++ spinlock_t *locked = radix_node_lock(root, node); ++ if (locked) ++ context->locked = locked; ++ pathp->locked = locked; ++ } else ++ pathp->locked = NULL; ++} ++ ++static inline void radix_path_unlock(struct radix_tree_context *context, ++ struct radix_tree_path *punlock) ++{ ++ if (context && punlock->locked && ++ context->locked != punlock->locked) ++ spin_unlock(punlock->locked); ++} ++#else ++#define RADIX_TREE_CONTEXT(context, root) do { } while (0) ++#define radix_ladder_lock(context, node) do { } while (0) ++#define radix_path_init(context, pathp) do { } while (0) ++#define radix_path_lock(context, pathp, node) do { } while (0) ++#define radix_path_unlock(context, punlock) do { } while (0) ++#endif ++ + /** + * radix_tree_insert - insert into a radix tree + * @root: radix tree root +@@ -286,6 +390,8 @@ int radix_tree_insert(struct radix_tree_ + unsigned int height, shift; + int offset; + int error; ++ int tag; ++ RADIX_TREE_CONTEXT(context, root); + + BUG_ON(radix_tree_is_indirect_ptr(item)); + +@@ -305,9 +411,8 @@ int radix_tree_insert(struct radix_tree_ + while (height > 0) { + if (slot == NULL) { + /* Have to add a child node. */ +- if (!(slot = radix_tree_node_alloc(root))) ++ if (!(slot = radix_tree_node_alloc(root, height))) + return -ENOMEM; +- slot->height = height; + if (node) { + rcu_assign_pointer(node->slots[offset], slot); + node->count++; +@@ -319,6 +424,9 @@ int radix_tree_insert(struct radix_tree_ + /* Go a level down */ + offset = (index >> shift) & RADIX_TREE_MAP_MASK; + node = slot; ++ ++ radix_ladder_lock(context, node); ++ + slot = node->slots[offset]; + shift -= RADIX_TREE_MAP_SHIFT; + height--; +@@ -330,12 +438,12 @@ int radix_tree_insert(struct radix_tree_ + if (node) { + node->count++; + rcu_assign_pointer(node->slots[offset], item); +- BUG_ON(tag_get(node, 0, offset)); +- BUG_ON(tag_get(node, 1, offset)); ++ for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) ++ BUG_ON(tag_get(node, tag, offset)); + } else { + rcu_assign_pointer(root->rnode, item); +- BUG_ON(root_tag_get(root, 0)); +- BUG_ON(root_tag_get(root, 1)); ++ for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) ++ BUG_ON(root_tag_get(root, tag)); + } + + return 0; +@@ -359,6 +467,7 @@ void **radix_tree_lookup_slot(struct rad + { + unsigned int height, shift; + struct radix_tree_node *node, **slot; ++ RADIX_TREE_CONTEXT(context, root); + + node = rcu_dereference(root->rnode); + if (node == NULL) +@@ -384,6 +493,8 @@ void **radix_tree_lookup_slot(struct rad + if (node == NULL) + return NULL; + ++ radix_ladder_lock(context, node); ++ + shift -= RADIX_TREE_MAP_SHIFT; + height--; + } while (height > 0); +@@ -459,6 +570,7 @@ void *radix_tree_tag_set(struct radix_tr + { + unsigned int height, shift; + struct radix_tree_node *slot; ++ RADIX_TREE_CONTEXT(context, root); + + height = root->height; + BUG_ON(index > radix_tree_maxindex(height)); +@@ -466,9 +578,15 @@ void *radix_tree_tag_set(struct radix_tr + slot = radix_tree_indirect_to_ptr(root->rnode); + shift = (height - 1) * RADIX_TREE_MAP_SHIFT; + ++ /* set the root's tag bit */ ++ if (slot && !root_tag_get(root, tag)) ++ root_tag_set(root, tag); ++ + while (height > 0) { + int offset; + ++ radix_ladder_lock(context, slot); ++ + offset = (index >> shift) & RADIX_TREE_MAP_MASK; + if (!tag_get(slot, tag, offset)) + tag_set(slot, tag, offset); +@@ -478,14 +596,24 @@ void *radix_tree_tag_set(struct radix_tr + height--; + } + +- /* set the root's tag bit */ +- if (slot && !root_tag_get(root, tag)) +- root_tag_set(root, tag); +- + return slot; + } + EXPORT_SYMBOL(radix_tree_tag_set); + ++/* ++ * the change can never propagate upwards from here. ++ */ ++static inline int radix_tree_unlock_tag(struct radix_tree_root *root, ++ struct radix_tree_path *pathp, int tag) ++{ ++ int this, other; ++ ++ this = tag_get(pathp->node, tag, pathp->offset); ++ other = any_tag_set_but(pathp->node, tag, pathp->offset); ++ ++ return !this || other; ++} ++ + /** + * radix_tree_tag_clear - clear a tag on a radix tree node + * @root: radix tree root +@@ -508,15 +636,19 @@ void *radix_tree_tag_clear(struct radix_ + * since the "list" is null terminated. + */ + struct radix_tree_path path[RADIX_TREE_MAX_PATH + 1], *pathp = path; ++ struct radix_tree_path *punlock = path, *piter; + struct radix_tree_node *slot = NULL; + unsigned int height, shift; ++ RADIX_TREE_CONTEXT(context, root); ++ ++ pathp->node = NULL; ++ radix_path_init(context, pathp); + + height = root->height; + if (index > radix_tree_maxindex(height)) + goto out; + + shift = (height - 1) * RADIX_TREE_MAP_SHIFT; +- pathp->node = NULL; + slot = radix_tree_indirect_to_ptr(root->rnode); + + while (height > 0) { +@@ -526,10 +658,17 @@ void *radix_tree_tag_clear(struct radix_ + goto out; + + offset = (index >> shift) & RADIX_TREE_MAP_MASK; +- pathp[1].offset = offset; +- pathp[1].node = slot; +- slot = slot->slots[offset]; + pathp++; ++ pathp->offset = offset; ++ pathp->node = slot; ++ radix_path_lock(context, pathp, slot); ++ ++ if (radix_tree_unlock_tag(root, pathp, tag)) { ++ for (; punlock < pathp; punlock++) ++ radix_path_unlock(context, punlock); ++ } ++ ++ slot = slot->slots[offset]; + shift -= RADIX_TREE_MAP_SHIFT; + height--; + } +@@ -537,20 +676,22 @@ void *radix_tree_tag_clear(struct radix_ + if (slot == NULL) + goto out; + +- while (pathp->node) { +- if (!tag_get(pathp->node, tag, pathp->offset)) +- goto out; +- tag_clear(pathp->node, tag, pathp->offset); +- if (any_tag_set(pathp->node, tag)) +- goto out; +- pathp--; ++ for (piter = pathp; piter >= punlock; piter--) { ++ if (piter->node) { ++ if (!tag_get(piter->node, tag, piter->offset)) ++ break; ++ tag_clear(piter->node, tag, piter->offset); ++ if (any_tag_set(piter->node, tag)) ++ break; ++ } else { ++ if (root_tag_get(root, tag)) ++ root_tag_clear(root, tag); ++ } + } + +- /* clear the root's tag bit */ +- if (root_tag_get(root, tag)) +- root_tag_clear(root, tag); +- + out: ++ for (; punlock < pathp; punlock++) ++ radix_path_unlock(context, punlock); + return slot; + } + EXPORT_SYMBOL(radix_tree_tag_clear); +@@ -1039,6 +1180,7 @@ static inline void radix_tree_shrink(str + while (root->height > 0) { + struct radix_tree_node *to_free = root->rnode; + void *newptr; ++ int tag; + + BUG_ON(!radix_tree_is_indirect_ptr(to_free)); + to_free = radix_tree_indirect_to_ptr(to_free); +@@ -1065,14 +1207,29 @@ static inline void radix_tree_shrink(str + root->rnode = newptr; + root->height--; + /* must only free zeroed nodes into the slab */ +- tag_clear(to_free, 0, 0); +- tag_clear(to_free, 1, 0); ++ for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) ++ tag_clear(to_free, tag, 0); + to_free->slots[0] = NULL; + to_free->count = 0; +- radix_tree_node_free(to_free); + } + } + ++static inline int radix_tree_unlock_all(struct radix_tree_root *root, ++ struct radix_tree_path *pathp) ++{ ++ int tag; ++ int unlock = 1; ++ ++ for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) { ++ if (!radix_tree_unlock_tag(root, pathp, tag)) { ++ unlock = 0; ++ break; ++ } ++ } ++ ++ return unlock; ++} ++ + /** + * radix_tree_delete - delete an item from a radix tree + * @root: radix tree root +@@ -1089,11 +1246,15 @@ void *radix_tree_delete(struct radix_tre + * since the "list" is null terminated. + */ + struct radix_tree_path path[RADIX_TREE_MAX_PATH + 1], *pathp = path; ++ struct radix_tree_path *punlock = path, *piter; + struct radix_tree_node *slot = NULL; +- struct radix_tree_node *to_free; + unsigned int height, shift; + int tag; + int offset; ++ RADIX_TREE_CONTEXT(context, root); ++ ++ pathp->node = NULL; ++ radix_path_init(context, pathp); + + height = root->height; + if (index > radix_tree_maxindex(height)) +@@ -1108,7 +1269,6 @@ void *radix_tree_delete(struct radix_tre + slot = radix_tree_indirect_to_ptr(slot); + + shift = (height - 1) * RADIX_TREE_MAP_SHIFT; +- pathp->node = NULL; + + do { + if (slot == NULL) +@@ -1118,6 +1278,13 @@ void *radix_tree_delete(struct radix_tre + offset = (index >> shift) & RADIX_TREE_MAP_MASK; + pathp->offset = offset; + pathp->node = slot; ++ radix_path_lock(context, pathp, slot); ++ ++ if (slot->count > 2 && radix_tree_unlock_all(root, pathp)) { ++ for (; punlock < pathp; punlock++) ++ radix_path_unlock(context, punlock); ++ } ++ + slot = slot->slots[offset]; + shift -= RADIX_TREE_MAP_SHIFT; + height--; +@@ -1130,41 +1297,45 @@ void *radix_tree_delete(struct radix_tre + * Clear all tags associated with the just-deleted item + */ + for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) { +- if (tag_get(pathp->node, tag, pathp->offset)) +- radix_tree_tag_clear(root, index, tag); ++ for (piter = pathp; piter >= punlock; piter--) { ++ if (piter->node) { ++ if (!tag_get(piter->node, tag, piter->offset)) ++ break; ++ tag_clear(piter->node, tag, piter->offset); ++ if (any_tag_set(piter->node, tag)) ++ break; ++ } else { ++ if (root_tag_get(root, tag)) ++ root_tag_clear(root, tag); ++ } ++ } + } + +- to_free = NULL; +- /* Now free the nodes we do not need anymore */ +- while (pathp->node) { +- pathp->node->slots[pathp->offset] = NULL; +- pathp->node->count--; +- /* +- * Queue the node for deferred freeing after the +- * last reference to it disappears (set NULL, above). +- */ +- if (to_free) +- radix_tree_node_free(to_free); ++ /* Now unhook the nodes we do not need anymore */ ++ for (piter = pathp; piter >= punlock && piter->node; piter--) { ++ piter->node->slots[piter->offset] = NULL; ++ piter->node->count--; + +- if (pathp->node->count) { +- if (pathp->node == ++ if (piter->node->count) { ++ if (piter->node == + radix_tree_indirect_to_ptr(root->rnode)) + radix_tree_shrink(root); + goto out; + } ++ } + +- /* Node with zero slots in use so free it */ +- to_free = pathp->node; +- pathp--; ++ BUG_ON(piter->node); + +- } + root_tag_clear_all(root); + root->height = 0; + root->rnode = NULL; +- if (to_free) +- radix_tree_node_free(to_free); + + out: ++ for (; punlock <= pathp; punlock++) { ++ radix_path_unlock(context, punlock); ++ if (punlock->node && punlock->node->count == 0) ++ radix_tree_node_free(punlock->node); ++ } + return slot; + } + EXPORT_SYMBOL(radix_tree_delete); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0194-tasklet-fix-preemption-race.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0194-tasklet-fix-preemption-race.patch @@ -0,0 +1,103 @@ +From johnstul@us.ibm.com Wed Jun 6 04:17:34 2007 +Return-Path: +Received: from e3.ny.us.ibm.com (e3.ny.us.ibm.com [32.97.182.143]) (using + TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate + requested) by mail.tglx.de (Postfix) with ESMTP id 1CCC065C065 for + ; Wed, 6 Jun 2007 04:17:34 +0200 (CEST) +Received: from d01relay04.pok.ibm.com (d01relay04.pok.ibm.com + [9.56.227.236]) by e3.ny.us.ibm.com (8.13.8/8.13.8) with ESMTP id + l561EvIT011411 for ; Tue, 5 Jun 2007 21:14:57 -0400 +Received: from d01av04.pok.ibm.com (d01av04.pok.ibm.com [9.56.224.64]) by + d01relay04.pok.ibm.com (8.13.8/8.13.8/NCO v8.3) with ESMTP id + l562HUG6545736 for ; Tue, 5 Jun 2007 22:17:30 -0400 +Received: from d01av04.pok.ibm.com (loopback [127.0.0.1]) by + d01av04.pok.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id l562HUu0027167 + for ; Tue, 5 Jun 2007 22:17:30 -0400 +Received: from [9.47.21.16] (cog.beaverton.ibm.com [9.47.21.16]) by + d01av04.pok.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id + l562HTkh027139; Tue, 5 Jun 2007 22:17:29 -0400 +Subject: [PATCH -rt] Fix TASKLET_STATE_SCHED WARN_ON() +From: john stultz +To: Ingo Molnar +Cc: Thomas Gleixner , Steven Rostedt , "Paul E. McKenney" , lkml +Content-Type: text/plain +Date: Tue, 05 Jun 2007 19:17:23 -0700 +Message-Id: <1181096244.6018.20.camel@localhost> +Mime-Version: 1.0 +X-Mailer: Evolution 2.10.1 +X-Evolution-Source: imap://tglx%40linutronix.de@localhost:8993/ +Content-Transfer-Encoding: 8bit + +Hey Ingo, + So we've been seeing the following trace fairly frequently on our SMP +boxes when running kernbench: + +BUG: at kernel/softirq.c:639 __tasklet_action() + +Call Trace: + [] dump_trace+0xaa/0x32a + [] show_trace+0x41/0x5c + [] dump_stack+0x15/0x17 + [] __tasklet_action+0xdf/0x12e + [] tasklet_action+0x27/0x29 + [] ksoftirqd+0x16c/0x271 + [] kthread+0xf5/0x128 + [] child_rip+0xa/0x12 + + +Paul also pointed this out awhile back: http://lkml.org/lkml/2007/2/25/1 + + +Anyway, I think I finally found the issue. Its a bit hard to explain, +but the idea is while __tasklet_action is running the tasklet function +on CPU1, if a call to tasklet_schedule() on CPU2 is made, and if right +after we mark the TASKLET_STATE_SCHED bit we are preempted, +__tasklet_action on CPU1 might be able to re-run the function, clear the +bit and unlock the tasklet before CPU2 enters __tasklet_common_schedule. +Once __tasklet_common_schedule locks the tasklet, we will add the +tasklet to the list with the TASKLET_STATE_SCHED *unset*. + +I've verified this race occurs w/ a WARN_ON in +__tasklet_common_schedule(). + + +This fix avoids this race by making sure *after* we've locked the +tasklet that the STATE_SCHED bit is set before adding it to the list. + +Does it look ok to you? + +thanks +-john + +Signed-off-by: John Stultz + +--- + kernel/softirq.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/softirq.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/softirq.c 2008-10-08 22:23:45.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/softirq.c 2008-10-08 22:23:45.000000000 -0400 +@@ -459,10 +459,17 @@ static void inline + __tasklet_common_schedule(struct tasklet_struct *t, struct tasklet_head *head, unsigned int nr) + { + if (tasklet_trylock(t)) { +- WARN_ON(t->next != NULL); +- t->next = head->list; +- head->list = t; +- raise_softirq_irqoff(nr); ++ /* We may have been preempted before tasklet_trylock ++ * and __tasklet_action may have already run. ++ * So double check the sched bit while the takslet ++ * is locked before adding it to the list. ++ */ ++ if (test_bit(TASKLET_STATE_SCHED, &t->state)) { ++ WARN_ON(t->next != NULL); ++ t->next = head->list; ++ head->list = t; ++ raise_softirq_irqoff(nr); ++ } + tasklet_unlock(t); + } + } --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0236-preempt-realtime-sched.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0236-preempt-realtime-sched.patch @@ -0,0 +1,1008 @@ +--- + include/linux/sched.h | 47 ++++++ + kernel/sched.c | 375 +++++++++++++++++++++++++++++++++++++++++++------- + kernel/sched_rt.c | 60 +++++++- + 3 files changed, 431 insertions(+), 51 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/sched.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/sched.h 2008-10-08 22:23:46.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/sched.h 2008-10-08 22:23:58.000000000 -0400 +@@ -91,6 +91,16 @@ struct sched_param { + + #include + ++#ifdef CONFIG_PREEMPT ++extern int kernel_preemption; ++#else ++# define kernel_preemption 0 ++#endif ++#ifdef CONFIG_PREEMPT_VOLUNTARY ++extern int voluntary_preemption; ++#else ++# define voluntary_preemption 0 ++#endif + #ifdef CONFIG_PREEMPT_SOFTIRQS + extern int softirq_preemption; + #else +@@ -200,6 +210,28 @@ extern struct semaphore kernel_sem; + #define set_task_state(tsk, state_value) \ + set_mb((tsk)->state, (state_value)) + ++// #define PREEMPT_DIRECT ++ ++#ifdef CONFIG_X86_LOCAL_APIC ++extern void nmi_show_all_regs(void); ++#else ++# define nmi_show_all_regs() do { } while (0) ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct exec_domain; ++ + /* + * set_current_state() includes a barrier so that the write of current->state + * is correctly serialised wrt the caller's subsequent test of whether to +@@ -319,6 +351,11 @@ extern signed long FASTCALL(schedule_tim + extern signed long schedule_timeout_interruptible(signed long timeout); + extern signed long schedule_timeout_uninterruptible(signed long timeout); + asmlinkage void schedule(void); ++/* ++ * This one can be called with interrupts disabled, only ++ * to be used by lowlevel arch code! ++ */ ++asmlinkage void __sched __schedule(void); + + struct nsproxy; + struct user_namespace; +@@ -1419,6 +1456,15 @@ extern struct pid *cad_pid; + extern void free_task(struct task_struct *tsk); + #define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0) + ++#ifdef CONFIG_PREEMPT_RT ++extern void __put_task_struct_cb(struct rcu_head *rhp); ++ ++static inline void put_task_struct(struct task_struct *t) ++{ ++ if (atomic_dec_and_test(&t->usage)) ++ call_rcu(&t->rcu, __put_task_struct_cb); ++} ++#else + extern void __put_task_struct(struct task_struct *t); + + static inline void put_task_struct(struct task_struct *t) +@@ -1426,6 +1472,7 @@ static inline void put_task_struct(struc + if (atomic_dec_and_test(&t->usage)) + __put_task_struct(t); + } ++#endif + + /* + * Per process flags +Index: linux-2.6.24.7-rt21/kernel/sched.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched.c 2008-10-08 22:23:46.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched.c 2008-10-08 22:23:58.000000000 -0400 +@@ -4,6 +4,7 @@ + * Kernel scheduler and related syscalls + * + * Copyright (C) 1991-2002 Linus Torvalds ++ * Copyright (C) 2004 Red Hat, Inc., Ingo Molnar + * + * 1996-12-23 Modified by Dave Grothe to fix bugs in semaphores and + * make semaphores SMP safe +@@ -16,6 +17,7 @@ + * by Davide Libenzi, preemptible kernel bits by Robert Love. + * 2003-09-03 Interactivity tuning by Con Kolivas. + * 2004-04-02 Scheduler domains code by Nick Piggin ++ * 2004-10-13 Real-Time Preemption support by Ingo Molnar + * 2007-04-15 Work begun on replacing all interactivity tuning with a + * fair scheduling design by Con Kolivas. + * 2007-05-05 Load balancing (smp-nice) and other improvements +@@ -59,6 +61,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -114,6 +117,20 @@ unsigned long long __attribute__((weak)) + #define NICE_0_LOAD SCHED_LOAD_SCALE + #define NICE_0_SHIFT SCHED_LOAD_SHIFT + ++#if (BITS_PER_LONG < 64) ++#define JIFFIES_TO_NS64(TIME) \ ++ ((unsigned long long)(TIME) * ((unsigned long) (1000000000 / HZ))) ++ ++#define NS64_TO_JIFFIES(TIME) \ ++ ((((unsigned long long)((TIME)) >> BITS_PER_LONG) * \ ++ (1 + NS_TO_JIFFIES(~0UL))) + NS_TO_JIFFIES((unsigned long)(TIME))) ++#else /* BITS_PER_LONG < 64 */ ++ ++#define NS64_TO_JIFFIES(TIME) NS_TO_JIFFIES(TIME) ++#define JIFFIES_TO_NS64(TIME) JIFFIES_TO_NS(TIME) ++ ++#endif /* BITS_PER_LONG < 64 */ ++ + /* + * These are the 'tuning knobs' of the scheduler: + * +@@ -143,6 +160,32 @@ static inline void sg_inc_cpu_power(stru + } + #endif + ++#define TASK_PREEMPTS_CURR(p, rq) \ ++ ((p)->prio < (rq)->curr->prio) ++ ++/* ++ * Tweaks for current ++ */ ++ ++#ifdef CURRENT_PTR ++struct task_struct * const ___current = &init_task; ++struct task_struct ** const current_ptr = (struct task_struct ** const)&___current; ++struct thread_info * const current_ti = &init_thread_union.thread_info; ++struct thread_info ** const current_ti_ptr = (struct thread_info ** const)¤t_ti; ++ ++EXPORT_SYMBOL(___current); ++EXPORT_SYMBOL(current_ti); ++ ++/* ++ * The scheduler itself doesnt want 'current' to be cached ++ * during context-switches: ++ */ ++# undef current ++# define current __current() ++# undef current_thread_info ++# define current_thread_info() __current_thread_info() ++#endif ++ + static inline int rt_policy(int policy) + { + if (unlikely(policy == SCHED_FIFO) || unlikely(policy == SCHED_RR)) +@@ -278,6 +321,7 @@ struct rt_rq { + struct list_head *rt_load_balance_head, *rt_load_balance_curr; + unsigned long rt_nr_running; + unsigned long rt_nr_migratory; ++ unsigned long rt_nr_uninterruptible; + /* highest queued rt task prio */ + int highest_prio; + int overloaded; +@@ -324,7 +368,7 @@ static struct root_domain def_root_domai + */ + struct rq { + /* runqueue lock: */ +- spinlock_t lock; ++ raw_spinlock_t lock; + + /* + * nr_running and cpu_load should be in the same cacheline because +@@ -357,6 +401,8 @@ struct rq { + */ + unsigned long nr_uninterruptible; + ++ unsigned long switch_timestamp; ++ unsigned long slice_avg; + struct task_struct *curr, *idle; + unsigned long next_balance; + struct mm_struct *prev_mm; +@@ -406,6 +452,13 @@ struct rq { + + /* BKL stats */ + unsigned int bkl_count; ++ ++ /* RT-overload stats: */ ++ unsigned long rto_schedule; ++ unsigned long rto_schedule_tail; ++ unsigned long rto_wakeup; ++ unsigned long rto_pulled; ++ unsigned long rto_pushed; + #endif + struct lock_class_key rq_lock_key; + }; +@@ -569,11 +622,23 @@ unsigned long long notrace cpu_clock(int + } + EXPORT_SYMBOL_GPL(cpu_clock); + ++/* ++ * We really dont want to do anything complex within switch_to() ++ * on PREEMPT_RT - this check enforces this. ++ */ ++#ifdef prepare_arch_switch ++# ifdef CONFIG_PREEMPT_RT ++# error FIXME ++# else ++# define _finish_arch_switch finish_arch_switch ++# endif ++#endif ++ + #ifndef prepare_arch_switch + # define prepare_arch_switch(next) do { } while (0) + #endif + #ifndef finish_arch_switch +-# define finish_arch_switch(prev) do { } while (0) ++# define _finish_arch_switch(prev) do { } while (0) + #endif + + static inline int task_current(struct rq *rq, struct task_struct *p) +@@ -604,7 +669,7 @@ static inline void finish_lock_switch(st + */ + spin_acquire(&rq->lock.dep_map, 0, 0, _THIS_IP_); + +- spin_unlock_irq(&rq->lock); ++ spin_unlock(&rq->lock); + } + + #else /* __ARCH_WANT_UNLOCKED_CTXSW */ +@@ -645,8 +710,8 @@ static inline void finish_lock_switch(st + smp_wmb(); + prev->oncpu = 0; + #endif +-#ifndef __ARCH_WANT_INTERRUPTS_ON_CTXSW +- local_irq_enable(); ++#ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW ++ local_irq_disable(); + #endif + } + #endif /* __ARCH_WANT_UNLOCKED_CTXSW */ +@@ -1093,6 +1158,8 @@ static inline int normal_prio(struct tas + prio = MAX_RT_PRIO-1 - p->rt_priority; + else + prio = __normal_prio(p); ++ ++// trace_special_pid(p->pid, PRIO(p), __PRIO(prio)); + return prio; + } + +@@ -1593,6 +1660,13 @@ try_to_wake_up(struct task_struct *p, un + long old_state; + struct rq *rq; + ++#ifdef CONFIG_PREEMPT_RT ++ /* ++ * sync wakeups can increase wakeup latencies: ++ */ ++ if (rt_task(p)) ++ sync = 0; ++#endif + rq = task_rq_lock(p, &flags); + old_state = p->state; + if (!(old_state & state)) +@@ -1658,7 +1732,10 @@ out_activate: + + out_running: + trace_kernel_sched_wakeup(rq, p); +- p->state = TASK_RUNNING; ++ if (mutex) ++ p->state = TASK_RUNNING_MUTEX; ++ else ++ p->state = TASK_RUNNING; + #ifdef CONFIG_SMP + if (p->sched_class->task_wake_up) + p->sched_class->task_wake_up(rq, p); +@@ -1962,7 +2039,7 @@ static void finish_task_switch(struct rq + * Manfred Spraul + */ + prev_state = prev->state; +- finish_arch_switch(prev); ++ _finish_arch_switch(prev); + finish_lock_switch(rq, prev); + #ifdef CONFIG_SMP + if (current->sched_class->post_schedule) +@@ -1989,12 +2066,15 @@ static void finish_task_switch(struct rq + asmlinkage void schedule_tail(struct task_struct *prev) + __releases(rq->lock) + { +- struct rq *rq = this_rq(); +- +- finish_task_switch(rq, prev); ++ preempt_disable(); // TODO: move this to fork setup ++ finish_task_switch(this_rq(), prev); ++ __preempt_enable_no_resched(); ++ local_irq_enable(); + #ifdef __ARCH_WANT_UNLOCKED_CTXSW + /* In this case, finish_task_switch does not reenable preemption */ + preempt_enable(); ++#else ++ preempt_check_resched(); + #endif + if (current->set_child_tid) + put_user(task_pid_vnr(current), current->set_child_tid); +@@ -2043,6 +2123,11 @@ context_switch(struct rq *rq, struct tas + spin_release(&rq->lock.dep_map, 1, _THIS_IP_); + #endif + ++#ifdef CURRENT_PTR ++ barrier(); ++ *current_ptr = next; ++ *current_ti_ptr = next->thread_info; ++#endif + /* Here we just switch the register state and the stack. */ + switch_to(prev, next, prev); + +@@ -2089,6 +2174,11 @@ unsigned long nr_uninterruptible(void) + return sum; + } + ++unsigned long nr_uninterruptible_cpu(int cpu) ++{ ++ return cpu_rq(cpu)->nr_uninterruptible; ++} ++ + unsigned long long nr_context_switches(void) + { + int i; +@@ -3569,6 +3659,8 @@ void scheduler_tick(void) + struct task_struct *curr = rq->curr; + u64 next_tick = rq->tick_timestamp + TICK_NSEC; + ++ BUG_ON(!irqs_disabled()); ++ + spin_lock(&rq->lock); + __update_rq_clock(rq); + /* +@@ -3666,8 +3758,8 @@ static noinline void __schedule_bug(stru + { + struct pt_regs *regs = get_irq_regs(); + +- printk(KERN_ERR "BUG: scheduling while atomic: %s/%d/0x%08x\n", +- prev->comm, prev->pid, preempt_count()); ++ printk(KERN_ERR "BUG: scheduling while atomic: %s/0x%08x/%d, CPU#%d\n", ++ prev->comm, preempt_count(), prev->pid, smp_processor_id()); + + debug_show_held_locks(prev); + if (irqs_disabled()) +@@ -3684,6 +3776,8 @@ static noinline void __schedule_bug(stru + */ + static inline void schedule_debug(struct task_struct *prev) + { ++ WARN_ON(system_state == SYSTEM_BOOTING); ++ + /* + * Test if we are atomic. Since do_exit() needs to call into + * schedule() atomically, we ignore that path for now. +@@ -3738,14 +3832,13 @@ pick_next_task(struct rq *rq, struct tas + /* + * schedule() is the main scheduler function. + */ +-asmlinkage void __sched schedule(void) ++asmlinkage void __sched __schedule(void) + { + struct task_struct *prev, *next; + long *switch_count; + struct rq *rq; + int cpu; + +-need_resched: + preempt_disable(); + cpu = smp_processor_id(); + rq = cpu_rq(cpu); +@@ -3754,7 +3847,6 @@ need_resched: + switch_count = &prev->nivcsw; + + release_kernel_lock(prev); +-need_resched_nonpreemptible: + + schedule_debug(prev); + +@@ -3764,19 +3856,25 @@ need_resched_nonpreemptible: + local_irq_disable(); + __update_rq_clock(rq); + spin_lock(&rq->lock); ++ cpu = smp_processor_id(); + clear_tsk_need_resched(prev); + clear_tsk_need_resched_delayed(prev); + +- if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) { ++ if ((prev->state & ~TASK_RUNNING_MUTEX) && ++ !(preempt_count() & PREEMPT_ACTIVE)) { + if (unlikely((prev->state & TASK_INTERRUPTIBLE) && + unlikely(signal_pending(prev)))) { + prev->state = TASK_RUNNING; + } else { ++ touch_softlockup_watchdog(); + deactivate_task(rq, prev, 1); + } + switch_count = &prev->nvcsw; + } + ++ if (preempt_count() & PREEMPT_ACTIVE) ++ sub_preempt_count(PREEMPT_ACTIVE); ++ + #ifdef CONFIG_SMP + if (prev->sched_class->pre_schedule) + prev->sched_class->pre_schedule(rq, prev); +@@ -3796,22 +3894,90 @@ need_resched_nonpreemptible: + ++*switch_count; + + context_switch(rq, prev, next); /* unlocks the rq */ +- } else +- spin_unlock_irq(&rq->lock); ++ __preempt_enable_no_resched(); ++ } else { ++ __preempt_enable_no_resched(); ++ spin_unlock(&rq->lock); ++ } + +- if (unlikely(reacquire_kernel_lock(current) < 0)) { +- cpu = smp_processor_id(); +- rq = cpu_rq(cpu); +- goto need_resched_nonpreemptible; ++ reacquire_kernel_lock(current); ++ if (!irqs_disabled()) { ++ static int once = 1; ++ if (once) { ++ once = 0; ++ print_irqtrace_events(current); ++ WARN_ON(1); ++ } + } +- __preempt_enable_no_resched(); +- if (unlikely(test_thread_flag(TIF_NEED_RESCHED) || +- test_thread_flag(TIF_NEED_RESCHED_DELAYED))) +- goto need_resched; ++} ++ ++/* ++ * schedule() is the main scheduler function. ++ */ ++asmlinkage void __sched schedule(void) ++{ ++ WARN_ON(system_state == SYSTEM_BOOTING); ++ /* ++ * Test if we have interrupts disabled. ++ */ ++ if (unlikely(irqs_disabled())) { ++ printk(KERN_ERR "BUG: scheduling with irqs disabled: " ++ "%s/0x%08x/%d\n", current->comm, preempt_count(), ++ current->pid); ++ print_symbol("caller is %s\n", ++ (long)__builtin_return_address(0)); ++ dump_stack(); ++ } ++ ++ if (unlikely(current->flags & PF_NOSCHED)) { ++ current->flags &= ~PF_NOSCHED; ++ printk(KERN_ERR "%s:%d userspace BUG: scheduling in " ++ "user-atomic context!\n", current->comm, current->pid); ++ dump_stack(); ++ send_sig(SIGUSR2, current, 1); ++ } ++ ++ local_irq_disable(); ++ ++ do { ++ __schedule(); ++ } while (unlikely(test_thread_flag(TIF_NEED_RESCHED) || ++ test_thread_flag(TIF_NEED_RESCHED_DELAYED))); ++ ++ local_irq_enable(); + } + EXPORT_SYMBOL(schedule); + + #ifdef CONFIG_PREEMPT ++ ++/* ++ * Global flag to turn preemption off on a CONFIG_PREEMPT kernel: ++ */ ++int kernel_preemption = 1; ++ ++static int __init preempt_setup (char *str) ++{ ++ if (!strncmp(str, "off", 3)) { ++ if (kernel_preemption) { ++ printk(KERN_INFO "turning off kernel preemption!\n"); ++ kernel_preemption = 0; ++ } ++ return 1; ++ } ++ if (!strncmp(str, "on", 2)) { ++ if (!kernel_preemption) { ++ printk(KERN_INFO "turning on kernel preemption!\n"); ++ kernel_preemption = 1; ++ } ++ return 1; ++ } ++ get_option(&str, &kernel_preemption); ++ ++ return 1; ++} ++ ++__setup("preempt=", preempt_setup); ++ + /* + * this is the entry point to schedule() from in-kernel preemption + * off of preempt_enable. Kernel preemptions off return from interrupt +@@ -3824,6 +3990,8 @@ asmlinkage void __sched preempt_schedule + struct task_struct *task = current; + int saved_lock_depth; + #endif ++ if (!kernel_preemption) ++ return; + /* + * If there is a non-zero preempt_count or interrupts are disabled, + * we do not want to preempt the current task. Just return.. +@@ -3832,6 +4000,7 @@ asmlinkage void __sched preempt_schedule + return; + + do { ++ local_irq_disable(); + add_preempt_count(PREEMPT_ACTIVE); + + /* +@@ -3843,11 +4012,11 @@ asmlinkage void __sched preempt_schedule + saved_lock_depth = task->lock_depth; + task->lock_depth = -1; + #endif +- schedule(); ++ __schedule(); + #ifdef CONFIG_PREEMPT_BKL + task->lock_depth = saved_lock_depth; + #endif +- sub_preempt_count(PREEMPT_ACTIVE); ++ local_irq_enable(); + + /* + * Check again in case we missed a preemption opportunity +@@ -3859,10 +4028,10 @@ asmlinkage void __sched preempt_schedule + EXPORT_SYMBOL(preempt_schedule); + + /* +- * this is the entry point to schedule() from kernel preemption +- * off of irq context. +- * Note, that this is called and return with irqs disabled. This will +- * protect us against recursive calling from irq. ++ * this is is the entry point for the IRQ return path. Called with ++ * interrupts disabled. To avoid infinite irq-entry recursion problems ++ * with fast-paced IRQ sources we do all of this carefully to never ++ * enable interrupts again. + */ + asmlinkage void __sched preempt_schedule_irq(void) + { +@@ -3871,10 +4040,18 @@ asmlinkage void __sched preempt_schedule + struct task_struct *task = current; + int saved_lock_depth; + #endif +- /* Catch callers which need to be fixed */ +- WARN_ON_ONCE(ti->preempt_count || !irqs_disabled()); ++ ++ if (!kernel_preemption) ++ return; ++ /* ++ * If there is a non-zero preempt_count then just return. ++ * (interrupts are disabled) ++ */ ++ if (unlikely(ti->preempt_count)) ++ return; + + do { ++ local_irq_disable(); + add_preempt_count(PREEMPT_ACTIVE); + + /* +@@ -3886,13 +4063,12 @@ asmlinkage void __sched preempt_schedule + saved_lock_depth = task->lock_depth; + task->lock_depth = -1; + #endif +- local_irq_enable(); +- schedule(); ++ __schedule(); ++ + local_irq_disable(); + #ifdef CONFIG_PREEMPT_BKL + task->lock_depth = saved_lock_depth; + #endif +- sub_preempt_count(PREEMPT_ACTIVE); + + /* + * Check again in case we missed a preemption opportunity +@@ -4156,7 +4332,7 @@ EXPORT_SYMBOL(sleep_on_timeout); + void rt_mutex_setprio(struct task_struct *p, int prio) + { + unsigned long flags; +- int oldprio, on_rq, running; ++ int oldprio, prev_resched, on_rq, running; + struct rq *rq; + const struct sched_class *prev_class = p->sched_class; + +@@ -4180,12 +4356,17 @@ void rt_mutex_setprio(struct task_struct + + p->prio = prio; + ++// trace_special_pid(p->pid, __PRIO(oldprio), PRIO(p)); ++ prev_resched = _need_resched(); ++ + if (running) + p->sched_class->set_curr_task(rq); + if (on_rq) { + enqueue_task(rq, p, 0); + check_class_changed(rq, p, prev_class, oldprio, running); + } ++// trace_special(prev_resched, _need_resched(), 0); ++ + task_rq_unlock(rq, &flags); + } + +@@ -4777,14 +4958,17 @@ asmlinkage long sys_sched_yield(void) + */ + spin_unlock_no_resched(&rq->lock); + +- schedule(); ++ __schedule(); ++ ++ local_irq_enable(); ++ preempt_check_resched(); + + return 0; + } + + static void __cond_resched(void) + { +-#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP ++#if defined(CONFIG_DEBUG_SPINLOCK_SLEEP) || defined(CONFIG_DEBUG_PREEMPT) + __might_sleep(__FILE__, __LINE__); + #endif + /* +@@ -4793,10 +4977,11 @@ static void __cond_resched(void) + * cond_resched() call. + */ + do { ++ local_irq_disable(); + add_preempt_count(PREEMPT_ACTIVE); +- schedule(); +- sub_preempt_count(PREEMPT_ACTIVE); ++ __schedule(); + } while (need_resched()); ++ local_irq_enable(); + } + + int __sched cond_resched(void) +@@ -4822,7 +5007,7 @@ int __cond_resched_raw_spinlock(raw_spin + { + int ret = 0; + +- if (need_lockbreak(lock)) { ++ if (need_lockbreak_raw(lock)) { + spin_unlock(lock); + cpu_relax(); + ret = 1; +@@ -4838,6 +5023,25 @@ int __cond_resched_raw_spinlock(raw_spin + } + EXPORT_SYMBOL(__cond_resched_raw_spinlock); + ++#ifdef CONFIG_PREEMPT_RT ++ ++int __cond_resched_spinlock(spinlock_t *lock) ++{ ++#if (defined(CONFIG_SMP) && defined(CONFIG_PREEMPT)) || defined(CONFIG_PREEMPT_RT) ++ if (lock->break_lock) { ++ lock->break_lock = 0; ++ spin_unlock_no_resched(lock); ++ __cond_resched(); ++ spin_lock(lock); ++ return 1; ++ } ++#endif ++ return 0; ++} ++EXPORT_SYMBOL(__cond_resched_spinlock); ++ ++#endif ++ + /* + * Voluntarily preempt a process context that has softirqs disabled: + */ +@@ -4884,11 +5088,15 @@ int cond_resched_hardirq_context(void) + WARN_ON_ONCE(!irqs_disabled()); + + if (hardirq_need_resched()) { ++#ifndef CONFIG_PREEMPT_RT + irq_exit(); ++#endif + local_irq_enable(); + __cond_resched(); ++#ifndef CONFIG_PREEMPT_RT + local_irq_disable(); + __irq_enter(); ++#endif + + return 1; + } +@@ -4896,17 +5104,58 @@ int cond_resched_hardirq_context(void) + } + EXPORT_SYMBOL(cond_resched_hardirq_context); + ++#ifdef CONFIG_PREEMPT_VOLUNTARY ++ ++int voluntary_preemption = 1; ++ ++EXPORT_SYMBOL(voluntary_preemption); ++ ++static int __init voluntary_preempt_setup (char *str) ++{ ++ if (!strncmp(str, "off", 3)) ++ voluntary_preemption = 0; ++ else ++ get_option(&str, &voluntary_preemption); ++ if (!voluntary_preemption) ++ printk("turning off voluntary preemption!\n"); ++ ++ return 1; ++} ++ ++__setup("voluntary-preempt=", voluntary_preempt_setup); ++ ++#endif ++ + /** + * yield - yield the current processor to other threads. + * + * This is a shortcut for kernel-space yielding - it marks the + * thread runnable and calls sys_sched_yield(). + */ +-void __sched yield(void) ++void __sched __yield(void) + { + set_current_state(TASK_RUNNING); + sys_sched_yield(); + } ++ ++void __sched yield(void) ++{ ++ static int once = 1; ++ ++ /* ++ * it's a bug to rely on yield() with RT priorities. We print ++ * the first occurance after bootup ... this will still give ++ * us an idea about the scope of the problem, without spamming ++ * the syslog: ++ */ ++ if (once && rt_task(current)) { ++ once = 0; ++ printk(KERN_ERR "BUG: %s:%d RT task yield()-ing!\n", ++ current->comm, current->pid); ++ dump_stack(); ++ } ++ __yield(); ++} + EXPORT_SYMBOL(yield); + + /* +@@ -5089,6 +5338,7 @@ static void show_task(struct task_struct + void show_state_filter(unsigned long state_filter) + { + struct task_struct *g, *p; ++ int do_unlock = 1; + + #if BITS_PER_LONG == 32 + printk(KERN_INFO +@@ -5097,7 +5347,16 @@ void show_state_filter(unsigned long sta + printk(KERN_INFO + " task PC stack pid father\n"); + #endif ++#ifdef CONFIG_PREEMPT_RT ++ if (!read_trylock(&tasklist_lock)) { ++ printk("hm, tasklist_lock write-locked.\n"); ++ printk("ignoring ...\n"); ++ do_unlock = 0; ++ } ++#else + read_lock(&tasklist_lock); ++#endif ++ + do_each_thread(g, p) { + /* + * reset the NMI-timeout, listing all files on a slow +@@ -5113,7 +5372,8 @@ void show_state_filter(unsigned long sta + #ifdef CONFIG_SCHED_DEBUG + sysrq_sched_debug_show(); + #endif +- read_unlock(&tasklist_lock); ++ if (do_unlock) ++ read_unlock(&tasklist_lock); + /* + * Only show locks if all tasks are dumped: + */ +@@ -5154,7 +5414,9 @@ void __cpuinit init_idle(struct task_str + spin_unlock_irqrestore(&rq->lock, flags); + + /* Set the preempt count _outside_ the spinlocks! */ +-#if defined(CONFIG_PREEMPT) && !defined(CONFIG_PREEMPT_BKL) ++#if defined(CONFIG_PREEMPT) && \ ++ !defined(CONFIG_PREEMPT_BKL) && \ ++ !defined(CONFIG_PREEMPT_RT) + task_thread_info(idle)->preempt_count = (idle->lock_depth >= 0); + #else + task_thread_info(idle)->preempt_count = 0; +@@ -5279,11 +5541,18 @@ EXPORT_SYMBOL_GPL(set_cpus_allowed); + static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu) + { + struct rq *rq_dest, *rq_src; ++ unsigned long flags; + int ret = 0, on_rq; + + if (unlikely(cpu_is_offline(dest_cpu))) + return ret; + ++ /* ++ * PREEMPT_RT: this relies on write_lock_irq(&tasklist_lock) ++ * disabling interrupts - which on PREEMPT_RT does not do: ++ */ ++ local_irq_save(flags); ++ + rq_src = cpu_rq(src_cpu); + rq_dest = cpu_rq(dest_cpu); + +@@ -5307,6 +5576,8 @@ static int __migrate_task(struct task_st + ret = 1; + out: + double_rq_unlock(rq_src, rq_dest); ++ local_irq_restore(flags); ++ + return ret; + } + +@@ -7100,6 +7371,9 @@ void __init sched_init(void) + atomic_inc(&init_mm.mm_count); + enter_lazy_tlb(&init_mm, current); + ++#ifdef CONFIG_PREEMPT_RT ++ printk("Real-Time Preemption Support (C) 2004-2007 Ingo Molnar\n"); ++#endif + /* + * Make us the idle thread. Technically, schedule() should not be + * called from this thread, however somewhere below it might be, +@@ -7121,13 +7395,16 @@ void __might_sleep(char *file, int line) + + if ((in_atomic() || irqs_disabled()) && + system_state == SYSTEM_RUNNING && !oops_in_progress) { ++ if (debug_direct_keyboard && hardirq_count()) ++ return; + if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy) + return; + prev_jiffy = jiffies; + printk(KERN_ERR "BUG: sleeping function called from invalid" +- " context at %s:%d\n", file, line); +- printk("in_atomic():%d, irqs_disabled():%d\n", +- in_atomic(), irqs_disabled()); ++ " context %s(%d) at %s:%d\n", ++ current->comm, current->pid, file, line); ++ printk("in_atomic():%d [%08x], irqs_disabled():%d\n", ++ in_atomic(), preempt_count(), irqs_disabled()); + debug_show_held_locks(current); + if (irqs_disabled()) + print_irqtrace_events(current); +Index: linux-2.6.24.7-rt21/kernel/sched_rt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched_rt.c 2008-10-08 22:23:05.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched_rt.c 2008-10-08 22:23:58.000000000 -0400 +@@ -115,6 +115,48 @@ static inline void dec_rt_tasks(struct t + #endif /* CONFIG_SMP */ + } + ++static inline void incr_rt_nr_uninterruptible(struct task_struct *p, ++ struct rq *rq) ++{ ++ rq->rt.rt_nr_uninterruptible++; ++} ++ ++static inline void decr_rt_nr_uninterruptible(struct task_struct *p, ++ struct rq *rq) ++{ ++ rq->rt.rt_nr_uninterruptible--; ++} ++ ++unsigned long rt_nr_running(void) ++{ ++ unsigned long i, sum = 0; ++ ++ for_each_online_cpu(i) ++ sum += cpu_rq(i)->rt.rt_nr_running; ++ ++ return sum; ++} ++ ++unsigned long rt_nr_running_cpu(int cpu) ++{ ++ return cpu_rq(cpu)->rt.rt_nr_running; ++} ++ ++unsigned long rt_nr_uninterruptible(void) ++{ ++ unsigned long i, sum = 0; ++ ++ for_each_online_cpu(i) ++ sum += cpu_rq(i)->rt.rt_nr_uninterruptible; ++ ++ return sum; ++} ++ ++unsigned long rt_nr_uninterruptible_cpu(int cpu) ++{ ++ return cpu_rq(cpu)->rt.rt_nr_uninterruptible; ++} ++ + static void enqueue_task_rt(struct rq *rq, struct task_struct *p, int wakeup) + { + struct rt_prio_array *array = &rq->rt.active; +@@ -122,6 +164,9 @@ static void enqueue_task_rt(struct rq *r + list_add_tail(&p->run_list, array->queue + p->prio); + __set_bit(p->prio, array->bitmap); + inc_rt_tasks(p, rq); ++ ++ if (p->state == TASK_UNINTERRUPTIBLE) ++ decr_rt_nr_uninterruptible(p, rq); + } + + /* +@@ -133,6 +178,9 @@ static void dequeue_task_rt(struct rq *r + + update_curr_rt(rq); + ++ if (p->state == TASK_UNINTERRUPTIBLE) ++ incr_rt_nr_uninterruptible(p, rq); ++ + list_del(&p->run_list); + if (list_empty(array->queue + p->prio)) + __clear_bit(p->prio, array->bitmap); +@@ -500,6 +548,8 @@ static int push_rt_task(struct rq *rq) + + resched_task(lowest_rq->curr); + ++ schedstat_inc(rq, rto_pushed); ++ + spin_unlock(&lowest_rq->lock); + + ret = 1; +@@ -606,6 +656,7 @@ static int pull_rt_task(struct rq *this_ + */ + next = p; + ++ schedstat_inc(src_rq, rto_pulled); + } + out: + spin_unlock(&src_rq->lock); +@@ -617,8 +668,10 @@ static int pull_rt_task(struct rq *this_ + static void pre_schedule_rt(struct rq *rq, struct task_struct *prev) + { + /* Try to pull RT tasks here if we lower this rq's prio */ +- if (unlikely(rt_task(prev)) && rq->rt.highest_prio > prev->prio) ++ if (unlikely(rt_task(prev)) && rq->rt.highest_prio > prev->prio) { + pull_rt_task(rq); ++ schedstat_inc(rq, rto_schedule); ++ } + } + + static void post_schedule_rt(struct rq *rq) +@@ -633,6 +686,7 @@ static void post_schedule_rt(struct rq * + if (unlikely(rq->rt.overloaded)) { + spin_lock_irq(&rq->lock); + push_rt_tasks(rq); ++ schedstat_inc(rq, rto_schedule_tail); + spin_unlock_irq(&rq->lock); + } + } +@@ -642,8 +696,10 @@ static void task_wake_up_rt(struct rq *r + { + if (!task_running(rq, p) && + (p->prio >= rq->rt.highest_prio) && +- rq->rt.overloaded) ++ rq->rt.overloaded) { + push_rt_tasks(rq); ++ schedstat_inc(rq, rto_wakeup); ++ } + } + + static unsigned long --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0529-powerpc-xics-move-the-call-to-irq-radix-revmap-from-xics-startup-to-xics-host-map.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0529-powerpc-xics-move-the-call-to-irq-radix-revmap-from-xics-startup-to-xics-host-map.patch @@ -0,0 +1,79 @@ +Subject: powerpc - XICS: move the call to irq_radix_revmap + from xics_startup to xics_host_map +From: Sebastien Dugue +Date: Wed, 23 Jul 2008 17:00:24 +0200 +From: Sebastien Dugue +Date: Tue, 22 Jul 2008 13:05:24 +0200 +Subject: [PATCH][RT] powerpc - XICS: move the call to irq_radix_revmap from xics_startup to xics_host_map + + This patch moves the insertion of an irq into the reverse mapping radix tree +from xics_startup() into xics_host_map(). + + The reason for this change is that xics_startup() is called with preemption +disabled (which is not the case for xics_host_map()) which is a problem under a +preempt-rt kernel as we cannot even allocate GFP_ATOMIC memory for the radix tree +nodes. + + +Signed-off-by: Sebastien Dugue +Cc: Tim Chavez +Cc: Jean Pierre Dion +Cc: linuxppc-dev@ozlabs.org +Cc: paulus@samba.org +Cc: Gilles Carry +Signed-off-by: Thomas Gleixner +Cc: Benjamin Herrenschmidt +Cc: Paul Mackerras +Cc: Michael Ellerman + +--- + arch/powerpc/platforms/pseries/xics.c | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/powerpc/platforms/pseries/xics.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/platforms/pseries/xics.c 2008-10-08 22:23:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/platforms/pseries/xics.c 2008-10-08 22:25:11.000000000 -0400 +@@ -262,12 +262,6 @@ static void xics_mask_irq(unsigned int v + + static unsigned int xics_startup(unsigned int virq) + { +- unsigned int irq; +- +- /* force a reverse mapping of the interrupt so it gets in the cache */ +- irq = (unsigned int)irq_map[virq].hwirq; +- irq_radix_revmap(xics_host, irq); +- + /* unmask it */ + xics_unmask_irq(virq); + return 0; +@@ -488,8 +482,14 @@ static int xics_host_match(struct irq_ho + static int xics_host_map_direct(struct irq_host *h, unsigned int virq, + irq_hw_number_t hw) + { ++ unsigned int irq; ++ + pr_debug("xics: map_direct virq %d, hwirq 0x%lx\n", virq, hw); + ++ /* force a reverse mapping of the interrupt so it gets in the cache */ ++ irq = (unsigned int)irq_map[virq].hwirq; ++ irq_radix_revmap(xics_host, irq); ++ + get_irq_desc(virq)->status |= IRQ_LEVEL; + set_irq_chip_and_handler(virq, &xics_pic_direct, handle_fasteoi_irq); + return 0; +@@ -498,8 +498,14 @@ static int xics_host_map_direct(struct i + static int xics_host_map_lpar(struct irq_host *h, unsigned int virq, + irq_hw_number_t hw) + { ++ unsigned int irq; ++ + pr_debug("xics: map_direct virq %d, hwirq 0x%lx\n", virq, hw); + ++ /* force a reverse mapping of the interrupt so it gets in the cache */ ++ irq = (unsigned int)irq_map[virq].hwirq; ++ irq_radix_revmap(xics_host, irq); ++ + get_irq_desc(virq)->status |= IRQ_LEVEL; + set_irq_chip_and_handler(virq, &xics_pic_lpar, handle_fasteoi_irq); + return 0; --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0052-0039-sched-get-rid-of-new_cpu-in-try_to_wake_up.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0052-0039-sched-get-rid-of-new_cpu-in-try_to_wake_up.patch @@ -0,0 +1,55 @@ +From 48bbd36b0a1a82e2601ad726d9f1e1338e2af12b Mon Sep 17 00:00:00 2001 +From: Dmitry Adamushko +Date: Tue, 11 Dec 2007 10:02:47 +0100 +Subject: [PATCH] sched: get rid of 'new_cpu' in try_to_wake_up() + +Clean-up try_to_wake_up(). + +Get rid of the 'new_cpu' variable in try_to_wake_up() [ that's, one #ifdef section less ]. +Also remove a few redundant blank lines. + +Signed-off-by: Dmitry Adamushko +Signed-off-by: Ingo Molnar + +--- + kernel/sched.c | 11 +++-------- + 1 file changed, 3 insertions(+), 8 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/sched.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched.c 2008-10-08 22:23:03.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched.c 2008-10-08 22:23:04.000000000 -0400 +@@ -1545,9 +1545,6 @@ static int try_to_wake_up(struct task_st + unsigned long flags; + long old_state; + struct rq *rq; +-#ifdef CONFIG_SMP +- int new_cpu; +-#endif + + rq = task_rq_lock(p, &flags); + old_state = p->state; +@@ -1565,9 +1562,9 @@ static int try_to_wake_up(struct task_st + if (unlikely(task_running(rq, p))) + goto out_activate; + +- new_cpu = p->sched_class->select_task_rq(p, sync); +- if (new_cpu != cpu) { +- set_task_cpu(p, new_cpu); ++ cpu = p->sched_class->select_task_rq(p, sync); ++ if (cpu != orig_cpu) { ++ set_task_cpu(p, cpu); + task_rq_unlock(rq, &flags); + /* might preempt at this point */ + rq = task_rq_lock(p, &flags); +@@ -1594,10 +1591,8 @@ static int try_to_wake_up(struct task_st + } + } + } +- + #endif + +- + out_activate: + #endif /* CONFIG_SMP */ + schedstat_inc(p, se.nr_wakeups); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0280-s_files-schedule_on_each_cpu_wq.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0280-s_files-schedule_on_each_cpu_wq.patch @@ -0,0 +1,112 @@ +--- + include/linux/workqueue.h | 1 + kernel/workqueue.c | 65 ++++++++++++++++++++++++++++++++++++++-------- + 2 files changed, 55 insertions(+), 11 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/workqueue.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/workqueue.h 2008-10-08 22:23:59.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/workqueue.h 2008-10-08 22:24:10.000000000 -0400 +@@ -195,6 +195,7 @@ extern int FASTCALL(schedule_delayed_wor + unsigned long delay)); + extern int schedule_delayed_work_on(int cpu, struct delayed_work *work, + unsigned long delay); ++extern int schedule_on_each_cpu_wq(struct workqueue_struct *wq, work_func_t func); + extern int schedule_on_each_cpu(work_func_t func); + extern int current_is_keventd(void); + extern int keventd_up(void); +Index: linux-2.6.24.7-rt21/kernel/workqueue.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/workqueue.c 2008-10-08 22:23:59.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/workqueue.c 2008-10-08 22:24:10.000000000 -0400 +@@ -244,6 +244,20 @@ int queue_delayed_work_on(int cpu, struc + } + EXPORT_SYMBOL_GPL(queue_delayed_work_on); + ++static void leak_check(void *func) ++{ ++ if (!in_atomic() && lockdep_depth(current) <= 0) ++ return; ++ printk(KERN_ERR "BUG: workqueue leaked lock or atomic: " ++ "%s/0x%08x/%d\n", ++ current->comm, preempt_count(), ++ current->pid); ++ printk(KERN_ERR " last function: "); ++ print_symbol("%s\n", (unsigned long)func); ++ debug_show_held_locks(current); ++ dump_stack(); ++} ++ + static void run_workqueue(struct cpu_workqueue_struct *cwq) + { + spin_lock_irq(&cwq->lock); +@@ -276,22 +290,13 @@ static void run_workqueue(struct cpu_wor + + BUG_ON(get_wq_data(work) != cwq); + work_clear_pending(work); ++ leak_check(NULL); + lock_acquire(&cwq->wq->lockdep_map, 0, 0, 0, 2, _THIS_IP_); + lock_acquire(&lockdep_map, 0, 0, 0, 2, _THIS_IP_); + f(work); + lock_release(&lockdep_map, 1, _THIS_IP_); + lock_release(&cwq->wq->lockdep_map, 1, _THIS_IP_); +- +- if (unlikely(in_atomic() || lockdep_depth(current) > 0)) { +- printk(KERN_ERR "BUG: workqueue leaked lock or atomic: " +- "%s/0x%08x/%d\n", +- current->comm, preempt_count(), +- task_pid_nr(current)); +- printk(KERN_ERR " last function: "); +- print_symbol("%s\n", (unsigned long)f); +- debug_show_held_locks(current); +- dump_stack(); +- } ++ leak_check(f); + + spin_lock_irq(&cwq->lock); + cwq->current_work = NULL; +@@ -623,6 +628,44 @@ int schedule_on_each_cpu(work_func_t fun + return 0; + } + ++/** ++ * schedule_on_each_cpu_wq - call a function on each online CPU on a per-CPU wq ++ * @func: the function to call ++ * ++ * Returns zero on success. ++ * Returns -ve errno on failure. ++ * ++ * Appears to be racy against CPU hotplug. ++ * ++ * schedule_on_each_cpu() is very slow. ++ */ ++int schedule_on_each_cpu_wq(struct workqueue_struct *wq, work_func_t func) ++{ ++ int cpu; ++ struct work_struct *works; ++ ++ if (is_single_threaded(wq)) { ++ WARN_ON(1); ++ return -EINVAL; ++ } ++ works = alloc_percpu(struct work_struct); ++ if (!works) ++ return -ENOMEM; ++ ++ for_each_online_cpu(cpu) { ++ struct work_struct *work = per_cpu_ptr(works, cpu); ++ ++ INIT_WORK(work, func); ++ set_bit(WORK_STRUCT_PENDING, work_data_bits(work)); ++ __queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work); ++ } ++ flush_workqueue(wq); ++ free_percpu(works); ++ ++ return 0; ++} ++ ++ + void flush_scheduled_work(void) + { + flush_workqueue(keventd_wq); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0399-no-warning-for-irqs-disabled-in-local-bh-enable.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0399-no-warning-for-irqs-disabled-in-local-bh-enable.patch @@ -0,0 +1,32 @@ +From: Kevin Hilman +Subject: [PATCH/RFC -rt] local_bh_enable() is safe for irqs_disabled() + +In local_bh_enable() there is a WARN_ON(irqs_disabled()), but looking +at the rest of the code, it seems it expects to be used with +interrupts off, so is this warning really necessary? + +I hit this warning in the ads7846 touchscreen driver timer function +where enable_irq() may be called with interrupts disabled. Since +enable_irq now calls local_bh_disable/enable for IRQ resend, this +warning is triggered. + +Patch against 2.6.23.9-rt12 + +Signed-off-by: Kevin Hilman + +--- + kernel/softirq.c | 1 - + 1 file changed, 1 deletion(-) + +Index: linux-2.6.24.7-rt21/kernel/softirq.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/softirq.c 2008-10-08 22:24:21.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/softirq.c 2008-10-08 22:24:39.000000000 -0400 +@@ -207,7 +207,6 @@ void local_bh_enable(void) + + WARN_ON_ONCE(in_irq()); + #endif +- WARN_ON_ONCE(irqs_disabled()); + + #ifdef CONFIG_TRACE_IRQFLAGS + local_irq_save(flags); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0167-rt-mutex-trivial-route-cast-fix.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0167-rt-mutex-trivial-route-cast-fix.patch @@ -0,0 +1,17 @@ +--- + net/ipv4/route.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/net/ipv4/route.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/net/ipv4/route.c 2008-10-08 22:22:36.000000000 -0400 ++++ linux-2.6.24.7-rt21/net/ipv4/route.c 2008-10-08 22:23:37.000000000 -0400 +@@ -240,7 +240,7 @@ static spinlock_t *rt_hash_locks; + spin_lock_init(&rt_hash_locks[i]); \ + } + #else +-# define rt_hash_lock_addr(slot) NULL ++# define rt_hash_lock_addr(slot) ((spinlock_t *)NULL) + # define rt_hash_lock_init() + #endif + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0287-fix-circular-locking-deadlock.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0287-fix-circular-locking-deadlock.patch @@ -0,0 +1,140 @@ +On Thu, 2007-08-16 at 09:39 +0200, Peter Zijlstra wrote: +> On Wed, 2007-08-15 at 18:39 -0700, john stultz wrote: +> > Hey Ingo, Thomas, +> > +> > I was playing with the latency tracer on 2.6.23-rc2-rt2 while a "make +> > -j8" was going on in the background and the box hung with this on the +> > console: +> +> Hmm, this would have been me :-/ +> +> I'll go play... + + +Could you give this a spin... + +(not sure on the added rmbs, but they can't hurt) + +--- +Fix a deadlock in the fine grain locked list primitives. + +Delete and splice use a double lock, which normally locks in the +prev->cur order. For delete this is deadlock free provided one will +never delete the list head - which is exactly what splice attempts. + +In order to solve this, use the reverse locking order for splice - which +then assumes that the list passes is indeed the list head (no fancy +dummy item headless lists here). + +Signed-off-by: Peter Zijlstra +--- + lib/lock_list.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 60 insertions(+), 6 deletions(-) + +Index: linux-2.6.24.7-rt21/lib/lock_list.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/lib/lock_list.c 2008-10-08 22:24:11.000000000 -0400 ++++ linux-2.6.24.7-rt21/lib/lock_list.c 2008-10-08 22:24:12.000000000 -0400 +@@ -11,7 +11,7 @@ + * + * Passed pointers are assumed to be stable by external means such as + * refcounts or RCU. The individual list entries are assumed to be RCU +- * freed (requirement of __lock_list_del). ++ * freed (requirement of __lock_list). + */ + + #include +@@ -19,12 +19,9 @@ + void lock_list_add(struct lock_list_head *new, + struct lock_list_head *list) + { +- struct lock_list_head *next; +- + spin_lock(&new->lock); + spin_lock_nested(&list->lock, LOCK_LIST_NESTING_PREV); +- next = list->next; +- __list_add(&new->head, &list->head, &next->head); ++ __list_add(&new->head, &list->head, &list->next->head); + spin_unlock(&list->lock); + spin_unlock(&new->lock); + } +@@ -35,6 +32,13 @@ static spinlock_t *__lock_list(struct lo + spinlock_t *lock = NULL; + + again: ++ /* ++ * all modifications are done under spinlocks ++ * but this read is not, the unlock acks as a wmb ++ * for modifications. ++ */ ++ smp_rmb(); ++ + prev = entry->prev; + if (prev == entry) + goto one; +@@ -52,6 +56,56 @@ one: + return lock; + } + ++/* ++ * deadlock galore... ++ * ++ * when using __lock_list to lock the list head we get this: ++ * ++ * lock H 2 1 ++ * lock 1 a b ++ * lock 2 A B ++ * ++ * list: ..-> [H] <-> [1] <-> [2] <-.. ++ * ++ * obvious dead-lock, to solve this we must use a reverse order ++ * when trying to acquire a double lock on the head: ++ * ++ * lock H r 1 2 ++ * lock 1 a b ++ * lock 2 A B ++ * ++ * list: ..-> [H] <-> [1] <-> [2] <-.. ++ */ ++static spinlock_t *__lock_list_reverse(struct lock_list_head *entry) ++{ ++ struct lock_list_head *prev; ++ spinlock_t *lock = NULL; ++ ++ spin_lock(&entry->lock); ++again: ++ /* ++ * all modifications are done under spinlocks ++ * but this read is not, the unlock acks as a wmb ++ * for modifications. ++ */ ++ smp_rmb(); ++ prev = entry->prev; ++ if (prev == entry) ++ goto done; ++ ++ spin_lock_nested(&prev->lock, LOCK_LIST_NESTING_PREV); ++ if (unlikely(entry->prev != prev)) { ++ /* ++ * we lost ++ */ ++ spin_unlock(&prev->lock); ++ goto again; ++ } ++ lock = &prev->lock; ++done: ++ return lock; ++} ++ + void lock_list_del_init(struct lock_list_head *entry) + { + spinlock_t *lock; +@@ -71,7 +125,7 @@ void lock_list_splice_init(struct lock_l + spinlock_t *lock; + + rcu_read_lock(); +- lock = __lock_list(list); ++ lock = __lock_list_reverse(list); + if (!list_empty(&list->head)) { + spin_lock_nested(&head->lock, LOCK_LIST_NESTING_NEXT); + __list_splice(&list->head, &head->head); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0195-tasklet-more-fixes.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0195-tasklet-more-fixes.patch @@ -0,0 +1,176 @@ +From linux-kernel-owner@vger.kernel.org Thu Jun 14 23:21:31 2007 +Return-Path: + +X-Spam-Checker-Version: SpamAssassin 3.1.7-deb (2006-10-05) on debian +X-Spam-Level: +X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable + version=3.1.7-deb +Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by + mail.tglx.de (Postfix) with ESMTP id F2D8065C3D9 for ; + Thu, 14 Jun 2007 23:21:31 +0200 (CEST) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id + S1756447AbXFNVVF (ORCPT ); Thu, 14 Jun 2007 + 17:21:05 -0400 +Received: (majordomo@vger.kernel.org) by vger.kernel.org id + S1753441AbXFNVUw (ORCPT ); Thu, 14 Jun 2007 + 17:20:52 -0400 +Received: from e33.co.us.ibm.com ([32.97.110.151]:53331 "EHLO + e33.co.us.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP + id S1752693AbXFNVUv (ORCPT ); Thu, 14 + Jun 2007 17:20:51 -0400 +Received: from d03relay02.boulder.ibm.com (d03relay02.boulder.ibm.com + [9.17.195.227]) by e33.co.us.ibm.com (8.13.8/8.13.8) with ESMTP id + l5ELKnM3030113 for ; Thu, 14 Jun 2007 + 17:20:49 -0400 +Received: from d03av01.boulder.ibm.com (d03av01.boulder.ibm.com + [9.17.195.167]) by d03relay02.boulder.ibm.com (8.13.8/8.13.8/NCO v8.3) with + ESMTP id l5ELKniv268710 for ; Thu, 14 Jun + 2007 15:20:49 -0600 +Received: from d03av01.boulder.ibm.com (loopback [127.0.0.1]) by + d03av01.boulder.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id + l5ELKm9A010919 for ; Thu, 14 Jun 2007 + 15:20:49 -0600 +Received: from [9.67.41.186] (wecm-9-67-41-186.wecm.ibm.com [9.67.41.186]) + by d03av01.boulder.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id + l5ELKl3X010835; Thu, 14 Jun 2007 15:20:47 -0600 +Subject: Re: [PATCH -rt] Fix TASKLET_STATE_SCHED WARN_ON() +From: john stultz +To: Ingo Molnar +Cc: Thomas Gleixner , Steven Rostedt , "Paul E. McKenney" , lkml +In-Reply-To: <1181096244.6018.20.camel@localhost> +References: <1181096244.6018.20.camel@localhost> +Content-Type: text/plain +Date: Thu, 14 Jun 2007 14:20:20 -0700 +Message-Id: <1181856020.6276.14.camel@localhost.localdomain> +Mime-Version: 1.0 +X-Mailer: Evolution 2.10.1 +Sender: linux-kernel-owner@vger.kernel.org +Precedence: bulk +X-Mailing-List: linux-kernel@vger.kernel.org +X-Filter-To: .Kernel.LKML +X-Evolution-Source: imap://tglx%40linutronix.de@localhost:8993/ +Content-Transfer-Encoding: 8bit + +On Tue, 2007-06-05 at 19:17 -0700, john stultz wrote: +> Hey Ingo, +> So we've been seeing the following trace fairly frequently on our SMP +> boxes when running kernbench: +> +> BUG: at kernel/softirq.c:639 __tasklet_action() +> +> Call Trace: +> [] dump_trace+0xaa/0x32a +> [] show_trace+0x41/0x5c +> [] dump_stack+0x15/0x17 +> [] __tasklet_action+0xdf/0x12e +> [] tasklet_action+0x27/0x29 +> [] ksoftirqd+0x16c/0x271 +> [] kthread+0xf5/0x128 +> [] child_rip+0xa/0x12 +> +> +> Paul also pointed this out awhile back: http://lkml.org/lkml/2007/2/25/1 +> +> +> Anyway, I think I finally found the issue. Its a bit hard to explain, +> but the idea is while __tasklet_action is running the tasklet function +> on CPU1, if a call to tasklet_schedule() on CPU2 is made, and if right +> after we mark the TASKLET_STATE_SCHED bit we are preempted, +> __tasklet_action on CPU1 might be able to re-run the function, clear the +> bit and unlock the tasklet before CPU2 enters __tasklet_common_schedule. +> Once __tasklet_common_schedule locks the tasklet, we will add the +> tasklet to the list with the TASKLET_STATE_SCHED *unset*. +> +> I've verified this race occurs w/ a WARN_ON in +> __tasklet_common_schedule(). +> +> +> This fix avoids this race by making sure *after* we've locked the +> tasklet that the STATE_SCHED bit is set before adding it to the list. +> +> Does it look ok to you? +> +> thanks +> -john +> +> Signed-off-by: John Stultz +> +> Index: 2.6-rt/kernel/softirq.c +> =================================================================== +> --- 2.6-rt.orig/kernel/softirq.c 2007-06-05 18:30:54.000000000 -0700 +> +++ 2.6-rt/kernel/softirq.c 2007-06-05 18:36:44.000000000 -0700 +> @@ -544,10 +544,17 @@ static void inline +> __tasklet_common_schedule(struct tasklet_struct *t, struct tasklet_head *head, unsigned int nr) +> { +> if (tasklet_trylock(t)) { +> - WARN_ON(t->next != NULL); +> - t->next = head->list; +> - head->list = t; +> - raise_softirq_irqoff(nr); +> + /* We may have been preempted before tasklet_trylock +> + * and __tasklet_action may have already run. +> + * So double check the sched bit while the takslet +> + * is locked before adding it to the list. +> + */ +> + if (test_bit(TASKLET_STATE_SCHED, &t->state)) { +> + WARN_ON(t->next != NULL); +> + t->next = head->list; +> + head->list = t; +> + raise_softirq_irqoff(nr); +> + } +> tasklet_unlock(t); +> } +> } + +So while digging on a strange OOM issue we were seeing (which actually +ended up being fixed by Steven's softirq patch), I noticed that the fix +above is incomplete. With only the patch above, we may no longer have +unscheduled tasklets added to the list, but we may end up with scheduled +tasklets that are not on the list (and will stay that way!). + +The following additional patch should correct this issue. Although since +we weren't actually hitting it, the issue is a bit theoretical, so I've +not been able to prove it really fixes anything. + +thanks +-john + +--- + kernel/softirq.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/kernel/softirq.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/softirq.c 2008-10-08 22:23:45.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/softirq.c 2008-10-08 22:23:45.000000000 -0400 +@@ -459,6 +459,7 @@ static void inline + __tasklet_common_schedule(struct tasklet_struct *t, struct tasklet_head *head, unsigned int nr) + { + if (tasklet_trylock(t)) { ++again: + /* We may have been preempted before tasklet_trylock + * and __tasklet_action may have already run. + * So double check the sched bit while the takslet +@@ -469,8 +470,21 @@ __tasklet_common_schedule(struct tasklet + t->next = head->list; + head->list = t; + raise_softirq_irqoff(nr); ++ tasklet_unlock(t); ++ } else { ++ /* This is subtle. If we hit the corner case above ++ * It is possible that we get preempted right here, ++ * and another task has successfully called ++ * tasklet_schedule(), then this function, and ++ * failed on the trylock. Thus we must be sure ++ * before releasing the tasklet lock, that the ++ * SCHED_BIT is clear. Otherwise the tasklet ++ * may get its SCHED_BIT set, but not added to the ++ * list ++ */ ++ if (!tasklet_tryunlock(t)) ++ goto again; + } +- tasklet_unlock(t); + } + } + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0152-preempt-irqs-ppc.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0152-preempt-irqs-ppc.patch @@ -0,0 +1,133 @@ +--- + arch/powerpc/kernel/entry_32.S | 6 +++--- + arch/powerpc/kernel/irq.c | 2 -- + arch/powerpc/kernel/ppc_ksyms.c | 1 - + arch/powerpc/platforms/iseries/setup.c | 6 ++++-- + arch/powerpc/platforms/pseries/setup.c | 6 ++++-- + include/asm-powerpc/thread_info.h | 5 +++++ + 6 files changed, 16 insertions(+), 10 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/powerpc/kernel/entry_32.S +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/kernel/entry_32.S 2008-10-08 22:23:11.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/kernel/entry_32.S 2008-10-08 22:23:33.000000000 -0400 +@@ -662,7 +662,7 @@ user_exc_return: /* r10 contains MSR_KE + /* Check current_thread_info()->flags */ + rlwinm r9,r1,0,0,(31-THREAD_SHIFT) + lwz r9,TI_FLAGS(r9) +- andi. r0,r9,(_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NEED_RESCHED) ++ andi. r0,r9,(_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED) + bne do_work + + restore_user: +@@ -897,7 +897,7 @@ global_dbcr0: + #endif /* !(CONFIG_4xx || CONFIG_BOOKE) */ + + do_work: /* r10 contains MSR_KERNEL here */ +- andi. r0,r9,_TIF_NEED_RESCHED ++ andi. r0,r9,(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED) + beq do_user_signal + + do_resched: /* r10 contains MSR_KERNEL here */ +@@ -911,7 +911,7 @@ recheck: + MTMSRD(r10) /* disable interrupts */ + rlwinm r9,r1,0,0,(31-THREAD_SHIFT) + lwz r9,TI_FLAGS(r9) +- andi. r0,r9,_TIF_NEED_RESCHED ++ andi. r0,r9,(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED) + bne- do_resched + andi. r0,r9,_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK + beq restore_user +Index: linux-2.6.24.7-rt21/arch/powerpc/kernel/irq.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/kernel/irq.c 2008-10-08 22:23:10.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/kernel/irq.c 2008-10-08 22:23:33.000000000 -0400 +@@ -94,8 +94,6 @@ extern atomic_t ipi_sent; + #endif + + #ifdef CONFIG_PPC64 +-EXPORT_SYMBOL(irq_desc); +- + int distribute_irqs = 1; + + static inline notrace unsigned long get_hard_enabled(void) +Index: linux-2.6.24.7-rt21/arch/powerpc/kernel/ppc_ksyms.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/kernel/ppc_ksyms.c 2008-10-08 22:23:10.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/kernel/ppc_ksyms.c 2008-10-08 22:23:33.000000000 -0400 +@@ -167,7 +167,6 @@ EXPORT_SYMBOL(screen_info); + + #ifdef CONFIG_PPC32 + EXPORT_SYMBOL(timer_interrupt); +-EXPORT_SYMBOL(irq_desc); + EXPORT_SYMBOL(tb_ticks_per_jiffy); + EXPORT_SYMBOL(console_drivers); + EXPORT_SYMBOL(cacheable_memcpy); +Index: linux-2.6.24.7-rt21/arch/powerpc/platforms/iseries/setup.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/platforms/iseries/setup.c 2008-10-08 22:22:37.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/platforms/iseries/setup.c 2008-10-08 22:23:33.000000000 -0400 +@@ -564,12 +564,14 @@ static void iseries_shared_idle(void) + { + while (1) { + tick_nohz_stop_sched_tick(); +- while (!need_resched() && !hvlpevent_is_pending()) { ++ while (!need_resched() && !need_resched_delayed() ++ && !hvlpevent_is_pending()) { + local_irq_disable(); + ppc64_runlatch_off(); + + /* Recheck with irqs off */ +- if (!need_resched() && !hvlpevent_is_pending()) ++ if (!need_resched() && !need_resched_delayed() ++ && !hvlpevent_is_pending()) + yield_shared_processor(); + + HMT_medium(); +Index: linux-2.6.24.7-rt21/arch/powerpc/platforms/pseries/setup.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/platforms/pseries/setup.c 2008-10-08 22:22:37.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/platforms/pseries/setup.c 2008-10-08 22:23:33.000000000 -0400 +@@ -413,7 +413,8 @@ static void pseries_dedicated_idle_sleep + set_thread_flag(TIF_POLLING_NRFLAG); + + while (get_tb() < start_snooze) { +- if (need_resched() || cpu_is_offline(cpu)) ++ if (need_resched() || need_resched_delayed() || ++ cpu_is_offline(cpu)) + goto out; + ppc64_runlatch_off(); + HMT_low(); +@@ -424,7 +425,8 @@ static void pseries_dedicated_idle_sleep + clear_thread_flag(TIF_POLLING_NRFLAG); + smp_mb(); + local_irq_disable(); +- if (need_resched() || cpu_is_offline(cpu)) ++ if (need_resched() || need_resched_delayed() || ++ cpu_is_offline(cpu)) + goto out; + } + +Index: linux-2.6.24.7-rt21/include/asm-powerpc/thread_info.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-powerpc/thread_info.h 2008-10-08 22:22:37.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-powerpc/thread_info.h 2008-10-08 22:23:33.000000000 -0400 +@@ -124,6 +124,9 @@ static inline struct thread_info *curren + #define TIF_FREEZE 14 /* Freezing for suspend */ + #define TIF_RUNLATCH 15 /* Is the runlatch enabled? */ + #define TIF_ABI_PENDING 16 /* 32/64 bit switch needed */ ++#define TIF_NEED_RESCHED_DELAYED \ ++ 17 /* reschedule on return to userspace */ ++ + + /* as above, but as bit values */ + #define _TIF_SYSCALL_TRACE (1< +To: linux-kernel@vger.kernel.org, mingo@elte.hu +Cc: Gautham R Shenoy , K. Prasad , + mathieu.desnoyers@polymtl.ca, linux-rt-users@vger.kernel.org, + dipankar@in.ibm.com, paulmck@linux.vnet.ibm.com +Subject: [PATCH 2/2] Markers Implementation for Preempt RCU Boost Tracing - + Ver II + +This patch converts the tracing mechanism of Preempt RCU boosting into +markers. The handler functions for these markers are included inside +rcupreempt_trace.c and will be included only when PREEMPT_RCU_BOOST is +chosen. + +Signed-off-by: K.Prasad +--- + include/linux/rcupreempt_trace.h | 40 +++++++ + kernel/rcupreempt-boost.c | 211 ++++----------------------------------- + kernel/rcupreempt_trace.c | 183 +++++++++++++++++++++++++++++++++ + 3 files changed, 245 insertions(+), 189 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/rcupreempt_trace.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/rcupreempt_trace.h 2008-10-08 22:24:41.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/rcupreempt_trace.h 2008-10-08 22:24:41.000000000 -0400 +@@ -96,5 +96,45 @@ extern int rcupreempt_flip_flag(int cpu) + extern int rcupreempt_mb_flag(int cpu); + extern char *rcupreempt_try_flip_state_name(void); + ++#ifdef CONFIG_PREEMPT_RCU_BOOST ++struct preempt_rcu_boost_trace { ++ unsigned long rbs_stat_task_boost_called; ++ unsigned long rbs_stat_task_boosted; ++ unsigned long rbs_stat_boost_called; ++ unsigned long rbs_stat_try_boost; ++ unsigned long rbs_stat_boosted; ++ unsigned long rbs_stat_unboost_called; ++ unsigned long rbs_stat_unboosted; ++ unsigned long rbs_stat_try_boost_readers; ++ unsigned long rbs_stat_boost_readers; ++ unsigned long rbs_stat_try_unboost_readers; ++ unsigned long rbs_stat_unboost_readers; ++ unsigned long rbs_stat_over_taken; ++}; ++ ++#define DEFINE_PREEMPT_RCU_BOOST_MARKER_HANDLER(preempt_rcu_boost_var) \ ++void preempt_rcu_boost_var##_callback(const struct marker *mdata, \ ++ void *private_data, const char *format, ...) \ ++{ \ ++ struct preempt_rcu_boost_trace *boost_trace; \ ++ boost_trace = (&per_cpu(boost_trace_data, smp_processor_id())); \ ++ boost_trace->rbs_stat_##preempt_rcu_boost_var++; \ ++} ++ ++struct preempt_rcu_boost_probe { ++ const char *name; ++ const char *format; ++ marker_probe_func *probe_func; ++}; ++ ++#define INIT_PREEMPT_RCU_BOOST_PROBE(preempt_rcu_boost_probe_worker) \ ++{ \ ++ .name = __stringify(preempt_rcu_boost_probe_worker), \ ++ .probe_func = preempt_rcu_boost_probe_worker##_callback \ ++} ++ ++extern int read_rcu_boost_prio(void); ++#endif /* CONFIG_PREEMPT_RCU_BOOST */ ++ + #endif /* __KERNEL__ */ + #endif /* __LINUX_RCUPREEMPT_TRACE_H */ +Index: linux-2.6.24.7-rt21/kernel/rcupreempt-boost.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rcupreempt-boost.c 2008-10-08 22:24:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rcupreempt-boost.c 2008-10-08 22:24:41.000000000 -0400 +@@ -40,186 +40,9 @@ struct rcu_boost_dat { + int rbs_prio; /* CPU copy of rcu_boost_prio */ + struct list_head rbs_toboost; /* Preempted RCU readers */ + struct list_head rbs_boosted; /* RCU readers that have been boosted */ +-#ifdef CONFIG_RCU_TRACE +- /* The rest are for statistics */ +- unsigned long rbs_stat_task_boost_called; +- unsigned long rbs_stat_task_boosted; +- unsigned long rbs_stat_boost_called; +- unsigned long rbs_stat_try_boost; +- unsigned long rbs_stat_boosted; +- unsigned long rbs_stat_unboost_called; +- unsigned long rbs_stat_unboosted; +- unsigned long rbs_stat_try_boost_readers; +- unsigned long rbs_stat_boost_readers; +- unsigned long rbs_stat_try_unboost_readers; +- unsigned long rbs_stat_unboost_readers; +- unsigned long rbs_stat_over_taken; +-#endif /* CONFIG_RCU_TRACE */ + }; + + static DEFINE_PER_CPU(struct rcu_boost_dat, rcu_boost_data); +-#define RCU_BOOST_ME &__get_cpu_var(rcu_boost_data) +- +-#ifdef CONFIG_RCU_TRACE +- +-#define RCUPREEMPT_BOOST_TRACE_BUF_SIZE 4096 +-static char rcupreempt_boost_trace_buf[RCUPREEMPT_BOOST_TRACE_BUF_SIZE]; +- +-static ssize_t rcuboost_read(struct file *filp, char __user *buffer, +- size_t count, loff_t *ppos) +-{ +- static DEFINE_MUTEX(mutex); +- int cnt = 0; +- int cpu; +- struct rcu_boost_dat *rbd; +- ssize_t bcount; +- unsigned long task_boost_called = 0; +- unsigned long task_boosted = 0; +- unsigned long boost_called = 0; +- unsigned long try_boost = 0; +- unsigned long boosted = 0; +- unsigned long unboost_called = 0; +- unsigned long unboosted = 0; +- unsigned long try_boost_readers = 0; +- unsigned long boost_readers = 0; +- unsigned long try_unboost_readers = 0; +- unsigned long unboost_readers = 0; +- unsigned long over_taken = 0; +- +- mutex_lock(&mutex); +- +- for_each_online_cpu(cpu) { +- rbd = &per_cpu(rcu_boost_data, cpu); +- +- task_boost_called += rbd->rbs_stat_task_boost_called; +- task_boosted += rbd->rbs_stat_task_boosted; +- boost_called += rbd->rbs_stat_boost_called; +- try_boost += rbd->rbs_stat_try_boost; +- boosted += rbd->rbs_stat_boosted; +- unboost_called += rbd->rbs_stat_unboost_called; +- unboosted += rbd->rbs_stat_unboosted; +- try_boost_readers += rbd->rbs_stat_try_boost_readers; +- boost_readers += rbd->rbs_stat_boost_readers; +- try_unboost_readers += rbd->rbs_stat_try_boost_readers; +- unboost_readers += rbd->rbs_stat_boost_readers; +- over_taken += rbd->rbs_stat_over_taken; +- } +- +- cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], +- RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, +- "task_boost_called = %ld\n", +- task_boost_called); +- cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], +- RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, +- "task_boosted = %ld\n", +- task_boosted); +- cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], +- RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, +- "boost_called = %ld\n", +- boost_called); +- cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], +- RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, +- "try_boost = %ld\n", +- try_boost); +- cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], +- RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, +- "boosted = %ld\n", +- boosted); +- cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], +- RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, +- "unboost_called = %ld\n", +- unboost_called); +- cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], +- RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, +- "unboosted = %ld\n", +- unboosted); +- cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], +- RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, +- "try_boost_readers = %ld\n", +- try_boost_readers); +- cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], +- RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, +- "boost_readers = %ld\n", +- boost_readers); +- cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], +- RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, +- "try_unboost_readers = %ld\n", +- try_unboost_readers); +- cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], +- RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, +- "unboost_readers = %ld\n", +- unboost_readers); +- cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], +- RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, +- "over_taken = %ld\n", +- over_taken); +- cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], +- RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, +- "rcu_boost_prio = %d\n", +- rcu_boost_prio); +- bcount = simple_read_from_buffer(buffer, count, ppos, +- rcupreempt_boost_trace_buf, strlen(rcupreempt_boost_trace_buf)); +- mutex_unlock(&mutex); +- +- return bcount; +-} +- +-static struct file_operations rcuboost_fops = { +- .read = rcuboost_read, +-}; +- +-static struct dentry *rcuboostdir; +-int rcu_trace_boost_create(struct dentry *rcudir) +-{ +- rcuboostdir = debugfs_create_file("rcuboost", 0444, rcudir, +- NULL, &rcuboost_fops); +- if (!rcuboostdir) +- return 0; +- +- return 1; +-} +-EXPORT_SYMBOL_GPL(rcu_trace_boost_create); +- +-void rcu_trace_boost_destroy(void) +-{ +- if (rcuboostdir) +- debugfs_remove(rcuboostdir); +- rcuboostdir = NULL; +-} +-EXPORT_SYMBOL_GPL(rcu_trace_boost_destroy); +- +-#define RCU_BOOST_TRACE_FUNC_DECL(type) \ +- static void rcu_trace_boost_##type(struct rcu_boost_dat *rbd) \ +- { \ +- rbd->rbs_stat_##type++; \ +- } +-RCU_BOOST_TRACE_FUNC_DECL(task_boost_called) +-RCU_BOOST_TRACE_FUNC_DECL(task_boosted) +-RCU_BOOST_TRACE_FUNC_DECL(boost_called) +-RCU_BOOST_TRACE_FUNC_DECL(try_boost) +-RCU_BOOST_TRACE_FUNC_DECL(boosted) +-RCU_BOOST_TRACE_FUNC_DECL(unboost_called) +-RCU_BOOST_TRACE_FUNC_DECL(unboosted) +-RCU_BOOST_TRACE_FUNC_DECL(try_boost_readers) +-RCU_BOOST_TRACE_FUNC_DECL(boost_readers) +-RCU_BOOST_TRACE_FUNC_DECL(try_unboost_readers) +-RCU_BOOST_TRACE_FUNC_DECL(unboost_readers) +-RCU_BOOST_TRACE_FUNC_DECL(over_taken) +-#else /* CONFIG_RCU_TRACE */ +-/* These were created by the above macro "RCU_BOOST_TRACE_FUNC_DECL" */ +-# define rcu_trace_boost_task_boost_called(rbd) do { } while (0) +-# define rcu_trace_boost_task_boosted(rbd) do { } while (0) +-# define rcu_trace_boost_boost_called(rbd) do { } while (0) +-# define rcu_trace_boost_try_boost(rbd) do { } while (0) +-# define rcu_trace_boost_boosted(rbd) do { } while (0) +-# define rcu_trace_boost_unboost_called(rbd) do { } while (0) +-# define rcu_trace_boost_unboosted(rbd) do { } while (0) +-# define rcu_trace_boost_try_boost_readers(rbd) do { } while (0) +-# define rcu_trace_boost_boost_readers(rbd) do { } while (0) +-# define rcu_trace_boost_try_unboost_readers(rbd) do { } while (0) +-# define rcu_trace_boost_unboost_readers(rbd) do { } while (0) +-# define rcu_trace_boost_over_taken(rbd) do { } while (0) +-#endif /* CONFIG_RCU_TRACE */ + + static inline int rcu_is_boosted(struct task_struct *task) + { +@@ -234,10 +57,10 @@ static void rcu_boost_task(struct task_s + WARN_ON(!irqs_disabled()); + WARN_ON_SMP(!spin_is_locked(&task->pi_lock)); + +- rcu_trace_boost_task_boost_called(RCU_BOOST_ME); ++ trace_mark(task_boost_called, "NULL"); + + if (task->rcu_prio < task->prio) { +- rcu_trace_boost_task_boosted(RCU_BOOST_ME); ++ trace_mark(task_boosted, "NULL"); + task_setprio(task, task->rcu_prio); + } + } +@@ -261,7 +84,7 @@ void __rcu_preempt_boost(void) + + WARN_ON(!current->rcu_read_lock_nesting); + +- rcu_trace_boost_boost_called(RCU_BOOST_ME); ++ trace_mark(boost_called, "NULL"); + + /* check to see if we are already boosted */ + if (unlikely(rcu_is_boosted(curr))) +@@ -279,7 +102,7 @@ void __rcu_preempt_boost(void) + + curr->rcub_rbdp = rbd; + +- rcu_trace_boost_try_boost(rbd); ++ trace_mark(try_boost, "NULL"); + + prio = rt_mutex_getprio(curr); + +@@ -288,7 +111,7 @@ void __rcu_preempt_boost(void) + if (prio <= rbd->rbs_prio) + goto out; + +- rcu_trace_boost_boosted(curr->rcub_rbdp); ++ trace_mark(boosted, "NULL"); + + curr->rcu_prio = rbd->rbs_prio; + rcu_boost_task(curr); +@@ -313,7 +136,7 @@ void __rcu_preempt_unboost(void) + int prio; + unsigned long flags; + +- rcu_trace_boost_unboost_called(RCU_BOOST_ME); ++ trace_mark(unboost_called, "NULL"); + + /* if not boosted, then ignore */ + if (likely(!rcu_is_boosted(curr))) +@@ -351,7 +174,7 @@ void __rcu_preempt_unboost(void) + + list_del_init(&curr->rcub_entry); + +- rcu_trace_boost_unboosted(rbd); ++ trace_mark(unboosted, "NULL"); + + curr->rcu_prio = MAX_PRIO; + +@@ -412,7 +235,7 @@ static int __rcu_boost_readers(struct rc + * Another task may have taken over. + */ + if (curr->rcu_preempt_counter != rcu_boost_counter) { +- rcu_trace_boost_over_taken(rbd); ++ trace_mark(over_taken, "NULL"); + return 1; + } + +@@ -443,7 +266,7 @@ void rcu_boost_readers(void) + + prio = rt_mutex_getprio(curr); + +- rcu_trace_boost_try_boost_readers(RCU_BOOST_ME); ++ trace_mark(try_boost_readers, "NULL"); + + if (prio >= rcu_boost_prio) { + /* already boosted */ +@@ -453,7 +276,7 @@ void rcu_boost_readers(void) + + rcu_boost_prio = prio; + +- rcu_trace_boost_boost_readers(RCU_BOOST_ME); ++ trace_mark(boost_readers, "NULL"); + + /* Flag that we are the one to unboost */ + curr->rcu_preempt_counter = ++rcu_boost_counter; +@@ -486,12 +309,12 @@ void rcu_unboost_readers(void) + + spin_lock_irqsave(&rcu_boost_wake_lock, flags); + +- rcu_trace_boost_try_unboost_readers(RCU_BOOST_ME); ++ trace_mark(try_unboost_readers, "NULL"); + + if (current->rcu_preempt_counter != rcu_boost_counter) + goto out; + +- rcu_trace_boost_unboost_readers(RCU_BOOST_ME); ++ trace_mark(unboost_readers, "NULL"); + + /* + * We could also put in something that +@@ -514,6 +337,16 @@ void rcu_unboost_readers(void) + } + + /* ++ * This function exports the rcu_boost_prio variable for use by ++ * modules that need it e.g. RCU_TRACE module ++ */ ++int read_rcu_boost_prio(void) ++{ ++ return rcu_boost_prio; ++} ++EXPORT_SYMBOL_GPL(read_rcu_boost_prio); ++ ++/* + * The krcupreemptd wakes up every "rcu_preempt_thread_secs" + * seconds at the minimum priority of 1 to do a + * synchronize_rcu. This ensures that grace periods finish +Index: linux-2.6.24.7-rt21/kernel/rcupreempt_trace.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rcupreempt_trace.c 2008-10-08 22:24:41.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rcupreempt_trace.c 2008-10-08 22:24:41.000000000 -0400 +@@ -51,6 +51,163 @@ static char *rcupreempt_trace_buf; + + static DEFINE_PER_CPU(struct rcupreempt_trace, trace_data); + ++#ifdef CONFIG_PREEMPT_RCU_BOOST ++#define RCUPREEMPT_BOOST_TRACE_BUF_SIZE 4096 ++static char rcupreempt_boost_trace_buf[RCUPREEMPT_BOOST_TRACE_BUF_SIZE]; ++static DEFINE_PER_CPU(struct preempt_rcu_boost_trace, boost_trace_data); ++ ++DEFINE_PREEMPT_RCU_BOOST_MARKER_HANDLER(task_boost_called); ++DEFINE_PREEMPT_RCU_BOOST_MARKER_HANDLER(task_boosted); ++DEFINE_PREEMPT_RCU_BOOST_MARKER_HANDLER(boost_called); ++DEFINE_PREEMPT_RCU_BOOST_MARKER_HANDLER(try_boost); ++DEFINE_PREEMPT_RCU_BOOST_MARKER_HANDLER(boosted); ++DEFINE_PREEMPT_RCU_BOOST_MARKER_HANDLER(unboost_called); ++DEFINE_PREEMPT_RCU_BOOST_MARKER_HANDLER(unboosted); ++DEFINE_PREEMPT_RCU_BOOST_MARKER_HANDLER(try_boost_readers); ++DEFINE_PREEMPT_RCU_BOOST_MARKER_HANDLER(boost_readers); ++DEFINE_PREEMPT_RCU_BOOST_MARKER_HANDLER(try_unboost_readers); ++DEFINE_PREEMPT_RCU_BOOST_MARKER_HANDLER(unboost_readers); ++DEFINE_PREEMPT_RCU_BOOST_MARKER_HANDLER(over_taken); ++ ++static struct preempt_rcu_boost_probe preempt_rcu_boost_probe_array[] = ++{ ++ INIT_PREEMPT_RCU_BOOST_PROBE(task_boost_called), ++ INIT_PREEMPT_RCU_BOOST_PROBE(task_boosted), ++ INIT_PREEMPT_RCU_BOOST_PROBE(boost_called), ++ INIT_PREEMPT_RCU_BOOST_PROBE(try_boost), ++ INIT_PREEMPT_RCU_BOOST_PROBE(boosted), ++ INIT_PREEMPT_RCU_BOOST_PROBE(unboost_called), ++ INIT_PREEMPT_RCU_BOOST_PROBE(unboosted), ++ INIT_PREEMPT_RCU_BOOST_PROBE(try_boost_readers), ++ INIT_PREEMPT_RCU_BOOST_PROBE(boost_readers), ++ INIT_PREEMPT_RCU_BOOST_PROBE(try_unboost_readers), ++ INIT_PREEMPT_RCU_BOOST_PROBE(unboost_readers), ++ INIT_PREEMPT_RCU_BOOST_PROBE(over_taken) ++}; ++ ++static ssize_t rcuboost_read(struct file *filp, char __user *buffer, ++ size_t count, loff_t *ppos) ++{ ++ static DEFINE_MUTEX(mutex); ++ int cnt = 0; ++ int cpu; ++ struct preempt_rcu_boost_trace *prbt; ++ ssize_t bcount; ++ unsigned long task_boost_called = 0; ++ unsigned long task_boosted = 0; ++ unsigned long boost_called = 0; ++ unsigned long try_boost = 0; ++ unsigned long boosted = 0; ++ unsigned long unboost_called = 0; ++ unsigned long unboosted = 0; ++ unsigned long try_boost_readers = 0; ++ unsigned long boost_readers = 0; ++ unsigned long try_unboost_readers = 0; ++ unsigned long unboost_readers = 0; ++ unsigned long over_taken = 0; ++ ++ mutex_lock(&mutex); ++ ++ for_each_online_cpu(cpu) { ++ prbt = &per_cpu(boost_trace_data, cpu); ++ ++ task_boost_called += prbt->rbs_stat_task_boost_called; ++ task_boosted += prbt->rbs_stat_task_boosted; ++ boost_called += prbt->rbs_stat_boost_called; ++ try_boost += prbt->rbs_stat_try_boost; ++ boosted += prbt->rbs_stat_boosted; ++ unboost_called += prbt->rbs_stat_unboost_called; ++ unboosted += prbt->rbs_stat_unboosted; ++ try_boost_readers += prbt->rbs_stat_try_boost_readers; ++ boost_readers += prbt->rbs_stat_boost_readers; ++ try_unboost_readers += prbt->rbs_stat_try_boost_readers; ++ unboost_readers += prbt->rbs_stat_boost_readers; ++ over_taken += prbt->rbs_stat_over_taken; ++ } ++ ++ cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], ++ RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, ++ "task_boost_called = %ld\n", ++ task_boost_called); ++ cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], ++ RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, ++ "task_boosted = %ld\n", ++ task_boosted); ++ cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], ++ RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, ++ "boost_called = %ld\n", ++ boost_called); ++ cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], ++ RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, ++ "try_boost = %ld\n", ++ try_boost); ++ cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], ++ RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, ++ "boosted = %ld\n", ++ boosted); ++ cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], ++ RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, ++ "unboost_called = %ld\n", ++ unboost_called); ++ cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], ++ RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, ++ "unboosted = %ld\n", ++ unboosted); ++ cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], ++ RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, ++ "try_boost_readers = %ld\n", ++ try_boost_readers); ++ cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], ++ RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, ++ "boost_readers = %ld\n", ++ boost_readers); ++ cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], ++ RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, ++ "try_unboost_readers = %ld\n", ++ try_unboost_readers); ++ cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], ++ RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, ++ "unboost_readers = %ld\n", ++ unboost_readers); ++ cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], ++ RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, ++ "over_taken = %ld\n", ++ over_taken); ++ cnt += snprintf(&rcupreempt_boost_trace_buf[cnt], ++ RCUPREEMPT_BOOST_TRACE_BUF_SIZE - cnt, ++ "rcu_boost_prio = %d\n", ++ read_rcu_boost_prio()); ++ bcount = simple_read_from_buffer(buffer, count, ppos, ++ rcupreempt_boost_trace_buf, strlen(rcupreempt_boost_trace_buf)); ++ mutex_unlock(&mutex); ++ ++ return bcount; ++} ++ ++static struct file_operations rcuboost_fops = { ++ .read = rcuboost_read, ++}; ++ ++static struct dentry *rcuboostdir; ++int rcu_trace_boost_create(struct dentry *rcudir) ++{ ++ rcuboostdir = debugfs_create_file("rcuboost", 0444, rcudir, ++ NULL, &rcuboost_fops); ++ if (!rcuboostdir) ++ return 0; ++ ++ return 1; ++} ++ ++void rcu_trace_boost_destroy(void) ++{ ++ if (rcuboostdir) ++ debugfs_remove(rcuboostdir); ++ rcuboostdir = NULL; ++} ++ ++#endif /* CONFIG_PREEMPT_RCU_BOOST */ ++ + struct rcupreempt_trace *rcupreempt_trace_cpu(int cpu) + { + return &per_cpu(trace_data, cpu); +@@ -350,6 +507,10 @@ static int rcupreempt_debugfs_init(void) + if (!ctrsdir) + goto free_out; + ++#ifdef CONFIG_PREEMPT_RCU_BOOST ++ if (!rcu_trace_boost_create(rcudir)) ++ goto free_out; ++#endif /* CONFIG_PREEMPT_RCU_BOOST */ + return 0; + free_out: + if (ctrsdir) +@@ -382,6 +543,22 @@ static int __init rcupreempt_trace_init( + } + printk(KERN_INFO "RCU Preempt markers registered\n"); + ++#ifdef CONFIG_PREEMPT_RCU_BOOST ++ for (i = 0; i < ARRAY_SIZE(preempt_rcu_boost_probe_array); i++) { ++ struct preempt_rcu_boost_probe *p = \ ++ &preempt_rcu_boost_probe_array[i]; ++ ret = marker_probe_register(p->name, p->format, ++ p->probe_func, p); ++ if (ret) ++ printk(KERN_INFO "Unable to register Preempt RCU Boost \ ++ probe %s\n", preempt_rcu_boost_probe_array[i].name); ++ ret = marker_arm(p->name); ++ if (ret) ++ printk(KERN_INFO "Unable to arm Preempt RCU Boost \ ++ markers %s\n", p->name); ++} ++#endif /* CONFIG_PREEMPT_RCU_BOOST */ ++ + mutex_init(&rcupreempt_trace_mutex); + rcupreempt_trace_buf = kmalloc(RCUPREEMPT_TRACE_BUF_SIZE, GFP_KERNEL); + if (!rcupreempt_trace_buf) +@@ -400,6 +577,12 @@ static void __exit rcupreempt_trace_clea + marker_probe_unregister(rcupreempt_probe_array[i].name); + printk(KERN_INFO "RCU Preempt markers unregistered\n"); + ++#ifdef CONFIG_PREEMPT_RCU_BOOST ++ rcu_trace_boost_destroy(); ++ for (i = 0; i < ARRAY_SIZE(preempt_rcu_boost_probe_array); i++) ++ marker_probe_unregister(preempt_rcu_boost_probe_array[i].name); ++ printk(KERN_INFO "Preempt RCU Boost markers unregistered\n"); ++#endif /* CONFIG_PREEMPT_RCU_BOOST */ + debugfs_remove(statdir); + debugfs_remove(gpdir); + debugfs_remove(ctrsdir); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0348-powerpc-rearrange-thread-flags-to-work-with-andi-instruction.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0348-powerpc-rearrange-thread-flags-to-work-with-andi-instruction.patch @@ -0,0 +1,46 @@ +From tony@bakeyournoodle.com Wed Sep 26 10:25:29 2007 +Date: Tue, 04 Sep 2007 17:09:02 +1000 +From: Tony Breeds +To: linux-rt-users@vger.kernel.org +Subject: [PATCH 1/5] [POWERPC] Rearrange thread flags to work with the + "andi" instruction. + +Signed-off-by: Tony Breeds + +--- + + include/asm-powerpc/thread_info.h | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +Index: linux-2.6.24.7-rt21/include/asm-powerpc/thread_info.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-powerpc/thread_info.h 2008-10-08 22:23:53.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-powerpc/thread_info.h 2008-10-08 22:24:27.000000000 -0400 +@@ -121,11 +121,11 @@ static inline struct thread_info *curren + #define TIF_RESTOREALL 11 /* Restore all regs (implies NOERROR) */ + #define TIF_NOERROR 12 /* Force successful syscall return */ + #define TIF_RESTORE_SIGMASK 13 /* Restore signal mask in do_signal */ +-#define TIF_FREEZE 14 /* Freezing for suspend */ +-#define TIF_RUNLATCH 15 /* Is the runlatch enabled? */ +-#define TIF_ABI_PENDING 16 /* 32/64 bit switch needed */ + #define TIF_NEED_RESCHED_DELAYED \ +- 17 /* reschedule on return to userspace */ ++ 14 /* reschedule on return to userspace */ ++#define TIF_FREEZE 15 /* Freezing for suspend */ ++#define TIF_RUNLATCH 16 /* Is the runlatch enabled? */ ++#define TIF_ABI_PENDING 17 /* 32/64 bit switch needed */ + + + /* as above, but as bit values */ +@@ -142,10 +142,10 @@ static inline struct thread_info *curren + #define _TIF_RESTOREALL (1< + +Fixes spurious system load spikes observed in /proc/loadavgrt, as described in: + + Bug 253103: /proc/loadavgrt issues weird results + https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=253103 + +Signed-off-by: Luis Claudio R. Goncalves > +--- + +--- + kernel/sched.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +Index: linux-2.6.24.7-rt21/kernel/sched.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched.c 2008-10-08 22:24:26.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched.c 2008-10-08 22:24:29.000000000 -0400 +@@ -2201,6 +2201,13 @@ unsigned long nr_iowait(void) + for_each_possible_cpu(i) + sum += atomic_read(&cpu_rq(i)->nr_iowait); + ++ /* ++ * Since we read the counters lockless, it might be slightly ++ * inaccurate. Do not allow it to go below zero though: ++ */ ++ if (unlikely((long)sum < 0)) ++ sum = 0; ++ + return sum; + } + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0136-m68knommu-add-cmpxchg-in-default-fashion.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0136-m68knommu-add-cmpxchg-in-default-fashion.patch @@ -0,0 +1,63 @@ +From 46a77f70fc1a6f11c01eb8265feea0ab93c3cbac Mon Sep 17 00:00:00 2001 +From: Sebastian Siewior +Date: Fri, 18 Apr 2008 17:02:27 +0200 +Subject: [PATCH] m68knommu: add cmpxchg in default fashion + +not RT-safe, generic + +Signed-off-by: Sebastian Siewior +Signed-off-by: Thomas Gleixner +--- + include/asm-m68knommu/system.h | 34 +++++++++++++++++++++++++--------- + 1 file changed, 25 insertions(+), 9 deletions(-) + +Index: linux-2.6.24.7-rt21/include/asm-m68knommu/system.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-m68knommu/system.h 2008-10-08 22:22:38.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-m68knommu/system.h 2008-10-08 22:23:29.000000000 -0400 +@@ -192,20 +192,36 @@ static inline unsigned long __xchg(unsig + * indicated by comparing RETURN with OLD. + */ + #define __HAVE_ARCH_CMPXCHG 1 ++extern unsigned long __cmpxchg_called_with_bad_pointer(volatile void *p, ++ unsigned long old, unsigned long new, int size); + +-static __inline__ unsigned long +-cmpxchg(volatile int *p, int old, int new) ++static inline unsigned long ++__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) + { +- unsigned long flags; +- int prev; ++ unsigned long flags, prev; ++ volatile unsigned int *p = ptr; + +- local_irq_save(flags); +- if ((prev = *p) == old) +- *p = new; +- local_irq_restore(flags); +- return(prev); ++ if (size == 4) { ++ ++ local_irq_save(flags); ++ if ((prev = *p) == old) ++ *p = new; ++ local_irq_restore(flags); ++ return prev; ++ } ++ ++ /* we should not get here, if you do we end up with a linker error */ ++ return __cmpxchg_called_with_bad_pointer(p, old, new, size); + } + ++#define cmpxchg(ptr,o,n) \ ++ ({ \ ++ __typeof__(*(ptr)) _o_ = (o); \ ++ __typeof__(*(ptr)) _n_ = (n); \ ++ (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ ++ (unsigned long)_n_, sizeof(*(ptr))); \ ++ }) ++ + + #ifdef CONFIG_M68332 + #define HARD_RESET_NOW() ({ \ --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0358-watchdog_use_timer_and_hpet_on_x86_64.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0358-watchdog_use_timer_and_hpet_on_x86_64.patch @@ -0,0 +1,35 @@ +This modifies nmi_watchdog_tick behavior for +x86_64 arch to consider both timer and hpet IRQs +just as the i386 arch does. + +Signed-off-by: David Bahi + +--- + arch/x86/kernel/nmi_64.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/nmi_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/nmi_64.c 2008-10-08 22:24:09.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/nmi_64.c 2008-10-08 22:24:29.000000000 -0400 +@@ -371,7 +371,6 @@ nmi_watchdog_tick(struct pt_regs * regs, + touched = 1; + } + +- sum = read_pda(apic_timer_irqs) + read_pda(irq0_irqs); + if (__get_cpu_var(nmi_touch)) { + __get_cpu_var(nmi_touch) = 0; + touched = 1; +@@ -387,6 +386,12 @@ nmi_watchdog_tick(struct pt_regs * regs, + cpu_clear(cpu, backtrace_mask); + } + ++ /* ++ * Take the local apic timer and PIT/HPET into account. We don't ++ * know which one is active, when we have highres/dyntick on ++ */ ++ sum = read_pda(apic_timer_irqs) + kstat_cpu(cpu).irqs[0]; ++ + #ifdef CONFIG_X86_MCE + /* Could check oops_in_progress here too, but it's safer + not too */ --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0283-qrcu.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0283-qrcu.patch @@ -0,0 +1,193 @@ +From: "Paul E. McKenney" +Subject: [PATCH] QRCU with lockless fastpath + +Hello! + +This is an updated version of Oleg Nesterov's QRCU that avoids the +earlier lock acquisition on the synchronize_qrcu() fastpath. This passes +rcutorture on x86 and the weakly ordered POWER. A promela model of the +code passes as noted before for 2 readers and 3 updaters and for 3 readers +and 2 updaters. 3 readers and 3 updaters runs every machine that I have +access to out of memory -- nothing like a little combinatorial explosion! +However, after some thought, the proof ended up being simple enough: + +1. If synchronize_qrcu() exits too soon, then by definition + there has been a reader present during synchronize_srcu()'s + full execution. + +2. The counter corresponding to this reader will be at least + 1 at all times. + +3. The synchronize_qrcu() code forces at least one of the counters + to be at least one at all times -- if there is a reader, the + sum will be at least two. (Unfortunately, we cannot fetch + the pair of counters atomically.) + +4. Therefore, the only way that synchronize_qrcu()s fastpath can + see a sum of 1 is if it races with another synchronize_qrcu() -- + the first synchronize_qrcu() must read one of the counters before + the second synchronize_qrcu() increments it, and must read the + other counter after the second synchronize_qrcu() decrements it. + There can be at most one reader present through this entire + operation -- otherwise, the first synchronize_qrcu() will see + a sum of 2 or greater. + +5. But the second synchronize_qrcu() will not release the mutex + until after the reader is done. During this time, the first + synchronize_qrcu() will always see a sum of at least 2, and + therefore cannot take the remainder of the fastpath until the + reader is done. + +6. Because the second synchronize_qrcu() holds the mutex, no other + synchronize_qrcu() can manipulate the counters until the reader + is done. A repeat of the race called out in #4 above therefore + cannot happen until after the reader is done, in which case it + is safe for the first synchronize_qrcu() to proceed. + +Therefore, two summations of the counter separated by a memory barrier +suffices and the implementation shown below also suffices. + +(And, yes, the fastpath -could- check for a sum of zero and exit +immediately, but this would help only in case of a three-way race +between two synchronize_qrcu()s and a qrcu_read_unlock(), would add +another compare, so is not worth it.) + +Signed-off-by: Paul E. McKenney +--- + + include/linux/srcu.h | 22 +++++++++++++ + kernel/srcu.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 108 insertions(+) + +Index: linux-2.6.24.7-rt21/include/linux/srcu.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/srcu.h 2008-10-08 22:22:26.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/srcu.h 2008-10-08 22:24:11.000000000 -0400 +@@ -27,6 +27,8 @@ + #ifndef _LINUX_SRCU_H + #define _LINUX_SRCU_H + ++#include ++ + struct srcu_struct_array { + int c[2]; + }; +@@ -50,4 +52,24 @@ void srcu_read_unlock(struct srcu_struct + void synchronize_srcu(struct srcu_struct *sp); + long srcu_batches_completed(struct srcu_struct *sp); + ++/* ++ * fully compatible with srcu, but optimized for writers. ++ */ ++ ++struct qrcu_struct { ++ int completed; ++ atomic_t ctr[2]; ++ wait_queue_head_t wq; ++ struct mutex mutex; ++}; ++ ++int init_qrcu_struct(struct qrcu_struct *qp); ++int qrcu_read_lock(struct qrcu_struct *qp); ++void qrcu_read_unlock(struct qrcu_struct *qp, int idx); ++void synchronize_qrcu(struct qrcu_struct *qp); ++ ++static inline void cleanup_qrcu_struct(struct qrcu_struct *qp) ++{ ++} ++ + #endif +Index: linux-2.6.24.7-rt21/kernel/srcu.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/srcu.c 2008-10-08 22:22:26.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/srcu.c 2008-10-08 22:24:11.000000000 -0400 +@@ -256,3 +256,89 @@ EXPORT_SYMBOL_GPL(srcu_read_unlock); + EXPORT_SYMBOL_GPL(synchronize_srcu); + EXPORT_SYMBOL_GPL(srcu_batches_completed); + EXPORT_SYMBOL_GPL(srcu_readers_active); ++ ++int init_qrcu_struct(struct qrcu_struct *qp) ++{ ++ qp->completed = 0; ++ atomic_set(qp->ctr + 0, 1); ++ atomic_set(qp->ctr + 1, 0); ++ init_waitqueue_head(&qp->wq); ++ mutex_init(&qp->mutex); ++ ++ return 0; ++} ++ ++int qrcu_read_lock(struct qrcu_struct *qp) ++{ ++ for (;;) { ++ int idx = qp->completed & 0x1; ++ if (likely(atomic_inc_not_zero(qp->ctr + idx))) ++ return idx; ++ } ++} ++ ++void qrcu_read_unlock(struct qrcu_struct *qp, int idx) ++{ ++ if (atomic_dec_and_test(qp->ctr + idx)) ++ wake_up(&qp->wq); ++} ++ ++void synchronize_qrcu(struct qrcu_struct *qp) ++{ ++ int idx; ++ ++ smp_mb(); /* Force preceding change to happen before fastpath check. */ ++ ++ /* ++ * Fastpath: If the two counters sum to "1" at a given point in ++ * time, there are no readers. However, it takes two separate ++ * loads to sample both counters, which won't occur simultaneously. ++ * So we might race with a counter switch, so that we might see ++ * ctr[0]==0, then the counter might switch, then we might see ++ * ctr[1]==1 (unbeknownst to us because there is a reader still ++ * there). So we do a read memory barrier and recheck. If the ++ * same race happens again, there must have been a second counter ++ * switch. This second counter switch could not have happened ++ * until all preceding readers finished, so if the condition ++ * is true both times, we may safely proceed. ++ * ++ * This relies critically on the atomic increment and atomic ++ * decrement being seen as executing in order. ++ */ ++ ++ if (atomic_read(&qp->ctr[0]) + atomic_read(&qp->ctr[1]) <= 1) { ++ smp_rmb(); /* Keep two checks independent. */ ++ if (atomic_read(&qp->ctr[0]) + atomic_read(&qp->ctr[1]) <= 1) ++ goto out; ++ } ++ ++ mutex_lock(&qp->mutex); ++ ++ idx = qp->completed & 0x1; ++ if (atomic_read(qp->ctr + idx) == 1) ++ goto out_unlock; ++ ++ atomic_inc(qp->ctr + (idx ^ 0x1)); ++ ++ /* ++ * Prevent subsequent decrement from being seen before previous ++ * increment -- such an inversion could cause the fastpath ++ * above to falsely conclude that there were no readers. Also, ++ * reduce the likelihood that qrcu_read_lock() will loop. ++ */ ++ ++ smp_mb__after_atomic_inc(); ++ qp->completed++; ++ ++ atomic_dec(qp->ctr + idx); ++ __wait_event(qp->wq, !atomic_read(qp->ctr + idx)); ++out_unlock: ++ mutex_unlock(&qp->mutex); ++out: ++ smp_mb(); /* force subsequent free after qrcu_read_unlock(). */ ++} ++ ++EXPORT_SYMBOL_GPL(init_qrcu_struct); ++EXPORT_SYMBOL_GPL(qrcu_read_lock); ++EXPORT_SYMBOL_GPL(qrcu_read_unlock); ++EXPORT_SYMBOL_GPL(synchronize_qrcu); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0562-ftrace-fix-preempt-trace-fix.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0562-ftrace-fix-preempt-trace-fix.patch @@ -0,0 +1,24 @@ +From: Steven Rostedt +Subject: ftrace: fix the preempt-disable start fix + +Signed-off-by: Steven Rostedt +--- + kernel/trace/trace_irqsoff.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/trace/trace_irqsoff.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/trace_irqsoff.c 2008-10-08 22:25:09.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/trace_irqsoff.c 2008-10-08 22:25:19.000000000 -0400 +@@ -364,9 +364,9 @@ void trace_preempt_on(unsigned long a0, + + void trace_preempt_off(unsigned long a0, unsigned long a1) + { +- start_critical_timing(a0, a1); ++ tracing_hist_preempt_start(); + if (preempt_trace()) +- tracing_hist_preempt_start(); ++ start_critical_timing(a0, a1); + } + #endif /* CONFIG_PREEMPT_TRACER */ + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0107-nmi-profiling-base.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0107-nmi-profiling-base.patch @@ -0,0 +1,420 @@ +Subject: [patch] nmi-driven profiling for /proc/profile +From: Ingo Molnar + +nmi-driven profiling for /proc/profile + +Signed-off-by: Ingo Molnar +--- + arch/x86/kernel/crash.c | 8 ---- + arch/x86/kernel/irq_64.c | 2 + + arch/x86/kernel/nmi_32.c | 89 ++++++++++++++++++++++++++++++++++++++++++---- + arch/x86/kernel/nmi_64.c | 64 +++++++++++++++++++++++++++++++-- + include/asm-x86/apic_32.h | 2 + + include/asm-x86/apic_64.h | 2 + + include/linux/profile.h | 1 + kernel/profile.c | 9 +++- + kernel/time/tick-common.c | 1 + kernel/time/tick-sched.c | 2 - + 10 files changed, 156 insertions(+), 24 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/crash.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/crash.c 2008-10-08 22:22:41.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/crash.c 2008-10-08 22:23:22.000000000 -0400 +@@ -78,14 +78,6 @@ static int crash_nmi_callback(struct not + return 1; + } + +-static void smp_send_nmi_allbutself(void) +-{ +- cpumask_t mask = cpu_online_map; +- cpu_clear(safe_smp_processor_id(), mask); +- if (!cpus_empty(mask)) +- send_IPI_mask(mask, NMI_VECTOR); +-} +- + static struct notifier_block crash_nmi_nb = { + .notifier_call = crash_nmi_callback, + }; +Index: linux-2.6.24.7-rt21/arch/x86/kernel/irq_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/irq_64.c 2008-10-08 22:23:08.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/irq_64.c 2008-10-08 22:23:22.000000000 -0400 +@@ -147,6 +147,8 @@ asmlinkage unsigned int do_IRQ(struct pt + unsigned vector = ~regs->orig_rax; + unsigned irq; + ++ irq_show_regs_callback(smp_processor_id(), regs); ++ + exit_idle(); + irq_enter(); + irq = __get_cpu_var(vector_irq)[vector]; +Index: linux-2.6.24.7-rt21/arch/x86/kernel/nmi_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/nmi_32.c 2008-10-08 22:23:06.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/nmi_32.c 2008-10-08 22:23:22.000000000 -0400 +@@ -25,6 +25,7 @@ + + #include + #include ++#include + + #include "mach_traps.h" + +@@ -42,7 +43,7 @@ static cpumask_t backtrace_mask = CPU_MA + atomic_t nmi_active = ATOMIC_INIT(0); /* oprofile uses this */ + + unsigned int nmi_watchdog = NMI_DEFAULT; +-static unsigned int nmi_hz = HZ; ++static unsigned int nmi_hz = 1000; + + static DEFINE_PER_CPU(short, wd_enabled); + +@@ -93,7 +94,7 @@ static int __init check_nmi_watchdog(voi + for_each_possible_cpu(cpu) + prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count; + local_irq_enable(); +- mdelay((20*1000)/nmi_hz); // wait 20 ticks ++ mdelay((100*1000)/nmi_hz); /* wait 100 ticks */ + + for_each_possible_cpu(cpu) { + #ifdef CONFIG_SMP +@@ -318,6 +319,46 @@ EXPORT_SYMBOL(touch_nmi_watchdog); + + extern void die_nmi(struct pt_regs *, const char *msg); + ++int nmi_show_regs[NR_CPUS]; ++ ++void nmi_show_all_regs(void) ++{ ++ int i; ++ ++ if (system_state == SYSTEM_BOOTING) ++ return; ++ ++ printk(KERN_WARNING "nmi_show_all_regs(): start on CPU#%d.\n", ++ raw_smp_processor_id()); ++ dump_stack(); ++ ++ for_each_online_cpu(i) ++ nmi_show_regs[i] = 1; ++ ++ smp_send_nmi_allbutself(); ++ ++ for_each_online_cpu(i) { ++ while (nmi_show_regs[i] == 1) ++ barrier(); ++ } ++} ++ ++static DEFINE_SPINLOCK(nmi_print_lock); ++ ++void irq_show_regs_callback(int cpu, struct pt_regs *regs) ++{ ++ if (!nmi_show_regs[cpu]) ++ return; ++ ++ nmi_show_regs[cpu] = 0; ++ spin_lock(&nmi_print_lock); ++ printk(KERN_WARNING "NMI show regs on CPU#%d:\n", cpu); ++ printk(KERN_WARNING "apic_timer_irqs: %d\n", ++ per_cpu(irq_stat, cpu).apic_timer_irqs); ++ show_regs(regs); ++ spin_unlock(&nmi_print_lock); ++} ++ + notrace __kprobes int + nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) + { +@@ -332,6 +373,8 @@ nmi_watchdog_tick(struct pt_regs * regs, + int cpu = smp_processor_id(); + int rc=0; + ++ __profile_tick(CPU_PROFILING, regs); ++ + /* check for other users first */ + if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) + == NOTIFY_STOP) { +@@ -356,6 +399,9 @@ nmi_watchdog_tick(struct pt_regs * regs, + sum = per_cpu(irq_stat, cpu).apic_timer_irqs + + per_cpu(irq_stat, cpu).irq0_irqs; + ++ irq_show_regs_callback(cpu, regs); ++ ++ /* if the apic timer isn't firing, this cpu isn't doing much */ + /* if the none of the timers isn't firing, this cpu isn't doing much */ + if (!touched && last_irq_sums[cpu] == sum) { + /* +@@ -363,11 +409,30 @@ nmi_watchdog_tick(struct pt_regs * regs, + * wait a few IRQs (5 seconds) before doing the oops ... + */ + alert_counter[cpu]++; +- if (alert_counter[cpu] == 5*nmi_hz) +- /* +- * die_nmi will return ONLY if NOTIFY_STOP happens.. +- */ +- die_nmi(regs, "BUG: NMI Watchdog detected LOCKUP"); ++ if (alert_counter[cpu] && !(alert_counter[cpu] % (5*nmi_hz))) { ++ int i; ++ ++ spin_lock(&nmi_print_lock); ++ printk(KERN_WARNING "NMI watchdog detected lockup on " ++ "CPU#%d (%d/%d)\n", cpu, alert_counter[cpu], ++ 5*nmi_hz); ++ show_regs(regs); ++ spin_unlock(&nmi_print_lock); ++ ++ for_each_online_cpu(i) { ++ if (i == cpu) ++ continue; ++ nmi_show_regs[i] = 1; ++ while (nmi_show_regs[i] == 1) ++ cpu_relax(); ++ } ++ printk(KERN_WARNING "NMI watchdog running again ...\n"); ++ for_each_online_cpu(i) ++ alert_counter[i] = 0; ++ ++ ++ } ++ + } else { + last_irq_sums[cpu] = sum; + alert_counter[cpu] = 0; +@@ -465,5 +530,15 @@ void __trigger_all_cpu_backtrace(void) + } + } + ++void smp_send_nmi_allbutself(void) ++{ ++#ifdef CONFIG_SMP ++ cpumask_t mask = cpu_online_map; ++ cpu_clear(safe_smp_processor_id(), mask); ++ if (!cpus_empty(mask)) ++ send_IPI_mask(mask, NMI_VECTOR); ++#endif ++} ++ + EXPORT_SYMBOL(nmi_active); + EXPORT_SYMBOL(nmi_watchdog); +Index: linux-2.6.24.7-rt21/arch/x86/kernel/nmi_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/nmi_64.c 2008-10-08 22:23:06.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/nmi_64.c 2008-10-08 22:23:22.000000000 -0400 +@@ -20,11 +20,13 @@ + #include + #include + #include ++#include + + #include + #include + #include + #include ++#include + + int unknown_nmi_panic; + int nmi_watchdog_enabled; +@@ -42,7 +44,7 @@ atomic_t nmi_active = ATOMIC_INIT(0); / + int panic_on_timeout; + + unsigned int nmi_watchdog = NMI_DEFAULT; +-static unsigned int nmi_hz = HZ; ++static unsigned int nmi_hz = 1000; + + static DEFINE_PER_CPU(short, wd_enabled); + +@@ -301,7 +303,7 @@ void touch_nmi_watchdog(void) + unsigned cpu; + + /* +- * Tell other CPUs to reset their alert counters. We cannot ++ * Tell other CPUs to reset their alert counters. We cannot + * do it ourselves because the alert count increase is not + * atomic. + */ +@@ -314,6 +316,41 @@ void touch_nmi_watchdog(void) + touch_softlockup_watchdog(); + } + ++int nmi_show_regs[NR_CPUS]; ++ ++void nmi_show_all_regs(void) ++{ ++ int i; ++ ++ if (system_state == SYSTEM_BOOTING) ++ return; ++ ++ smp_send_nmi_allbutself(); ++ ++ for_each_online_cpu(i) ++ nmi_show_regs[i] = 1; ++ ++ for_each_online_cpu(i) { ++ while (nmi_show_regs[i] == 1) ++ barrier(); ++ } ++} ++ ++static DEFINE_SPINLOCK(nmi_print_lock); ++ ++void irq_show_regs_callback(int cpu, struct pt_regs *regs) ++{ ++ if (!nmi_show_regs[cpu]) ++ return; ++ ++ nmi_show_regs[cpu] = 0; ++ spin_lock(&nmi_print_lock); ++ printk(KERN_WARNING "NMI show regs on CPU#%d:\n", cpu); ++ printk(KERN_WARNING "apic_timer_irqs: %d\n", read_pda(apic_timer_irqs)); ++ show_regs(regs); ++ spin_unlock(&nmi_print_lock); ++} ++ + notrace int __kprobes + nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) + { +@@ -322,6 +359,9 @@ nmi_watchdog_tick(struct pt_regs * regs, + int cpu = smp_processor_id(); + int rc = 0; + ++ irq_show_regs_callback(cpu, regs); ++ __profile_tick(CPU_PROFILING, regs); ++ + /* check for other users first */ + if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) + == NOTIFY_STOP) { +@@ -358,9 +398,20 @@ nmi_watchdog_tick(struct pt_regs * regs, + * wait a few IRQs (5 seconds) before doing the oops ... + */ + local_inc(&__get_cpu_var(alert_counter)); +- if (local_read(&__get_cpu_var(alert_counter)) == 5*nmi_hz) ++ if (local_read(&__get_cpu_var(alert_counter)) == 5*nmi_hz) { ++ int i; ++ ++ for_each_online_cpu(i) { ++ if (i == cpu) ++ continue; ++ nmi_show_regs[i] = 1; ++ while (nmi_show_regs[i] == 1) ++ cpu_relax(); ++ } ++ + die_nmi("NMI Watchdog detected LOCKUP on CPU %d\n", regs, + panic_on_timeout); ++ } + } else { + __get_cpu_var(last_irq_sum) = sum; + local_set(&__get_cpu_var(alert_counter), 0); +@@ -478,6 +529,13 @@ void __trigger_all_cpu_backtrace(void) + } + } + ++void smp_send_nmi_allbutself(void) ++{ ++#ifdef CONFIG_SMP ++ send_IPI_allbutself(NMI_VECTOR); ++#endif ++} ++ + EXPORT_SYMBOL(nmi_active); + EXPORT_SYMBOL(nmi_watchdog); + EXPORT_SYMBOL(touch_nmi_watchdog); +Index: linux-2.6.24.7-rt21/include/asm-x86/apic_32.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/apic_32.h 2008-10-08 22:22:41.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/apic_32.h 2008-10-08 22:23:22.000000000 -0400 +@@ -118,6 +118,8 @@ extern int local_apic_timer_c2_ok; + + extern int local_apic_timer_disabled; + ++extern void smp_send_nmi_allbutself(void); ++ + #else /* !CONFIG_X86_LOCAL_APIC */ + static inline void lapic_shutdown(void) { } + #define local_apic_timer_c2_ok 1 +Index: linux-2.6.24.7-rt21/include/asm-x86/apic_64.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/apic_64.h 2008-10-08 22:22:41.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/apic_64.h 2008-10-08 22:23:22.000000000 -0400 +@@ -87,6 +87,8 @@ extern void setup_APIC_extended_lvt(unsi + + extern int apic_is_clustered_box(void); + ++extern void smp_send_nmi_allbutself(void); ++ + #define K8_APIC_EXT_LVT_BASE 0x500 + #define K8_APIC_EXT_INT_MSG_FIX 0x0 + #define K8_APIC_EXT_INT_MSG_SMI 0x2 +Index: linux-2.6.24.7-rt21/include/linux/profile.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/profile.h 2008-10-08 22:22:41.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/profile.h 2008-10-08 22:23:22.000000000 -0400 +@@ -23,6 +23,7 @@ struct notifier_block; + + /* init basic kernel profiler */ + void __init profile_init(void); ++void __profile_tick(int type, struct pt_regs *regs); + void profile_tick(int); + + /* +Index: linux-2.6.24.7-rt21/kernel/profile.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/profile.c 2008-10-08 22:22:41.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/profile.c 2008-10-08 22:23:22.000000000 -0400 +@@ -412,16 +412,19 @@ void profile_hits(int type, void *__pc, + + EXPORT_SYMBOL_GPL(profile_hits); + +-void profile_tick(int type) ++void __profile_tick(int type, struct pt_regs *regs) + { +- struct pt_regs *regs = get_irq_regs(); +- + if (type == CPU_PROFILING && timer_hook) + timer_hook(regs); + if (!user_mode(regs) && cpu_isset(smp_processor_id(), prof_cpu_mask)) + profile_hit(type, (void *)profile_pc(regs)); + } + ++void profile_tick(int type) ++{ ++ return __profile_tick(type, get_irq_regs()); ++} ++ + #ifdef CONFIG_PROC_FS + #include + #include +Index: linux-2.6.24.7-rt21/kernel/time/tick-common.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/time/tick-common.c 2008-10-08 22:22:41.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/time/tick-common.c 2008-10-08 22:23:22.000000000 -0400 +@@ -68,7 +68,6 @@ static void tick_periodic(int cpu) + } + + update_process_times(user_mode(get_irq_regs())); +- profile_tick(CPU_PROFILING); + } + + /* +Index: linux-2.6.24.7-rt21/kernel/time/tick-sched.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/time/tick-sched.c 2008-10-08 22:22:41.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/time/tick-sched.c 2008-10-08 22:23:22.000000000 -0400 +@@ -440,7 +440,6 @@ static void tick_nohz_handler(struct clo + } + + update_process_times(user_mode(regs)); +- profile_tick(CPU_PROFILING); + + /* Do not restart, when we are in the idle loop */ + if (ts->tick_stopped) +@@ -554,7 +553,6 @@ static enum hrtimer_restart tick_sched_t + */ + spin_unlock(&base->lock); + update_process_times(user_mode(regs)); +- profile_tick(CPU_PROFILING); + spin_lock(&base->lock); + } + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0486-marker-upstream-example.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0486-marker-upstream-example.patch @@ -0,0 +1,74 @@ +From: Steven Rostedt +Subject: markers: update samples to markers upstream. + +Update the marker sample code to match upstream. + +Signed-off-by: Steven Rostedt +--- + samples/markers/probe-example.c | 24 +++++++++--------------- + 1 file changed, 9 insertions(+), 15 deletions(-) + +Index: linux-2.6.24.7-rt21/samples/markers/probe-example.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/samples/markers/probe-example.c 2008-10-08 22:22:12.000000000 -0400 ++++ linux-2.6.24.7-rt21/samples/markers/probe-example.c 2008-10-08 22:25:00.000000000 -0400 +@@ -20,31 +20,27 @@ struct probe_data { + marker_probe_func *probe_func; + }; + +-void probe_subsystem_event(const struct marker *mdata, void *private, +- const char *format, ...) ++void probe_subsystem_event(void *private, void *calldata, ++ const char *format, va_list *args) + { +- va_list ap; + /* Declare args */ + unsigned int value; + const char *mystr; + + /* Assign args */ +- va_start(ap, format); +- value = va_arg(ap, typeof(value)); +- mystr = va_arg(ap, typeof(mystr)); ++ value = va_arg(*args, typeof(value)); ++ mystr = va_arg(*args, typeof(mystr)); + + /* Call printk */ + printk(KERN_DEBUG "Value %u, string %s\n", value, mystr); + + /* or count, check rights, serialize data in a buffer */ +- +- va_end(ap); + } + + atomic_t eventb_count = ATOMIC_INIT(0); + +-void probe_subsystem_eventb(const struct marker *mdata, void *private, +- const char *format, ...) ++void probe_subsystem_eventb(void *private, void *calldata, ++ const char *format, va_list *args) + { + /* Increment counter */ + atomic_inc(&eventb_count); +@@ -72,10 +68,6 @@ static int __init probe_init(void) + if (result) + printk(KERN_INFO "Unable to register probe %s\n", + probe_array[i].name); +- result = marker_arm(probe_array[i].name); +- if (result) +- printk(KERN_INFO "Unable to arm probe %s\n", +- probe_array[i].name); + } + return 0; + } +@@ -85,7 +77,9 @@ static void __exit probe_fini(void) + int i; + + for (i = 0; i < ARRAY_SIZE(probe_array); i++) +- marker_probe_unregister(probe_array[i].name); ++ marker_probe_unregister(probe_array[i].name, ++ probe_array[i].probe_func, &probe_array[i]); ++ + printk(KERN_INFO "Number of event b : %u\n", + atomic_read(&eventb_count)); + } --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0526-bz235099-idle-load-fix.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0526-bz235099-idle-load-fix.patch @@ -0,0 +1,153 @@ +Michal Schmidt's fix for load average calculation + +From: Michal Schmidt + +Subject: Re: [PATCH] idle load == # of CPUs + +This is an attempt to fix https://bugzilla.redhat.com/show_bug.cgi?id=253099 + +The bug is caused by the fact that the local timer interrupts happen usually +at the same time on all CPUs. All CPUs then raise their timer softirqs. When +calc_load() runs, it sees not only itself but all the other softirq-timer +per-cpu threads running too. And softirq-sched too, which is woken up from +scheduler_tick(). + +In a BZ comment I speculated about three possible solutions: +(a) Somehow make sure the timer interrupts are synchronized between CPUs, but with a per-CPU offset, so that they don't fire at the same time. +(b) Make the timer softirq threads (and softirq-sched?) special and not take them into loadavg calculation. +(c) Don't calculate loadavg from the timer softirq. It should be possible to run calc_load() periodically from a hrtimer. + +This patch implements (b). +Comments welcome. + +Michal +--- + + fs/proc/proc_misc.c | 22 ++++++++++++++++------ + kernel/timer.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 64 insertions(+), 7 deletions(-) + +Index: linux-2.6.24.7-rt21/fs/proc/proc_misc.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/proc/proc_misc.c 2008-10-08 22:24:15.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/proc/proc_misc.c 2008-10-08 22:25:10.000000000 -0400 +@@ -83,10 +83,15 @@ static int loadavg_read_proc(char *page, + { + int a, b, c; + int len; ++ unsigned long seq; ++ ++ do { ++ seq = read_seqbegin(&xtime_lock); ++ a = avenrun[0] + (FIXED_1/200); ++ b = avenrun[1] + (FIXED_1/200); ++ c = avenrun[2] + (FIXED_1/200); ++ } while (read_seqretry(&xtime_lock, seq)); + +- a = avenrun[0] + (FIXED_1/200); +- b = avenrun[1] + (FIXED_1/200); +- c = avenrun[2] + (FIXED_1/200); + len = sprintf(page,"%d.%02d %d.%02d %d.%02d %ld/%d %d\n", + LOAD_INT(a), LOAD_FRAC(a), + LOAD_INT(b), LOAD_FRAC(b), +@@ -104,10 +109,15 @@ static int loadavg_rt_read_proc(char *pa + extern unsigned long rt_nr_running(void); + int a, b, c; + int len; ++ unsigned long seq; ++ ++ do { ++ seq = read_seqbegin(&xtime_lock); ++ a = avenrun_rt[0] + (FIXED_1/200); ++ b = avenrun_rt[1] + (FIXED_1/200); ++ c = avenrun_rt[2] + (FIXED_1/200); ++ } while (read_seqretry(&xtime_lock, seq)); + +- a = avenrun_rt[0] + (FIXED_1/200); +- b = avenrun_rt[1] + (FIXED_1/200); +- c = avenrun_rt[2] + (FIXED_1/200); + len = sprintf(page,"%d.%02d %d.%02d %d.%02d %ld/%d %d\n", + LOAD_INT(a), LOAD_FRAC(a), + LOAD_INT(b), LOAD_FRAC(b), +Index: linux-2.6.24.7-rt21/kernel/timer.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/timer.c 2008-10-08 22:24:49.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/timer.c 2008-10-08 22:25:10.000000000 -0400 +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -929,7 +930,7 @@ void update_process_times(int user_tick) + static unsigned long count_active_tasks(void) + { + /* +- * On PREEMPT_RT, we are running in the timer softirq thread, ++ * On PREEMPT_RT, we are running in the loadavg thread, + * so consider 1 less running tasks: + */ + #ifdef CONFIG_PREEMPT_RT +@@ -999,6 +1000,50 @@ static inline void calc_load(unsigned lo + } + } + ++#ifdef CONFIG_PREEMPT_RT ++static int loadavg_calculator(void *data) ++{ ++ unsigned long now, last; ++ ++ last = jiffies; ++ while (!kthread_should_stop()) { ++ struct timespec delay = { ++ .tv_sec = LOAD_FREQ / HZ, ++ .tv_nsec = 0 ++ }; ++ ++ hrtimer_nanosleep(&delay, NULL, HRTIMER_MODE_REL, ++ CLOCK_MONOTONIC); ++ now = jiffies; ++ write_seqlock_irq(&xtime_lock); ++ calc_load(now - last); ++ write_sequnlock_irq(&xtime_lock); ++ last = now; ++ } ++ ++ return 0; ++} ++ ++static int __init start_loadavg_calculator(void) ++{ ++ struct task_struct *p; ++ struct sched_param param = { .sched_priority = MAX_USER_RT_PRIO/2 }; ++ ++ p = kthread_create(loadavg_calculator, NULL, "loadavg"); ++ if (IS_ERR(p)) { ++ printk(KERN_ERR "Could not create the loadavg thread.\n"); ++ return 1; ++ } ++ ++ sched_setscheduler(p, SCHED_FIFO, ¶m); ++ wake_up_process(p); ++ ++ return 0; ++} ++ ++late_initcall(start_loadavg_calculator); ++#endif ++ + /* + * Called by the local, per-CPU timer interrupt on SMP. + */ +@@ -1027,7 +1072,9 @@ static inline void update_times(void) + ticks = jiffies - last_tick; + if (ticks) { + last_tick += ticks; ++#ifndef CONFIG_PREEMPT_RT + calc_load(ticks); ++#endif + } + write_sequnlock_irqrestore(&xtime_lock, flags); + } --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0360-call_rcu_bh-rename-of-call_rcu.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0360-call_rcu_bh-rename-of-call_rcu.patch @@ -0,0 +1,49 @@ +Subject: [PATCH] just rename call_rcu_bh instead of making it a macro + +Seems that I found a box that has a config that passes call_rcu_bh as a +function pointer (see net/sctp/sm_make_chunk.c), so declaring the +call_rcu_bh has a macro function isn't good enough. + +This patch makes it just another name of call_rcu for rcupreempt. + +Signed-off-by: Steven Rostedt + +--- + include/linux/rcupdate.h | 4 ++-- + include/linux/rcupreempt.h | 7 ++++++- + 2 files changed, 8 insertions(+), 3 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/rcupdate.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/rcupdate.h 2008-10-08 22:23:26.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/rcupdate.h 2008-10-08 22:24:30.000000000 -0400 +@@ -221,9 +221,9 @@ extern struct lockdep_map rcu_lock_map; + * and may be nested. + */ + #ifdef CONFIG_CLASSIC_RCU +-#define call_rcu(head, func) call_rcu_classic(head, func) ++#define call_rcu call_rcu_classic + #else /* #ifdef CONFIG_CLASSIC_RCU */ +-#define call_rcu(head, func) call_rcu_preempt(head, func) ++#define call_rcu call_rcu_preempt + #endif /* #else #ifdef CONFIG_CLASSIC_RCU */ + + /** +Index: linux-2.6.24.7-rt21/include/linux/rcupreempt.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/rcupreempt.h 2008-10-08 22:23:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/rcupreempt.h 2008-10-08 22:24:30.000000000 -0400 +@@ -42,7 +42,12 @@ + #include + #include + +-#define call_rcu_bh(head, rcu) call_rcu(head, rcu) ++/* ++ * Someone might want to pass call_rcu_bh as a function pointer. ++ * So this needs to just be a rename and not a macro function. ++ * (no parentheses) ++ */ ++#define call_rcu_bh call_rcu_preempt + #define rcu_bh_qsctr_inc(cpu) do { } while (0) + #define __rcu_read_lock_bh() { rcu_read_lock(); local_bh_disable(); } + #define __rcu_read_unlock_bh() { local_bh_enable(); rcu_read_unlock(); } --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0050-0037-sched-whitespace-cleanups-in-topology.h.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0050-0037-sched-whitespace-cleanups-in-topology.h.patch @@ -0,0 +1,26 @@ +From e7e60ed8c8913b8bcebab7e9147d32b3aa430fb8 Mon Sep 17 00:00:00 2001 +From: Ingo Molnar +Date: Tue, 11 Dec 2007 10:02:47 +0100 +Subject: [PATCH] sched: whitespace cleanups in topology.h + +whitespace cleanups in topology.h. + +Signed-off-by: Ingo Molnar + +--- + include/linux/topology.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/include/linux/topology.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/topology.h 2008-10-08 22:22:46.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/topology.h 2008-10-08 22:23:03.000000000 -0400 +@@ -5,7 +5,7 @@ + * + * Copyright (C) 2002, IBM Corp. + * +- * All rights reserved. ++ * 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 --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0190-bh-state-lock.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0190-bh-state-lock.patch @@ -0,0 +1,100 @@ + +I was compiling a kernel in a shell that I set to a priority of 20, +and it locked up on the bit_spin_lock crap of jbd. + +This patch adds another spinlock to the buffer head and uses that +instead of the bit_spins. + +From: Steven Rostedt +Signed-off-by: Ingo Molnar + +-- + + fs/buffer.c | 3 ++- + include/linux/buffer_head.h | 1 + + include/linux/jbd.h | 12 ++++++------ + 3 files changed, 9 insertions(+), 7 deletions(-) + +Index: linux-2.6.24.7-rt21/fs/buffer.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/buffer.c 2008-10-08 22:23:44.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/buffer.c 2008-10-08 22:23:44.000000000 -0400 +@@ -40,7 +40,6 @@ + #include + #include + #include +-#include + + static int fsync_buffers_list(spinlock_t *lock, struct list_head *list); + +@@ -3167,6 +3166,7 @@ struct buffer_head *alloc_buffer_head(gf + if (ret) { + INIT_LIST_HEAD(&ret->b_assoc_buffers); + spin_lock_init(&ret->b_uptodate_lock); ++ spin_lock_init(&ret->b_state_lock); + get_cpu_var(bh_accounting).nr++; + recalc_bh_state(); + put_cpu_var(bh_accounting); +@@ -3179,6 +3179,7 @@ void free_buffer_head(struct buffer_head + { + BUG_ON(!list_empty(&bh->b_assoc_buffers)); + BUG_ON(spin_is_locked(&bh->b_uptodate_lock)); ++ BUG_ON(spin_is_locked(&bh->b_state_lock)); + kmem_cache_free(bh_cachep, bh); + get_cpu_var(bh_accounting).nr--; + recalc_bh_state(); +Index: linux-2.6.24.7-rt21/include/linux/buffer_head.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/buffer_head.h 2008-10-08 22:23:44.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/buffer_head.h 2008-10-08 22:23:44.000000000 -0400 +@@ -70,6 +70,7 @@ struct buffer_head { + associated with */ + atomic_t b_count; /* users using this buffer_head */ + spinlock_t b_uptodate_lock; ++ spinlock_t b_state_lock; + }; + + /* +Index: linux-2.6.24.7-rt21/include/linux/jbd.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/jbd.h 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/jbd.h 2008-10-08 22:23:44.000000000 -0400 +@@ -319,32 +319,32 @@ static inline struct journal_head *bh2jh + + static inline void jbd_lock_bh_state(struct buffer_head *bh) + { +- bit_spin_lock(BH_State, &bh->b_state); ++ spin_lock(&bh->b_state_lock); + } + + static inline int jbd_trylock_bh_state(struct buffer_head *bh) + { +- return bit_spin_trylock(BH_State, &bh->b_state); ++ return spin_trylock(&bh->b_state_lock); + } + + static inline int jbd_is_locked_bh_state(struct buffer_head *bh) + { +- return bit_spin_is_locked(BH_State, &bh->b_state); ++ return spin_is_locked(&bh->b_state_lock); + } + + static inline void jbd_unlock_bh_state(struct buffer_head *bh) + { +- bit_spin_unlock(BH_State, &bh->b_state); ++ spin_unlock(&bh->b_state_lock); + } + + static inline void jbd_lock_bh_journal_head(struct buffer_head *bh) + { +- bit_spin_lock(BH_JournalHead, &bh->b_state); ++ spin_lock_irq(&bh->b_uptodate_lock); + } + + static inline void jbd_unlock_bh_journal_head(struct buffer_head *bh) + { +- bit_spin_unlock(BH_JournalHead, &bh->b_state); ++ spin_unlock_irq(&bh->b_uptodate_lock); + } + + struct jbd_revoke_table_s; --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0281-s_files-pipe-fix.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0281-s_files-pipe-fix.patch @@ -0,0 +1,38 @@ +Subject: s_files: free_write_pipe() fix +From: Ingo Molnar + +file_kill() has to look at the file's inode (for the barrier logic), +hence make sure we free the inode before the file. + +Signed-off-by: Ingo Molnar +--- + fs/pipe.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +Index: linux-2.6.24.7-rt21/fs/pipe.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/pipe.c 2008-10-08 22:24:00.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/pipe.c 2008-10-08 22:24:11.000000000 -0400 +@@ -1011,12 +1011,17 @@ struct file *create_write_pipe(void) + return ERR_PTR(err); + } + +-void free_write_pipe(struct file *f) ++void free_write_pipe(struct file *file) + { +- free_pipe_info(f->f_dentry->d_inode); +- dput(f->f_path.dentry); +- mntput(f->f_path.mnt); +- put_filp(f); ++ struct dentry *dentry = file->f_path.dentry; ++ struct vfsmount *mnt = file->f_path.mnt; ++ ++ free_pipe_info(file->f_dentry->d_inode); ++ file->f_path.dentry = NULL; ++ file->f_path.mnt = NULL; ++ put_filp(file); ++ dput(dentry); ++ mntput(mnt); + } + + struct file *create_read_pipe(struct file *wrf) --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0502-rwlock-slowunlock-mutex-fix.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0502-rwlock-slowunlock-mutex-fix.patch @@ -0,0 +1,32 @@ +From: Steven Rostedt +Subject: rwlock: reset mutex on multilpe readers in unlock + +Reset the rwlock mutex owner to readers if the lock is currently held +by other readers. + +Signed-off-by: Steven Rostedt +--- + kernel/rtmutex.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +Index: linux-2.6.24.7-rt21/kernel/rtmutex.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rtmutex.c 2008-10-08 22:25:04.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rtmutex.c 2008-10-08 22:25:04.000000000 -0400 +@@ -1795,6 +1795,16 @@ rt_read_slowunlock(struct rw_mutex *rwm, + + wakeup_next_waiter(mutex, savestate); + ++ /* ++ * If we woke up a reader but the lock is already held by readers ++ * we need to set the mutex owner to RT_RW_READER, since the ++ * wakeup_next_waiter set it to the pending reader. ++ */ ++ if (reader_count) { ++ WARN_ON(waiter->write_lock); ++ rt_mutex_set_owner(mutex, RT_RW_READER, 0); ++ } ++ + if (rt_mutex_has_waiters(mutex)) { + waiter = rt_mutex_top_waiter(mutex); + rwm->prio = waiter->task->prio; --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0477-adapt-remove-extra-try-to-lock.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0477-adapt-remove-extra-try-to-lock.patch @@ -0,0 +1,44 @@ +From ghaskins@novell.com Sat May 24 00:14:29 2008 +Date: Tue, 20 May 2008 10:49:36 -0400 +From: Gregory Haskins +To: mingo@elte.hu, tglx@linutronix.de, rostedt@goodmis.org, + linux-rt-users@vger.kernel.org +Cc: linux-kernel@vger.kernel.org, sdietrich@novell.com, pmorreale@novell.com, + mkohari@novell.com, ghaskins@novell.com +Subject: [PATCH 5/5] remove the extra call to try_to_take_lock + + [ The following text is in the "utf-8" character set. ] + [ Your display is set for the "iso-8859-1" character set. ] + [ Some characters may be displayed incorrectly. ] + +From: Peter W. Morreale + +Remove the redundant attempt to get the lock. While it is true that the +exit path with this patch adds an un-necessary xchg (in the event the +lock is granted without further traversal in the loop) experimentation +shows that we almost never encounter this situation. + +Signed-off-by: Peter W. Morreale +Signed-off-by: Gregory Haskins +--- + + kernel/rtmutex.c | 6 ------ + 1 file changed, 6 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/rtmutex.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rtmutex.c 2008-10-08 22:24:58.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rtmutex.c 2008-10-08 22:24:58.000000000 -0400 +@@ -842,12 +842,6 @@ rt_spin_lock_slowlock(struct rt_mutex *l + spin_lock_irqsave(&lock->wait_lock, flags); + init_lists(lock); + +- /* Try to acquire the lock again: */ +- if (do_try_to_take_rt_mutex(lock, STEAL_LATERAL)) { +- spin_unlock_irqrestore(&lock->wait_lock, flags); +- return; +- } +- + BUG_ON(rt_mutex_owner(lock) == current); + + /* --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0197-kstat-add-rt-stats.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0197-kstat-add-rt-stats.patch @@ -0,0 +1,131 @@ +From: Thomas Gleixner +Subject: add rt stats to /proc/stat + +add RT stats to /proc/stat + +Signed-off-by: Ingo Molnar + + fs/proc/proc_misc.c | 24 ++++++++++++++++++------ + include/linux/kernel_stat.h | 2 ++ + kernel/sched.c | 6 +++++- + 3 files changed, 25 insertions(+), 7 deletions(-) + +Index: linux-2.6.24.7-rt21/fs/proc/proc_misc.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/proc/proc_misc.c 2008-10-08 22:22:33.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/proc/proc_misc.c 2008-10-08 22:23:46.000000000 -0400 +@@ -455,7 +455,8 @@ static int show_stat(struct seq_file *p, + { + int i; + unsigned long jif; +- cputime64_t user, nice, system, idle, iowait, irq, softirq, steal; ++ cputime64_t user_rt, user, nice, system_rt, system, idle, ++ iowait, irq, softirq, steal; + cputime64_t guest; + u64 sum = 0; + struct timespec boottime; +@@ -465,7 +466,7 @@ static int show_stat(struct seq_file *p, + if (!per_irq_sum) + return -ENOMEM; + +- user = nice = system = idle = iowait = ++ user_rt = user = nice = system_rt = system = idle = iowait = + irq = softirq = steal = cputime64_zero; + guest = cputime64_zero; + getboottime(&boottime); +@@ -482,6 +483,8 @@ static int show_stat(struct seq_file *p, + irq = cputime64_add(irq, kstat_cpu(i).cpustat.irq); + softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq); + steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal); ++ user_rt = cputime64_add(user_rt, kstat_cpu(i).cpustat.user_rt); ++ system_rt = cputime64_add(system_rt, kstat_cpu(i).cpustat.system_rt); + guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest); + for (j = 0; j < NR_IRQS; j++) { + unsigned int temp = kstat_cpu(i).irqs[j]; +@@ -490,7 +493,10 @@ static int show_stat(struct seq_file *p, + } + } + +- seq_printf(p, "cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n", ++ user = cputime64_add(user_rt, user); ++ system = cputime64_add(system_rt, system); ++ ++ seq_printf(p, "cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n", + (unsigned long long)cputime64_to_clock_t(user), + (unsigned long long)cputime64_to_clock_t(nice), + (unsigned long long)cputime64_to_clock_t(system), +@@ -499,13 +505,17 @@ static int show_stat(struct seq_file *p, + (unsigned long long)cputime64_to_clock_t(irq), + (unsigned long long)cputime64_to_clock_t(softirq), + (unsigned long long)cputime64_to_clock_t(steal), ++ (unsigned long long)cputime64_to_clock_t(user_rt), ++ (unsigned long long)cputime64_to_clock_t(system_rt), + (unsigned long long)cputime64_to_clock_t(guest)); + for_each_online_cpu(i) { + + /* Copy values here to work around gcc-2.95.3, gcc-2.96 */ +- user = kstat_cpu(i).cpustat.user; ++ user_rt = kstat_cpu(i).cpustat.user_rt; ++ system_rt = kstat_cpu(i).cpustat.system_rt; ++ user = cputime64_add(user_rt, kstat_cpu(i).cpustat.user); + nice = kstat_cpu(i).cpustat.nice; +- system = kstat_cpu(i).cpustat.system; ++ system = cputime64_add(system_rt, kstat_cpu(i).cpustat.system); + idle = kstat_cpu(i).cpustat.idle; + iowait = kstat_cpu(i).cpustat.iowait; + irq = kstat_cpu(i).cpustat.irq; +@@ -513,7 +523,7 @@ static int show_stat(struct seq_file *p, + steal = kstat_cpu(i).cpustat.steal; + guest = kstat_cpu(i).cpustat.guest; + seq_printf(p, +- "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu %llu\n", ++ "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n", + i, + (unsigned long long)cputime64_to_clock_t(user), + (unsigned long long)cputime64_to_clock_t(nice), +@@ -523,6 +533,8 @@ static int show_stat(struct seq_file *p, + (unsigned long long)cputime64_to_clock_t(irq), + (unsigned long long)cputime64_to_clock_t(softirq), + (unsigned long long)cputime64_to_clock_t(steal), ++ (unsigned long long)cputime64_to_clock_t(user_rt), ++ (unsigned long long)cputime64_to_clock_t(system_rt), + (unsigned long long)cputime64_to_clock_t(guest)); + } + seq_printf(p, "intr %llu", (unsigned long long)sum); +Index: linux-2.6.24.7-rt21/include/linux/kernel_stat.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/kernel_stat.h 2008-10-08 22:22:33.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/kernel_stat.h 2008-10-08 22:23:46.000000000 -0400 +@@ -23,6 +23,8 @@ struct cpu_usage_stat { + cputime64_t idle; + cputime64_t iowait; + cputime64_t steal; ++ cputime64_t user_rt; ++ cputime64_t system_rt; + cputime64_t guest; + }; + +Index: linux-2.6.24.7-rt21/kernel/sched.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched.c 2008-10-08 22:23:37.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched.c 2008-10-08 22:23:46.000000000 -0400 +@@ -3450,7 +3450,9 @@ void account_user_time(struct task_struc + + /* Add user time to cpustat. */ + tmp = cputime_to_cputime64(cputime); +- if (TASK_NICE(p) > 0) ++ if (rt_task(p)) ++ cpustat->user_rt = cputime64_add(cpustat->user_rt, tmp); ++ else if (TASK_NICE(p) > 0) + cpustat->nice = cputime64_add(cpustat->nice, tmp); + else + cpustat->user = cputime64_add(cpustat->user, tmp); +@@ -3509,6 +3511,8 @@ void account_system_time(struct task_str + cpustat->irq = cputime64_add(cpustat->irq, tmp); + else if (softirq_count() || (p->flags & PF_SOFTIRQ)) + cpustat->softirq = cputime64_add(cpustat->softirq, tmp); ++ else if (rt_task(p)) ++ cpustat->system_rt = cputime64_add(cpustat->system_rt, tmp); + else if (p != rq->idle) + cpustat->system = cputime64_add(cpustat->system, tmp); + else if (atomic_read(&rq->nr_iowait) > 0) --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0392-send-nmi-all-preempt-disable.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0392-send-nmi-all-preempt-disable.patch @@ -0,0 +1,35 @@ +--- + arch/x86/kernel/nmi_32.c | 2 ++ + arch/x86/kernel/nmi_64.c | 2 ++ + 2 files changed, 4 insertions(+) + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/nmi_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/nmi_32.c 2008-10-08 22:24:19.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/nmi_32.c 2008-10-08 22:24:38.000000000 -0400 +@@ -538,9 +538,11 @@ void smp_send_nmi_allbutself(void) + { + #ifdef CONFIG_SMP + cpumask_t mask = cpu_online_map; ++ preempt_disable(); + cpu_clear(safe_smp_processor_id(), mask); + if (!cpus_empty(mask)) + send_IPI_mask(mask, NMI_VECTOR); ++ preempt_enable(); + #endif + } + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/nmi_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/nmi_64.c 2008-10-08 22:24:29.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/nmi_64.c 2008-10-08 22:24:38.000000000 -0400 +@@ -539,7 +539,9 @@ void __trigger_all_cpu_backtrace(void) + void smp_send_nmi_allbutself(void) + { + #ifdef CONFIG_SMP ++ preempt_disable(); + send_IPI_allbutself(NMI_VECTOR); ++ preempt_enable(); + #endif + } + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0286-s_files.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0286-s_files.patch @@ -0,0 +1,322 @@ +Subject: remove global files_lock + +remove the global files_lock by reworking super_block and tty file lists. +these are replaced by percpu_lists which are fine grain locked lists +(lock_list) with a per cpu list head. + +Signed-off-by: Peter Zijlstra +--- + drivers/char/tty_io.c | 23 ++++++++++------------- + fs/file_table.c | 34 ++++++++++++++++++---------------- + fs/proc/generic.c | 2 ++ + fs/super.c | 12 ++++++++---- + include/linux/fs.h | 14 +++++++------- + include/linux/tty.h | 2 +- + security/selinux/hooks.c | 9 ++++++--- + 7 files changed, 52 insertions(+), 44 deletions(-) + +Index: linux-2.6.24.7-rt21/drivers/char/tty_io.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/char/tty_io.c 2008-10-08 22:24:02.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/char/tty_io.c 2008-10-08 22:24:12.000000000 -0400 +@@ -242,14 +242,13 @@ int tty_paranoia_check(struct tty_struct + static int check_tty_count(struct tty_struct *tty, const char *routine) + { + #ifdef CHECK_TTY_COUNT +- struct list_head *p; ++ struct file *filp; + int count = 0; +- +- file_list_lock(); +- list_for_each(p, &tty->tty_files) { ++ ++ percpu_list_fold(&tty->tty_files); ++ lock_list_for_each_entry(filp, percpu_list_head(&tty->tty_files), f_u.fu_llist) + count++; +- } +- file_list_unlock(); ++ + if (tty->driver->type == TTY_DRIVER_TYPE_PTY && + tty->driver->subtype == PTY_TYPE_SLAVE && + tty->link && tty->link->count) +@@ -1376,9 +1375,8 @@ static void do_tty_hangup(struct work_st + spin_unlock(&redirect_lock); + + check_tty_count(tty, "do_tty_hangup"); +- file_list_lock(); + /* This breaks for file handles being sent over AF_UNIX sockets ? */ +- list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) { ++ lock_list_for_each_entry(filp, percpu_list_head(&tty->tty_files), f_u.fu_llist) { + if (filp->f_op->write == redirected_tty_write) + cons_filp = filp; + if (filp->f_op->write != tty_write) +@@ -1387,7 +1385,6 @@ static void do_tty_hangup(struct work_st + tty_fasync(-1, filp, 0); /* can't block */ + filp->f_op = &hung_up_tty_fops; + } +- file_list_unlock(); + + /* FIXME! What are the locking issues here? This may me overdoing things.. + * this question is especially important now that we've removed the irqlock. */ +@@ -2268,9 +2265,9 @@ static void release_one_tty(struct tty_s + tty->magic = 0; + tty->driver->refcount--; + +- file_list_lock(); +- list_del_init(&tty->tty_files); +- file_list_unlock(); ++ percpu_list_fold(&tty->tty_files); ++ lock_list_del_init(percpu_list_head(&tty->tty_files)); ++ percpu_list_destroy(&tty->tty_files); + + free_tty_struct(tty); + } +@@ -3734,7 +3731,7 @@ static void initialize_tty_struct(struct + mutex_init(&tty->atomic_read_lock); + mutex_init(&tty->atomic_write_lock); + spin_lock_init(&tty->read_lock); +- INIT_LIST_HEAD(&tty->tty_files); ++ percpu_list_init(&tty->tty_files); + INIT_WORK(&tty->SAK_work, do_SAK_work); + } + +Index: linux-2.6.24.7-rt21/fs/file_table.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/file_table.c 2008-10-08 22:22:25.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/file_table.c 2008-10-08 22:24:12.000000000 -0400 +@@ -28,9 +28,6 @@ struct files_stat_struct files_stat = { + .max_files = NR_FILE + }; + +-/* public. Not pretty! */ +-__cacheline_aligned_in_smp DEFINE_SPINLOCK(files_lock); +- + static struct percpu_counter nr_files __cacheline_aligned_in_smp; + + static inline void file_free_rcu(struct rcu_head *head) +@@ -111,7 +108,7 @@ struct file *get_empty_filp(void) + goto fail_sec; + + tsk = current; +- INIT_LIST_HEAD(&f->f_u.fu_list); ++ INIT_LOCK_LIST_HEAD(&f->f_u.fu_llist); + atomic_set(&f->f_count, 1); + rwlock_init(&f->f_owner.lock); + f->f_uid = tsk->fsuid; +@@ -303,31 +300,35 @@ void put_filp(struct file *file) + } + } + +-void file_move(struct file *file, struct list_head *list) ++void file_move(struct file *file, struct percpu_list *list) + { + if (!list) + return; +- file_list_lock(); +- list_move(&file->f_u.fu_list, list); +- file_list_unlock(); ++ ++ file_kill(file); ++ percpu_list_add(list, &file->f_u.fu_llist); + } + + void file_kill(struct file *file) + { +- if (!list_empty(&file->f_u.fu_list)) { +- file_list_lock(); +- list_del_init(&file->f_u.fu_list); +- file_list_unlock(); ++ if (file && file->f_mapping && file->f_mapping->host) { ++ struct super_block *sb = file->f_mapping->host->i_sb; ++ if (sb) ++ synchronize_qrcu(&sb->s_qrcu); + } ++ ++ lock_list_del_init(&file->f_u.fu_llist); + } + + int fs_may_remount_ro(struct super_block *sb) + { + struct file *file; ++ int idx; + + /* Check that no files are currently opened for writing. */ +- file_list_lock(); +- list_for_each_entry(file, &sb->s_files, f_u.fu_list) { ++ idx = qrcu_read_lock(&sb->s_qrcu); ++ percpu_list_fold(&sb->s_files); ++ lock_list_for_each_entry(file, percpu_list_head(&sb->s_files), f_u.fu_llist) { + struct inode *inode = file->f_path.dentry->d_inode; + + /* File with pending delete? */ +@@ -338,10 +339,11 @@ int fs_may_remount_ro(struct super_block + if (S_ISREG(inode->i_mode) && (file->f_mode & FMODE_WRITE)) + goto too_bad; + } +- file_list_unlock(); ++ qrcu_read_unlock(&sb->s_qrcu, idx); + return 1; /* Tis' cool bro. */ + too_bad: +- file_list_unlock(); ++ lock_list_for_each_entry_stop(file, f_u.fu_llist); ++ qrcu_read_unlock(&sb->s_qrcu, idx); + return 0; + } + +Index: linux-2.6.24.7-rt21/fs/proc/generic.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/proc/generic.c 2008-10-08 22:22:25.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/proc/generic.c 2008-10-08 22:24:12.000000000 -0400 +@@ -698,6 +698,8 @@ void remove_proc_entry(const char *name, + goto out; + len = strlen(fn); + ++ percpu_list_fold(&proc_mnt->mnt_sb->s_files); ++ + spin_lock(&proc_subdir_lock); + for (p = &parent->subdir; *p; p=&(*p)->next ) { + if (!proc_match(len, fn, *p)) +Index: linux-2.6.24.7-rt21/fs/super.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/super.c 2008-10-08 22:22:25.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/super.c 2008-10-08 22:24:12.000000000 -0400 +@@ -64,7 +64,8 @@ static struct super_block *alloc_super(s + INIT_LIST_HEAD(&s->s_dirty); + INIT_LIST_HEAD(&s->s_io); + INIT_LIST_HEAD(&s->s_more_io); +- INIT_LIST_HEAD(&s->s_files); ++ percpu_list_init(&s->s_files); ++ init_qrcu_struct(&s->s_qrcu); + INIT_LIST_HEAD(&s->s_instances); + INIT_HLIST_HEAD(&s->s_anon); + INIT_LIST_HEAD(&s->s_inodes); +@@ -103,6 +104,7 @@ out: + */ + static inline void destroy_super(struct super_block *s) + { ++ percpu_list_destroy(&s->s_files); + security_sb_free(s); + kfree(s->s_subtype); + kfree(s); +@@ -565,13 +567,15 @@ out: + static void mark_files_ro(struct super_block *sb) + { + struct file *f; ++ int idx; + +- file_list_lock(); +- list_for_each_entry(f, &sb->s_files, f_u.fu_list) { ++ idx = qrcu_read_lock(&sb->s_qrcu); ++ percpu_list_fold(&sb->s_files); ++ lock_list_for_each_entry(f, percpu_list_head(&sb->s_files), f_u.fu_llist) { + if (S_ISREG(f->f_path.dentry->d_inode->i_mode) && file_count(f)) + f->f_mode &= ~FMODE_WRITE; + } +- file_list_unlock(); ++ qrcu_read_unlock(&sb->s_qrcu, idx); + } + + /** +Index: linux-2.6.24.7-rt21/include/linux/fs.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/fs.h 2008-10-08 22:22:25.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/fs.h 2008-10-08 22:24:12.000000000 -0400 +@@ -279,12 +279,14 @@ extern int dir_notify_enable; + #include + #include + #include ++#include + #include + #include + #include + #include + #include + #include ++#include + + #include + #include +@@ -776,11 +778,11 @@ static inline int ra_has_index(struct fi + + struct file { + /* +- * fu_list becomes invalid after file_free is called and queued via ++ * fu_llist becomes invalid after file_free is called and queued via + * fu_rcuhead for RCU freeing + */ + union { +- struct list_head fu_list; ++ struct lock_list_head fu_llist; + struct rcu_head fu_rcuhead; + } f_u; + struct path f_path; +@@ -809,9 +811,6 @@ struct file { + #endif /* #ifdef CONFIG_EPOLL */ + struct address_space *f_mapping; + }; +-extern spinlock_t files_lock; +-#define file_list_lock() spin_lock(&files_lock); +-#define file_list_unlock() spin_unlock(&files_lock); + + #define get_file(x) atomic_inc(&(x)->f_count) + #define file_count(x) atomic_read(&(x)->f_count) +@@ -1007,7 +1006,8 @@ struct super_block { + struct list_head s_io; /* parked for writeback */ + struct list_head s_more_io; /* parked for more writeback */ + struct hlist_head s_anon; /* anonymous dentries for (nfs) exporting */ +- struct list_head s_files; ++ struct percpu_list s_files; ++ struct qrcu_struct s_qrcu; + + struct block_device *s_bdev; + struct mtd_info *s_mtd; +@@ -1777,7 +1777,7 @@ static inline void insert_inode_hash(str + } + + extern struct file * get_empty_filp(void); +-extern void file_move(struct file *f, struct list_head *list); ++extern void file_move(struct file *f, struct percpu_list *list); + extern void file_kill(struct file *f); + #ifdef CONFIG_BLOCK + struct bio; +Index: linux-2.6.24.7-rt21/include/linux/tty.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/tty.h 2008-10-08 22:22:25.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/tty.h 2008-10-08 22:24:12.000000000 -0400 +@@ -211,7 +211,7 @@ struct tty_struct { + struct work_struct hangup_work; + void *disc_data; + void *driver_data; +- struct list_head tty_files; ++ struct percpu_list tty_files; + + #define N_TTY_BUF_SIZE 4096 + +Index: linux-2.6.24.7-rt21/security/selinux/hooks.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/security/selinux/hooks.c 2008-10-08 22:22:25.000000000 -0400 ++++ linux-2.6.24.7-rt21/security/selinux/hooks.c 2008-10-08 22:24:12.000000000 -0400 +@@ -1747,8 +1747,11 @@ static inline void flush_unauthorized_fi + mutex_lock(&tty_mutex); + tty = get_current_tty(); + if (tty) { +- file_list_lock(); +- file = list_entry(tty->tty_files.next, typeof(*file), f_u.fu_list); ++ lock_list_for_each_entry(file, ++ percpu_list_head(&tty->tty_files), ++ f_u.fu_llist) ++ break; ++ + if (file) { + /* Revalidate access to controlling tty. + Use inode_has_perm on the tty inode directly rather +@@ -1760,8 +1763,8 @@ static inline void flush_unauthorized_fi + FILE__READ | FILE__WRITE, NULL)) { + drop_tty = 1; + } ++ lock_list_for_each_entry_stop(file, f_u.fu_llist); + } +- file_list_unlock(); + } + mutex_unlock(&tty_mutex); + /* Reset controlling tty. */ --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0132-arm-fix-atomic-cmpxchg.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0132-arm-fix-atomic-cmpxchg.patch @@ -0,0 +1,21 @@ +--- + include/asm-arm/atomic.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/include/asm-arm/atomic.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-arm/atomic.h 2008-10-08 22:23:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-arm/atomic.h 2008-10-08 22:23:28.000000000 -0400 +@@ -189,10 +189,10 @@ static inline unsigned long __cmpxchg(vo + volatile unsigned long *p = ptr; + + if (size == 4) { +- local_irq_save(flags); ++ raw_local_irq_save(flags); + if ((prev = *p) == old) + *p = new; +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + return(prev); + } else + return wrong_size_cmpxchg(ptr); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0033-0017-sched-break-out-early-if-RT-task-cannot-be-migrated.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0033-0017-sched-break-out-early-if-RT-task-cannot-be-migrated.patch @@ -0,0 +1,29 @@ +From 8c0e147455278f9b1ea9f102dfe9d1961ff4c8fe Mon Sep 17 00:00:00 2001 +From: Gregory Haskins +Date: Tue, 11 Dec 2007 10:02:38 +0100 +Subject: [PATCH] sched: break out early if RT task cannot be migrated + +We don't need to bother searching if the task cannot be migrated + +Signed-off-by: Gregory Haskins +Signed-off-by: Steven Rostedt +Signed-off-by: Ingo Molnar + +--- + kernel/sched_rt.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/kernel/sched_rt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched_rt.c 2008-10-08 22:22:59.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched_rt.c 2008-10-08 22:23:00.000000000 -0400 +@@ -172,7 +172,8 @@ static int select_task_rq_rt(struct task + * that is just being woken and probably will have + * cold cache anyway. + */ +- if (unlikely(rt_task(rq->curr))) { ++ if (unlikely(rt_task(rq->curr)) && ++ (p->nr_cpus_allowed > 1)) { + int cpu = find_lowest_rq(p); + + return (cpu == -1) ? task_cpu(p) : cpu; --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0346-irq-mask-fix.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0346-irq-mask-fix.patch @@ -0,0 +1,91 @@ +Subject: genirq: fix simple and fasteoi irq handlers +From: Jarek Poplawski + +After the "genirq: do not mask interrupts by default" patch interrupts +should be disabled not immediately upon request, but after they happen. +But, handle_simple_irq() and handle_fasteoi_irq() can skip this once or +more if an irq is just serviced (IRQ_INPROGRESS), possibly disrupting a +driver's work. + +The main reason of problems here, pointing the broken patch and making +the first patch which can fix this was done by Marcin Slusarz. +Additional test patches of Thomas Gleixner and Ingo Molnar tested by +Marcin Slusarz helped to narrow possible reasons even more. Thanks. + +PS: this patch fixes only one evident error here, but there could be +more places affected by above-mentioned change in irq handling. + +PS 2: +After rethinking, IMHO, there are two most probable scenarios here: + +1. After hw resend there could be a conflict between retriggered +edge type irq and the next level type one: e.g. if this level type +irq (io_apic is enabled then) is triggered while retriggered irq is +serviced (IRQ_INPROGRESS) there is goto out with eoi, and probably +the next such levels are triggered and looping, so probably kind of +flood in io_apic until this retriggered edge service has ended. +2. There is something wrong with ioapic_retrigger_irq (less probable +because this should be probably seen with 'normal' edge retriggers, +but on the other hand, they could be less common). + +So, if there is #1, this fixed patch should work. + +But, since level types don't need this retriggers too much I think +this "don't mask interrupts by default" idea should be rethinked: +is there enough gain to risk such hard to diagnose errors? + +So, IMHO, there should be at least possibility to turn this off for +level types in config (it should be a visible option, so people could +find & try this before writing for help or changing a network card). + + +Signed-off-by: Jarek Poplawski +Signed-off-by: Ingo Molnar +--- + kernel/irq/chip.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/irq/chip.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/irq/chip.c 2008-10-08 22:23:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/irq/chip.c 2008-10-08 22:24:27.000000000 -0400 +@@ -340,6 +340,8 @@ handle_simple_irq(unsigned int irq, stru + + spin_lock(&desc->lock); + desc->status &= ~IRQ_INPROGRESS; ++ if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) ++ desc->chip->unmask(irq); + out_unlock: + spin_unlock(&desc->lock); + } +@@ -418,18 +420,16 @@ handle_fasteoi_irq(unsigned int irq, str + + spin_lock(&desc->lock); + +- if (unlikely(desc->status & IRQ_INPROGRESS)) +- goto out; +- + desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); + kstat_cpu(cpu).irqs[irq]++; + + /* +- * If its disabled or no action available ++ * If it's running, disabled or no action available + * then mask it and get out of here: + */ + action = desc->action; +- if (unlikely(!action || (desc->status & IRQ_DISABLED))) { ++ if (unlikely(!action || (desc->status & (IRQ_INPROGRESS | ++ IRQ_DISABLED)))) { + desc->status |= IRQ_PENDING; + if (desc->chip->mask) + desc->chip->mask(irq); +@@ -455,6 +455,8 @@ handle_fasteoi_irq(unsigned int irq, str + + spin_lock(&desc->lock); + desc->status &= ~IRQ_INPROGRESS; ++ if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) ++ desc->chip->unmask(irq); + out: + desc->chip->eoi(irq); + spin_unlock(&desc->lock); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0114-lockdep-show-held-locks.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0114-lockdep-show-held-locks.patch @@ -0,0 +1,64 @@ +Subject: [patch] lockdep: show held locks when showing a stackdump +From: Ingo Molnar + +show held locks when printing a backtrace. + +Signed-off-by: Ingo Molnar + +--- + arch/x86/kernel/traps_32.c | 1 + + arch/x86/kernel/traps_64.c | 1 + + kernel/lockdep.c | 9 +++++++-- + 3 files changed, 9 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/traps_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/traps_32.c 2008-10-08 22:23:09.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/traps_32.c 2008-10-08 22:23:24.000000000 -0400 +@@ -271,6 +271,7 @@ static void show_stack_log_lvl(struct ta + } + printk("\n%sCall Trace:\n", log_lvl); + show_trace_log_lvl(task, regs, esp, log_lvl); ++ debug_show_held_locks(task); + } + + void show_stack(struct task_struct *task, unsigned long *esp) +Index: linux-2.6.24.7-rt21/arch/x86/kernel/traps_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/traps_64.c 2008-10-08 22:23:09.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/traps_64.c 2008-10-08 22:23:24.000000000 -0400 +@@ -320,6 +320,7 @@ print_trace_warning_symbol(void *data, c + { + print_symbol(msg, symbol); + printk("\n"); ++ debug_show_held_locks(tsk); + } + + static void print_trace_warning(void *data, char *msg) +Index: linux-2.6.24.7-rt21/kernel/lockdep.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/lockdep.c 2008-10-08 22:23:06.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/lockdep.c 2008-10-08 22:23:24.000000000 -0400 +@@ -512,7 +512,11 @@ static void print_lock(struct held_lock + + static void lockdep_print_held_locks(struct task_struct *curr) + { +- int i, depth = curr->lockdep_depth; ++ int i, depth; ++ ++ if (!curr) ++ curr = current; ++ depth = curr->lockdep_depth; + + if (!depth) { + printk("no locks held by %s/%d.\n", curr->comm, task_pid_nr(curr)); +@@ -3229,7 +3233,8 @@ void debug_show_held_locks(struct task_s + printk("INFO: lockdep is turned off.\n"); + return; + } +- lockdep_print_held_locks(task); ++ if (task == current) ++ lockdep_print_held_locks(task); + } + + EXPORT_SYMBOL_GPL(debug_show_held_locks); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0176-rt-mutex-x86-64.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0176-rt-mutex-x86-64.patch @@ -0,0 +1,465 @@ +--- + arch/x86/Kconfig | 2 - + arch/x86/kernel/entry_64.S | 18 +++++----- + arch/x86/kernel/tsc_sync.c | 2 - + arch/x86/kernel/vsyscall_64.c | 2 - + arch/x86/kernel/x8664_ksyms_64.c | 10 +++-- + arch/x86/lib/thunk_64.S | 12 ++++-- + include/asm-x86/semaphore_64.h | 67 +++++++++++++++++++++++---------------- + include/asm-x86/spinlock_64.h | 28 ++++++++-------- + include/asm-x86/thread_info_64.h | 2 + + 9 files changed, 81 insertions(+), 62 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/x86/Kconfig +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/Kconfig 2008-10-08 22:23:38.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/Kconfig 2008-10-08 22:23:40.000000000 -0400 +@@ -107,7 +107,7 @@ config ASM_SEMAPHORES + + config RWSEM_XCHGADD_ALGORITHM + bool +- depends on X86_XADD && !RWSEM_GENERIC_SPINLOCK ++ depends on X86_XADD && !RWSEM_GENERIC_SPINLOCK && !PREEMPT_RT + default y + + config ARCH_HAS_ILOG2_U32 +Index: linux-2.6.24.7-rt21/arch/x86/kernel/entry_64.S +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/entry_64.S 2008-10-08 22:23:09.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/entry_64.S 2008-10-08 22:23:40.000000000 -0400 +@@ -375,8 +375,8 @@ sysret_check: + /* Handle reschedules */ + /* edx: work, edi: workmask */ + sysret_careful: +- bt $TIF_NEED_RESCHED,%edx +- jnc sysret_signal ++ testl $(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED),%edx ++ jz sysret_signal + TRACE_IRQS_ON + sti + pushq %rdi +@@ -399,7 +399,7 @@ sysret_signal: + leaq -ARGOFFSET(%rsp),%rdi # &pt_regs -> arg1 + xorl %esi,%esi # oldset -> arg2 + call ptregscall_common +-1: movl $_TIF_NEED_RESCHED,%edi ++1: movl $(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED),%edi + /* Use IRET because user could have changed frame. This + works because ptregscall_common has called FIXUP_TOP_OF_STACK. */ + cli +@@ -456,8 +456,8 @@ int_with_check: + /* First do a reschedule test. */ + /* edx: work, edi: workmask */ + int_careful: +- bt $TIF_NEED_RESCHED,%edx +- jnc int_very_careful ++ testl $(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED),%edx ++ jz int_very_careful + TRACE_IRQS_ON + sti + pushq %rdi +@@ -492,7 +492,7 @@ int_signal: + movq %rsp,%rdi # &ptregs -> arg1 + xorl %esi,%esi # oldset -> arg2 + call do_notify_resume +-1: movl $_TIF_NEED_RESCHED,%edi ++1: movl $(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED),%edi + int_restore_rest: + RESTORE_REST + cli +@@ -698,8 +698,8 @@ bad_iret: + /* edi: workmask, edx: work */ + retint_careful: + CFI_RESTORE_STATE +- bt $TIF_NEED_RESCHED,%edx +- jnc retint_signal ++ testl $(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED),%edx ++ jz retint_signal + TRACE_IRQS_ON + sti + pushq %rdi +@@ -725,7 +725,7 @@ retint_signal: + RESTORE_REST + cli + TRACE_IRQS_OFF +- movl $_TIF_NEED_RESCHED,%edi ++ movl $(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED),%edi + GET_THREAD_INFO(%rcx) + jmp retint_check + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/tsc_sync.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/tsc_sync.c 2008-10-08 22:23:17.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/tsc_sync.c 2008-10-08 22:23:40.000000000 -0400 +@@ -33,7 +33,7 @@ static __cpuinitdata atomic_t stop_count + * we want to have the fastest, inlined, non-debug version + * of a critical section, to be able to prove TSC time-warps: + */ +-static __cpuinitdata raw_spinlock_t sync_lock = __RAW_SPIN_LOCK_UNLOCKED; ++static __cpuinitdata __raw_spinlock_t sync_lock = __RAW_SPIN_LOCK_UNLOCKED; + static __cpuinitdata cycles_t last_tsc; + static __cpuinitdata cycles_t max_warp; + static __cpuinitdata int nr_warps; +Index: linux-2.6.24.7-rt21/arch/x86/kernel/vsyscall_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/vsyscall_64.c 2008-10-08 22:23:06.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/vsyscall_64.c 2008-10-08 22:23:40.000000000 -0400 +@@ -55,7 +55,7 @@ int __vgetcpu_mode __section_vgetcpu_mod + + struct vsyscall_gtod_data __vsyscall_gtod_data __section_vsyscall_gtod_data = + { +- .lock = SEQLOCK_UNLOCKED, ++ .lock = __RAW_SEQLOCK_UNLOCKED(__vsyscall_gtod_data.lock), + .sysctl_enabled = 1, + }; + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/x8664_ksyms_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/x8664_ksyms_64.c 2008-10-08 22:23:06.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/x8664_ksyms_64.c 2008-10-08 22:23:40.000000000 -0400 +@@ -17,10 +17,12 @@ EXPORT_SYMBOL(mcount); + + EXPORT_SYMBOL(kernel_thread); + +-EXPORT_SYMBOL(__down_failed); +-EXPORT_SYMBOL(__down_failed_interruptible); +-EXPORT_SYMBOL(__down_failed_trylock); +-EXPORT_SYMBOL(__up_wakeup); ++#ifdef CONFIG_RWSEM_GENERIC_SPINLOCK ++EXPORT_SYMBOL(__compat_down_failed); ++EXPORT_SYMBOL(__compat_down_failed_interruptible); ++EXPORT_SYMBOL(__compat_down_failed_trylock); ++EXPORT_SYMBOL(__compat_up_wakeup); ++#endif + + EXPORT_SYMBOL(__get_user_1); + EXPORT_SYMBOL(__get_user_2); +Index: linux-2.6.24.7-rt21/arch/x86/lib/thunk_64.S +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/lib/thunk_64.S 2008-10-08 22:23:06.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/lib/thunk_64.S 2008-10-08 22:23:40.000000000 -0400 +@@ -40,11 +40,13 @@ + thunk rwsem_wake_thunk,rwsem_wake + thunk rwsem_downgrade_thunk,rwsem_downgrade_wake + #endif +- +- thunk __down_failed,__down +- thunk_retrax __down_failed_interruptible,__down_interruptible +- thunk_retrax __down_failed_trylock,__down_trylock +- thunk __up_wakeup,__up ++ ++#ifdef CONFIG_RWSEM_GENERIC_SPINLOCK ++ thunk __compat_down_failed,__compat_down ++ thunk_retrax __compat_down_failed_interruptible,__compat_down_interruptible ++ thunk_retrax __compat_down_failed_trylock,__compat_down_trylock ++ thunk __compat_up_wakeup,__compat_up ++#endif + + #ifdef CONFIG_TRACE_IRQFLAGS + /* put return address in rdi (arg1) */ +Index: linux-2.6.24.7-rt21/include/asm-x86/semaphore_64.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/semaphore_64.h 2008-10-08 22:22:35.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/semaphore_64.h 2008-10-08 22:23:40.000000000 -0400 +@@ -5,6 +5,10 @@ + + #ifdef __KERNEL__ + ++#ifndef CONFIG_PREEMPT_RT ++# define compat_semaphore semaphore ++#endif ++ + /* + * SMP- and interrupt-safe semaphores.. + * +@@ -43,28 +47,33 @@ + #include + #include + +-struct semaphore { ++struct compat_semaphore { + atomic_t count; + int sleepers; + wait_queue_head_t wait; + }; + +-#define __SEMAPHORE_INITIALIZER(name, n) \ ++#define __COMPAT_SEMAPHORE_INITIALIZER(name, n) \ + { \ + .count = ATOMIC_INIT(n), \ + .sleepers = 0, \ + .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ + } + +-#define __DECLARE_SEMAPHORE_GENERIC(name,count) \ +- struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) ++#define __COMPAT_MUTEX_INITIALIZER(name) \ ++ __COMPAT_SEMAPHORE_INITIALIZER(name,1) ++ ++#define __COMPAT_DECLARE_SEMAPHORE_GENERIC(name,count) \ ++ struct compat_semaphore name = __COMPAT_SEMAPHORE_INITIALIZER(name,count) + +-#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) ++#define COMPAT_DECLARE_MUTEX(name) __COMPAT_DECLARE_SEMAPHORE_GENERIC(name,1) + +-static inline void sema_init (struct semaphore *sem, int val) ++#define compat_sema_count(sem) atomic_read(&(sem)->count) ++ ++static inline void compat_sema_init (struct compat_semaphore *sem, int val) + { + /* +- * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); ++ * *sem = (struct compat_semaphore)__SEMAPHORE_INITIALIZER((*sem),val); + * + * i'd rather use the more flexible initialization above, but sadly + * GCC 2.7.2.3 emits a bogus warning. EGCS doesn't. Oh well. +@@ -74,32 +83,33 @@ static inline void sema_init (struct sem + init_waitqueue_head(&sem->wait); + } + +-static inline void init_MUTEX (struct semaphore *sem) ++static inline void compat_init_MUTEX (struct compat_semaphore *sem) + { +- sema_init(sem, 1); ++ compat_sema_init(sem, 1); + } + +-static inline void init_MUTEX_LOCKED (struct semaphore *sem) ++static inline void compat_init_MUTEX_LOCKED (struct compat_semaphore *sem) + { +- sema_init(sem, 0); ++ compat_sema_init(sem, 0); + } + +-asmlinkage void __down_failed(void /* special register calling convention */); +-asmlinkage int __down_failed_interruptible(void /* params in registers */); +-asmlinkage int __down_failed_trylock(void /* params in registers */); +-asmlinkage void __up_wakeup(void /* special register calling convention */); ++asmlinkage void __compat_down_failed(void /* special register calling convention */); ++asmlinkage int __compat_down_failed_interruptible(void /* params in registers */); ++asmlinkage int __compat_down_failed_trylock(void /* params in registers */); ++asmlinkage void __compat_up_wakeup(void /* special register calling convention */); + +-asmlinkage void __down(struct semaphore * sem); +-asmlinkage int __down_interruptible(struct semaphore * sem); +-asmlinkage int __down_trylock(struct semaphore * sem); +-asmlinkage void __up(struct semaphore * sem); ++asmlinkage void __compat_down(struct compat_semaphore * sem); ++asmlinkage int __compat_down_interruptible(struct compat_semaphore * sem); ++asmlinkage int __compat_down_trylock(struct compat_semaphore * sem); ++asmlinkage void __compat_up(struct compat_semaphore * sem); ++asmlinkage int compat_sem_is_locked(struct compat_semaphore *sem); + + /* + * This is ugly, but we want the default case to fall through. + * "__down_failed" is a special asm handler that calls the C + * routine that actually waits. See arch/x86_64/kernel/semaphore.c + */ +-static inline void down(struct semaphore * sem) ++static inline void compat_down(struct compat_semaphore * sem) + { + might_sleep(); + +@@ -107,7 +117,7 @@ static inline void down(struct semaphore + "# atomic down operation\n\t" + LOCK_PREFIX "decl %0\n\t" /* --sem->count */ + "jns 1f\n\t" +- "call __down_failed\n" ++ "call __compat_down_failed\n" + "1:" + :"=m" (sem->count) + :"D" (sem) +@@ -118,7 +128,7 @@ static inline void down(struct semaphore + * Interruptible try to acquire a semaphore. If we obtained + * it, return zero. If we were interrupted, returns -EINTR + */ +-static inline int down_interruptible(struct semaphore * sem) ++static inline int compat_down_interruptible(struct compat_semaphore * sem) + { + int result; + +@@ -129,7 +139,7 @@ static inline int down_interruptible(str + "xorl %0,%0\n\t" + LOCK_PREFIX "decl %1\n\t" /* --sem->count */ + "jns 2f\n\t" +- "call __down_failed_interruptible\n" ++ "call __compat_down_failed_interruptible\n" + "2:\n" + :"=&a" (result), "=m" (sem->count) + :"D" (sem) +@@ -141,7 +151,7 @@ static inline int down_interruptible(str + * Non-blockingly attempt to down() a semaphore. + * Returns zero if we acquired it + */ +-static inline int down_trylock(struct semaphore * sem) ++static inline int compat_down_trylock(struct compat_semaphore * sem) + { + int result; + +@@ -150,7 +160,7 @@ static inline int down_trylock(struct se + "xorl %0,%0\n\t" + LOCK_PREFIX "decl %1\n\t" /* --sem->count */ + "jns 2f\n\t" +- "call __down_failed_trylock\n\t" ++ "call __compat_down_failed_trylock\n\t" + "2:\n" + :"=&a" (result), "=m" (sem->count) + :"D" (sem) +@@ -164,17 +174,20 @@ static inline int down_trylock(struct se + * The default case (no contention) will result in NO + * jumps for both down() and up(). + */ +-static inline void up(struct semaphore * sem) ++static inline void compat_up(struct compat_semaphore * sem) + { + __asm__ __volatile__( + "# atomic up operation\n\t" + LOCK_PREFIX "incl %0\n\t" /* ++sem->count */ + "jg 1f\n\t" +- "call __up_wakeup\n" ++ "call __compat_up_wakeup\n" + "1:" + :"=m" (sem->count) + :"D" (sem) + :"memory"); + } ++ ++#include ++ + #endif /* __KERNEL__ */ + #endif +Index: linux-2.6.24.7-rt21/include/asm-x86/spinlock_64.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/spinlock_64.h 2008-10-08 22:22:35.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/spinlock_64.h 2008-10-08 22:23:40.000000000 -0400 +@@ -17,12 +17,12 @@ + * (the type definitions are in asm/spinlock_types.h) + */ + +-static inline int __raw_spin_is_locked(raw_spinlock_t *lock) ++static inline int __raw_spin_is_locked(__raw_spinlock_t *lock) + { + return *(volatile signed int *)(&(lock)->slock) <= 0; + } + +-static inline void __raw_spin_lock(raw_spinlock_t *lock) ++static inline void __raw_spin_lock(__raw_spinlock_t *lock) + { + asm volatile( + "\n1:\t" +@@ -40,7 +40,7 @@ static inline void __raw_spin_lock(raw_s + * Same as __raw_spin_lock, but reenable interrupts during spinning. + */ + #ifndef CONFIG_PROVE_LOCKING +-static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags) ++static inline void __raw_spin_lock_flags(__raw_spinlock_t *lock, unsigned long flags) + { + asm volatile( + "\n1:\t" +@@ -65,7 +65,7 @@ static inline void __raw_spin_lock_flags + } + #endif + +-static inline int __raw_spin_trylock(raw_spinlock_t *lock) ++static inline int __raw_spin_trylock(__raw_spinlock_t *lock) + { + int oldval; + +@@ -77,12 +77,12 @@ static inline int __raw_spin_trylock(raw + return oldval > 0; + } + +-static inline void __raw_spin_unlock(raw_spinlock_t *lock) ++static inline void __raw_spin_unlock(__raw_spinlock_t *lock) + { + asm volatile("movl $1,%0" :"=m" (lock->slock) :: "memory"); + } + +-static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) ++static inline void __raw_spin_unlock_wait(__raw_spinlock_t *lock) + { + while (__raw_spin_is_locked(lock)) + cpu_relax(); +@@ -102,17 +102,17 @@ static inline void __raw_spin_unlock_wai + * with the high bit (sign) being the "contended" bit. + */ + +-static inline int __raw_read_can_lock(raw_rwlock_t *lock) ++static inline int __raw_read_can_lock(__raw_rwlock_t *lock) + { + return (int)(lock)->lock > 0; + } + +-static inline int __raw_write_can_lock(raw_rwlock_t *lock) ++static inline int __raw_write_can_lock(__raw_rwlock_t *lock) + { + return (lock)->lock == RW_LOCK_BIAS; + } + +-static inline void __raw_read_lock(raw_rwlock_t *rw) ++static inline void __raw_read_lock(__raw_rwlock_t *rw) + { + asm volatile(LOCK_PREFIX "subl $1,(%0)\n\t" + "jns 1f\n" +@@ -121,7 +121,7 @@ static inline void __raw_read_lock(raw_r + ::"D" (rw), "i" (RW_LOCK_BIAS) : "memory"); + } + +-static inline void __raw_write_lock(raw_rwlock_t *rw) ++static inline void __raw_write_lock(__raw_rwlock_t *rw) + { + asm volatile(LOCK_PREFIX "subl %1,(%0)\n\t" + "jz 1f\n" +@@ -130,7 +130,7 @@ static inline void __raw_write_lock(raw_ + ::"D" (rw), "i" (RW_LOCK_BIAS) : "memory"); + } + +-static inline int __raw_read_trylock(raw_rwlock_t *lock) ++static inline int __raw_read_trylock(__raw_rwlock_t *lock) + { + atomic_t *count = (atomic_t *)lock; + atomic_dec(count); +@@ -140,7 +140,7 @@ static inline int __raw_read_trylock(raw + return 0; + } + +-static inline int __raw_write_trylock(raw_rwlock_t *lock) ++static inline int __raw_write_trylock(__raw_rwlock_t *lock) + { + atomic_t *count = (atomic_t *)lock; + if (atomic_sub_and_test(RW_LOCK_BIAS, count)) +@@ -149,12 +149,12 @@ static inline int __raw_write_trylock(ra + return 0; + } + +-static inline void __raw_read_unlock(raw_rwlock_t *rw) ++static inline void __raw_read_unlock(__raw_rwlock_t *rw) + { + asm volatile(LOCK_PREFIX " ; incl %0" :"=m" (rw->lock) : : "memory"); + } + +-static inline void __raw_write_unlock(raw_rwlock_t *rw) ++static inline void __raw_write_unlock(__raw_rwlock_t *rw) + { + asm volatile(LOCK_PREFIX " ; addl $" RW_LOCK_BIAS_STR ",%0" + : "=m" (rw->lock) : : "memory"); +Index: linux-2.6.24.7-rt21/include/asm-x86/thread_info_64.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/thread_info_64.h 2008-10-08 22:22:35.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/thread_info_64.h 2008-10-08 22:23:40.000000000 -0400 +@@ -111,6 +111,7 @@ static inline struct thread_info *stack_ + #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ + #define TIF_SINGLESTEP 4 /* reenable singlestep on user return*/ + #define TIF_IRET 5 /* force IRET */ ++#define TIF_NEED_RESCHED_DELAYED 6 /* reschedul on return to userspace */ + #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ + #define TIF_SECCOMP 8 /* secure computing */ + #define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal */ +@@ -133,6 +134,7 @@ static inline struct thread_info *stack_ + #define _TIF_SECCOMP (1< +Received: from smtp.ocgnet.org (smtp.ocgnet.org [64.20.243.3]) by + mail.tglx.de (Postfix) with ESMTP id 0FCC865C065 for ; + Fri, 18 May 2007 06:46:43 +0200 (CEST) +Received: from smtp.ocgnet.org (localhost [127.0.0.1]) by smtp.ocgnet.org + (Postfix) with ESMTP id 616355203FB; Thu, 17 May 2007 23:46:39 -0500 (CDT) +X-Spam-Checker-Version: SpamAssassin 3.1.3-gr0 (2006-06-01) on + smtp.ocgnet.org +X-Spam-Level: +X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=no + version=3.1.3-gr0 +Received: from master.linux-sh.org (124x34x33x190.ap124.ftth.ucom.ne.jp + [124.34.33.190]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 + bits)) (No client certificate requested) by smtp.ocgnet.org (Postfix) with + ESMTP id E1F585203E0; Thu, 17 May 2007 23:46:38 -0500 (CDT) +Received: from localhost (unknown [127.0.0.1]) by master.linux-sh.org + (Postfix) with ESMTP id 4984664C7C; Fri, 18 May 2007 04:46:00 +0000 (UTC) +X-Virus-Scanned: amavisd-new at linux-sh.org +Received: from master.linux-sh.org ([127.0.0.1]) by localhost + (master.linux-sh.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id + BE+H5LV2TYuQ; Fri, 18 May 2007 13:46:00 +0900 (JST) +Received: by master.linux-sh.org (Postfix, from userid 500) id 08A5664C7D; + Fri, 18 May 2007 13:46:00 +0900 (JST) +Date: Fri, 18 May 2007 13:45:59 +0900 +From: Paul Mundt +To: Ingo Molnar , Thomas Gleixner +Cc: linux-kernel@vger.kernel.org +Subject: [PATCH -rt] futex_performance_hack sysctl build fix +Message-ID: <20070518044559.GB22660@linux-sh.org> +Mail-Followup-To: Paul Mundt , Ingo Molnar + , Thomas Gleixner , + linux-kernel@vger.kernel.org +MIME-Version: 1.0 +Content-Type: text/plain; charset=us-ascii +Content-Disposition: inline +User-Agent: Mutt/1.5.13 (2006-08-11) +X-Virus-Scanned: ClamAV using ClamSMTP +X-Evolution-Source: imap://tglx%40linutronix.de@localhost:8993/ +Content-Transfer-Encoding: 8bit + +-rt adds a futex_performance_hack sysctl, which is only defined if +kernel/futex.c is built in. This fixes the build in the CONFIG_FUTEX=n +case. + +Signed-off-by: Paul Mundt + +-- + + kernel/sysctl.c | 2 ++ + 1 file changed, 2 insertions(+) + +Index: linux-2.6.24.7-rt21/kernel/sysctl.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sysctl.c 2008-10-08 22:24:10.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sysctl.c 2008-10-08 22:24:10.000000000 -0400 +@@ -340,6 +340,7 @@ static struct ctl_table kern_table[] = { + .proc_handler = &proc_dointvec, + }, + #endif ++#ifdef CONFIG_FUTEX + { + .ctl_name = CTL_UNNUMBERED, + .procname = "futex_performance_hack", +@@ -348,6 +349,7 @@ static struct ctl_table kern_table[] = { + .mode = 0644, + .proc_handler = &proc_dointvec, + }, ++#endif + { + .ctl_name = CTL_UNNUMBERED, + .procname = "prof_pid", --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0533-hotplug-smp-boot-fix.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0533-hotplug-smp-boot-fix.patch @@ -0,0 +1,43 @@ +--- + arch/x86/kernel/head64.c | 1 + + arch/x86/kernel/smpboot_64.c | 2 +- + include/asm-x86/proto.h | 1 + + 3 files changed, 3 insertions(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/head64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/head64.c 2008-10-08 22:23:51.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/head64.c 2008-10-08 22:25:12.000000000 -0400 +@@ -70,6 +70,7 @@ void __init x86_64_start_kernel(char * r + cpu_pda(i) = &boot_cpu_pda[i]; + + pda_init(0); ++ allocate_stacks(0); + copy_bootdata(__va(real_mode_data)); + #ifdef CONFIG_SMP + cpu_set(0, cpu_online_map); +Index: linux-2.6.24.7-rt21/arch/x86/kernel/smpboot_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/smpboot_64.c 2008-10-08 22:25:07.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/smpboot_64.c 2008-10-08 22:25:12.000000000 -0400 +@@ -538,7 +538,7 @@ static void __cpuinit do_fork_idle(struc + static char boot_exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ] + __attribute__((section(".bss.page_aligned"))); + +-static int __cpuinit allocate_stacks(int cpu) ++int __cpuinit allocate_stacks(int cpu) + { + static const unsigned int order[N_EXCEPTION_STACKS] = { + [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STACK_ORDER, +Index: linux-2.6.24.7-rt21/include/asm-x86/proto.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/proto.h 2008-10-08 22:22:09.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/proto.h 2008-10-08 22:25:12.000000000 -0400 +@@ -10,6 +10,7 @@ struct pt_regs; + + extern void start_kernel(void); + extern void pda_init(int); ++extern int allocate_stacks(int cpu); + + extern void early_idt_handler(void); + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0067-trace-histograms.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0067-trace-histograms.patch @@ -0,0 +1,867 @@ +Critical latency timings histogram + +This patch adds hooks into the latency tracer to give +us histograms of interrupts off, preemption off and +wakeup timings. + +This code was based off of work done by Yi Yang + +But heavily modified to work with the new tracer, and some +clean ups by Steven Rostedt + +This adds the following to /debugfs/tracing + + latency_hist/ - root dir for historgrams. + + Under latency_hist there is (depending on what's configured): + + interrupt_off_latency/ - latency histograms of interrupts off. + + preempt_interrupts_off_latency/ - latency histograms of + preemption and/or interrupts off. + + preempt_off_latency/ - latency histograms of preemption off. + + wakeup_latency/ - latency histograms of wakeup timings. + + Under each of the above is a file labeled: + + CPU# for each possible CPU were # is the CPU number. + + reset - writing into this file will reset the histogram + back to zeros and start again. + + +Signed-off-by: Steven Rostedt +--- + kernel/trace/Kconfig | 22 + + kernel/trace/Makefile | 4 + kernel/trace/trace_hist.c | 638 +++++++++++++++++++++++++++++++++++++++++++ + kernel/trace/trace_hist.h | 39 ++ + kernel/trace/trace_irqsoff.c | 19 + + 5 files changed, 722 insertions(+) + +Index: linux-2.6.24.7-rt21/kernel/trace/Kconfig +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/Kconfig 2008-10-08 22:23:08.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/Kconfig 2008-10-08 22:23:08.000000000 -0400 +@@ -134,3 +134,25 @@ config FTRACE_STARTUP_TEST + a series of tests are made to verify that the tracer is + functioning properly. It will do tests on all the configured + tracers of ftrace. ++ ++config INTERRUPT_OFF_HIST ++ bool "Interrupts off critical timings histogram" ++ depends on IRQSOFF_TRACER ++ help ++ This option uses the infrastructure of the critical ++ irqs off timings to create a histogram of latencies. ++ ++config PREEMPT_OFF_HIST ++ bool "Preempt off critical timings histogram" ++ depends on PREEMPT_TRACER ++ help ++ This option uses the infrastructure of the critical ++ preemption off timings to create a histogram of latencies. ++ ++config WAKEUP_LATENCY_HIST ++ bool "Interrupts off critical timings histogram" ++ select TRACING ++ select MARKERS ++ help ++ This option uses the infrastructure of the wakeup tracer ++ to create a histogram of latencies. +Index: linux-2.6.24.7-rt21/kernel/trace/Makefile +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/Makefile 2008-10-08 22:23:08.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/Makefile 2008-10-08 22:23:08.000000000 -0400 +@@ -21,4 +21,8 @@ obj-$(CONFIG_SCHED_TRACER) += trace_sche + obj-$(CONFIG_MMIOTRACE) += trace_mmiotrace.o + obj-$(CONFIG_EVENT_TRACER) += trace_events.o + ++obj-$(CONFIG_INTERRUPT_OFF_HIST) += trace_hist.o ++obj-$(CONFIG_PREEMPT_OFF_HIST) += trace_hist.o ++obj-$(CONFIG_WAKEUP_LATENCY_HIST) += trace_hist.o ++ + libftrace-y := ftrace.o +Index: linux-2.6.24.7-rt21/kernel/trace/trace_hist.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/kernel/trace/trace_hist.c 2008-10-08 22:23:08.000000000 -0400 +@@ -0,0 +1,638 @@ ++/* ++ * kernel/trace/trace_hist.c ++ * ++ * Add support for histograms of preemption-off latency and ++ * interrupt-off latency and wakeup latency, it depends on ++ * Real-Time Preemption Support. ++ * ++ * Copyright (C) 2005 MontaVista Software, Inc. ++ * Yi Yang ++ * ++ * Converted to work with the new latency tracer. ++ * Copyright (C) 2008 Red Hat, Inc. ++ * Steven Rostedt ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "trace.h" ++#include "trace_hist.h" ++ ++enum { ++ INTERRUPT_LATENCY = 0, ++ PREEMPT_LATENCY, ++ PREEMPT_INTERRUPT_LATENCY, ++ WAKEUP_LATENCY, ++}; ++ ++#define MAX_ENTRY_NUM 10240 ++ ++struct hist_data { ++ atomic_t hist_mode; /* 0 log, 1 don't log */ ++ unsigned long min_lat; ++ unsigned long avg_lat; ++ unsigned long max_lat; ++ unsigned long long beyond_hist_bound_samples; ++ unsigned long long accumulate_lat; ++ unsigned long long total_samples; ++ unsigned long long hist_array[MAX_ENTRY_NUM]; ++}; ++ ++static char *latency_hist_dir_root = "latency_hist"; ++ ++#ifdef CONFIG_INTERRUPT_OFF_HIST ++static DEFINE_PER_CPU(struct hist_data, interrupt_off_hist); ++static char *interrupt_off_hist_dir = "interrupt_off_latency"; ++#endif ++ ++#ifdef CONFIG_PREEMPT_OFF_HIST ++static DEFINE_PER_CPU(struct hist_data, preempt_off_hist); ++static char *preempt_off_hist_dir = "preempt_off_latency"; ++#endif ++ ++#if defined(CONFIG_PREEMPT_OFF_HIST) && defined(CONFIG_INTERRUPT_OFF_HIST) ++static DEFINE_PER_CPU(struct hist_data, preempt_irqs_off_hist); ++static char *preempt_irqs_off_hist_dir = "preempt_interrupts_off_latency"; ++#endif ++ ++#ifdef CONFIG_WAKEUP_LATENCY_HIST ++static DEFINE_PER_CPU(struct hist_data, wakeup_latency_hist); ++static char *wakeup_latency_hist_dir = "wakeup_latency"; ++#endif ++ ++static inline u64 u64_div(u64 x, u64 y) ++{ ++ do_div(x, y); ++ return x; ++} ++ ++void notrace latency_hist(int latency_type, int cpu, unsigned long latency) ++{ ++ struct hist_data *my_hist; ++ ++ if ((cpu < 0) || (cpu >= NR_CPUS) || (latency_type < INTERRUPT_LATENCY) ++ || (latency_type > WAKEUP_LATENCY) || (latency < 0)) ++ return; ++ ++ switch (latency_type) { ++#ifdef CONFIG_INTERRUPT_OFF_HIST ++ case INTERRUPT_LATENCY: ++ my_hist = &per_cpu(interrupt_off_hist, cpu); ++ break; ++#endif ++ ++#ifdef CONFIG_PREEMPT_OFF_HIST ++ case PREEMPT_LATENCY: ++ my_hist = &per_cpu(preempt_off_hist, cpu); ++ break; ++#endif ++ ++#if defined(CONFIG_PREEMPT_OFF_HIST) && defined(CONFIG_INTERRUPT_OFF_HIST) ++ case PREEMPT_INTERRUPT_LATENCY: ++ my_hist = &per_cpu(preempt_irqs_off_hist, cpu); ++ break; ++#endif ++ ++#ifdef CONFIG_WAKEUP_LATENCY_HIST ++ case WAKEUP_LATENCY: ++ my_hist = &per_cpu(wakeup_latency_hist, cpu); ++ break; ++#endif ++ default: ++ return; ++ } ++ ++ if (atomic_read(&my_hist->hist_mode) == 0) ++ return; ++ ++ if (latency >= MAX_ENTRY_NUM) ++ my_hist->beyond_hist_bound_samples++; ++ else ++ my_hist->hist_array[latency]++; ++ ++ if (latency < my_hist->min_lat) ++ my_hist->min_lat = latency; ++ else if (latency > my_hist->max_lat) ++ my_hist->max_lat = latency; ++ ++ my_hist->total_samples++; ++ my_hist->accumulate_lat += latency; ++ my_hist->avg_lat = (unsigned long) u64_div(my_hist->accumulate_lat, ++ my_hist->total_samples); ++ return; ++} ++ ++static void *l_start(struct seq_file *m, loff_t *pos) ++{ ++ loff_t *index_ptr = kmalloc(sizeof(loff_t), GFP_KERNEL); ++ loff_t index = *pos; ++ struct hist_data *my_hist = m->private; ++ ++ if (!index_ptr) ++ return NULL; ++ ++ if (index == 0) { ++ atomic_dec(&my_hist->hist_mode); ++ seq_printf(m, "#Minimum latency: %lu microseconds.\n" ++ "#Average latency: %lu microseconds.\n" ++ "#Maximum latency: %lu microseconds.\n" ++ "#Total samples: %llu\n" ++ "#There are %llu samples greater or equal" ++ " than %d microseconds\n" ++ "#usecs\t%16s\n" ++ , my_hist->min_lat ++ , my_hist->avg_lat ++ , my_hist->max_lat ++ , my_hist->total_samples ++ , my_hist->beyond_hist_bound_samples ++ , MAX_ENTRY_NUM, "samples"); ++ } ++ if (index >= MAX_ENTRY_NUM) ++ return NULL; ++ ++ *index_ptr = index; ++ return index_ptr; ++} ++ ++static void *l_next(struct seq_file *m, void *p, loff_t *pos) ++{ ++ loff_t *index_ptr = p; ++ struct hist_data *my_hist = m->private; ++ ++ if (++*pos >= MAX_ENTRY_NUM) { ++ atomic_inc(&my_hist->hist_mode); ++ return NULL; ++ } ++ *index_ptr = *pos; ++ return index_ptr; ++} ++ ++static void l_stop(struct seq_file *m, void *p) ++{ ++ kfree(p); ++} ++ ++static int l_show(struct seq_file *m, void *p) ++{ ++ int index = *(loff_t *) p; ++ struct hist_data *my_hist = m->private; ++ ++ seq_printf(m, "%5d\t%16llu\n", index, my_hist->hist_array[index]); ++ return 0; ++} ++ ++static struct seq_operations latency_hist_seq_op = { ++ .start = l_start, ++ .next = l_next, ++ .stop = l_stop, ++ .show = l_show ++}; ++ ++static int latency_hist_open(struct inode *inode, struct file *file) ++{ ++ int ret; ++ ++ ret = seq_open(file, &latency_hist_seq_op); ++ if (!ret) { ++ struct seq_file *seq = file->private_data; ++ seq->private = inode->i_private; ++ } ++ return ret; ++} ++ ++static struct file_operations latency_hist_fops = { ++ .open = latency_hist_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = seq_release, ++}; ++ ++static void hist_reset(struct hist_data *hist) ++{ ++ atomic_dec(&hist->hist_mode); ++ ++ memset(hist->hist_array, 0, sizeof(hist->hist_array)); ++ hist->beyond_hist_bound_samples = 0UL; ++ hist->min_lat = 0xFFFFFFFFUL; ++ hist->max_lat = 0UL; ++ hist->total_samples = 0UL; ++ hist->accumulate_lat = 0UL; ++ hist->avg_lat = 0UL; ++ ++ atomic_inc(&hist->hist_mode); ++} ++ ++ssize_t latency_hist_reset(struct file *file, const char __user *a, ++ size_t size, loff_t *off) ++{ ++ int cpu; ++ struct hist_data *hist; ++ int latency_type = (long)file->private_data; ++ ++ switch (latency_type) { ++ ++#ifdef CONFIG_WAKEUP_LATENCY_HIST ++ case WAKEUP_LATENCY: ++ for_each_online_cpu(cpu) { ++ hist = &per_cpu(wakeup_latency_hist, cpu); ++ hist_reset(hist); ++ } ++ break; ++#endif ++ ++#ifdef CONFIG_PREEMPT_OFF_HIST ++ case PREEMPT_LATENCY: ++ for_each_online_cpu(cpu) { ++ hist = &per_cpu(preempt_off_hist, cpu); ++ hist_reset(hist); ++ } ++ break; ++#endif ++ ++#ifdef CONFIG_INTERRUPT_OFF_HIST ++ case INTERRUPT_LATENCY: ++ for_each_online_cpu(cpu) { ++ hist = &per_cpu(interrupt_off_hist, cpu); ++ hist_reset(hist); ++ } ++ break; ++#endif ++ ++#if defined(CONFIG_INTERRUPT_OFF_HIST) && defined(CONFIG_PREEMPT_OFF_HIST) ++ case PREEMPT_INTERRUPT_LATENCY: ++ for_each_online_cpu(cpu) { ++ hist = &per_cpu(preempt_irqs_off_hist, cpu); ++ hist_reset(hist); ++ } ++ break; ++#endif ++ } ++ ++ return size; ++} ++ ++static struct file_operations latency_hist_reset_fops = { ++ .open = tracing_open_generic, ++ .write = latency_hist_reset, ++}; ++ ++#if defined(CONFIG_INTERRUPT_OFF_HIST) || defined(CONFIG_PREEMPT_OFF_HIST) ++#ifdef CONFIG_INTERRUPT_OFF_HIST ++static DEFINE_PER_CPU(cycles_t, hist_irqsoff_start); ++static DEFINE_PER_CPU(int, hist_irqsoff_tracing); ++#endif ++#ifdef CONFIG_PREEMPT_OFF_HIST ++static DEFINE_PER_CPU(cycles_t, hist_preemptoff_start); ++static DEFINE_PER_CPU(int, hist_preemptoff_tracing); ++#endif ++#if defined(CONFIG_INTERRUPT_OFF_HIST) && defined(CONFIG_PREEMPT_OFF_HIST) ++static DEFINE_PER_CPU(cycles_t, hist_preemptirqsoff_start); ++static DEFINE_PER_CPU(int, hist_preemptirqsoff_tracing); ++#endif ++ ++notrace void tracing_hist_preempt_start(void) ++{ ++ cycle_t uninitialized_var(start); ++ int start_set = 0; ++ int cpu; ++ ++ if (!preempt_count() && !irqs_disabled()) ++ return; ++ ++ /* cpu is only used if we are in atomic */ ++ cpu = raw_smp_processor_id(); ++ ++#ifdef CONFIG_INTERRUPT_OFF_HIST ++ if (irqs_disabled() && ++ !per_cpu(hist_irqsoff_tracing, cpu)) { ++ per_cpu(hist_irqsoff_tracing, cpu) = 1; ++ start_set++; ++ start = ftrace_now(cpu); ++ per_cpu(hist_irqsoff_start, cpu) = start; ++ } ++#endif ++ ++#ifdef CONFIG_PREEMPT_OFF_HIST ++ if (preempt_count() && ++ !per_cpu(hist_preemptoff_tracing, cpu)) { ++ per_cpu(hist_preemptoff_tracing, cpu) = 1; ++ if (1 || !(start_set++)) ++ start = ftrace_now(cpu); ++ per_cpu(hist_preemptoff_start, cpu) = start; ++ ++ } ++#endif ++ ++#if defined(CONFIG_INTERRUPT_OFF_HIST) && defined(CONFIG_PREEMPT_OFF_HIST) ++ if (!per_cpu(hist_preemptirqsoff_tracing, cpu)) { ++ per_cpu(hist_preemptirqsoff_tracing, cpu) = 1; ++ if (1 || !(start_set)) ++ start = ftrace_now(cpu); ++ per_cpu(hist_preemptirqsoff_start, cpu) = start; ++ } ++#endif ++} ++ ++notrace void tracing_hist_preempt_stop(int irqs_on) ++{ ++ long latency; ++ cycle_t start; ++ cycle_t uninitialized_var(stop); ++ int stop_set = 0; ++ int cpu; ++ ++ /* irqs_on == TRACE_STOP if we must stop tracing. */ ++ ++ /* cpu is only used if we are in atomic */ ++ cpu = raw_smp_processor_id(); ++ ++#ifdef CONFIG_INTERRUPT_OFF_HIST ++ if (irqs_on && ++ per_cpu(hist_irqsoff_tracing, cpu)) { ++ stop = ftrace_now(cpu); ++ stop_set++; ++ start = per_cpu(hist_irqsoff_start, cpu); ++ latency = (long)nsecs_to_usecs(stop - start); ++ if (latency > 1000000) { ++ printk("%d: latency = %ld (%lu)\n", __LINE__, latency, latency); ++ printk("%d: start=%Ld stop=%Ld\n", __LINE__, start, stop); ++ } ++ barrier(); ++ per_cpu(hist_irqsoff_tracing, cpu) = 0; ++ latency_hist(INTERRUPT_LATENCY, cpu, latency); ++ } ++#endif ++ ++#ifdef CONFIG_PREEMPT_OFF_HIST ++ if ((!irqs_on || irqs_on == TRACE_STOP) && ++ per_cpu(hist_preemptoff_tracing, cpu)) { ++ WARN_ON(!preempt_count()); ++ if (1 || !(stop_set++)) ++ stop = ftrace_now(cpu); ++ start = per_cpu(hist_preemptoff_start, cpu); ++ latency = (long)nsecs_to_usecs(stop - start); ++ if (latency > 1000000) { ++ printk("%d: latency = %ld (%lu)\n", __LINE__, latency, latency); ++ printk("%d: start=%Ld stop=%Ld\n", __LINE__, start, stop); ++ } ++ barrier(); ++ per_cpu(hist_preemptoff_tracing, cpu) = 0; ++ latency_hist(PREEMPT_LATENCY, cpu, latency); ++ } ++#endif ++ ++#if defined(CONFIG_INTERRUPT_OFF_HIST) && defined(CONFIG_PREEMPT_OFF_HIST) ++ if (((!irqs_on && !irqs_disabled()) || ++ (irqs_on && !preempt_count()) || ++ (irqs_on == TRACE_STOP)) && ++ per_cpu(hist_preemptirqsoff_tracing, cpu)) { ++ WARN_ON(!preempt_count() && !irqs_disabled()); ++ if (1 || !stop_set) ++ stop = ftrace_now(cpu); ++ start = per_cpu(hist_preemptirqsoff_start, cpu); ++ latency = (long)nsecs_to_usecs(stop - start); ++ if (latency > 1000000) { ++ printk("%d: latency = %ld (%lu)\n", __LINE__, latency, latency); ++ printk("%d: start=%Ld stop=%Ld\n", __LINE__, start, stop); ++ } ++ barrier(); ++ per_cpu(hist_preemptirqsoff_tracing, cpu) = 0; ++ latency_hist(PREEMPT_INTERRUPT_LATENCY, cpu, latency); ++ } ++#endif ++} ++#endif ++ ++#ifdef CONFIG_WAKEUP_LATENCY_HIST ++int tracing_wakeup_hist __read_mostly = 1; ++ ++static unsigned wakeup_prio = (unsigned)-1 ; ++static struct task_struct *wakeup_task; ++static cycle_t wakeup_start; ++static DEFINE_SPINLOCK(wakeup_lock); ++ ++notrace void tracing_hist_wakeup_start(struct task_struct *p, ++ struct task_struct *curr) ++{ ++ unsigned long flags; ++ ++ if (likely(!rt_task(p)) || ++ p->prio >= wakeup_prio || ++ p->prio >= curr->prio) ++ return; ++ ++ spin_lock_irqsave(&wakeup_lock, flags); ++ if (wakeup_task) ++ put_task_struct(wakeup_task); ++ ++ get_task_struct(p); ++ wakeup_task = p; ++ wakeup_prio = p->prio; ++ wakeup_start = ftrace_now(raw_smp_processor_id()); ++ spin_unlock_irqrestore(&wakeup_lock, flags); ++} ++ ++notrace void tracing_hist_wakeup_stop(struct task_struct *next) ++{ ++ unsigned long flags; ++ long latency; ++ cycle_t stop; ++ ++ if (next != wakeup_task) ++ return; ++ ++ stop = ftrace_now(raw_smp_processor_id()); ++ ++ spin_lock_irqsave(&wakeup_lock, flags); ++ if (wakeup_task != next) ++ goto out; ++ ++ latency = (long)nsecs_to_usecs(stop - wakeup_start); ++ ++ latency_hist(WAKEUP_LATENCY, smp_processor_id(), latency); ++ ++ put_task_struct(wakeup_task); ++ wakeup_task = NULL; ++ wakeup_prio = (unsigned)-1; ++ out: ++ spin_unlock_irqrestore(&wakeup_lock, flags); ++ ++} ++ ++static void ++sched_switch_callback(void *probe_data, void *call_data, ++ const char *format, va_list *args) ++{ ++ struct task_struct *prev; ++ struct task_struct *next; ++ struct rq *__rq; ++ ++ /* skip prev_pid %d next_pid %d prev_state %ld */ ++ (void)va_arg(*args, int); ++ (void)va_arg(*args, int); ++ (void)va_arg(*args, long); ++ __rq = va_arg(*args, typeof(__rq)); ++ prev = va_arg(*args, typeof(prev)); ++ next = va_arg(*args, typeof(next)); ++ ++ tracing_hist_wakeup_stop(next); ++} ++ ++static void ++wake_up_callback(void *probe_data, void *call_data, ++ const char *format, va_list *args) ++{ ++ struct task_struct *curr; ++ struct task_struct *task; ++ struct rq *__rq; ++ ++ /* Skip pid %d state %ld */ ++ (void)va_arg(*args, int); ++ (void)va_arg(*args, long); ++ /* now get the meat: "rq %p task %p rq->curr %p" */ ++ __rq = va_arg(*args, typeof(__rq)); ++ task = va_arg(*args, typeof(task)); ++ curr = va_arg(*args, typeof(curr)); ++ ++ tracing_hist_wakeup_start(task, curr); ++} ++ ++#endif ++ ++static __init int latency_hist_init(void) ++{ ++ struct dentry *latency_hist_root = NULL; ++ struct dentry *dentry; ++ struct dentry *entry; ++ int i = 0, len = 0; ++ struct hist_data *my_hist; ++ char name[64]; ++ ++ dentry = tracing_init_dentry(); ++ ++ latency_hist_root = ++ debugfs_create_dir(latency_hist_dir_root, dentry); ++ ++#ifdef CONFIG_INTERRUPT_OFF_HIST ++ dentry = debugfs_create_dir(interrupt_off_hist_dir, ++ latency_hist_root); ++ for_each_possible_cpu(i) { ++ len = sprintf(name, "CPU%d", i); ++ name[len] = '\0'; ++ entry = debugfs_create_file(name, 0444, dentry, ++ &per_cpu(interrupt_off_hist, i), ++ &latency_hist_fops); ++ my_hist = &per_cpu(interrupt_off_hist, i); ++ atomic_set(&my_hist->hist_mode, 1); ++ my_hist->min_lat = 0xFFFFFFFFUL; ++ } ++ entry = debugfs_create_file("reset", 0444, dentry, ++ (void *)INTERRUPT_LATENCY, ++ &latency_hist_reset_fops); ++#endif ++ ++#ifdef CONFIG_PREEMPT_OFF_HIST ++ dentry = debugfs_create_dir(preempt_off_hist_dir, ++ latency_hist_root); ++ for_each_possible_cpu(i) { ++ len = sprintf(name, "CPU%d", i); ++ name[len] = '\0'; ++ entry = debugfs_create_file(name, 0444, dentry, ++ &per_cpu(preempt_off_hist, i), ++ &latency_hist_fops); ++ my_hist = &per_cpu(preempt_off_hist, i); ++ atomic_set(&my_hist->hist_mode, 1); ++ my_hist->min_lat = 0xFFFFFFFFUL; ++ } ++ entry = debugfs_create_file("reset", 0444, dentry, ++ (void *)PREEMPT_LATENCY, ++ &latency_hist_reset_fops); ++#endif ++ ++#if defined(CONFIG_INTERRUPT_OFF_HIST) && defined(CONFIG_PREEMPT_OFF_HIST) ++ dentry = debugfs_create_dir(preempt_irqs_off_hist_dir, ++ latency_hist_root); ++ for_each_possible_cpu(i) { ++ len = sprintf(name, "CPU%d", i); ++ name[len] = '\0'; ++ entry = debugfs_create_file(name, 0444, dentry, ++ &per_cpu(preempt_off_hist, i), ++ &latency_hist_fops); ++ my_hist = &per_cpu(preempt_irqs_off_hist, i); ++ atomic_set(&my_hist->hist_mode, 1); ++ my_hist->min_lat = 0xFFFFFFFFUL; ++ } ++ entry = debugfs_create_file("reset", 0444, dentry, ++ (void *)PREEMPT_INTERRUPT_LATENCY, ++ &latency_hist_reset_fops); ++#endif ++ ++#ifdef CONFIG_WAKEUP_LATENCY_HIST ++ ++ i = marker_probe_register("kernel_sched_wakeup", ++ "pid %d state %ld ## rq %p task %p rq->curr %p", ++ wake_up_callback, NULL); ++ if (i) { ++ pr_info("wakeup hist: Couldn't add marker" ++ " probe to kernel_sched_wakeup\n"); ++ goto out_wake; ++ } ++ ++ i = marker_probe_register("kernel_sched_wakeup_new", ++ "pid %d state %ld ## rq %p task %p rq->curr %p", ++ wake_up_callback, NULL); ++ if (i) { ++ pr_info("wakeup hist: Couldn't add marker" ++ " probe to kernel_sched_wakeup_new\n"); ++ goto fail_deprobe; ++ } ++ ++ i = marker_probe_register("kernel_sched_schedule", ++ "prev_pid %d next_pid %d prev_state %ld " ++ "## rq %p prev %p next %p", ++ sched_switch_callback, NULL); ++ if (i) { ++ pr_info("wakeup hist: Couldn't add marker" ++ " probe to kernel_sched_schedule\n"); ++ goto fail_deprobe_wake_new; ++ } ++ ++ dentry = debugfs_create_dir(wakeup_latency_hist_dir, ++ latency_hist_root); ++ for_each_possible_cpu(i) { ++ len = sprintf(name, "CPU%d", i); ++ name[len] = '\0'; ++ entry = debugfs_create_file(name, 0444, dentry, ++ &per_cpu(wakeup_latency_hist, i), ++ &latency_hist_fops); ++ my_hist = &per_cpu(wakeup_latency_hist, i); ++ atomic_set(&my_hist->hist_mode, 1); ++ my_hist->min_lat = 0xFFFFFFFFUL; ++ } ++ entry = debugfs_create_file("reset", 0444, dentry, ++ (void *)WAKEUP_LATENCY, ++ &latency_hist_reset_fops); ++ ++ goto out_wake; ++ ++fail_deprobe_wake_new: ++ marker_probe_unregister("kernel_sched_wakeup_new", ++ wake_up_callback, NULL); ++fail_deprobe: ++ marker_probe_unregister("kernel_sched_wakeup", ++ wake_up_callback, NULL); ++ out_wake: ++#endif ++ return 0; ++ ++} ++ ++__initcall(latency_hist_init); +Index: linux-2.6.24.7-rt21/kernel/trace/trace_hist.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/kernel/trace/trace_hist.h 2008-10-08 22:23:08.000000000 -0400 +@@ -0,0 +1,39 @@ ++/* ++ * kernel/trace/trace_hist.h ++ * ++ * Add support for histograms of preemption-off latency and ++ * interrupt-off latency and wakeup latency, it depends on ++ * Real-Time Preemption Support. ++ * ++ * Copyright (C) 2005 MontaVista Software, Inc. ++ * Yi Yang ++ * ++ * Converted to work with the new latency tracer. ++ * Copyright (C) 2008 Red Hat, Inc. ++ * Steven Rostedt ++ * ++ */ ++#ifndef _LIB_TRACING_TRACER_HIST_H_ ++#define _LIB_TRACING_TRACER_HIST_H_ ++ ++#if defined(CONFIG_INTERRUPT_OFF_HIST) || defined(CONFIG_PREEMPT_OFF_HIST) ++# define TRACE_STOP 2 ++void tracing_hist_preempt_start(void); ++void tracing_hist_preempt_stop(int irqs_on); ++#else ++# define tracing_hist_preempt_start() do { } while (0) ++# define tracing_hist_preempt_stop(irqs_off) do { } while (0) ++#endif ++ ++#ifdef CONFIG_WAKEUP_LATENCY_HIST ++void tracing_hist_wakeup_start(struct task_struct *p, ++ struct task_struct *curr); ++void tracing_hist_wakeup_stop(struct task_struct *next); ++extern int tracing_wakeup_hist; ++#else ++# define tracing_hist_wakeup_start(p, curr) do { } while (0) ++# define tracing_hist_wakeup_stop(next) do { } while (0) ++# define tracing_wakeup_hist 0 ++#endif ++ ++#endif /* ifndef _LIB_TRACING_TRACER_HIST_H_ */ +Index: linux-2.6.24.7-rt21/kernel/trace/trace_irqsoff.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/trace_irqsoff.c 2008-10-08 22:23:06.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/trace_irqsoff.c 2008-10-08 22:23:08.000000000 -0400 +@@ -17,6 +17,7 @@ + #include + + #include "trace.h" ++#include "trace_hist.h" + + static struct trace_array *irqsoff_trace __read_mostly; + static int tracer_enabled __read_mostly; +@@ -252,10 +253,14 @@ void start_critical_timings(void) + { + if (preempt_trace() || irq_trace()) + start_critical_timing(CALLER_ADDR0, CALLER_ADDR1); ++ ++ tracing_hist_preempt_start(); + } + + void stop_critical_timings(void) + { ++ tracing_hist_preempt_stop(TRACE_STOP); ++ + if (preempt_trace() || irq_trace()) + stop_critical_timing(CALLER_ADDR0, CALLER_ADDR1); + } +@@ -264,6 +269,8 @@ void stop_critical_timings(void) + #ifdef CONFIG_PROVE_LOCKING + void time_hardirqs_on(unsigned long a0, unsigned long a1) + { ++ tracing_hist_preempt_stop(1); ++ + if (!preempt_trace() && irq_trace()) + stop_critical_timing(a0, a1); + } +@@ -272,6 +279,8 @@ void time_hardirqs_off(unsigned long a0, + { + if (!preempt_trace() && irq_trace()) + start_critical_timing(a0, a1); ++ ++ tracing_hist_preempt_start(); + } + + #else /* !CONFIG_PROVE_LOCKING */ +@@ -305,6 +314,8 @@ inline void print_irqtrace_events(struct + */ + void trace_hardirqs_on(void) + { ++ tracing_hist_preempt_stop(1); ++ + if (!preempt_trace() && irq_trace()) + stop_critical_timing(CALLER_ADDR0, CALLER_ADDR1); + } +@@ -314,11 +325,15 @@ void trace_hardirqs_off(void) + { + if (!preempt_trace() && irq_trace()) + start_critical_timing(CALLER_ADDR0, CALLER_ADDR1); ++ ++ tracing_hist_preempt_start(); + } + EXPORT_SYMBOL(trace_hardirqs_off); + + void trace_hardirqs_on_caller(unsigned long caller_addr) + { ++ tracing_hist_preempt_stop(1); ++ + if (!preempt_trace() && irq_trace()) + stop_critical_timing(CALLER_ADDR0, caller_addr); + } +@@ -328,6 +343,8 @@ void trace_hardirqs_off_caller(unsigned + { + if (!preempt_trace() && irq_trace()) + start_critical_timing(CALLER_ADDR0, caller_addr); ++ ++ tracing_hist_preempt_start(); + } + EXPORT_SYMBOL(trace_hardirqs_off_caller); + +@@ -337,12 +354,14 @@ EXPORT_SYMBOL(trace_hardirqs_off_caller) + #ifdef CONFIG_PREEMPT_TRACER + void trace_preempt_on(unsigned long a0, unsigned long a1) + { ++ tracing_hist_preempt_stop(0); + stop_critical_timing(a0, a1); + } + + void trace_preempt_off(unsigned long a0, unsigned long a1) + { + start_critical_timing(a0, a1); ++ tracing_hist_preempt_start(); + } + #endif /* CONFIG_PREEMPT_TRACER */ + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0383-rt-delayed-prio.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0383-rt-delayed-prio.patch @@ -0,0 +1,89 @@ +Subject: rt: PI-workqueue: propagate prio for delayed work + +Delayed work looses its enqueue priority, and will be enqueued on the prio +of the softirq thread. Ammend this. + +Signed-off-by: Peter Zijlstra +--- + include/linux/workqueue.h | 1 + + kernel/workqueue.c | 16 ++++++++++------ + 2 files changed, 11 insertions(+), 6 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/workqueue.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/workqueue.h 2008-10-08 22:24:35.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/workqueue.h 2008-10-08 22:24:35.000000000 -0400 +@@ -40,6 +40,7 @@ struct work_struct { + struct delayed_work { + struct work_struct work; + struct timer_list timer; ++ int prio; + }; + + struct execute_work { +Index: linux-2.6.24.7-rt21/kernel/workqueue.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/workqueue.c 2008-10-08 22:24:35.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/workqueue.c 2008-10-08 22:24:35.000000000 -0400 +@@ -153,12 +153,12 @@ static void insert_work(struct cpu_workq + + /* Preempt must be disabled. */ + static void __queue_work(struct cpu_workqueue_struct *cwq, +- struct work_struct *work) ++ struct work_struct *work, int prio) + { + unsigned long flags; + + spin_lock_irqsave(&cwq->lock, flags); +- insert_work(cwq, work, current->normal_prio, current->normal_prio); ++ insert_work(cwq, work, prio, prio); + spin_unlock_irqrestore(&cwq->lock, flags); + } + +@@ -180,7 +180,7 @@ int fastcall queue_work(struct workqueue + + if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) { + BUG_ON(!plist_node_empty(&work->entry)); +- __queue_work(wq_per_cpu(wq, cpu), work); ++ __queue_work(wq_per_cpu(wq, cpu), work, current->normal_prio); + ret = 1; + } + return ret; +@@ -193,7 +193,8 @@ void delayed_work_timer_fn(unsigned long + struct cpu_workqueue_struct *cwq = get_wq_data(&dwork->work); + struct workqueue_struct *wq = cwq->wq; + +- __queue_work(wq_per_cpu(wq, raw_smp_processor_id()), &dwork->work); ++ __queue_work(wq_per_cpu(wq, raw_smp_processor_id()), ++ &dwork->work, dwork->prio); + } + + /** +@@ -236,6 +237,7 @@ int queue_delayed_work_on(int cpu, struc + BUG_ON(!plist_node_empty(&work->entry)); + + /* This stores cwq for the moment, for the timer_fn */ ++ dwork->prio = current->normal_prio; + set_wq_data(work, wq_per_cpu(wq, raw_smp_processor_id())); + timer->expires = jiffies + delay; + timer->data = (unsigned long)dwork; +@@ -725,7 +727,8 @@ int schedule_on_each_cpu(void (*func)(vo + work->info = info; + INIT_WORK(&work->work, schedule_on_each_cpu_func); + set_bit(WORK_STRUCT_PENDING, work_data_bits(&work->work)); +- __queue_work(per_cpu_ptr(keventd_wq->cpu_wq, cpu), &work->work); ++ __queue_work(per_cpu_ptr(keventd_wq->cpu_wq, cpu), ++ &work->work, current->normal_prio); + } + unlock_cpu_hotplug(); + +@@ -772,7 +775,8 @@ int schedule_on_each_cpu_wq(struct workq + + INIT_WORK(work, func); + set_bit(WORK_STRUCT_PENDING, work_data_bits(work)); +- __queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work); ++ __queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work, ++ current->normal_prio); + } + flush_workqueue(wq); + free_percpu(works); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0445-rtmutex-remove-xchg.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0445-rtmutex-remove-xchg.patch @@ -0,0 +1,24 @@ +From: Steven Rostedt +Subject: rtmutex - remove double xchg + +No reason to update current if we are running. We'll do that when we exit +the loop. + +Signed-off-by: Steven Rostedt +--- + kernel/rtmutex.c | 2 -- + 1 file changed, 2 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/rtmutex.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rtmutex.c 2008-10-08 22:24:50.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rtmutex.c 2008-10-08 22:24:50.000000000 -0400 +@@ -748,8 +748,6 @@ rt_spin_lock_slowlock(struct rt_mutex *l + update_current(TASK_UNINTERRUPTIBLE, &saved_state); + if (waiter.task) + schedule_rt_mutex(lock); +- else +- update_current(TASK_RUNNING_MUTEX, &saved_state); + + spin_lock_irqsave(&lock->wait_lock, flags); + current->flags |= saved_flags; --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0116-lockdep-prettify.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0116-lockdep-prettify.patch @@ -0,0 +1,45 @@ +Subject: [patch] lockdep: prettify output +From: Ingo Molnar + +recent changes to the lockdep code made some of the printouts +uglier - mend them. + +Signed-off-by: Ingo Molnar +--- + kernel/lockdep.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/lockdep.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/lockdep.c 2008-10-08 22:23:24.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/lockdep.c 2008-10-08 22:23:24.000000000 -0400 +@@ -581,7 +581,7 @@ static void print_lock_dependencies(stru + + static void print_kernel_version(void) + { +- printk("%s %.*s\n", init_utsname()->release, ++ printk("[ %s %.*s\n", init_utsname()->release, + (int)strcspn(init_utsname()->version, " "), + init_utsname()->version); + } +@@ -3129,13 +3129,13 @@ void __init lockdep_info(void) + { + printk("Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar\n"); + +- printk("... MAX_LOCKDEP_SUBCLASSES: %lu\n", MAX_LOCKDEP_SUBCLASSES); +- printk("... MAX_LOCK_DEPTH: %lu\n", MAX_LOCK_DEPTH); +- printk("... MAX_LOCKDEP_KEYS: %lu\n", MAX_LOCKDEP_KEYS); +- printk("... CLASSHASH_SIZE: %lu\n", CLASSHASH_SIZE); +- printk("... MAX_LOCKDEP_ENTRIES: %lu\n", MAX_LOCKDEP_ENTRIES); +- printk("... MAX_LOCKDEP_CHAINS: %lu\n", MAX_LOCKDEP_CHAINS); +- printk("... CHAINHASH_SIZE: %lu\n", CHAINHASH_SIZE); ++ printk("... MAX_LOCKDEP_SUBCLASSES: %6lu\n", MAX_LOCKDEP_SUBCLASSES); ++ printk("... MAX_LOCK_DEPTH: %6lu\n", MAX_LOCK_DEPTH); ++ printk("... MAX_LOCKDEP_KEYS: %6lu\n", MAX_LOCKDEP_KEYS); ++ printk("... CLASSHASH_SIZE: %6lu\n", CLASSHASH_SIZE); ++ printk("... MAX_LOCKDEP_ENTRIES: %6lu\n", MAX_LOCKDEP_ENTRIES); ++ printk("... MAX_LOCKDEP_CHAINS: %6lu\n", MAX_LOCKDEP_CHAINS); ++ printk("... CHAINHASH_SIZE: %6lu\n", CHAINHASH_SIZE); + + printk(" memory used by lock dependency info: %lu kB\n", + (sizeof(struct lock_class) * MAX_LOCKDEP_KEYS + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0173-rt-mutex-mips.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0173-rt-mutex-mips.patch @@ -0,0 +1,250 @@ +--- + arch/mips/Kconfig | 15 +++++++++++---- + arch/mips/kernel/Makefile | 4 +++- + include/asm-mips/atomic.h | 26 +++++++++++++++++++++----- + include/asm-mips/semaphore.h | 30 +++++++++++++++++++++--------- + 4 files changed, 56 insertions(+), 19 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/mips/Kconfig +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/mips/Kconfig 2008-10-08 22:22:35.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/mips/Kconfig 2008-10-08 22:23:39.000000000 -0400 +@@ -52,6 +52,7 @@ config BCM47XX + select CEVT_R4K + select CSRC_R4K + select DMA_NONCOHERENT ++ select NO_SPINLOCK + select HW_HAS_PCI + select IRQ_CPU + select SYS_HAS_CPU_MIPS32_R1 +@@ -703,10 +704,17 @@ endmenu + + config RWSEM_GENERIC_SPINLOCK + bool ++ depends on !PREEMPT_RT + default y + + config RWSEM_XCHGADD_ALGORITHM + bool ++ depends on !PREEMPT_RT ++ ++config ASM_SEMAPHORES ++ bool ++# depends on !PREEMPT_RT ++ default y + + config ARCH_HAS_ILOG2_U32 + bool +@@ -808,6 +816,9 @@ config DMA_NONCOHERENT + config DMA_NEED_PCI_MAP_STATE + bool + ++config NO_SPINLOCK ++ bool ++ + config EARLY_PRINTK + bool "Early printk" if EMBEDDED && DEBUG_KERNEL + depends on SYS_HAS_EARLY_PRINTK +@@ -1889,10 +1900,6 @@ config SECCOMP + + endmenu + +-config RWSEM_GENERIC_SPINLOCK +- bool +- default y +- + config LOCKDEP_SUPPORT + bool + default y +Index: linux-2.6.24.7-rt21/arch/mips/kernel/Makefile +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/mips/kernel/Makefile 2008-10-08 22:22:35.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/mips/kernel/Makefile 2008-10-08 22:23:39.000000000 -0400 +@@ -5,7 +5,7 @@ + extra-y := head.o init_task.o vmlinux.lds + + obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ +- ptrace.o reset.o semaphore.o setup.o signal.o syscall.o \ ++ ptrace.o reset.o setup.o signal.o syscall.o \ + time.o topology.o traps.o unaligned.o + + obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o +@@ -26,6 +26,8 @@ obj-$(CONFIG_MODULES) += mips_ksyms.o m + obj-$(CONFIG_CPU_LOONGSON2) += r4k_fpu.o r4k_switch.o + obj-$(CONFIG_CPU_MIPS32) += r4k_fpu.o r4k_switch.o + obj-$(CONFIG_CPU_MIPS64) += r4k_fpu.o r4k_switch.o ++obj-$(CONFIG_ASM_SEMAPHORES) += semaphore.o ++ + obj-$(CONFIG_CPU_R3000) += r2300_fpu.o r2300_switch.o + obj-$(CONFIG_CPU_R4000) += r4k_fpu.o r4k_switch.o + obj-$(CONFIG_CPU_R4300) += r4k_fpu.o r4k_switch.o +Index: linux-2.6.24.7-rt21/include/asm-mips/atomic.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-mips/atomic.h 2008-10-08 22:22:35.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-mips/atomic.h 2008-10-08 22:23:39.000000000 -0400 +@@ -171,7 +171,9 @@ static __inline__ int atomic_add_return( + : "=&r" (result), "=&r" (temp), "=m" (v->counter) + : "Ir" (i), "m" (v->counter) + : "memory"); +- } else { ++ } ++#if !defined(CONFIG_NO_SPINLOCK) && !defined(CONFIG_PREEMPT_RT) ++ else { + unsigned long flags; + + raw_local_irq_save(flags); +@@ -180,6 +182,7 @@ static __inline__ int atomic_add_return( + v->counter = result; + raw_local_irq_restore(flags); + } ++#endif + + smp_llsc_mb(); + +@@ -223,7 +226,9 @@ static __inline__ int atomic_sub_return( + : "=&r" (result), "=&r" (temp), "=m" (v->counter) + : "Ir" (i), "m" (v->counter) + : "memory"); +- } else { ++ } ++#if !defined(CONFIG_NO_SPINLOCK) && !defined(CONFIG_PREEMPT_RT) ++ else { + unsigned long flags; + + raw_local_irq_save(flags); +@@ -232,6 +237,7 @@ static __inline__ int atomic_sub_return( + v->counter = result; + raw_local_irq_restore(flags); + } ++#endif + + smp_llsc_mb(); + +@@ -291,7 +297,9 @@ static __inline__ int atomic_sub_if_posi + : "=&r" (result), "=&r" (temp), "=m" (v->counter) + : "Ir" (i), "m" (v->counter) + : "memory"); +- } else { ++ } ++#if !defined(CONFIG_NO_SPINLOCK) && !defined(CONFIG_PREEMPT_RT) ++ else { + unsigned long flags; + + raw_local_irq_save(flags); +@@ -301,6 +309,7 @@ static __inline__ int atomic_sub_if_posi + v->counter = result; + raw_local_irq_restore(flags); + } ++#endif + + smp_llsc_mb(); + +@@ -552,7 +561,9 @@ static __inline__ long atomic64_add_retu + : "=&r" (result), "=&r" (temp), "=m" (v->counter) + : "Ir" (i), "m" (v->counter) + : "memory"); +- } else { ++ } ++#if !defined(CONFIG_NO_SPINLOCK) && !defined(CONFIG_PREEMPT_RT) ++ else { + unsigned long flags; + + raw_local_irq_save(flags); +@@ -561,6 +572,8 @@ static __inline__ long atomic64_add_retu + v->counter = result; + raw_local_irq_restore(flags); + } ++#endif ++#endif + + smp_llsc_mb(); + +@@ -604,7 +617,9 @@ static __inline__ long atomic64_sub_retu + : "=&r" (result), "=&r" (temp), "=m" (v->counter) + : "Ir" (i), "m" (v->counter) + : "memory"); +- } else { ++ } ++#if !defined(CONFIG_NO_SPINLOCK) && !defined(CONFIG_PREEMPT_RT) ++ else { + unsigned long flags; + + raw_local_irq_save(flags); +@@ -682,6 +697,7 @@ static __inline__ long atomic64_sub_if_p + v->counter = result; + raw_local_irq_restore(flags); + } ++#endif + + smp_llsc_mb(); + +Index: linux-2.6.24.7-rt21/include/asm-mips/semaphore.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-mips/semaphore.h 2008-10-08 22:22:35.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-mips/semaphore.h 2008-10-08 22:23:39.000000000 -0400 +@@ -24,12 +24,20 @@ + + #ifdef __KERNEL__ + +-#include +-#include + #include + #include + +-struct semaphore { ++/* ++ * On !PREEMPT_RT all semaphores are compat: ++ */ ++#ifndef CONFIG_PREEMPT_RT ++# define compat_semaphore semaphore ++#endif ++ ++#include ++#include ++ ++struct compat_semaphore { + /* + * Note that any negative value of count is equivalent to 0, + * but additionally indicates that some process(es) might be +@@ -78,31 +86,35 @@ static inline void down(struct semaphore + * Try to get the semaphore, take the slow path if we fail. + */ + if (unlikely(atomic_dec_return(&sem->count) < 0)) +- __down(sem); ++ __compat_down(sem); + } + +-static inline int down_interruptible(struct semaphore * sem) ++static inline int compat_down_interruptible(struct compat_semaphore * sem) + { + int ret = 0; + + might_sleep(); + + if (unlikely(atomic_dec_return(&sem->count) < 0)) +- ret = __down_interruptible(sem); ++ ret = __compat_down_interruptible(sem); + return ret; + } + +-static inline int down_trylock(struct semaphore * sem) ++static inline int compat_down_trylock(struct compat_semaphore * sem) + { + return atomic_dec_if_positive(&sem->count) < 0; + } + +-static inline void up(struct semaphore * sem) ++static inline void compat_up(struct compat_semaphore * sem) + { + if (unlikely(atomic_inc_return(&sem->count) <= 0)) +- __up(sem); ++ __compat_up(sem); + } + ++#define compat_sema_count(sem) atomic_read(&(sem)->count) ++ ++#include ++ + #endif /* __KERNEL__ */ + + #endif /* __ASM_SEMAPHORE_H */ --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0102-move-native-irq.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0102-move-native-irq.patch @@ -0,0 +1,36 @@ +--- + kernel/irq/migration.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/irq/migration.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/irq/migration.c 2008-10-08 22:22:41.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/irq/migration.c 2008-10-08 22:23:20.000000000 -0400 +@@ -61,6 +61,7 @@ void move_masked_irq(int irq) + void move_native_irq(int irq) + { + struct irq_desc *desc = irq_desc + irq; ++ int mask = 1; + + if (likely(!(desc->status & IRQ_MOVE_PENDING))) + return; +@@ -68,8 +69,17 @@ void move_native_irq(int irq) + if (unlikely(desc->status & IRQ_DISABLED)) + return; + +- desc->chip->mask(irq); ++ /* ++ * If the irq is already in progress, it should be masked. ++ * If we unmask it, we might cause an interrupt storm on RT. ++ */ ++ if (unlikely(desc->status & IRQ_INPROGRESS)) ++ mask = 0; ++ ++ if (mask) ++ desc->chip->mask(irq); + move_masked_irq(irq); +- desc->chip->unmask(irq); ++ if (mask) ++ desc->chip->unmask(irq); + } + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0096-floppy-resume-fix.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0096-floppy-resume-fix.patch @@ -0,0 +1,77 @@ +Subject: [patch] floppy: suspend/resume fix +From: Ingo Molnar + +introduce a floppy platform-driver and suspend/resume ops to +stop/start the floppy driver. Bug reported by Mikael Pettersson. + +Signed-off-by: Ingo Molnar +--- + drivers/block/floppy.c | 31 ++++++++++++++++++++++++++++++- + 1 file changed, 30 insertions(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/drivers/block/floppy.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/block/floppy.c 2008-10-08 22:22:41.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/block/floppy.c 2008-10-08 22:23:19.000000000 -0400 +@@ -4149,6 +4149,28 @@ static void floppy_device_release(struct + complete(&device_release); + } + ++static int floppy_suspend(struct platform_device *dev, pm_message_t state) ++{ ++ floppy_release_irq_and_dma(); ++ ++ return 0; ++} ++ ++static int floppy_resume(struct platform_device *dev) ++{ ++ floppy_grab_irq_and_dma(); ++ ++ return 0; ++} ++ ++static struct platform_driver floppy_driver = { ++ .suspend = floppy_suspend, ++ .resume = floppy_resume, ++ .driver = { ++ .name = "floppy", ++ }, ++}; ++ + static struct platform_device floppy_device[N_DRIVE]; + + static struct kobject *floppy_find(dev_t dev, int *part, void *data) +@@ -4197,10 +4219,14 @@ static int __init floppy_init(void) + if (err) + goto out_put_disk; + ++ err = platform_driver_register(&floppy_driver); ++ if (err) ++ goto out_unreg_blkdev; ++ + floppy_queue = blk_init_queue(do_fd_request, &floppy_lock); + if (!floppy_queue) { + err = -ENOMEM; +- goto out_unreg_blkdev; ++ goto out_unreg_driver; + } + blk_queue_max_sectors(floppy_queue, 64); + +@@ -4349,6 +4375,8 @@ out_flush_work: + out_unreg_region: + blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); + blk_cleanup_queue(floppy_queue); ++out_unreg_driver: ++ platform_driver_unregister(&floppy_driver); + out_unreg_blkdev: + unregister_blkdev(FLOPPY_MAJOR, "fd"); + out_put_disk: +@@ -4544,6 +4572,7 @@ void cleanup_module(void) + init_completion(&device_release); + blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); + unregister_blkdev(FLOPPY_MAJOR, "fd"); ++ platform_driver_unregister(&floppy_driver); + + for (drive = 0; drive < N_DRIVE; drive++) { + del_timer_sync(&motor_off_timer[drive]); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0537-trace-ktime-scalar.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0537-trace-ktime-scalar.patch @@ -0,0 +1,113 @@ +Subject: ftrace: print ktime values in readable form +From: Thomas Gleixner +Date: Sat, 26 Jul 2008 23:01:37 +0200 + +Printing the tv64 member of the ktime_t expiry/timestamp is unreadable +on 32bit machines which don't have KTIME_SCALAR set. + +Convert the ktime_t value to a timespec instead and print sec.nsec +value, which makes the time values much easier to read also on those +machines which use the 64bit scalar nsec storage. + +Signed-off-by: Thomas Gleixner +--- + kernel/trace/trace.c | 47 +++++++++++++++++++++++++++++++---------------- + 1 file changed, 31 insertions(+), 16 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/trace/trace.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/trace.c 2008-10-08 22:25:11.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/trace.c 2008-10-08 22:25:13.000000000 -0400 +@@ -1633,6 +1633,13 @@ extern unsigned long ia32_sys_call_table + # define IA32_NR_syscalls (ia32_syscall_end - ia32_sys_call_table) + #endif + ++static void trace_print_ktime(struct trace_seq *s, ktime_t t) ++{ ++ struct timespec ts = ktime_to_timespec(t); ++ ++ trace_seq_printf(s, " (%ld.%09ld)", ts.tv_sec, ts.tv_nsec); ++} ++ + static int + print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) + { +@@ -1728,23 +1735,23 @@ print_lat_fmt(struct trace_iterator *ite + break; + case TRACE_TIMER_SET: + seq_print_ip_sym(s, entry->timer.ip, sym_flags); +- trace_seq_printf(s, " (%Ld) (%p)\n", +- entry->timer.expire, entry->timer.timer); ++ trace_print_ktime(s, entry->timer.expire); ++ trace_seq_printf(s, " (%p)\n", entry->timer.timer); + break; + case TRACE_TIMER_TRIG: + seq_print_ip_sym(s, entry->timer.ip, sym_flags); +- trace_seq_printf(s, " (%Ld) (%p)\n", +- entry->timer.expire, entry->timer.timer); ++ trace_print_ktime(s, entry->timer.expire); ++ trace_seq_printf(s, " (%p)\n", entry->timer.timer); + break; + case TRACE_TIMESTAMP: + seq_print_ip_sym(s, entry->timestamp.ip, sym_flags); +- trace_seq_printf(s, " (%Ld)\n", +- entry->timestamp.now.tv64); ++ trace_print_ktime(s, entry->timestamp.now); ++ trace_seq_puts(s, "\n"); + break; + case TRACE_PROGRAM_EVENT: + seq_print_ip_sym(s, entry->program.ip, sym_flags); +- trace_seq_printf(s, " (%Ld) (%Ld)\n", +- entry->program.expire, entry->program.delta); ++ trace_print_ktime(s, entry->program.expire); ++ trace_seq_printf(s, " (%Ld)\n", entry->program.delta); + break; + case TRACE_TASK_ACT: + seq_print_ip_sym(s, entry->task.ip, sym_flags); +@@ -1822,6 +1829,14 @@ static int print_trace_fmt(struct trace_ + ret = trace_seq_printf(s, "[%02d] ", iter->cpu); + if (!ret) + return 0; ++ ++ ret = trace_seq_printf(s, "%c%c %2d ", ++ (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' : '.', ++ ((entry->flags & TRACE_FLAG_NEED_RESCHED) ? 'N' : '.'), ++ entry->preempt_count); ++ if (!ret) ++ return 0; ++ + ret = trace_seq_printf(s, "%5lu.%06lu: ", secs, usec_rem); + if (!ret) + return 0; +@@ -1908,23 +1923,23 @@ static int print_trace_fmt(struct trace_ + break; + case TRACE_TIMER_SET: + seq_print_ip_sym(s, entry->timer.ip, sym_flags); +- trace_seq_printf(s, " (%Ld) (%p)\n", +- entry->timer.expire, entry->timer.timer); ++ trace_print_ktime(s, entry->timer.expire); ++ trace_seq_printf(s, " (%p)\n", entry->timer.timer); + break; + case TRACE_TIMER_TRIG: + seq_print_ip_sym(s, entry->timer.ip, sym_flags); +- trace_seq_printf(s, " (%Ld) (%p)\n", +- entry->timer.expire, entry->timer.timer); ++ trace_print_ktime(s, entry->timer.expire); ++ trace_seq_printf(s, " (%p)\n", entry->timer.timer); + break; + case TRACE_TIMESTAMP: + seq_print_ip_sym(s, entry->timestamp.ip, sym_flags); +- trace_seq_printf(s, " (%Ld)\n", +- entry->timestamp.now.tv64); ++ trace_print_ktime(s, entry->timestamp.now); ++ trace_seq_puts(s, "\n"); + break; + case TRACE_PROGRAM_EVENT: + seq_print_ip_sym(s, entry->program.ip, sym_flags); +- trace_seq_printf(s, " (%Ld) (%Ld)\n", +- entry->program.expire, entry->program.delta); ++ trace_print_ktime(s, entry->program.expire); ++ trace_seq_printf(s, " (%Ld)\n", entry->program.delta); + break; + case TRACE_TASK_ACT: + seq_print_ip_sym(s, entry->task.ip, sym_flags); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0117-lockdep-more-entries.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0117-lockdep-more-entries.patch @@ -0,0 +1,23 @@ +--- + kernel/lockdep_internals.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/lockdep_internals.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/lockdep_internals.h 2008-10-08 22:22:40.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/lockdep_internals.h 2008-10-08 22:23:24.000000000 -0400 +@@ -15,12 +15,12 @@ + * table (if it's not there yet), and we check it for lock order + * conflicts and deadlocks. + */ +-#define MAX_LOCKDEP_ENTRIES 8192UL ++#define MAX_LOCKDEP_ENTRIES 16384UL + + #define MAX_LOCKDEP_KEYS_BITS 11 + #define MAX_LOCKDEP_KEYS (1UL << MAX_LOCKDEP_KEYS_BITS) + +-#define MAX_LOCKDEP_CHAINS_BITS 14 ++#define MAX_LOCKDEP_CHAINS_BITS 15 + #define MAX_LOCKDEP_CHAINS (1UL << MAX_LOCKDEP_CHAINS_BITS) + + /* --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0441-cache_pci_find_capability.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0441-cache_pci_find_capability.patch @@ -0,0 +1,195 @@ +From: Arnaldo Carvalho de Melo +Subject: [PATCH] Cache calls to pci_find_capability + + +The problem here is that everytime do_irqd masks/unmasks MSI interrupts +it would ask if the device has the MSI capability, and that involves +multiple calls to pci_conf1_read, that can take as high as 44us in +in/out calls, so I just cached results in struct pci_dev. + +With this patch the highest latency still is in masking/unmasking MSI +interrupts, but its down to 159us in a kernel with ftrace, using the +preemptirqsoff tracer: + + +I showed it to Jesse Barnes, the PCI maintainer and he said its 2.6.27 +material, and Rostedt said tglx is OK with it, so please add it to the +-50 kernel-rt release. + +Signed-off-by: Arnaldo Carvalho de Melo + +--- + drivers/pci/msi.c | 12 ++++++------ + drivers/pci/pci.c | 36 ++++++++++++++++++++++++++++++++++++ + drivers/pci/probe.c | 4 ++++ + include/linux/pci.h | 3 +++ + include/linux/pci_regs.h | 1 + + 5 files changed, 50 insertions(+), 6 deletions(-) + +Index: linux-2.6.24.7-rt21/drivers/pci/msi.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/pci/msi.c 2008-10-08 22:23:19.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/pci/msi.c 2008-10-08 22:24:49.000000000 -0400 +@@ -30,7 +30,7 @@ static void msi_set_enable(struct pci_de + int pos; + u16 control; + +- pos = pci_find_capability(dev, PCI_CAP_ID_MSI); ++ pos = pci_find_capability_cached(dev, PCI_CAP_ID_MSI); + if (pos) { + pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); + control &= ~PCI_MSI_FLAGS_ENABLE; +@@ -45,7 +45,7 @@ static void msix_set_enable(struct pci_d + int pos; + u16 control; + +- pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); ++ pos = pci_find_capability_cached(dev, PCI_CAP_ID_MSIX); + if (pos) { + pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control); + control &= ~PCI_MSIX_FLAGS_ENABLE; +@@ -311,7 +311,7 @@ static int msi_capability_init(struct pc + + msi_set_enable(dev, 0); /* Ensure msi is disabled as I set it up */ + +- pos = pci_find_capability(dev, PCI_CAP_ID_MSI); ++ pos = pci_find_capability_cached(dev, PCI_CAP_ID_MSI); + pci_read_config_word(dev, msi_control_reg(pos), &control); + /* MSI Entry Initialization */ + entry = alloc_msi_entry(); +@@ -384,7 +384,7 @@ static int msix_capability_init(struct p + + msix_set_enable(dev, 0);/* Ensure msix is disabled as I set it up */ + +- pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); ++ pos = pci_find_capability_cached(dev, PCI_CAP_ID_MSIX); + /* Request & Map MSI-X table region */ + pci_read_config_word(dev, msi_control_reg(pos), &control); + nr_entries = multi_msix_capable(control); +@@ -491,7 +491,7 @@ static int pci_msi_check_device(struct p + if (ret) + return ret; + +- if (!pci_find_capability(dev, type)) ++ if (!pci_find_capability_cached(dev, type)) + return -EINVAL; + + return 0; +@@ -610,7 +610,7 @@ int pci_enable_msix(struct pci_dev* dev, + if (status) + return status; + +- pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); ++ pos = pci_find_capability_cached(dev, PCI_CAP_ID_MSIX); + pci_read_config_word(dev, msi_control_reg(pos), &control); + nr_entries = multi_msix_capable(control); + if (nvec > nr_entries) +Index: linux-2.6.24.7-rt21/drivers/pci/pci.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/pci/pci.c 2008-10-08 22:22:15.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/pci/pci.c 2008-10-08 22:24:49.000000000 -0400 +@@ -170,6 +170,42 @@ int pci_find_capability(struct pci_dev * + } + + /** ++ * pci_find_capability_cached - query for devices' capabilities, cached version ++ * @dev: PCI device to query ++ * @cap: capability code ++ * ++ * Tell if a device supports a given PCI capability. ++ * Returns the address of the requested capability structure within the ++ * device's PCI configuration space or 0 in case the device does not ++ * support it. Possible values for @cap: ++ * ++ * %PCI_CAP_ID_PM Power Management ++ * %PCI_CAP_ID_AGP Accelerated Graphics Port ++ * %PCI_CAP_ID_VPD Vital Product Data ++ * %PCI_CAP_ID_SLOTID Slot Identification ++ * %PCI_CAP_ID_MSI Message Signalled Interrupts ++ * %PCI_CAP_ID_CHSWP CompactPCI HotSwap ++ * %PCI_CAP_ID_PCIX PCI-X ++ * %PCI_CAP_ID_EXP PCI Express ++ */ ++int pci_find_capability_cached(struct pci_dev *dev, int cap) ++{ ++ int pos = 0; ++ ++ WARN_ON_ONCE(cap <= 0 || cap > PCI_CAP_LIST_NR_ENTRIES); ++ ++ if (cap <= PCI_CAP_LIST_NR_ENTRIES) { ++ const int i = cap - 1; ++ if (dev->cached_capabilities[i] == -1) ++ dev->cached_capabilities[i] = pci_find_capability(dev, cap); ++ ++ pos = dev->cached_capabilities[i]; ++ } ++ ++ return pos; ++} ++ ++/** + * pci_bus_find_capability - query for devices' capabilities + * @bus: the PCI bus to query + * @devfn: PCI device to query +Index: linux-2.6.24.7-rt21/drivers/pci/probe.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/pci/probe.c 2008-10-08 22:22:15.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/pci/probe.c 2008-10-08 22:24:49.000000000 -0400 +@@ -854,6 +854,7 @@ static void pci_release_bus_bridge_dev(s + + struct pci_dev *alloc_pci_dev(void) + { ++ int i; + struct pci_dev *dev; + + dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL); +@@ -863,6 +864,9 @@ struct pci_dev *alloc_pci_dev(void) + INIT_LIST_HEAD(&dev->global_list); + INIT_LIST_HEAD(&dev->bus_list); + ++ for (i = 0; i < ARRAY_SIZE(dev->cached_capabilities); ++i) ++ dev->cached_capabilities[i] = -1; ++ + pci_msi_init_pci_dev(dev); + + return dev; +Index: linux-2.6.24.7-rt21/include/linux/pci.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/pci.h 2008-10-08 22:22:15.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/pci.h 2008-10-08 22:24:49.000000000 -0400 +@@ -193,6 +193,7 @@ struct pci_dev { + unsigned int msix_enabled:1; + unsigned int is_managed:1; + unsigned int is_pcie:1; ++ int cached_capabilities[PCI_CAP_LIST_NR_ENTRIES]; /* See pci_find_capability_cached */ + pci_dev_flags_t dev_flags; + atomic_t enable_cnt; /* pci_enable_device has been called */ + +@@ -494,6 +495,7 @@ struct pci_dev __deprecated *pci_find_sl + #endif /* CONFIG_PCI_LEGACY */ + + int pci_find_capability (struct pci_dev *dev, int cap); ++int pci_find_capability_cached(struct pci_dev *dev, int cap); + int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap); + int pci_find_ext_capability (struct pci_dev *dev, int cap); + int pci_find_ht_capability (struct pci_dev *dev, int ht_cap); +@@ -760,6 +762,7 @@ static inline int __pci_register_driver( + static inline int pci_register_driver(struct pci_driver *drv) { return 0;} + static inline void pci_unregister_driver(struct pci_driver *drv) { } + static inline int pci_find_capability (struct pci_dev *dev, int cap) {return 0; } ++static inline int pci_find_capability_cached(struct pci_dev *dev, int cap) {return 0; } + static inline int pci_find_next_capability (struct pci_dev *dev, u8 post, int cap) { return 0; } + static inline int pci_find_ext_capability (struct pci_dev *dev, int cap) {return 0; } + +Index: linux-2.6.24.7-rt21/include/linux/pci_regs.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/pci_regs.h 2008-10-08 22:22:15.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/pci_regs.h 2008-10-08 22:24:49.000000000 -0400 +@@ -210,6 +210,7 @@ + #define PCI_CAP_ID_AGP3 0x0E /* AGP Target PCI-PCI bridge */ + #define PCI_CAP_ID_EXP 0x10 /* PCI Express */ + #define PCI_CAP_ID_MSIX 0x11 /* MSI-X */ ++#define PCI_CAP_LIST_NR_ENTRIES PCI_CAP_ID_MSIX + #define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */ + #define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */ + #define PCI_CAP_SIZEOF 4 --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0023-0007-sched-disable-standard-balancer-for-RT-tasks.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0023-0007-sched-disable-standard-balancer-for-RT-tasks.patch @@ -0,0 +1,135 @@ +From a32200df1e2862b2ecb7a0367abbad6df466e536 Mon Sep 17 00:00:00 2001 +From: Steven Rostedt +Date: Tue, 11 Dec 2007 10:02:37 +0100 +Subject: [PATCH] sched: disable standard balancer for RT tasks + +Since we now take an active approach to load balancing, we don't need to +balance RT tasks via the normal task balancer. In fact, this code was +found to pull RT tasks away from CPUS that the active movement performed, +resulting in large latencies. + +Signed-off-by: Steven Rostedt +Signed-off-by: Ingo Molnar + +--- + kernel/sched_rt.c | 95 ++---------------------------------------------------- + 1 file changed, 4 insertions(+), 91 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/sched_rt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched_rt.c 2008-10-08 22:22:57.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched_rt.c 2008-10-08 22:22:57.000000000 -0400 +@@ -563,109 +563,22 @@ static void wakeup_balance_rt(struct rq + push_rt_tasks(rq); + } + +-/* +- * Load-balancing iterator. Note: while the runqueue stays locked +- * during the whole iteration, the current task might be +- * dequeued so the iterator has to be dequeue-safe. Here we +- * achieve that by always pre-iterating before returning +- * the current task: +- */ +-static struct task_struct *load_balance_start_rt(void *arg) +-{ +- struct rq *rq = arg; +- struct rt_prio_array *array = &rq->rt.active; +- struct list_head *head, *curr; +- struct task_struct *p; +- int idx; +- +- idx = sched_find_first_bit(array->bitmap); +- if (idx >= MAX_RT_PRIO) +- return NULL; +- +- head = array->queue + idx; +- curr = head->prev; +- +- p = list_entry(curr, struct task_struct, run_list); +- +- curr = curr->prev; +- +- rq->rt.rt_load_balance_idx = idx; +- rq->rt.rt_load_balance_head = head; +- rq->rt.rt_load_balance_curr = curr; +- +- return p; +-} +- +-static struct task_struct *load_balance_next_rt(void *arg) +-{ +- struct rq *rq = arg; +- struct rt_prio_array *array = &rq->rt.active; +- struct list_head *head, *curr; +- struct task_struct *p; +- int idx; +- +- idx = rq->rt.rt_load_balance_idx; +- head = rq->rt.rt_load_balance_head; +- curr = rq->rt.rt_load_balance_curr; +- +- /* +- * If we arrived back to the head again then +- * iterate to the next queue (if any): +- */ +- if (unlikely(head == curr)) { +- int next_idx = find_next_bit(array->bitmap, MAX_RT_PRIO, idx+1); +- +- if (next_idx >= MAX_RT_PRIO) +- return NULL; +- +- idx = next_idx; +- head = array->queue + idx; +- curr = head->prev; +- +- rq->rt.rt_load_balance_idx = idx; +- rq->rt.rt_load_balance_head = head; +- } +- +- p = list_entry(curr, struct task_struct, run_list); +- +- curr = curr->prev; +- +- rq->rt.rt_load_balance_curr = curr; +- +- return p; +-} +- + static unsigned long + load_balance_rt(struct rq *this_rq, int this_cpu, struct rq *busiest, + unsigned long max_load_move, + struct sched_domain *sd, enum cpu_idle_type idle, + int *all_pinned, int *this_best_prio) + { +- struct rq_iterator rt_rq_iterator; +- +- rt_rq_iterator.start = load_balance_start_rt; +- rt_rq_iterator.next = load_balance_next_rt; +- /* pass 'busiest' rq argument into +- * load_balance_[start|next]_rt iterators +- */ +- rt_rq_iterator.arg = busiest; +- +- return balance_tasks(this_rq, this_cpu, busiest, max_load_move, sd, +- idle, all_pinned, this_best_prio, &rt_rq_iterator); ++ /* don't touch RT tasks */ ++ return 0; + } + + static int + move_one_task_rt(struct rq *this_rq, int this_cpu, struct rq *busiest, + struct sched_domain *sd, enum cpu_idle_type idle) + { +- struct rq_iterator rt_rq_iterator; +- +- rt_rq_iterator.start = load_balance_start_rt; +- rt_rq_iterator.next = load_balance_next_rt; +- rt_rq_iterator.arg = busiest; +- +- return iter_move_one_task(this_rq, this_cpu, busiest, sd, idle, +- &rt_rq_iterator); ++ /* don't touch RT tasks */ ++ return 0; + } + #else /* CONFIG_SMP */ + # define schedule_tail_balance_rt(rq) do { } while (0) --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0393-printk-dont-bug-on-sched.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0393-printk-dont-bug-on-sched.patch @@ -0,0 +1,38 @@ +--- + kernel/rtmutex.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +Index: linux-2.6.24.7-rt21/kernel/rtmutex.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rtmutex.c 2008-10-08 22:24:32.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rtmutex.c 2008-10-08 22:24:38.000000000 -0400 +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + + #include "rtmutex_common.h" + +@@ -635,6 +636,9 @@ rt_spin_lock_fastlock(struct rt_mutex *l + /* Temporary HACK! */ + if (!current->in_printk) + might_sleep(); ++ else if (in_atomic() || irqs_disabled()) ++ /* don't grab locks for printk in atomic */ ++ return; + + if (likely(rt_mutex_cmpxchg(lock, NULL, current))) + rt_mutex_deadlock_account_lock(lock, current); +@@ -646,6 +650,11 @@ static inline void + rt_spin_lock_fastunlock(struct rt_mutex *lock, + void fastcall (*slowfn)(struct rt_mutex *lock)) + { ++ /* Temporary HACK! */ ++ if (current->in_printk && (in_atomic() || irqs_disabled())) ++ /* don't grab locks for printk in atomic */ ++ return; ++ + if (likely(rt_mutex_cmpxchg(lock, current, NULL))) + rt_mutex_deadlock_account_unlock(current); + else --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0304-kmap-atomic-i386-fix.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0304-kmap-atomic-i386-fix.patch @@ -0,0 +1,38 @@ +--- + arch/x86/mm/highmem_32.c | 2 +- + include/asm-x86/highmem.h | 6 +++--- + 2 files changed, 4 insertions(+), 4 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/x86/mm/highmem_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/mm/highmem_32.c 2008-10-08 22:24:16.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/mm/highmem_32.c 2008-10-08 22:24:17.000000000 -0400 +@@ -3,9 +3,9 @@ + + void *kmap(struct page *page) + { +- might_sleep(); + if (!PageHighMem(page)) + return page_address(page); ++ might_sleep(); + return kmap_high(page); + } + +Index: linux-2.6.24.7-rt21/include/asm-x86/highmem.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/highmem.h 2008-10-08 22:23:56.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/highmem.h 2008-10-08 22:24:17.000000000 -0400 +@@ -94,10 +94,10 @@ struct page *kmap_atomic_to_page(void *p + * on PREEMPT_RT kmap_atomic() is a wrapper that uses kmap(): + */ + #ifdef CONFIG_PREEMPT_RT +-# define kmap_atomic_prot(page, type, prot) kmap(page) +-# define kmap_atomic(page, type) kmap(page) ++# define kmap_atomic_prot(page, type, prot) ({ pagefault_disable(); kmap(page); }) ++# define kmap_atomic(page, type) ({ pagefault_disable(); kmap(page); }) + # define kmap_atomic_pfn(pfn, type) kmap(pfn_to_page(pfn)) +-# define kunmap_atomic(kvaddr, type) kunmap_virt(kvaddr) ++# define kunmap_atomic(kvaddr, type) do { pagefault_enable(); kunmap_virt(kvaddr); } while(0) + # define kmap_atomic_to_page(kvaddr) kmap_to_page(kvaddr) + #else + # define kmap_atomic_prot(page, type, prot) __kmap_atomic_prot(page, type, prot) --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0122-rcu-new-3.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0122-rcu-new-3.patch @@ -0,0 +1,1503 @@ +From paulmck@linux.vnet.ibm.com Thu Sep 27 00:03:19 2007 +Date: Mon, 10 Sep 2007 11:34:12 -0700 +From: Paul E. McKenney +To: linux-kernel@vger.kernel.org +Cc: linux-rt-users@vger.kernel.org, mingo@elte.hu, akpm@linux-foundation.org, + dipankar@in.ibm.com, josht@linux.vnet.ibm.com, tytso@us.ibm.com, + dvhltc@us.ibm.com, tglx@linutronix.de, a.p.zijlstra@chello.nl, + bunk@kernel.org, ego@in.ibm.com, oleg@tv-sign.ru, srostedt@redhat.com +Subject: [PATCH RFC 3/9] RCU: Preemptible RCU + +Work in progress, not for inclusion. + +This patch implements a new version of RCU which allows its read-side +critical sections to be preempted. It uses a set of counter pairs +to keep track of the read-side critical sections and flips them +when all tasks exit read-side critical section. The details +of this implementation can be found in this paper - + +http://www.rdrop.com/users/paulmck/RCU/OLSrtRCU.2006.08.11a.pdf + +This patch was developed as a part of the -rt kernel development and +meant to provide better latencies when read-side critical sections of +RCU don't disable preemption. As a consequence of keeping track of RCU +readers, the readers have a slight overhead (optimizations in the paper). +This implementation co-exists with the "classic" RCU implementations +and can be switched to at compiler. + +Also includes RCU tracing summarized in debugfs and RCU_SOFTIRQ for +the preemptible variant of RCU. + +Signed-off-by: Dipankar Sarma +Signed-off-by: Steven Rostedt (for RCU_SOFTIRQ) +Signed-off-by: Paul McKenney +--- + + include/linux/interrupt.h | 1 + include/linux/rcuclassic.h | 2 + include/linux/rcupdate.h | 7 + include/linux/rcupreempt.h | 78 +++ + include/linux/rcupreempt_trace.h | 100 +++++ + include/linux/sched.h | 5 + kernel/Kconfig.preempt | 39 + + kernel/Makefile | 7 + kernel/fork.c | 4 + kernel/rcupreempt.c | 766 +++++++++++++++++++++++++++++++++++++++ + kernel/rcupreempt_trace.c | 330 ++++++++++++++++ + 11 files changed, 1336 insertions(+), 3 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/interrupt.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/interrupt.h 2008-10-08 22:22:39.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/interrupt.h 2008-10-08 22:23:25.000000000 -0400 +@@ -256,6 +256,7 @@ enum + #ifdef CONFIG_HIGH_RES_TIMERS + HRTIMER_SOFTIRQ, + #endif ++ RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */ + }; + + /* softirq mask and active fields moved to irq_cpustat_t in +Index: linux-2.6.24.7-rt21/include/linux/rcuclassic.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/rcuclassic.h 2008-10-08 22:23:25.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/rcuclassic.h 2008-10-08 22:23:25.000000000 -0400 +@@ -142,8 +142,6 @@ extern int rcu_needs_cpu(int cpu); + extern void __rcu_init(void); + extern void rcu_check_callbacks(int cpu, int user); + extern void rcu_restart_cpu(int cpu); +-extern long rcu_batches_completed(void); +-extern long rcu_batches_completed_bh(void); + + #endif /* __KERNEL__ */ + #endif /* __LINUX_RCUCLASSIC_H */ +Index: linux-2.6.24.7-rt21/include/linux/rcupdate.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/rcupdate.h 2008-10-08 22:23:25.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/rcupdate.h 2008-10-08 22:23:25.000000000 -0400 +@@ -53,7 +53,11 @@ struct rcu_head { + void (*func)(struct rcu_head *head); + }; + ++#ifdef CONFIG_CLASSIC_RCU + #include ++#else /* #ifdef CONFIG_CLASSIC_RCU */ ++#include ++#endif /* #else #ifdef CONFIG_CLASSIC_RCU */ + + #define RCU_HEAD_INIT { .next = NULL, .func = NULL } + #define RCU_HEAD(head) struct rcu_head head = RCU_HEAD_INIT +@@ -241,10 +245,13 @@ extern void FASTCALL(call_rcu_bh(struct + /* Exported common interfaces */ + extern void synchronize_rcu(void); + extern void rcu_barrier(void); ++extern long rcu_batches_completed(void); ++extern long rcu_batches_completed_bh(void); + + /* Internal to kernel */ + extern void rcu_init(void); + extern void rcu_check_callbacks(int cpu, int user); ++extern int rcu_needs_cpu(int cpu); + + #endif /* __KERNEL__ */ + #endif /* __LINUX_RCUPDATE_H */ +Index: linux-2.6.24.7-rt21/include/linux/rcupreempt.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/include/linux/rcupreempt.h 2008-10-08 22:23:25.000000000 -0400 +@@ -0,0 +1,78 @@ ++/* ++ * Read-Copy Update mechanism for mutual exclusion (RT implementation) ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * Copyright (C) IBM Corporation, 2006 ++ * ++ * Author: Paul McKenney ++ * ++ * Based on the original work by Paul McKenney ++ * and inputs from Rusty Russell, Andrea Arcangeli and Andi Kleen. ++ * Papers: ++ * http://www.rdrop.com/users/paulmck/paper/rclockpdcsproof.pdf ++ * http://lse.sourceforge.net/locking/rclock_OLS.2001.05.01c.sc.pdf (OLS2001) ++ * ++ * For detailed explanation of Read-Copy Update mechanism see - ++ * Documentation/RCU ++ * ++ */ ++ ++#ifndef __LINUX_RCUPREEMPT_H ++#define __LINUX_RCUPREEMPT_H ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define rcu_qsctr_inc(cpu) ++#define rcu_bh_qsctr_inc(cpu) ++#define call_rcu_bh(head, rcu) call_rcu(head, rcu) ++ ++extern void __rcu_read_lock(void); ++extern void __rcu_read_unlock(void); ++extern int rcu_pending(int cpu); ++extern int rcu_needs_cpu(int cpu); ++ ++#define __rcu_read_lock_bh() { rcu_read_lock(); local_bh_disable(); } ++#define __rcu_read_unlock_bh() { local_bh_enable(); rcu_read_unlock(); } ++ ++#define __rcu_read_lock_nesting() (current->rcu_read_lock_nesting) ++ ++extern void __synchronize_sched(void); ++ ++extern void __rcu_init(void); ++extern void rcu_check_callbacks(int cpu, int user); ++extern void rcu_restart_cpu(int cpu); ++ ++#ifdef CONFIG_RCU_TRACE ++struct rcupreempt_trace; ++extern int *rcupreempt_flipctr(int cpu); ++extern long rcupreempt_data_completed(void); ++extern int rcupreempt_flip_flag(int cpu); ++extern int rcupreempt_mb_flag(int cpu); ++extern char *rcupreempt_try_flip_state_name(void); ++extern struct rcupreempt_trace *rcupreempt_trace_cpu(int cpu); ++#endif ++ ++struct softirq_action; ++ ++#endif /* __KERNEL__ */ ++#endif /* __LINUX_RCUPREEMPT_H */ +Index: linux-2.6.24.7-rt21/include/linux/rcupreempt_trace.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/include/linux/rcupreempt_trace.h 2008-10-08 22:23:25.000000000 -0400 +@@ -0,0 +1,100 @@ ++/* ++ * Read-Copy Update mechanism for mutual exclusion (RT implementation) ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * Copyright (C) IBM Corporation, 2006 ++ * ++ * Author: Paul McKenney ++ * ++ * Based on the original work by Paul McKenney ++ * and inputs from Rusty Russell, Andrea Arcangeli and Andi Kleen. ++ * Papers: ++ * http://www.rdrop.com/users/paulmck/paper/rclockpdcsproof.pdf ++ * http://lse.sourceforge.net/locking/rclock_OLS.2001.05.01c.sc.pdf (OLS2001) ++ * ++ * For detailed explanation of Read-Copy Update mechanism see - ++ * http://lse.sourceforge.net/locking/rcupdate.html ++ * ++ */ ++ ++#ifndef __LINUX_RCUPREEMPT_TRACE_H ++#define __LINUX_RCUPREEMPT_TRACE_H ++ ++#ifdef __KERNEL__ ++#include ++#include ++ ++#include ++ ++/* ++ * PREEMPT_RCU data structures. ++ */ ++ ++struct rcupreempt_trace { ++ long next_length; ++ long next_add; ++ long wait_length; ++ long wait_add; ++ long done_length; ++ long done_add; ++ long done_remove; ++ atomic_t done_invoked; ++ long rcu_check_callbacks; ++ atomic_t rcu_try_flip_1; ++ atomic_t rcu_try_flip_e1; ++ long rcu_try_flip_i1; ++ long rcu_try_flip_ie1; ++ long rcu_try_flip_g1; ++ long rcu_try_flip_a1; ++ long rcu_try_flip_ae1; ++ long rcu_try_flip_a2; ++ long rcu_try_flip_z1; ++ long rcu_try_flip_ze1; ++ long rcu_try_flip_z2; ++ long rcu_try_flip_m1; ++ long rcu_try_flip_me1; ++ long rcu_try_flip_m2; ++}; ++ ++#ifdef CONFIG_RCU_TRACE ++#define RCU_TRACE(fn, arg) fn(arg); ++#else ++#define RCU_TRACE(fn, arg) ++#endif ++ ++extern void rcupreempt_trace_move2done(struct rcupreempt_trace *trace); ++extern void rcupreempt_trace_move2wait(struct rcupreempt_trace *trace); ++extern void rcupreempt_trace_try_flip_1(struct rcupreempt_trace *trace); ++extern void rcupreempt_trace_try_flip_e1(struct rcupreempt_trace *trace); ++extern void rcupreempt_trace_try_flip_i1(struct rcupreempt_trace *trace); ++extern void rcupreempt_trace_try_flip_ie1(struct rcupreempt_trace *trace); ++extern void rcupreempt_trace_try_flip_g1(struct rcupreempt_trace *trace); ++extern void rcupreempt_trace_try_flip_a1(struct rcupreempt_trace *trace); ++extern void rcupreempt_trace_try_flip_ae1(struct rcupreempt_trace *trace); ++extern void rcupreempt_trace_try_flip_a2(struct rcupreempt_trace *trace); ++extern void rcupreempt_trace_try_flip_z1(struct rcupreempt_trace *trace); ++extern void rcupreempt_trace_try_flip_ze1(struct rcupreempt_trace *trace); ++extern void rcupreempt_trace_try_flip_z2(struct rcupreempt_trace *trace); ++extern void rcupreempt_trace_try_flip_m1(struct rcupreempt_trace *trace); ++extern void rcupreempt_trace_try_flip_me1(struct rcupreempt_trace *trace); ++extern void rcupreempt_trace_try_flip_m2(struct rcupreempt_trace *trace); ++extern void rcupreempt_trace_check_callbacks(struct rcupreempt_trace *trace); ++extern void rcupreempt_trace_done_remove(struct rcupreempt_trace *trace); ++extern void rcupreempt_trace_invoke(struct rcupreempt_trace *trace); ++extern void rcupreempt_trace_next_add(struct rcupreempt_trace *trace); ++ ++#endif /* __KERNEL__ */ ++#endif /* __LINUX_RCUPREEMPT_TRACE_H */ +Index: linux-2.6.24.7-rt21/include/linux/sched.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/sched.h 2008-10-08 22:23:09.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/sched.h 2008-10-08 22:23:25.000000000 -0400 +@@ -976,6 +976,11 @@ struct task_struct { + int nr_cpus_allowed; + unsigned int time_slice; + ++#ifdef CONFIG_PREEMPT_RCU ++ int rcu_read_lock_nesting; ++ int rcu_flipctr_idx; ++#endif /* #ifdef CONFIG_PREEMPT_RCU */ ++ + #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) + struct sched_info sched_info; + #endif +Index: linux-2.6.24.7-rt21/kernel/Kconfig.preempt +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/Kconfig.preempt 2008-10-08 22:22:39.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/Kconfig.preempt 2008-10-08 22:23:25.000000000 -0400 +@@ -52,6 +52,45 @@ config PREEMPT + + endchoice + ++choice ++ prompt "RCU implementation type:" ++ default CLASSIC_RCU ++ ++config CLASSIC_RCU ++ bool "Classic RCU" ++ help ++ This option selects the classic RCU implementation that is ++ designed for best read-side performance on non-realtime ++ systems. ++ ++ Say Y if you are unsure. ++ ++config PREEMPT_RCU ++ bool "Preemptible RCU" ++ depends on PREEMPT ++ help ++ This option reduces the latency of the kernel by making certain ++ RCU sections preemptible. Normally RCU code is non-preemptible, if ++ this option is selected then read-only RCU sections become ++ preemptible. This helps latency, but may expose bugs due to ++ now-naive assumptions about each RCU read-side critical section ++ remaining on a given CPU through its execution. ++ ++ Say N if you are unsure. ++ ++endchoice ++ ++config RCU_TRACE ++ bool "Enable tracing for RCU - currently stats in debugfs" ++ select DEBUG_FS ++ default y ++ help ++ This option provides tracing in RCU which presents stats ++ in debugfs for debugging RCU implementation. ++ ++ Say Y here if you want to enable RCU tracing ++ Say N if you are unsure. ++ + config PREEMPT_BKL + bool "Preempt The Big Kernel Lock" + depends on SMP || PREEMPT +Index: linux-2.6.24.7-rt21/kernel/Makefile +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/Makefile 2008-10-08 22:23:25.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/Makefile 2008-10-08 22:23:25.000000000 -0400 +@@ -6,7 +6,7 @@ obj-y = sched.o fork.o exec_domain.o + exit.o itimer.o time.o softirq.o resource.o \ + sysctl.o capability.o ptrace.o timer.o user.o user_namespace.o \ + signal.o sys.o kmod.o workqueue.o pid.o \ +- rcupdate.o rcuclassic.o extable.o params.o posix-timers.o \ ++ rcupdate.o extable.o params.o posix-timers.o \ + kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \ + hrtimer.o rwsem.o latency.o nsproxy.o srcu.o \ + utsname.o notifier.o +@@ -64,6 +64,11 @@ obj-$(CONFIG_DETECT_SOFTLOCKUP) += softl + obj-$(CONFIG_GENERIC_HARDIRQS) += irq/ + obj-$(CONFIG_SECCOMP) += seccomp.o + obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o ++obj-$(CONFIG_CLASSIC_RCU) += rcuclassic.o ++obj-$(CONFIG_PREEMPT_RCU) += rcupreempt.o ++ifeq ($(CONFIG_PREEMPT_RCU),y) ++obj-$(CONFIG_RCU_TRACE) += rcupreempt_trace.o ++endif + obj-$(CONFIG_RELAY) += relay.o + obj-$(CONFIG_SYSCTL) += utsname_sysctl.o + obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o +Index: linux-2.6.24.7-rt21/kernel/fork.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/fork.c 2008-10-08 22:23:06.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/fork.c 2008-10-08 22:23:25.000000000 -0400 +@@ -1045,6 +1045,10 @@ static struct task_struct *copy_process( + copy_flags(clone_flags, p); + INIT_LIST_HEAD(&p->children); + INIT_LIST_HEAD(&p->sibling); ++#ifdef CONFIG_PREEMPT_RCU ++ p->rcu_read_lock_nesting = 0; ++ p->rcu_flipctr_idx = 0; ++#endif /* #ifdef CONFIG_PREEMPT_RCU */ + p->vfork_done = NULL; + spin_lock_init(&p->alloc_lock); + +Index: linux-2.6.24.7-rt21/kernel/rcupreempt.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/kernel/rcupreempt.c 2008-10-08 22:23:25.000000000 -0400 +@@ -0,0 +1,766 @@ ++/* ++ * Read-Copy Update mechanism for mutual exclusion, realtime implementation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * Copyright IBM Corporation, 2006 ++ * ++ * Authors: Paul E. McKenney ++ * With thanks to Esben Nielsen, Bill Huey, and Ingo Molnar ++ * for pushing me away from locks and towards counters, and ++ * to Suparna Bhattacharya for pushing me completely away ++ * from atomic instructions on the read side. ++ * ++ * Papers: http://www.rdrop.com/users/paulmck/RCU ++ * ++ * For detailed explanation of Read-Copy Update mechanism see - ++ * Documentation/RCU/ *.txt ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * PREEMPT_RCU data structures. ++ */ ++ ++#define GP_STAGES 2 ++struct rcu_data { ++ spinlock_t lock; /* Protect rcu_data fields. */ ++ long completed; /* Number of last completed batch. */ ++ int waitlistcount; ++ struct tasklet_struct rcu_tasklet; ++ struct rcu_head *nextlist; ++ struct rcu_head **nexttail; ++ struct rcu_head *waitlist[GP_STAGES]; ++ struct rcu_head **waittail[GP_STAGES]; ++ struct rcu_head *donelist; ++ struct rcu_head **donetail; ++#ifdef CONFIG_RCU_TRACE ++ struct rcupreempt_trace trace; ++#endif /* #ifdef CONFIG_RCU_TRACE */ ++}; ++struct rcu_ctrlblk { ++ spinlock_t fliplock; /* Protect state-machine transitions. */ ++ long completed; /* Number of last completed batch. */ ++}; ++static DEFINE_PER_CPU(struct rcu_data, rcu_data); ++static struct rcu_ctrlblk rcu_ctrlblk = { ++ .fliplock = SPIN_LOCK_UNLOCKED, ++ .completed = 0, ++}; ++static DEFINE_PER_CPU(int [2], rcu_flipctr) = { 0, 0 }; ++ ++/* ++ * States for rcu_try_flip() and friends. ++ */ ++ ++enum rcu_try_flip_states { ++ rcu_try_flip_idle_state, /* "I" */ ++ rcu_try_flip_waitack_state, /* "A" */ ++ rcu_try_flip_waitzero_state, /* "Z" */ ++ rcu_try_flip_waitmb_state /* "M" */ ++}; ++static enum rcu_try_flip_states rcu_try_flip_state = rcu_try_flip_idle_state; ++#ifdef CONFIG_RCU_TRACE ++static char *rcu_try_flip_state_names[] = ++ { "idle", "waitack", "waitzero", "waitmb" }; ++#endif /* #ifdef CONFIG_RCU_TRACE */ ++ ++/* ++ * Enum and per-CPU flag to determine when each CPU has seen ++ * the most recent counter flip. ++ */ ++ ++enum rcu_flip_flag_values { ++ rcu_flip_seen, /* Steady/initial state, last flip seen. */ ++ /* Only GP detector can update. */ ++ rcu_flipped /* Flip just completed, need confirmation. */ ++ /* Only corresponding CPU can update. */ ++}; ++static DEFINE_PER_CPU(enum rcu_flip_flag_values, rcu_flip_flag) = rcu_flip_seen; ++ ++/* ++ * Enum and per-CPU flag to determine when each CPU has executed the ++ * needed memory barrier to fence in memory references from its last RCU ++ * read-side critical section in the just-completed grace period. ++ */ ++ ++enum rcu_mb_flag_values { ++ rcu_mb_done, /* Steady/initial state, no mb()s required. */ ++ /* Only GP detector can update. */ ++ rcu_mb_needed /* Flip just completed, need an mb(). */ ++ /* Only corresponding CPU can update. */ ++}; ++static DEFINE_PER_CPU(enum rcu_mb_flag_values, rcu_mb_flag) = rcu_mb_done; ++ ++/* ++ * Macro that prevents the compiler from reordering accesses, but does ++ * absolutely -nothing- to prevent CPUs from reordering. This is used ++ * only to mediate communication between mainline code and hardware ++ * interrupt and NMI handlers. ++ */ ++#define ORDERED_WRT_IRQ(x) (*(volatile typeof(x) *)&(x)) ++ ++/* ++ * RCU_DATA_ME: find the current CPU's rcu_data structure. ++ * RCU_DATA_CPU: find the specified CPU's rcu_data structure. ++ */ ++#define RCU_DATA_ME() (&__get_cpu_var(rcu_data)) ++#define RCU_DATA_CPU(cpu) (&per_cpu(rcu_data, cpu)) ++ ++/* ++ * Helper macro for tracing when the appropriate rcu_data is not ++ * cached in a local variable, but where the CPU number is so cached. ++ */ ++#define RCU_TRACE_CPU(f, cpu) RCU_TRACE(f, &(RCU_DATA_CPU(cpu)->trace)); ++ ++/* ++ * Helper macro for tracing when the appropriate rcu_data is not ++ * cached in a local variable. ++ */ ++#define RCU_TRACE_ME(f) RCU_TRACE(f, &(RCU_DATA_ME()->trace)); ++ ++/* ++ * Helper macro for tracing when the appropriate rcu_data is pointed ++ * to by a local variable. ++ */ ++#define RCU_TRACE_RDP(f, rdp) RCU_TRACE(f, &((rdp)->trace)); ++ ++/* ++ * Return the number of RCU batches processed thus far. Useful ++ * for debug and statistics. ++ */ ++long rcu_batches_completed(void) ++{ ++ return rcu_ctrlblk.completed; ++} ++EXPORT_SYMBOL_GPL(rcu_batches_completed); ++ ++/* ++ * Return the number of RCU batches processed thus far. Useful for debug ++ * and statistics. The _bh variant is identical to straight RCU. ++ */ ++long rcu_batches_completed_bh(void) ++{ ++ return rcu_ctrlblk.completed; ++} ++EXPORT_SYMBOL_GPL(rcu_batches_completed_bh); ++ ++void __rcu_read_lock(void) ++{ ++ int idx; ++ struct task_struct *me = current; ++ int nesting; ++ ++ nesting = ORDERED_WRT_IRQ(me->rcu_read_lock_nesting); ++ if (nesting != 0) { ++ ++ /* An earlier rcu_read_lock() covers us, just count it. */ ++ ++ me->rcu_read_lock_nesting = nesting + 1; ++ ++ } else { ++ unsigned long oldirq; ++ ++ /* ++ * Disable local interrupts to prevent the grace-period ++ * detection state machine from seeing us half-done. ++ * NMIs can still occur, of course, and might themselves ++ * contain rcu_read_lock(). ++ */ ++ ++ local_irq_save(oldirq); ++ ++ /* ++ * Outermost nesting of rcu_read_lock(), so increment ++ * the current counter for the current CPU. Use volatile ++ * casts to prevent the compiler from reordering. ++ */ ++ ++ idx = ORDERED_WRT_IRQ(rcu_ctrlblk.completed) & 0x1; ++ smp_read_barrier_depends(); /* @@@@ might be unneeded */ ++ ORDERED_WRT_IRQ(__get_cpu_var(rcu_flipctr)[idx])++; ++ ++ /* ++ * Now that the per-CPU counter has been incremented, we ++ * are protected from races with rcu_read_lock() invoked ++ * from NMI handlers on this CPU. We can therefore safely ++ * increment the nesting counter, relieving further NMIs ++ * of the need to increment the per-CPU counter. ++ */ ++ ++ ORDERED_WRT_IRQ(me->rcu_read_lock_nesting) = nesting + 1; ++ ++ /* ++ * Now that we have preventing any NMIs from storing ++ * to the ->rcu_flipctr_idx, we can safely use it to ++ * remember which counter to decrement in the matching ++ * rcu_read_unlock(). ++ */ ++ ++ ORDERED_WRT_IRQ(me->rcu_flipctr_idx) = idx; ++ local_irq_restore(oldirq); ++ } ++} ++EXPORT_SYMBOL_GPL(__rcu_read_lock); ++ ++void __rcu_read_unlock(void) ++{ ++ int idx; ++ struct task_struct *me = current; ++ int nesting; ++ ++ nesting = ORDERED_WRT_IRQ(me->rcu_read_lock_nesting); ++ if (nesting > 1) { ++ ++ /* ++ * We are still protected by the enclosing rcu_read_lock(), ++ * so simply decrement the counter. ++ */ ++ ++ me->rcu_read_lock_nesting = nesting - 1; ++ ++ } else { ++ unsigned long oldirq; ++ ++ /* ++ * Disable local interrupts to prevent the grace-period ++ * detection state machine from seeing us half-done. ++ * NMIs can still occur, of course, and might themselves ++ * contain rcu_read_lock() and rcu_read_unlock(). ++ */ ++ ++ local_irq_save(oldirq); ++ ++ /* ++ * Outermost nesting of rcu_read_unlock(), so we must ++ * decrement the current counter for the current CPU. ++ * This must be done carefully, because NMIs can ++ * occur at any point in this code, and any rcu_read_lock() ++ * and rcu_read_unlock() pairs in the NMI handlers ++ * must interact non-destructively with this code. ++ * Lots of volatile casts, and -very- careful ordering. ++ * ++ * Changes to this code, including this one, must be ++ * inspected, validated, and tested extremely carefully!!! ++ */ ++ ++ /* ++ * First, pick up the index. Enforce ordering for ++ * DEC Alpha. ++ */ ++ ++ idx = ORDERED_WRT_IRQ(me->rcu_flipctr_idx); ++ smp_read_barrier_depends(); /* @@@ Needed??? */ ++ ++ /* ++ * Now that we have fetched the counter index, it is ++ * safe to decrement the per-task RCU nesting counter. ++ * After this, any interrupts or NMIs will increment and ++ * decrement the per-CPU counters. ++ */ ++ ORDERED_WRT_IRQ(me->rcu_read_lock_nesting) = nesting - 1; ++ ++ /* ++ * It is now safe to decrement this task's nesting count. ++ * NMIs that occur after this statement will route their ++ * rcu_read_lock() calls through this "else" clause, and ++ * will thus start incrementing the per-CPU coutner on ++ * their own. They will also clobber ->rcu_flipctr_idx, ++ * but that is OK, since we have already fetched it. ++ */ ++ ++ ORDERED_WRT_IRQ(__get_cpu_var(rcu_flipctr)[idx])--; ++ local_irq_restore(oldirq); ++ } ++} ++EXPORT_SYMBOL_GPL(__rcu_read_unlock); ++ ++/* ++ * If a global counter flip has occurred since the last time that we ++ * advanced callbacks, advance them. Hardware interrupts must be ++ * disabled when calling this function. ++ */ ++static void __rcu_advance_callbacks(struct rcu_data *rdp) ++{ ++ int cpu; ++ int i; ++ int wlc = 0; ++ ++ if (rdp->completed != rcu_ctrlblk.completed) { ++ if (rdp->waitlist[GP_STAGES - 1] != NULL) { ++ *rdp->donetail = rdp->waitlist[GP_STAGES - 1]; ++ rdp->donetail = rdp->waittail[GP_STAGES - 1]; ++ RCU_TRACE_RDP(rcupreempt_trace_move2done, rdp); ++ } ++ for (i = GP_STAGES - 2; i >= 0; i--) { ++ if (rdp->waitlist[i] != NULL) { ++ rdp->waitlist[i + 1] = rdp->waitlist[i]; ++ rdp->waittail[i + 1] = rdp->waittail[i]; ++ wlc++; ++ } else { ++ rdp->waitlist[i + 1] = NULL; ++ rdp->waittail[i + 1] = ++ &rdp->waitlist[i + 1]; ++ } ++ } ++ if (rdp->nextlist != NULL) { ++ rdp->waitlist[0] = rdp->nextlist; ++ rdp->waittail[0] = rdp->nexttail; ++ wlc++; ++ rdp->nextlist = NULL; ++ rdp->nexttail = &rdp->nextlist; ++ RCU_TRACE_RDP(rcupreempt_trace_move2wait, rdp); ++ } else { ++ rdp->waitlist[0] = NULL; ++ rdp->waittail[0] = &rdp->waitlist[0]; ++ } ++ rdp->waitlistcount = wlc; ++ rdp->completed = rcu_ctrlblk.completed; ++ } ++ ++ /* ++ * Check to see if this CPU needs to report that it has seen ++ * the most recent counter flip, thereby declaring that all ++ * subsequent rcu_read_lock() invocations will respect this flip. ++ */ ++ ++ cpu = raw_smp_processor_id(); ++ if (per_cpu(rcu_flip_flag, cpu) == rcu_flipped) { ++ smp_mb(); /* Subsequent counter accesses must see new value */ ++ per_cpu(rcu_flip_flag, cpu) = rcu_flip_seen; ++ smp_mb(); /* Subsequent RCU read-side critical sections */ ++ /* seen -after- acknowledgement. */ ++ } ++} ++ ++/* ++ * Get here when RCU is idle. Decide whether we need to ++ * move out of idle state, and return non-zero if so. ++ * "Straightforward" approach for the moment, might later ++ * use callback-list lengths, grace-period duration, or ++ * some such to determine when to exit idle state. ++ * Might also need a pre-idle test that does not acquire ++ * the lock, but let's get the simple case working first... ++ */ ++ ++static int ++rcu_try_flip_idle(void) ++{ ++ int cpu; ++ ++ RCU_TRACE_ME(rcupreempt_trace_try_flip_i1); ++ if (!rcu_pending(smp_processor_id())) { ++ RCU_TRACE_ME(rcupreempt_trace_try_flip_ie1); ++ return 0; ++ } ++ ++ /* ++ * Do the flip. ++ */ ++ ++ RCU_TRACE_ME(rcupreempt_trace_try_flip_g1); ++ rcu_ctrlblk.completed++; /* stands in for rcu_try_flip_g2 */ ++ ++ /* ++ * Need a memory barrier so that other CPUs see the new ++ * counter value before they see the subsequent change of all ++ * the rcu_flip_flag instances to rcu_flipped. ++ */ ++ ++ smp_mb(); /* see above block comment. */ ++ ++ /* Now ask each CPU for acknowledgement of the flip. */ ++ ++ for_each_possible_cpu(cpu) ++ per_cpu(rcu_flip_flag, cpu) = rcu_flipped; ++ ++ return 1; ++} ++ ++/* ++ * Wait for CPUs to acknowledge the flip. ++ */ ++ ++static int ++rcu_try_flip_waitack(void) ++{ ++ int cpu; ++ ++ RCU_TRACE_ME(rcupreempt_trace_try_flip_a1); ++ for_each_possible_cpu(cpu) ++ if (per_cpu(rcu_flip_flag, cpu) != rcu_flip_seen) { ++ RCU_TRACE_ME(rcupreempt_trace_try_flip_ae1); ++ return 0; ++ } ++ ++ /* ++ * Make sure our checks above don't bleed into subsequent ++ * waiting for the sum of the counters to reach zero. ++ */ ++ ++ smp_mb(); /* see above block comment. */ ++ RCU_TRACE_ME(rcupreempt_trace_try_flip_a2); ++ return 1; ++} ++ ++/* ++ * Wait for collective ``last'' counter to reach zero, ++ * then tell all CPUs to do an end-of-grace-period memory barrier. ++ */ ++ ++static int ++rcu_try_flip_waitzero(void) ++{ ++ int cpu; ++ int lastidx = !(rcu_ctrlblk.completed & 0x1); ++ int sum = 0; ++ ++ /* Check to see if the sum of the "last" counters is zero. */ ++ ++ RCU_TRACE_ME(rcupreempt_trace_try_flip_z1); ++ for_each_possible_cpu(cpu) ++ sum += per_cpu(rcu_flipctr, cpu)[lastidx]; ++ if (sum != 0) { ++ RCU_TRACE_ME(rcupreempt_trace_try_flip_ze1); ++ return 0; ++ } ++ ++ smp_mb(); /* Don't call for memory barriers before we see zero. */ ++ ++ /* Call for a memory barrier from each CPU. */ ++ ++ for_each_possible_cpu(cpu) ++ per_cpu(rcu_mb_flag, cpu) = rcu_mb_needed; ++ ++ RCU_TRACE_ME(rcupreempt_trace_try_flip_z2); ++ return 1; ++} ++ ++/* ++ * Wait for all CPUs to do their end-of-grace-period memory barrier. ++ * Return 0 once all CPUs have done so. ++ */ ++ ++static int ++rcu_try_flip_waitmb(void) ++{ ++ int cpu; ++ ++ RCU_TRACE_ME(rcupreempt_trace_try_flip_m1); ++ for_each_possible_cpu(cpu) ++ if (per_cpu(rcu_mb_flag, cpu) != rcu_mb_done) { ++ RCU_TRACE_ME(rcupreempt_trace_try_flip_me1); ++ return 0; ++ } ++ ++ smp_mb(); /* Ensure that the above checks precede any following flip. */ ++ RCU_TRACE_ME(rcupreempt_trace_try_flip_m2); ++ return 1; ++} ++ ++/* ++ * Attempt a single flip of the counters. Remember, a single flip does ++ * -not- constitute a grace period. Instead, the interval between ++ * at least three consecutive flips is a grace period. ++ * ++ * If anyone is nuts enough to run this CONFIG_PREEMPT_RCU implementation ++ * on a large SMP, they might want to use a hierarchical organization of ++ * the per-CPU-counter pairs. ++ */ ++static void rcu_try_flip(void) ++{ ++ unsigned long oldirq; ++ ++ RCU_TRACE_ME(rcupreempt_trace_try_flip_1); ++ if (unlikely(!spin_trylock_irqsave(&rcu_ctrlblk.fliplock, oldirq))) { ++ RCU_TRACE_ME(rcupreempt_trace_try_flip_e1); ++ return; ++ } ++ ++ /* ++ * Take the next transition(s) through the RCU grace-period ++ * flip-counter state machine. ++ */ ++ ++ switch (rcu_try_flip_state) { ++ case rcu_try_flip_idle_state: ++ if (rcu_try_flip_idle()) ++ rcu_try_flip_state = rcu_try_flip_waitack_state; ++ break; ++ case rcu_try_flip_waitack_state: ++ if (rcu_try_flip_waitack()) ++ rcu_try_flip_state = rcu_try_flip_waitzero_state; ++ break; ++ case rcu_try_flip_waitzero_state: ++ if (rcu_try_flip_waitzero()) ++ rcu_try_flip_state = rcu_try_flip_waitmb_state; ++ break; ++ case rcu_try_flip_waitmb_state: ++ if (rcu_try_flip_waitmb()) ++ rcu_try_flip_state = rcu_try_flip_idle_state; ++ } ++ spin_unlock_irqrestore(&rcu_ctrlblk.fliplock, oldirq); ++} ++ ++/* ++ * Check to see if this CPU needs to do a memory barrier in order to ++ * ensure that any prior RCU read-side critical sections have committed ++ * their counter manipulations and critical-section memory references ++ * before declaring the grace period to be completed. ++ */ ++static void rcu_check_mb(int cpu) ++{ ++ if (per_cpu(rcu_mb_flag, cpu) == rcu_mb_needed) { ++ smp_mb(); /* Ensure RCU read-side accesses are visible. */ ++ per_cpu(rcu_mb_flag, cpu) = rcu_mb_done; ++ } ++} ++ ++void rcu_check_callbacks(int cpu, int user) ++{ ++ unsigned long oldirq; ++ struct rcu_data *rdp = RCU_DATA_CPU(cpu); ++ ++ rcu_check_mb(cpu); ++ if (rcu_ctrlblk.completed == rdp->completed) ++ rcu_try_flip(); ++ spin_lock_irqsave(&rdp->lock, oldirq); ++ RCU_TRACE_RDP(rcupreempt_trace_check_callbacks, rdp); ++ __rcu_advance_callbacks(rdp); ++ if (rdp->donelist == NULL) { ++ spin_unlock_irqrestore(&rdp->lock, oldirq); ++ } else { ++ spin_unlock_irqrestore(&rdp->lock, oldirq); ++ raise_softirq(RCU_SOFTIRQ); ++ } ++} ++ ++/* ++ * Needed by dynticks, to make sure all RCU processing has finished ++ * when we go idle: ++ */ ++void rcu_advance_callbacks(int cpu, int user) ++{ ++ unsigned long oldirq; ++ struct rcu_data *rdp = RCU_DATA_CPU(cpu); ++ ++ if (rcu_ctrlblk.completed == rdp->completed) { ++ rcu_try_flip(); ++ if (rcu_ctrlblk.completed == rdp->completed) ++ return; ++ } ++ spin_lock_irqsave(&rdp->lock, oldirq); ++ RCU_TRACE_RDP(rcupreempt_trace_check_callbacks, rdp); ++ __rcu_advance_callbacks(rdp); ++ spin_unlock_irqrestore(&rdp->lock, oldirq); ++} ++ ++static void rcu_process_callbacks(struct softirq_action *unused) ++{ ++ unsigned long flags; ++ struct rcu_head *next, *list; ++ struct rcu_data *rdp = RCU_DATA_ME(); ++ ++ spin_lock_irqsave(&rdp->lock, flags); ++ list = rdp->donelist; ++ if (list == NULL) { ++ spin_unlock_irqrestore(&rdp->lock, flags); ++ return; ++ } ++ rdp->donelist = NULL; ++ rdp->donetail = &rdp->donelist; ++ RCU_TRACE_RDP(rcupreempt_trace_done_remove, rdp); ++ spin_unlock_irqrestore(&rdp->lock, flags); ++ while (list) { ++ next = list->next; ++ list->func(list); ++ list = next; ++ RCU_TRACE_ME(rcupreempt_trace_invoke); ++ } ++} ++ ++void fastcall call_rcu(struct rcu_head *head, ++ void (*func)(struct rcu_head *rcu)) ++{ ++ unsigned long oldirq; ++ struct rcu_data *rdp; ++ ++ head->func = func; ++ head->next = NULL; ++ local_irq_save(oldirq); ++ rdp = RCU_DATA_ME(); ++ spin_lock(&rdp->lock); ++ __rcu_advance_callbacks(rdp); ++ *rdp->nexttail = head; ++ rdp->nexttail = &head->next; ++ RCU_TRACE_RDP(rcupreempt_trace_next_add, rdp); ++ spin_unlock(&rdp->lock); ++ local_irq_restore(oldirq); ++} ++EXPORT_SYMBOL_GPL(call_rcu); ++ ++/* ++ * Wait until all currently running preempt_disable() code segments ++ * (including hardware-irq-disable segments) complete. Note that ++ * in -rt this does -not- necessarily result in all currently executing ++ * interrupt -handlers- having completed. ++ */ ++void __synchronize_sched(void) ++{ ++ cpumask_t oldmask; ++ int cpu; ++ ++ if (sched_getaffinity(0, &oldmask) < 0) ++ oldmask = cpu_possible_map; ++ for_each_online_cpu(cpu) { ++ sched_setaffinity(0, cpumask_of_cpu(cpu)); ++ schedule(); ++ } ++ sched_setaffinity(0, oldmask); ++} ++EXPORT_SYMBOL_GPL(__synchronize_sched); ++ ++/* ++ * Check to see if any future RCU-related work will need to be done ++ * by the current CPU, even if none need be done immediately, returning ++ * 1 if so. Assumes that notifiers would take care of handling any ++ * outstanding requests from the RCU core. ++ * ++ * This function is part of the RCU implementation; it is -not- ++ * an exported member of the RCU API. ++ */ ++int rcu_needs_cpu(int cpu) ++{ ++ struct rcu_data *rdp = RCU_DATA_CPU(cpu); ++ ++ return (rdp->donelist != NULL || ++ !!rdp->waitlistcount || ++ rdp->nextlist != NULL); ++} ++ ++int rcu_pending(int cpu) ++{ ++ struct rcu_data *rdp = RCU_DATA_CPU(cpu); ++ ++ /* The CPU has at least one callback queued somewhere. */ ++ ++ if (rdp->donelist != NULL || ++ !!rdp->waitlistcount || ++ rdp->nextlist != NULL) ++ return 1; ++ ++ /* The RCU core needs an acknowledgement from this CPU. */ ++ ++ if ((per_cpu(rcu_flip_flag, cpu) == rcu_flipped) || ++ (per_cpu(rcu_mb_flag, cpu) == rcu_mb_needed)) ++ return 1; ++ ++ /* This CPU has fallen behind the global grace-period number. */ ++ ++ if (rdp->completed != rcu_ctrlblk.completed) ++ return 1; ++ ++ /* Nothing needed from this CPU. */ ++ ++ return 0; ++} ++ ++void __init __rcu_init(void) ++{ ++ int cpu; ++ int i; ++ struct rcu_data *rdp; ++ ++ for_each_possible_cpu(cpu) { ++ rdp = RCU_DATA_CPU(cpu); ++ spin_lock_init(&rdp->lock); ++ rdp->completed = 0; ++ rdp->waitlistcount = 0; ++ rdp->nextlist = NULL; ++ rdp->nexttail = &rdp->nextlist; ++ for (i = 0; i < GP_STAGES; i++) { ++ rdp->waitlist[i] = NULL; ++ rdp->waittail[i] = &rdp->waitlist[i]; ++ } ++ rdp->donelist = NULL; ++ rdp->donetail = &rdp->donelist; ++ } ++ open_softirq(RCU_SOFTIRQ, rcu_process_callbacks, NULL); ++} ++ ++/* ++ * Deprecated, use synchronize_rcu() or synchronize_sched() instead. ++ */ ++void synchronize_kernel(void) ++{ ++ synchronize_rcu(); ++} ++ ++#ifdef CONFIG_RCU_TRACE ++int *rcupreempt_flipctr(int cpu) ++{ ++ return &per_cpu(rcu_flipctr, cpu)[0]; ++} ++EXPORT_SYMBOL_GPL(rcupreempt_flipctr); ++ ++int rcupreempt_flip_flag(int cpu) ++{ ++ return per_cpu(rcu_flip_flag, cpu); ++} ++EXPORT_SYMBOL_GPL(rcupreempt_flip_flag); ++ ++int rcupreempt_mb_flag(int cpu) ++{ ++ return per_cpu(rcu_mb_flag, cpu); ++} ++EXPORT_SYMBOL_GPL(rcupreempt_mb_flag); ++ ++char *rcupreempt_try_flip_state_name(void) ++{ ++ return rcu_try_flip_state_names[rcu_try_flip_state]; ++} ++EXPORT_SYMBOL_GPL(rcupreempt_try_flip_state_name); ++ ++struct rcupreempt_trace *rcupreempt_trace_cpu(int cpu) ++{ ++ struct rcu_data *rdp = RCU_DATA_CPU(cpu); ++ ++ return &rdp->trace; ++} ++EXPORT_SYMBOL_GPL(rcupreempt_trace_cpu); ++ ++#endif /* #ifdef RCU_TRACE */ +Index: linux-2.6.24.7-rt21/kernel/rcupreempt_trace.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/kernel/rcupreempt_trace.c 2008-10-08 22:23:25.000000000 -0400 +@@ -0,0 +1,330 @@ ++/* ++ * Read-Copy Update tracing for realtime implementation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * Copyright IBM Corporation, 2006 ++ * ++ * Papers: http://www.rdrop.com/users/paulmck/RCU ++ * ++ * For detailed explanation of Read-Copy Update mechanism see - ++ * Documentation/RCU/ *.txt ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static struct mutex rcupreempt_trace_mutex; ++static char *rcupreempt_trace_buf; ++#define RCUPREEMPT_TRACE_BUF_SIZE 4096 ++ ++void rcupreempt_trace_move2done(struct rcupreempt_trace *trace) ++{ ++ trace->done_length += trace->wait_length; ++ trace->done_add += trace->wait_length; ++ trace->wait_length = 0; ++} ++void rcupreempt_trace_move2wait(struct rcupreempt_trace *trace) ++{ ++ trace->wait_length += trace->next_length; ++ trace->wait_add += trace->next_length; ++ trace->next_length = 0; ++} ++void rcupreempt_trace_try_flip_1(struct rcupreempt_trace *trace) ++{ ++ atomic_inc(&trace->rcu_try_flip_1); ++} ++void rcupreempt_trace_try_flip_e1(struct rcupreempt_trace *trace) ++{ ++ atomic_inc(&trace->rcu_try_flip_e1); ++} ++void rcupreempt_trace_try_flip_i1(struct rcupreempt_trace *trace) ++{ ++ trace->rcu_try_flip_i1++; ++} ++void rcupreempt_trace_try_flip_ie1(struct rcupreempt_trace *trace) ++{ ++ trace->rcu_try_flip_ie1++; ++} ++void rcupreempt_trace_try_flip_g1(struct rcupreempt_trace *trace) ++{ ++ trace->rcu_try_flip_g1++; ++} ++void rcupreempt_trace_try_flip_a1(struct rcupreempt_trace *trace) ++{ ++ trace->rcu_try_flip_a1++; ++} ++void rcupreempt_trace_try_flip_ae1(struct rcupreempt_trace *trace) ++{ ++ trace->rcu_try_flip_ae1++; ++} ++void rcupreempt_trace_try_flip_a2(struct rcupreempt_trace *trace) ++{ ++ trace->rcu_try_flip_a2++; ++} ++void rcupreempt_trace_try_flip_z1(struct rcupreempt_trace *trace) ++{ ++ trace->rcu_try_flip_z1++; ++} ++void rcupreempt_trace_try_flip_ze1(struct rcupreempt_trace *trace) ++{ ++ trace->rcu_try_flip_ze1++; ++} ++void rcupreempt_trace_try_flip_z2(struct rcupreempt_trace *trace) ++{ ++ trace->rcu_try_flip_z2++; ++} ++void rcupreempt_trace_try_flip_m1(struct rcupreempt_trace *trace) ++{ ++ trace->rcu_try_flip_m1++; ++} ++void rcupreempt_trace_try_flip_me1(struct rcupreempt_trace *trace) ++{ ++ trace->rcu_try_flip_me1++; ++} ++void rcupreempt_trace_try_flip_m2(struct rcupreempt_trace *trace) ++{ ++ trace->rcu_try_flip_m2++; ++} ++void rcupreempt_trace_check_callbacks(struct rcupreempt_trace *trace) ++{ ++ trace->rcu_check_callbacks++; ++} ++void rcupreempt_trace_done_remove(struct rcupreempt_trace *trace) ++{ ++ trace->done_remove += trace->done_length; ++ trace->done_length = 0; ++} ++void rcupreempt_trace_invoke(struct rcupreempt_trace *trace) ++{ ++ atomic_inc(&trace->done_invoked); ++} ++void rcupreempt_trace_next_add(struct rcupreempt_trace *trace) ++{ ++ trace->next_add++; ++ trace->next_length++; ++} ++ ++static void rcupreempt_trace_sum(struct rcupreempt_trace *sp) ++{ ++ struct rcupreempt_trace *cp; ++ int cpu; ++ ++ memset(sp, 0, sizeof(*sp)); ++ for_each_possible_cpu(cpu) { ++ cp = rcupreempt_trace_cpu(cpu); ++ sp->next_length += cp->next_length; ++ sp->next_add += cp->next_add; ++ sp->wait_length += cp->wait_length; ++ sp->wait_add += cp->wait_add; ++ sp->done_length += cp->done_length; ++ sp->done_add += cp->done_add; ++ sp->done_remove += cp->done_remove; ++ atomic_set(&sp->done_invoked, atomic_read(&cp->done_invoked)); ++ sp->rcu_check_callbacks += cp->rcu_check_callbacks; ++ atomic_set(&sp->rcu_try_flip_1, ++ atomic_read(&cp->rcu_try_flip_1)); ++ atomic_set(&sp->rcu_try_flip_e1, ++ atomic_read(&cp->rcu_try_flip_e1)); ++ sp->rcu_try_flip_i1 += cp->rcu_try_flip_i1; ++ sp->rcu_try_flip_ie1 += cp->rcu_try_flip_ie1; ++ sp->rcu_try_flip_g1 += cp->rcu_try_flip_g1; ++ sp->rcu_try_flip_a1 += cp->rcu_try_flip_a1; ++ sp->rcu_try_flip_ae1 += cp->rcu_try_flip_ae1; ++ sp->rcu_try_flip_a2 += cp->rcu_try_flip_a2; ++ sp->rcu_try_flip_z1 += cp->rcu_try_flip_z1; ++ sp->rcu_try_flip_ze1 += cp->rcu_try_flip_ze1; ++ sp->rcu_try_flip_z2 += cp->rcu_try_flip_z2; ++ sp->rcu_try_flip_m1 += cp->rcu_try_flip_m1; ++ sp->rcu_try_flip_me1 += cp->rcu_try_flip_me1; ++ sp->rcu_try_flip_m2 += cp->rcu_try_flip_m2; ++ } ++} ++ ++static ssize_t rcustats_read(struct file *filp, char __user *buffer, ++ size_t count, loff_t *ppos) ++{ ++ struct rcupreempt_trace trace; ++ ssize_t bcount; ++ int cnt = 0; ++ ++ rcupreempt_trace_sum(&trace); ++ mutex_lock(&rcupreempt_trace_mutex); ++ snprintf(&rcupreempt_trace_buf[cnt], RCUPREEMPT_TRACE_BUF_SIZE - cnt, ++ "ggp=%ld rcc=%ld\n", ++ rcu_batches_completed(), ++ trace.rcu_check_callbacks); ++ snprintf(&rcupreempt_trace_buf[cnt], RCUPREEMPT_TRACE_BUF_SIZE - cnt, ++ "na=%ld nl=%ld wa=%ld wl=%ld da=%ld dl=%ld dr=%ld di=%d\n" ++ "1=%d e1=%d i1=%ld ie1=%ld g1=%ld a1=%ld ae1=%ld a2=%ld\n" ++ "z1=%ld ze1=%ld z2=%ld m1=%ld me1=%ld m2=%ld\n", ++ ++ trace.next_add, trace.next_length, ++ trace.wait_add, trace.wait_length, ++ trace.done_add, trace.done_length, ++ trace.done_remove, atomic_read(&trace.done_invoked), ++ atomic_read(&trace.rcu_try_flip_1), ++ atomic_read(&trace.rcu_try_flip_e1), ++ trace.rcu_try_flip_i1, trace.rcu_try_flip_ie1, ++ trace.rcu_try_flip_g1, ++ trace.rcu_try_flip_a1, trace.rcu_try_flip_ae1, ++ trace.rcu_try_flip_a2, ++ trace.rcu_try_flip_z1, trace.rcu_try_flip_ze1, ++ trace.rcu_try_flip_z2, ++ trace.rcu_try_flip_m1, trace.rcu_try_flip_me1, ++ trace.rcu_try_flip_m2); ++ bcount = simple_read_from_buffer(buffer, count, ppos, ++ rcupreempt_trace_buf, strlen(rcupreempt_trace_buf)); ++ mutex_unlock(&rcupreempt_trace_mutex); ++ return bcount; ++} ++ ++static ssize_t rcugp_read(struct file *filp, char __user *buffer, ++ size_t count, loff_t *ppos) ++{ ++ long oldgp = rcu_batches_completed(); ++ ssize_t bcount; ++ ++ mutex_lock(&rcupreempt_trace_mutex); ++ synchronize_rcu(); ++ snprintf(rcupreempt_trace_buf, RCUPREEMPT_TRACE_BUF_SIZE, ++ "oldggp=%ld newggp=%ld\n", oldgp, rcu_batches_completed()); ++ bcount = simple_read_from_buffer(buffer, count, ppos, ++ rcupreempt_trace_buf, strlen(rcupreempt_trace_buf)); ++ mutex_unlock(&rcupreempt_trace_mutex); ++ return bcount; ++} ++ ++static ssize_t rcuctrs_read(struct file *filp, char __user *buffer, ++ size_t count, loff_t *ppos) ++{ ++ int cnt = 0; ++ int cpu; ++ int f = rcu_batches_completed() & 0x1; ++ ssize_t bcount; ++ ++ mutex_lock(&rcupreempt_trace_mutex); ++ ++ cnt += snprintf(&rcupreempt_trace_buf[cnt], RCUPREEMPT_TRACE_BUF_SIZE, ++ "CPU last cur F M\n"); ++ for_each_online_cpu(cpu) { ++ int *flipctr = rcupreempt_flipctr(cpu); ++ cnt += snprintf(&rcupreempt_trace_buf[cnt], ++ RCUPREEMPT_TRACE_BUF_SIZE - cnt, ++ "%3d %4d %3d %d %d\n", ++ cpu, ++ flipctr[!f], ++ flipctr[f], ++ rcupreempt_flip_flag(cpu), ++ rcupreempt_mb_flag(cpu)); ++ } ++ cnt += snprintf(&rcupreempt_trace_buf[cnt], ++ RCUPREEMPT_TRACE_BUF_SIZE - cnt, ++ "ggp = %ld, state = %s\n", ++ rcu_batches_completed(), ++ rcupreempt_try_flip_state_name()); ++ cnt += snprintf(&rcupreempt_trace_buf[cnt], ++ RCUPREEMPT_TRACE_BUF_SIZE - cnt, ++ "\n"); ++ bcount = simple_read_from_buffer(buffer, count, ppos, ++ rcupreempt_trace_buf, strlen(rcupreempt_trace_buf)); ++ mutex_unlock(&rcupreempt_trace_mutex); ++ return bcount; ++} ++ ++static struct file_operations rcustats_fops = { ++ .owner = THIS_MODULE, ++ .read = rcustats_read, ++}; ++ ++static struct file_operations rcugp_fops = { ++ .owner = THIS_MODULE, ++ .read = rcugp_read, ++}; ++ ++static struct file_operations rcuctrs_fops = { ++ .owner = THIS_MODULE, ++ .read = rcuctrs_read, ++}; ++ ++static struct dentry *rcudir, *statdir, *ctrsdir, *gpdir; ++static int rcupreempt_debugfs_init(void) ++{ ++ rcudir = debugfs_create_dir("rcu", NULL); ++ if (!rcudir) ++ goto out; ++ statdir = debugfs_create_file("rcustats", 0444, rcudir, ++ NULL, &rcustats_fops); ++ if (!statdir) ++ goto free_out; ++ ++ gpdir = debugfs_create_file("rcugp", 0444, rcudir, NULL, &rcugp_fops); ++ if (!gpdir) ++ goto free_out; ++ ++ ctrsdir = debugfs_create_file("rcuctrs", 0444, rcudir, ++ NULL, &rcuctrs_fops); ++ if (!ctrsdir) ++ goto free_out; ++ return 0; ++free_out: ++ if (statdir) ++ debugfs_remove(statdir); ++ if (gpdir) ++ debugfs_remove(gpdir); ++ debugfs_remove(rcudir); ++out: ++ return 1; ++} ++ ++static int __init rcupreempt_trace_init(void) ++{ ++ mutex_init(&rcupreempt_trace_mutex); ++ rcupreempt_trace_buf = kmalloc(RCUPREEMPT_TRACE_BUF_SIZE, GFP_KERNEL); ++ if (!rcupreempt_trace_buf) ++ return 1; ++ return rcupreempt_debugfs_init(); ++} ++ ++static void __exit rcupreempt_trace_cleanup(void) ++{ ++ debugfs_remove(statdir); ++ debugfs_remove(gpdir); ++ debugfs_remove(ctrsdir); ++ debugfs_remove(rcudir); ++ kfree(rcupreempt_trace_buf); ++} ++ ++ ++module_init(rcupreempt_trace_init); ++module_exit(rcupreempt_trace_cleanup); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0556-4ff4b9e19a80b73959ebeb28d1df40176686f0a8.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0556-4ff4b9e19a80b73959ebeb28d1df40176686f0a8.patch @@ -0,0 +1,55 @@ +commit 4ff4b9e19a80b73959ebeb28d1df40176686f0a8 +Author: Maciej W. Rozycki +Date: Fri Sep 5 14:05:31 2008 -0700 + + ntp: fix calculation of the next jiffie to trigger RTC sync + + We have a bug in the calculation of the next jiffie to trigger the RTC + synchronisation. The aim here is to run sync_cmos_clock() as close as + possible to the middle of a second. Which means we want this function to + be called less than or equal to half a jiffie away from when now.tv_nsec + equals 5e8 (500000000). + + If this is not the case for a given call to the function, for this purpose + instead of updating the RTC we calculate the offset in nanoseconds to the + next point in time where now.tv_nsec will be equal 5e8. The calculated + offset is then converted to jiffies as these are the unit used by the + timer. + + Hovewer timespec_to_jiffies() used here uses a ceil()-type rounding mode, + where the resulting value is rounded up. As a result the range of + now.tv_nsec when the timer will trigger is from 5e8 to 5e8 + TICK_NSEC + rather than the desired 5e8 - TICK_NSEC / 2 to 5e8 + TICK_NSEC / 2. + + As a result if for example sync_cmos_clock() happens to be called at the + time when now.tv_nsec is between 5e8 + TICK_NSEC / 2 and 5e8 to 5e8 + + TICK_NSEC, it will simply be rescheduled HZ jiffies later, falling in the + same range of now.tv_nsec again. Similarly for cases offsetted by an + integer multiple of TICK_NSEC. + + This change addresses the problem by subtracting TICK_NSEC / 2 from the + nanosecond offset to the next point in time where now.tv_nsec will be + equal 5e8, effectively shifting the following rounding in + timespec_to_jiffies() so that it produces a rounded-to-nearest result. + + Signed-off-by: Maciej W. Rozycki + Signed-off-by: Andrew Morton + Signed-off-by: Ingo Molnar + +--- + kernel/time/ntp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/kernel/time/ntp.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/time/ntp.c 2008-10-08 22:22:08.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/time/ntp.c 2008-10-08 22:25:17.000000000 -0400 +@@ -208,7 +208,7 @@ static void sync_cmos_clock(unsigned lon + if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2) + fail = update_persistent_clock(now); + +- next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec; ++ next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec - (TICK_NSEC / 2); + if (next.tv_nsec <= 0) + next.tv_nsec += NSEC_PER_SEC; + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0448-rwlocks-lateral-steal.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0448-rwlocks-lateral-steal.patch @@ -0,0 +1,238 @@ +From: Steven Rostedt + +Added lateral steal for rwlocks. + +Signed-off-by: Steven Rostedt + +--- + kernel/rtmutex.c | 58 +++++++++++++++++++++++++++++-------------------------- + 1 file changed, 31 insertions(+), 27 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/rtmutex.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rtmutex.c 2008-10-08 22:24:51.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rtmutex.c 2008-10-08 22:24:51.000000000 -0400 +@@ -1033,7 +1033,7 @@ update_rw_mutex_owner(struct rw_mutex *r + rt_mutex_set_owner(mutex, mtxowner, 0); + } + +-static int try_to_take_rw_read(struct rw_mutex *rwm) ++static int try_to_take_rw_read(struct rw_mutex *rwm, int mtx) + { + struct rt_mutex *mutex = &rwm->mutex; + struct rt_mutex_waiter *waiter; +@@ -1059,7 +1059,9 @@ static int try_to_take_rw_read(struct rw + } + + if (mtxowner && mtxowner != RT_RW_READER) { +- if (!try_to_steal_lock(mutex)) { ++ int mode = mtx ? STEAL_NORMAL : STEAL_LATERAL; ++ ++ if (!try_to_steal_lock(mutex, mode)) { + /* + * readers don't own the mutex, and rwm shows that a + * writer doesn't have it either. If we enter this +@@ -1076,7 +1078,7 @@ static int try_to_take_rw_read(struct rw + if (rt_mutex_has_waiters(mutex)) { + /* readers don't do PI */ + waiter = rt_mutex_top_waiter(mutex); +- if (current->prio >= waiter->task->prio) ++ if (!lock_is_stealable(waiter->task, mode)) + return 0; + /* + * The pending reader has PI waiters, +@@ -1107,7 +1109,7 @@ static int try_to_take_rw_read(struct rw + } + + static int +-try_to_take_rw_write(struct rw_mutex *rwm) ++try_to_take_rw_write(struct rw_mutex *rwm, int mtx) + { + struct rt_mutex *mutex = &rwm->mutex; + struct task_struct *own; +@@ -1129,7 +1131,7 @@ try_to_take_rw_write(struct rw_mutex *rw + */ + WARN_ON(own && !rt_mutex_owner_pending(mutex)); + +- if (!try_to_take_rt_mutex(mutex)) ++ if (!do_try_to_take_rt_mutex(mutex, mtx ? STEAL_NORMAL : STEAL_LATERAL)) + return 0; + + /* +@@ -1142,7 +1144,7 @@ try_to_take_rw_write(struct rw_mutex *rw + } + + static void +-rt_read_slowlock(struct rw_mutex *rwm) ++rt_read_slowlock(struct rw_mutex *rwm, int mtx) + { + struct rt_mutex_waiter waiter; + struct rt_mutex *mutex = &rwm->mutex; +@@ -1152,7 +1154,7 @@ rt_read_slowlock(struct rw_mutex *rwm) + spin_lock_irqsave(&mutex->wait_lock, flags); + init_lists(mutex); + +- if (try_to_take_rw_read(rwm)) { ++ if (try_to_take_rw_read(rwm, mtx)) { + spin_unlock_irqrestore(&mutex->wait_lock, flags); + return; + } +@@ -1178,7 +1180,7 @@ rt_read_slowlock(struct rw_mutex *rwm) + unsigned long saved_flags; + + /* Try to acquire the lock: */ +- if (try_to_take_rw_read(rwm)) ++ if (try_to_take_rw_read(rwm, mtx)) + break; + update_rw_mutex_owner(rwm); + +@@ -1230,7 +1232,8 @@ rt_read_slowlock(struct rw_mutex *rwm) + + static inline void + rt_read_fastlock(struct rw_mutex *rwm, +- void fastcall (*slowfn)(struct rw_mutex *rwm)) ++ void fastcall (*slowfn)(struct rw_mutex *rwm, int mtx), ++ int mtx) + { + retry: + if (likely(rt_rwlock_cmpxchg(rwm, NULL, current))) { +@@ -1246,17 +1249,17 @@ retry: + goto retry; + } + } else +- slowfn(rwm); ++ slowfn(rwm, mtx); + } + + void fastcall rt_mutex_down_read(struct rw_mutex *rwm) + { +- rt_read_fastlock(rwm, rt_read_slowlock); ++ rt_read_fastlock(rwm, rt_read_slowlock, 1); + } + + + static inline int +-rt_read_slowtrylock(struct rw_mutex *rwm) ++rt_read_slowtrylock(struct rw_mutex *rwm, int mtx) + { + struct rt_mutex *mutex = &rwm->mutex; + unsigned long flags; +@@ -1265,7 +1268,7 @@ rt_read_slowtrylock(struct rw_mutex *rwm + spin_lock_irqsave(&mutex->wait_lock, flags); + init_lists(mutex); + +- if (try_to_take_rw_read(rwm)) ++ if (try_to_take_rw_read(rwm, mtx)) + ret = 1; + + spin_unlock_irqrestore(&mutex->wait_lock, flags); +@@ -1275,7 +1278,7 @@ rt_read_slowtrylock(struct rw_mutex *rwm + + static inline int + rt_read_fasttrylock(struct rw_mutex *rwm, +- int fastcall (*slowfn)(struct rw_mutex *rwm)) ++ int fastcall (*slowfn)(struct rw_mutex *rwm, int mtx), int mtx) + { + retry: + if (likely(rt_rwlock_cmpxchg(rwm, NULL, current))) { +@@ -1292,16 +1295,16 @@ retry: + } + return 1; + } else +- return slowfn(rwm); ++ return slowfn(rwm, mtx); + } + + int __sched rt_mutex_down_read_trylock(struct rw_mutex *rwm) + { +- return rt_read_fasttrylock(rwm, rt_read_slowtrylock); ++ return rt_read_fasttrylock(rwm, rt_read_slowtrylock, 1); + } + + static void +-rt_write_slowlock(struct rw_mutex *rwm) ++rt_write_slowlock(struct rw_mutex *rwm, int mtx) + { + struct rt_mutex *mutex = &rwm->mutex; + struct rt_mutex_waiter waiter; +@@ -1317,7 +1320,7 @@ rt_write_slowlock(struct rw_mutex *rwm) + spin_lock_irqsave(&mutex->wait_lock, flags); + init_lists(mutex); + +- if (try_to_take_rw_write(rwm)) { ++ if (try_to_take_rw_write(rwm, mtx)) { + spin_unlock_irqrestore(&mutex->wait_lock, flags); + return; + } +@@ -1335,7 +1338,7 @@ rt_write_slowlock(struct rw_mutex *rwm) + unsigned long saved_flags; + + /* Try to acquire the lock: */ +- if (try_to_take_rw_write(rwm)) ++ if (try_to_take_rw_write(rwm, mtx)) + break; + update_rw_mutex_owner(rwm); + +@@ -1389,7 +1392,8 @@ rt_write_slowlock(struct rw_mutex *rwm) + + static inline void + rt_write_fastlock(struct rw_mutex *rwm, +- void fastcall (*slowfn)(struct rw_mutex *rwm)) ++ void fastcall (*slowfn)(struct rw_mutex *rwm, int mtx), ++ int mtx) + { + unsigned long val = (unsigned long)current | RT_RWLOCK_WRITER; + +@@ -1397,16 +1401,16 @@ rt_write_fastlock(struct rw_mutex *rwm, + rt_mutex_deadlock_account_lock(&rwm->mutex, current); + WARN_ON(atomic_read(&rwm->count)); + } else +- slowfn(rwm); ++ slowfn(rwm, mtx); + } + + void fastcall rt_mutex_down_write(struct rw_mutex *rwm) + { +- rt_write_fastlock(rwm, rt_write_slowlock); ++ rt_write_fastlock(rwm, rt_write_slowlock, 1); + } + + static int +-rt_write_slowtrylock(struct rw_mutex *rwm) ++rt_write_slowtrylock(struct rw_mutex *rwm, int mtx) + { + struct rt_mutex *mutex = &rwm->mutex; + unsigned long flags; +@@ -1415,7 +1419,7 @@ rt_write_slowtrylock(struct rw_mutex *rw + spin_lock_irqsave(&mutex->wait_lock, flags); + init_lists(mutex); + +- if (try_to_take_rw_write(rwm)) ++ if (try_to_take_rw_write(rwm, mtx)) + ret = 1; + + spin_unlock_irqrestore(&mutex->wait_lock, flags); +@@ -1425,7 +1429,7 @@ rt_write_slowtrylock(struct rw_mutex *rw + + static inline int + rt_write_fasttrylock(struct rw_mutex *rwm, +- int fastcall (*slowfn)(struct rw_mutex *rwm)) ++ int fastcall (*slowfn)(struct rw_mutex *rwm, int mtx), int mtx) + { + unsigned long val = (unsigned long)current | RT_RWLOCK_WRITER; + +@@ -1434,12 +1438,12 @@ rt_write_fasttrylock(struct rw_mutex *rw + WARN_ON(atomic_read(&rwm->count)); + return 1; + } else +- return slowfn(rwm); ++ return slowfn(rwm, mtx); + } + + int fastcall rt_mutex_down_write_trylock(struct rw_mutex *rwm) + { +- return rt_write_fasttrylock(rwm, rt_write_slowtrylock); ++ return rt_write_fasttrylock(rwm, rt_write_slowtrylock, 1); + } + + static void fastcall noinline __sched --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0451-multi-reader-limit.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0451-multi-reader-limit.patch @@ -0,0 +1,254 @@ +From: Steven Rostedt +Subject: implement reader limit on read write locks + +This patch allows for limiting the number of readers a lock may have. +The limit is default to "no limit". The read write locks now keep +track of, not only the number of times a lock is held by read, but also +the number of tasks that have a reader. i.e. If 2 tasks hold the same +read/write lock, and one task holds the lock twice, the count for the +read/write lock would be 3 and the owner count is 2. + +The limit of readers is controlled by + + /proc/sys/kernel/rwlock_reader_limit + +If this is set to zero or negative, than there is no limit. + +Signed-off-by: Steven Rostedt +--- + include/linux/rt_lock.h | 1 + kernel/rtmutex.c | 89 +++++++++++++++++++++++++++++++++++------------- + kernel/sysctl.c | 14 +++++++ + 3 files changed, 80 insertions(+), 24 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/rt_lock.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/rt_lock.h 2008-10-08 22:24:51.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/rt_lock.h 2008-10-08 22:24:52.000000000 -0400 +@@ -64,6 +64,7 @@ struct rw_mutex { + struct task_struct *owner; + struct rt_mutex mutex; + atomic_t count; /* number of times held for read */ ++ atomic_t owners; /* number of owners as readers */ + }; + + /* +Index: linux-2.6.24.7-rt21/kernel/rtmutex.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rtmutex.c 2008-10-08 22:24:51.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rtmutex.c 2008-10-08 22:24:52.000000000 -0400 +@@ -997,6 +997,8 @@ __rt_spin_lock_init(spinlock_t *lock, ch + } + EXPORT_SYMBOL(__rt_spin_lock_init); + ++int rt_rwlock_limit; ++ + static inline int rt_release_bkl(struct rt_mutex *lock, unsigned long flags); + static inline void rt_reacquire_bkl(int saved_lock_depth); + +@@ -1070,6 +1072,10 @@ static int try_to_take_rw_read(struct rw + goto taken; + } + ++ /* Check for rwlock limits */ ++ if (rt_rwlock_limit && atomic_read(&rwm->owners) >= rt_rwlock_limit) ++ return 0; ++ + if (mtxowner && mtxowner != RT_RW_READER) { + int mode = mtx ? STEAL_NORMAL : STEAL_LATERAL; + +@@ -1116,6 +1122,7 @@ static int try_to_take_rw_read(struct rw + rt_rwlock_set_owner(rwm, RT_RW_READER, 0); + taken: + if (incr) { ++ atomic_inc(&rwm->owners); + reader_count = current->reader_lock_count++; + if (likely(reader_count < MAX_RWLOCK_DEPTH)) { + current->owned_read_locks[reader_count].lock = rwm; +@@ -1293,6 +1300,7 @@ rt_read_fastlock(struct rw_mutex *rwm, + goto retry; + } + ++ atomic_inc(&rwm->owners); + reader_count = current->reader_lock_count++; + if (likely(reader_count < MAX_RWLOCK_DEPTH)) { + current->owned_read_locks[reader_count].lock = rwm; +@@ -1352,6 +1360,7 @@ retry: + goto retry; + } + ++ atomic_inc(&rwm->owners); + reader_count = current->reader_lock_count++; + if (likely(reader_count < MAX_RWLOCK_DEPTH)) { + current->owned_read_locks[reader_count].lock = rwm; +@@ -1543,6 +1552,7 @@ rt_read_slowunlock(struct rw_mutex *rwm, + struct rt_mutex *mutex = &rwm->mutex; + struct rt_mutex_waiter *waiter; + unsigned long flags; ++ unsigned int reader_count; + int savestate = !mtx; + int i; + +@@ -1565,6 +1575,7 @@ rt_read_slowunlock(struct rw_mutex *rwm, + if (!current->owned_read_locks[i].count) { + current->reader_lock_count--; + WARN_ON_ONCE(i != current->reader_lock_count); ++ atomic_dec(&rwm->owners); + } + break; + } +@@ -1572,20 +1583,34 @@ rt_read_slowunlock(struct rw_mutex *rwm, + WARN_ON_ONCE(i < 0); + + /* +- * If there are more readers, let the last one do any wakeups. +- * Also check to make sure the owner wasn't cleared when two +- * readers released the lock at the same time, and the count +- * went to zero before grabbing the wait_lock. ++ * If the last two (or more) readers unlocked at the same ++ * time, the owner could be cleared since the count went to ++ * zero. If this has happened, the rwm owner will not ++ * be set to current or readers. This means that another reader ++ * already reset the lock, so there is nothing left to do. + */ +- if (atomic_read(&rwm->count) || +- (rt_rwlock_owner(rwm) != current && +- rt_rwlock_owner(rwm) != RT_RW_READER)) { +- spin_unlock_irqrestore(&mutex->wait_lock, flags); +- return; +- } ++ if ((rt_rwlock_owner(rwm) != current && ++ rt_rwlock_owner(rwm) != RT_RW_READER)) ++ goto out; ++ ++ /* ++ * If there are more readers and we are under the limit ++ * let the last reader do the wakeups. ++ */ ++ reader_count = atomic_read(&rwm->count); ++ if (reader_count && ++ (!rt_rwlock_limit || atomic_read(&rwm->owners) >= rt_rwlock_limit)) ++ goto out; + + /* If no one is blocked, then clear all ownership */ + if (!rt_mutex_has_waiters(mutex)) { ++ /* ++ * If count is not zero, we are under the limit with ++ * no other readers. ++ */ ++ if (reader_count) ++ goto out; ++ + /* We could still have a pending reader waiting */ + if (rt_mutex_owner_pending(mutex)) { + /* set the rwm back to pending */ +@@ -1597,24 +1622,32 @@ rt_read_slowunlock(struct rw_mutex *rwm, + goto out; + } + +- /* We are the last reader with pending waiters. */ ++ /* ++ * If the next waiter is a reader, this can be because of ++ * two things. One is that we hit the reader limit, or ++ * Two, there is a pending writer. ++ * We still only wake up one reader at a time (even if ++ * we could wake up more). This is because we dont ++ * have any idea if a writer is pending. ++ */ + waiter = rt_mutex_top_waiter(mutex); +- if (waiter->write_lock) ++ if (waiter->write_lock) { ++ /* only wake up if there are no readers */ ++ if (reader_count) ++ goto out; + rwm->owner = RT_RW_PENDING_WRITE; +- else ++ } else { ++ /* ++ * It is also possible that the reader limit decreased. ++ * If the limit did decrease, we may not be able to ++ * wake up the reader if we are currently above the limit. ++ */ ++ if (rt_rwlock_limit && ++ unlikely(atomic_read(&rwm->owners) >= rt_rwlock_limit)) ++ goto out; + rwm->owner = RT_RW_PENDING_READ; ++ } + +- /* +- * It is possible to have a reader waiting. We still only +- * wake one up in that case. A way we can have a reader waiting +- * is because a writer woke up, a higher prio reader came +- * and stole the lock from the writer. But the writer now +- * is no longer waiting on the lock and needs to retake +- * the lock. We simply wake up the reader and let the +- * reader have the lock. If the writer comes by, it +- * will steal the lock from the reader. This is the +- * only time we can have a reader pending on a lock. +- */ + wakeup_next_waiter(mutex, savestate); + + out: +@@ -1630,15 +1663,22 @@ rt_read_fastunlock(struct rw_mutex *rwm, + int mtx) + { + WARN_ON(!atomic_read(&rwm->count)); ++ WARN_ON(!atomic_read(&rwm->owners)); + WARN_ON(!rwm->owner); + atomic_dec(&rwm->count); + if (likely(rt_rwlock_cmpxchg(rwm, current, NULL))) { + int reader_count = --current->reader_lock_count; ++ int owners; + rt_mutex_deadlock_account_unlock(current); + if (unlikely(reader_count < 0)) { + reader_count = 0; + WARN_ON_ONCE(1); + } ++ owners = atomic_dec_return(&rwm->owners); ++ if (unlikely(owners < 0)) { ++ atomic_set(&rwm->owners, 0); ++ WARN_ON_ONCE(1); ++ } + WARN_ON_ONCE(current->owned_read_locks[reader_count].lock != rwm); + } else + slowfn(rwm, mtx); +@@ -1789,6 +1829,7 @@ void rt_mutex_rwsem_init(struct rw_mutex + + rwm->owner = NULL; + atomic_set(&rwm->count, 0); ++ atomic_set(&rwm->owners, 0); + + __rt_mutex_init(mutex, name); + } +Index: linux-2.6.24.7-rt21/kernel/sysctl.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sysctl.c 2008-10-08 22:24:46.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sysctl.c 2008-10-08 22:24:52.000000000 -0400 +@@ -150,6 +150,10 @@ static int parse_table(int __user *, int + void __user *, size_t, struct ctl_table *); + #endif + ++#ifdef CONFIG_PREEMPT_RT ++extern int rt_rwlock_limit; ++#endif ++ + + #ifdef CONFIG_PROC_SYSCTL + static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp, +@@ -399,6 +403,16 @@ static struct ctl_table kern_table[] = { + .proc_handler = &proc_dointvec, + }, + #endif ++#ifdef CONFIG_PREEMPT_RT ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "rwlock_reader_limit", ++ .data = &rt_rwlock_limit, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif + { + .ctl_name = KERN_PANIC, + .procname = "panic", --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0148-preempt-irqs-x86-64.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0148-preempt-irqs-x86-64.patch @@ -0,0 +1,31 @@ +--- + arch/x86/kernel/i8259_64.c | 1 + + arch/x86/kernel/time_64.c | 3 ++- + 2 files changed, 3 insertions(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/i8259_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/i8259_64.c 2008-10-08 22:22:37.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/i8259_64.c 2008-10-08 22:23:32.000000000 -0400 +@@ -397,6 +397,7 @@ device_initcall(i8259A_init_sysfs); + + static struct irqaction irq2 = { + .handler = no_action, ++ .flags = IRQF_NODELAY, + .mask = CPU_MASK_NONE, + .name = "cascade", + }; +Index: linux-2.6.24.7-rt21/arch/x86/kernel/time_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/time_64.c 2008-10-08 22:22:37.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/time_64.c 2008-10-08 22:23:32.000000000 -0400 +@@ -259,7 +259,8 @@ static unsigned int __init tsc_calibrate + + static struct irqaction irq0 = { + .handler = timer_event_interrupt, +- .flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING, ++ .flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING | ++ IRQF_NODELAY, + .mask = CPU_MASK_NONE, + .name = "timer" + }; --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0409-kernel-bug-after-entering-something-from-login.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0409-kernel-bug-after-entering-something-from-login.patch @@ -0,0 +1,74 @@ +From r.schwebel@pengutronix.de Fri Jan 11 20:50:39 2008 +Date: Fri, 11 Jan 2008 23:35:49 +0100 +From: Robert Schwebel +To: Steven Rostedt +Cc: linux-rt-users@vger.kernel.org +Subject: lost patch for mpc52xx spinlock + + [ The following text is in the "iso-8859-15" character set. ] + [ Your display is set for the "iso-8859-1" character set. ] + [ Some special characters may be displayed incorrectly. ] + +Hi Steven, + +this patch from tglx seems to got lost, can you add it to the next +release? + +Robert +-- + Robert Schwebel | http://www.pengutronix.de + OSADL Testlab @ Pengutronix | http://www.osadl.org + +----------8<---------- + +Subject: Re: Kernel Bug when entering something after login +From: Thomas Gleixner +To: Juergen Beisert +Cc: linux-rt-users@vger.kernel.org +In-Reply-To: <200707251900.47704.juergen127@kreuzholzen.de> +References: <200707251900.47704.juergen127@kreuzholzen.de> +Date: Wed, 25 Jul 2007 21:06:38 +0200 +Message-Id: <1185390398.3227.8.camel@chaos> + +On Wed, 2007-07-25 at 19:00 +0200, Juergen Beisert wrote: +> [c0245db0] [c01bdb98] rt_spin_lock_slowlock+0x4c/0x224 (unreliable) +> [c0245e10] [c011823c] uart_start+0x24/0x48 +> [c0245e30] [c0113ff4] n_tty_receive_buf+0x170/0xfd4 +> [c0245ef0] [c010f0dc] flush_to_ldisc+0xe0/0x130 +> [c0245f20] [c011b51c] mpc52xx_uart_int+0x194/0x350 +> [c0245f50] [c0046dfc] handle_IRQ_event+0x6c/0x110 +> [c0245f80] [c00475ec] thread_simple_irq+0x90/0xf8 +> [c0245fa0] [c00479a0] do_irqd+0x34c/0x3cc +> [c0245fd0] [c0033380] kthread+0x48/0x84 +> [c0245ff0] [c00104ac] kernel_thread+0x44/0x60 +> Instruction dump: +> 70090008 40820144 80010064 bb410048 38210060 7c0803a6 4e800020 801c0010 +> 5400003a 7c001278 7c000034 5400d97e <0f000000> 39600004 91610008 80010008 +> note: IRQ-131[93] exited with preempt_count 1 + +Yup. That's a deadlock. In mainline this does not happen, as the +spinlock is a NOP. Turn on CONFIG_PROVE_LOCKING in mainline and you see +the problem as well. + +Solution below + + tglx + +--- + drivers/serial/mpc52xx_uart.c | 2 ++ + 1 file changed, 2 insertions(+) + +Index: linux-2.6.24.7-rt21/drivers/serial/mpc52xx_uart.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/serial/mpc52xx_uart.c 2008-10-08 22:22:17.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/serial/mpc52xx_uart.c 2008-10-08 22:24:42.000000000 -0400 +@@ -501,7 +501,9 @@ mpc52xx_uart_int_rx_chars(struct uart_po + } + } + ++ spin_unlock(&port->lock); + tty_flip_buffer_push(tty); ++ spin_lock(&port->lock); + + return in_be16(&PSC(port)->mpc52xx_psc_status) & MPC52xx_PSC_SR_RXRDY; + } --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0219-preempt-realtime-ppc-more-resched-fixups.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0219-preempt-realtime-ppc-more-resched-fixups.patch @@ -0,0 +1,82 @@ +--- + arch/powerpc/kernel/entry_64.S | 16 +++++++++++----- + arch/powerpc/kernel/idle.c | 3 ++- + include/asm-powerpc/thread_info.h | 3 ++- + 3 files changed, 15 insertions(+), 7 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/powerpc/kernel/entry_64.S +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/kernel/entry_64.S 2008-10-08 22:23:35.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/kernel/entry_64.S 2008-10-08 22:23:53.000000000 -0400 +@@ -471,7 +471,8 @@ _GLOBAL(ret_from_except_lite) + + #ifdef CONFIG_PREEMPT + clrrdi r9,r1,THREAD_SHIFT /* current_thread_info() */ +- li r0,_TIF_NEED_RESCHED /* bits to check */ ++ li r0,(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED) ++ /* bits to check */ + ld r3,_MSR(r1) + ld r4,TI_FLAGS(r9) + /* Move MSR_PR bit in r3 to _TIF_SIGPENDING position in r0 */ +@@ -579,16 +580,21 @@ do_work: + cmpdi r0,0 + crandc eq,cr1*4+eq,eq + bne restore ++ /* here we are preempting the current task */ + 1: +- /* preempt_schedule_irq() expects interrupts disabled. */ +- bl .preempt_schedule_irq ++ li r0,1 ++ stb r0,PACASOFTIRQEN(r13) ++ stb r0,PACAHARDIRQEN(r13) ++ ori r10,r10,MSR_EE ++ mtmsrd r10,1 /* reenable interrupts */ ++ bl .preempt_schedule + mfmsr r10 + clrrdi r9,r1,THREAD_SHIFT + rldicl r10,r10,48,1 /* disable interrupts again */ + rotldi r10,r10,16 + mtmsrd r10,1 + ld r4,TI_FLAGS(r9) +- andi. r0,r4,_TIF_NEED_RESCHED ++ andi. r0,r4,(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED) + bne 1b + b restore + +@@ -603,7 +609,7 @@ user_work: + ori r10,r10,MSR_EE + mtmsrd r10,1 + +- andi. r0,r4,_TIF_NEED_RESCHED ++ andi. r0,r4,(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED) + beq 1f + bl .schedule + b .ret_from_except_lite +Index: linux-2.6.24.7-rt21/arch/powerpc/kernel/idle.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/kernel/idle.c 2008-10-08 22:23:52.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/kernel/idle.c 2008-10-08 22:23:53.000000000 -0400 +@@ -61,7 +61,8 @@ void cpu_idle(void) + set_thread_flag(TIF_POLLING_NRFLAG); + while (1) { + tick_nohz_stop_sched_tick(); +- while (!need_resched() && !cpu_should_die()) { ++ while (!need_resched() && !need_resched_delayed() && ++ !cpu_should_die()) { + ppc64_runlatch_off(); + + if (ppc_md.power_save) { +Index: linux-2.6.24.7-rt21/include/asm-powerpc/thread_info.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-powerpc/thread_info.h 2008-10-08 22:23:33.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-powerpc/thread_info.h 2008-10-08 22:23:53.000000000 -0400 +@@ -150,7 +150,8 @@ static inline struct thread_info *curren + #define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP) + + #define _TIF_USER_WORK_MASK ( _TIF_SIGPENDING | \ +- _TIF_NEED_RESCHED | _TIF_RESTORE_SIGMASK) ++ _TIF_NEED_RESCHED | _TIF_RESTORE_SIGMASK | \ ++ _TIF_NEED_RESCHED_DELAYED) + #define _TIF_PERSYSCALL_MASK (_TIF_RESTOREALL|_TIF_NOERROR) + + /* Bits in local_flags */ --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0198-preempt-realtime-warn-and-bug-on.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0198-preempt-realtime-warn-and-bug-on.patch @@ -0,0 +1,34 @@ +--- + include/asm-generic/bug.h | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +Index: linux-2.6.24.7-rt21/include/asm-generic/bug.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-generic/bug.h 2008-10-08 22:22:33.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-generic/bug.h 2008-10-08 22:23:46.000000000 -0400 +@@ -3,6 +3,8 @@ + + #include + ++extern void __WARN_ON(const char *func, const char *file, const int line); ++ + #ifdef CONFIG_BUG + + #ifdef CONFIG_GENERIC_BUG +@@ -76,4 +78,16 @@ struct bug_entry { + # define WARN_ON_SMP(x) do { } while (0) + #endif + ++#ifdef CONFIG_PREEMPT_RT ++# define BUG_ON_RT(c) BUG_ON(c) ++# define BUG_ON_NONRT(c) do { } while (0) ++# define WARN_ON_RT(condition) WARN_ON(condition) ++# define WARN_ON_NONRT(condition) do { } while (0) ++#else ++# define BUG_ON_RT(c) do { } while (0) ++# define BUG_ON_NONRT(c) BUG_ON(c) ++# define WARN_ON_RT(condition) do { } while (0) ++# define WARN_ON_NONRT(condition) WARN_ON(condition) ++#endif ++ + #endif --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0334-quicklist-release-before-free-page.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0334-quicklist-release-before-free-page.patch @@ -0,0 +1,182 @@ +From peterz@infradead.org Mon Jul 23 21:40:44 2007 +Return-Path: +X-Spam-Checker-Version: SpamAssassin 3.1.7-deb (2006-10-05) on debian +X-Spam-Level: +X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham + version=3.1.7-deb +Received: from mx2.mail.elte.hu (mx2.mail.elte.hu [157.181.151.9]) (using + TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate + requested) by mail.tglx.de (Postfix) with ESMTP id CAC4B65C003 for + ; Mon, 23 Jul 2007 21:40:44 +0200 (CEST) +Received: from elvis.elte.hu ([157.181.1.14]) by mx2.mail.elte.hu with + esmtp (Exim) id 1ID3lr-0000tI-MW from for + ; Mon, 23 Jul 2007 21:40:43 +0200 +Received: by elvis.elte.hu (Postfix, from userid 1004) id 1D9593E2153; Mon, + 23 Jul 2007 21:40:43 +0200 (CEST) +Resent-From: Ingo Molnar +Resent-Date: Mon, 23 Jul 2007 21:40:40 +0200 +Resent-Message-ID: <20070723194040.GA7831@elte.hu> +Resent-To: Thomas Gleixner +X-Original-To: mingo@elvis.elte.hu +Delivered-To: mingo@elvis.elte.hu +Received: from mx3.mail.elte.hu (mx3.mail.elte.hu [157.181.1.138]) by + elvis.elte.hu (Postfix) with ESMTP id 03EA13E214E for + ; Mon, 23 Jul 2007 18:33:06 +0200 (CEST) +Received: from pentafluge.infradead.org ([213.146.154.40]) by + mx3.mail.elte.hu with esmtp (Exim) id 1ID0qK-0003mK-9A from + for ; Mon, 23 Jul 2007 18:33:08 +0200 +Received: from i55087.upc-i.chello.nl ([62.195.55.87] helo=[192.168.0.111]) + by pentafluge.infradead.org with esmtpsa (Exim 4.63 #1 (Red Hat Linux)) id + 1ID0qB-0003Kf-Tf; Mon, 23 Jul 2007 17:33:00 +0100 +Subject: Re: [PATCH] release quicklist before free_page +From: Peter Zijlstra +To: Daniel Walker +Cc: mingo@elte.hu, paulmck@linux.vnet.ibm.com, linux-kernel@vger.kernel.org, linux-rt-users@vger.kernel.org +In-Reply-To: <20070723152129.036573829@mvista.com> +References: <20070723152129.036573829@mvista.com> +Content-Type: text/plain +Date: Mon, 23 Jul 2007 18:32:58 +0200 +Message-Id: <1185208378.8197.20.camel@twins> +Mime-Version: 1.0 +X-Mailer: Evolution 2.10.1 +X-ELTE-VirusStatus: clean +X-ELTE-SpamScore: -1.0 +X-ELTE-SpamLevel: +X-ELTE-SpamCheck: no +X-ELTE-SpamVersion: ELTE 2.0 +X-ELTE-SpamCheck-Details: score=-1.0 required=5.9 tests=BAYES_00 + autolearn=no SpamAssassin version=3.0.3 -1.0 BAYES_00 BODY: + Bayesian spam probability is 0 to 1% [score: 0.0000] +Received-SPF: softfail (mx2: transitioning domain of elte.hu does not + designate 157.181.1.14 as permitted sender) client-ip=157.181.1.14; + envelope-from=mingo@elte.hu; helo=elvis.elte.hu; +X-ELTE-VirusStatus: clean +X-Evolution-Source: imap://tglx%40linutronix.de@localhost:8993/ +Content-Transfer-Encoding: 8bit + +On Mon, 2007-07-23 at 08:21 -0700, Daniel Walker wrote: +> Resolves, +> +> BUG: sleeping function called from invalid context cc1(29651) at kernel/rtmutex.c:636 +> in_atomic():1 [00000001], irqs_disabled():0 +> [] __might_sleep+0xf3/0xf9 +> [] __rt_spin_lock+0x21/0x3c +> [] get_zone_pcp+0x20/0x29 +> [] free_hot_cold_page+0xdc/0x167 +> [] add_preempt_count+0x12/0xcc +> [] pgd_dtor+0x0/0x1 +> [] quicklist_trim+0xb7/0xe3 +> [] check_pgt_cache+0x19/0x1c +> [] free_pgtables+0x54/0x12c +> [] add_preempt_count+0x12/0xcc +> [] unmap_region+0xeb/0x13b +> +> +> It looks like the quicklist isn't used after a few variables are evaluated. +> So no need to keep preemption disabled over the whole function. + +Not quite, it uses preempt_disable() to avoid migration and stick to a +cpu. Without that it might end up freeing pages from another quicklist. + +How about this - compile tested only +--- + +We cannot call the page allocator with preemption-disabled, use the +per_cpu_locked construct to allow preemption while guarding the per cpu +data. + +Signed-off-by: Peter Zijlstra +--- + include/linux/quicklist.h | 19 +++++++++++++++---- + mm/quicklist.c | 9 +++++---- + 2 files changed, 20 insertions(+), 8 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/quicklist.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/quicklist.h 2008-10-08 22:22:21.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/quicklist.h 2008-10-08 22:24:24.000000000 -0400 +@@ -18,7 +18,7 @@ struct quicklist { + int nr_pages; + }; + +-DECLARE_PER_CPU(struct quicklist, quicklist)[CONFIG_NR_QUICK]; ++DECLARE_PER_CPU_LOCKED(struct quicklist, quicklist)[CONFIG_NR_QUICK]; + + /* + * The two key functions quicklist_alloc and quicklist_free are inline so +@@ -30,19 +30,30 @@ DECLARE_PER_CPU(struct quicklist, quickl + * The fast patch in quicklist_alloc touched only a per cpu cacheline and + * the first cacheline of the page itself. There is minmal overhead involved. + */ +-static inline void *quicklist_alloc(int nr, gfp_t flags, void (*ctor)(void *)) ++static inline void *__quicklist_alloc(int cpu, int nr, gfp_t flags, void (*ctor)(void *)) + { + struct quicklist *q; + void **p = NULL; + +- q =&get_cpu_var(quicklist)[nr]; ++ q = &__get_cpu_var_locked(quicklist, cpu)[nr]; + p = q->page; + if (likely(p)) { + q->page = p[0]; + p[0] = NULL; + q->nr_pages--; + } +- put_cpu_var(quicklist); ++ return p; ++} ++ ++static inline void *quicklist_alloc(int nr, gfp_t flags, void (*ctor)(void *)) ++{ ++ struct quicklist *q; ++ void **p = NULL; ++ int cpu; ++ ++ (void)get_cpu_var_locked(quicklist, &cpu)[nr]; ++ p = __quicklist_alloc(cpu, nr, flags, ctor); ++ put_cpu_var_locked(quicklist, cpu); + if (likely(p)) + return p; + +Index: linux-2.6.24.7-rt21/mm/quicklist.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/mm/quicklist.c 2008-10-08 22:22:21.000000000 -0400 ++++ linux-2.6.24.7-rt21/mm/quicklist.c 2008-10-08 22:24:24.000000000 -0400 +@@ -19,7 +19,7 @@ + #include + #include + +-DEFINE_PER_CPU(struct quicklist, quicklist)[CONFIG_NR_QUICK]; ++DEFINE_PER_CPU_LOCKED(struct quicklist, quicklist)[CONFIG_NR_QUICK]; + + #define FRACTION_OF_NODE_MEM 16 + +@@ -59,8 +59,9 @@ void quicklist_trim(int nr, void (*dtor) + { + long pages_to_free; + struct quicklist *q; ++ int cpu; + +- q = &get_cpu_var(quicklist)[nr]; ++ q = &get_cpu_var_locked(quicklist, &cpu)[nr]; + if (q->nr_pages > min_pages) { + pages_to_free = min_pages_to_free(q, min_pages, max_free); + +@@ -69,7 +70,7 @@ void quicklist_trim(int nr, void (*dtor) + * We pass a gfp_t of 0 to quicklist_alloc here + * because we will never call into the page allocator. + */ +- void *p = quicklist_alloc(nr, 0, NULL); ++ void *p = __quicklist_alloc(cpu, nr, 0, NULL); + + if (dtor) + dtor(p); +@@ -77,7 +78,7 @@ void quicklist_trim(int nr, void (*dtor) + pages_to_free--; + } + } +- put_cpu_var(quicklist); ++ put_cpu_var_locked(quicklist, cpu); + } + + unsigned long quicklist_total_size(void) --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0473-rwlocks-fix-no-preempt-rt.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0473-rwlocks-fix-no-preempt-rt.patch @@ -0,0 +1,73 @@ +From: Steven Rostedt +Subject: rwlock: fix non PREEMPT_RT case + +Seems that the addition of RT_RW_READER broke the non PREEMPT_RT case. +This patch fixes it. + +Signed-off-by: Steven Rostedt +--- + kernel/rtmutex.c | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/rtmutex.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rtmutex.c 2008-10-08 22:24:53.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rtmutex.c 2008-10-08 22:24:57.000000000 -0400 +@@ -123,6 +123,12 @@ static inline void mark_rt_rwlock_check( + #endif /* CONFIG_PREEMPT_RT */ + #endif + ++#ifdef CONFIG_PREEMPT_RT ++#define task_is_reader(task) ((task) == RT_RW_READER) ++#else ++#define task_is_reader(task) (0) ++#endif ++ + int pi_initialized; + + /* +@@ -315,7 +321,7 @@ static int rt_mutex_adjust_prio_chain(st + /* + * Readers are special. We may need to boost more than one owner. + */ +- if (task == RT_RW_READER) { ++ if (task_is_reader(task)) { + ret = rt_mutex_adjust_readers(orig_lock, orig_waiter, + top_task, lock, + recursion_depth); +@@ -376,7 +382,7 @@ static inline int try_to_steal_lock(stru + if (pendowner == current) + return 1; + +- WARN_ON(rt_mutex_owner(lock) == RT_RW_READER); ++ WARN_ON(task_is_reader(rt_mutex_owner(lock))); + + spin_lock(&pendowner->pi_lock); + if (!lock_is_stealable(pendowner, mode)) { +@@ -506,7 +512,7 @@ static int task_blocks_on_rt_mutex(struc + + if (waiter == rt_mutex_top_waiter(lock)) { + /* readers are handled differently */ +- if (owner == RT_RW_READER) { ++ if (task_is_reader(owner)) { + res = rt_mutex_adjust_readers(lock, waiter, + current, lock, 0); + return res; +@@ -524,7 +530,7 @@ static int task_blocks_on_rt_mutex(struc + else if (debug_rt_mutex_detect_deadlock(waiter, detect_deadlock)) + chain_walk = 1; + +- if (!chain_walk || owner == RT_RW_READER) ++ if (!chain_walk || task_is_reader(owner)) + return 0; + + /* +@@ -624,7 +630,7 @@ static void remove_waiter(struct rt_mute + current->pi_blocked_on = NULL; + spin_unlock(¤t->pi_lock); + +- if (first && owner != current && owner != RT_RW_READER) { ++ if (first && owner != current && !task_is_reader(owner)) { + + spin_lock(&owner->pi_lock); + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0494-rwlock-torture.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0494-rwlock-torture.patch @@ -0,0 +1,834 @@ +From: Steven Rostedt +Subject: rwlock: rwlock torture test + +This patch adds an rwlock torture test that can be used to test rwlocks. +This may only be loaded as a module. Running this will severally bring +the system performance to an halt. + +Signed-off-by: Steven Rostedt +--- + kernel/Makefile | 1 + kernel/rwlock_torture.c | 781 ++++++++++++++++++++++++++++++++++++++++++++++++ + lib/Kconfig.debug | 11 + 3 files changed, 793 insertions(+) + +Index: linux-2.6.24.7-rt21/kernel/Makefile +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/Makefile 2008-10-08 22:24:56.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/Makefile 2008-10-08 22:25:02.000000000 -0400 +@@ -68,6 +68,7 @@ obj-$(CONFIG_SYSFS) += ksysfs.o + obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o + obj-$(CONFIG_GENERIC_HARDIRQS) += irq/ + obj-$(CONFIG_SECCOMP) += seccomp.o ++obj-$(CONFIG_RWLOCK_TORTURE_TEST) += rwlock_torture.o + obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o + obj-$(CONFIG_CLASSIC_RCU) += rcuclassic.o + obj-$(CONFIG_PREEMPT_RCU) += rcuclassic.o rcupreempt.o +Index: linux-2.6.24.7-rt21/kernel/rwlock_torture.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/kernel/rwlock_torture.c 2008-10-08 22:25:02.000000000 -0400 +@@ -0,0 +1,781 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "rtmutex_common.h" ++ ++#ifdef CONFIG_LOGDEV ++#include ++#else ++#define lfcnprint(x...) do { } while (0) ++#define lmark() do { } while(0) ++#define logdev_dump() do { } while (0) ++#endif ++ ++static DEFINE_RWLOCK(lock1); ++static DEFINE_RWLOCK(lock2); ++static DEFINE_RWLOCK(lock3); ++ ++static DECLARE_RWSEM(sem1); ++static DECLARE_RWSEM(sem2); ++static DECLARE_RWSEM(sem3); ++ ++static DEFINE_MUTEX(mutex1); ++static DEFINE_MUTEX(mutex2); ++static DEFINE_MUTEX(mutex3); ++ ++struct locks { ++ union { ++ struct rw_semaphore *sem; ++ rwlock_t *lock; ++ struct mutex *mutex; ++ }; ++ int type; ++ char *name; ++ int read_cnt; ++ int write_cnt; ++ int downgrade; ++ int taken; ++ int retaken; ++}; ++ ++enum { LOCK_TYPE_LOCK = 0, ++ LOCK_TYPE_SEM = 1, ++ LOCK_TYPE_MUTEX = 2 ++}; ++ ++static struct locks test_lock1 = { ++ { ++ .lock = &lock1, ++ }, ++ .type = LOCK_TYPE_LOCK, ++ .name = "lock1", ++}; ++ ++static struct locks test_lock2 = { ++ { ++ .lock = &lock2, ++ }, ++ .type = LOCK_TYPE_LOCK, ++ .name = "lock2", ++}; ++ ++static struct locks test_lock3 = { ++ { ++ .lock = &lock3, ++ }, ++ .type = LOCK_TYPE_LOCK, ++ .name = "lock3", ++}; ++ ++static struct locks test_sem1 = { ++ { ++ .sem = &sem1, ++ }, ++ .type = LOCK_TYPE_SEM, ++ .name = "sem1", ++}; ++ ++static struct locks test_sem2 = { ++ { ++ .sem = &sem2, ++ }, ++ .type = LOCK_TYPE_SEM, ++ .name = "sem2", ++}; ++ ++static struct locks test_sem3 = { ++ { ++ .sem = &sem3, ++ }, ++ .type = LOCK_TYPE_SEM, ++ .name = "sem3", ++}; ++ ++static struct locks test_mutex1 = { ++ { ++ .mutex = &mutex1, ++ }, ++ .type = LOCK_TYPE_MUTEX, ++ .name = "mutex1", ++}; ++ ++static struct locks test_mutex2 = { ++ { ++ .mutex = &mutex2, ++ }, ++ .type = LOCK_TYPE_MUTEX, ++ .name = "mutex2", ++}; ++ ++static struct locks test_mutex3 = { ++ { ++ .mutex = &mutex3, ++ }, ++ .type = LOCK_TYPE_MUTEX, ++ .name = "mutex3", ++}; ++ ++static int test_done; ++ ++#define TIME_MAX 20000 ++ ++#define DEFAULT_NR_THREADS 300 ++#define DEFAULT_NR_RT_THREADS 10 ++ ++/* times in usecs */ ++#define DEFAULT_SCHED_OTHER_TIME_US 1000 ++#define DEFAULT_SCHED_FIFO_TIME_US 200 ++ ++/* this is in millisecs */ ++#define DEFAULT_SCHED_FIFO_SLEEP_TIME 2 ++#define DEFAULT_SCHED_OTHER_SLEEP_TIME 1 ++ ++#define DEFAULT_RT_THREAD_PRIO 40 ++ ++#define NR_TESTS 3 ++static unsigned long sched_other_time_usecs = DEFAULT_SCHED_OTHER_TIME_US; ++static unsigned long sched_fifo_time_usecs = DEFAULT_SCHED_FIFO_TIME_US; ++static unsigned int sched_other_sleep_ms = DEFAULT_SCHED_OTHER_SLEEP_TIME; ++static unsigned int sched_fifo_sleep_ms = DEFAULT_SCHED_FIFO_SLEEP_TIME; ++ ++static unsigned long rt_thread_prio = DEFAULT_RT_THREAD_PRIO; ++static unsigned int thread_count = DEFAULT_NR_THREADS; ++static unsigned int rt_thread_count = DEFAULT_NR_RT_THREADS; ++static int test_time = 30; ++static struct task_struct **tsks; ++ ++static int perform_downgrade_write = 0; ++ ++enum { ++ LOCK_READ = 0, ++ LOCK_WRITE = 1, ++ SEM_READ = 2, ++ SEM_WRITE = 3, ++ MUTEX = 5 /* must be odd */ ++}; ++ ++#ifdef CONFIG_PREEMPT_RT ++static void show_rtm_owner(char *str, struct rt_mutex *rtm) ++{ ++ struct task_struct *owner; ++ unsigned long val; ++ char *name; ++ ++ rcu_read_lock(); ++ val = (unsigned long)rtm->owner; ++ owner = (struct task_struct *)(val & ~3UL); ++ name = "NULL"; ++ if (owner) { ++ if (owner == (struct task_struct *)0x100) ++ name = "READER"; ++ else ++ name = owner->comm; ++ } ++ printk("%s val: %lx owner: %s\n", str, val, name); ++ ++ rcu_read_unlock(); ++} ++ ++static void show_mutex_owner(char *str, struct mutex *mutex) ++{ ++ show_rtm_owner(str, &mutex->lock); ++} ++ ++static void show_rwm_owner(char *str, struct rw_mutex *rwm) ++{ ++ struct reader_lock_struct *rls; ++ struct task_struct *owner; ++ unsigned long val; ++ char *name; ++ ++ rcu_read_lock(); ++ val = (unsigned long)rwm->owner; ++ owner = (struct task_struct *)(val & ~3UL); ++ name = "NULL"; ++ if (owner) { ++ switch ((unsigned long)owner) { ++ case 0x100: ++ name = "READER"; ++ break; ++ case 0x200: ++ name = "PENDING READER"; ++ break; ++ case 0x400: ++ name = "PENDING WRITER"; ++ break; ++ default: ++ name = owner->comm; ++ } ++ } ++ printk("%s val: %lx owner: %s count %d owners %d ", str, val, name, ++ atomic_read(&rwm->count), ++ atomic_read(&rwm->owners)); ++ show_rtm_owner(" mutex: ", &rwm->mutex); ++ list_for_each_entry(rls, &rwm->readers, list) { ++ if (!rls->task) ++ printk("NULL TASK!!!\n"); ++ else ++ printk(" owned by: %s:%d\n", ++ rls->task->comm, rls->task->pid); ++ } ++ rcu_read_unlock(); ++} ++ ++static void show_rwlock_owner(char *str, rwlock_t *lock) ++{ ++ show_rwm_owner(str, &lock->owners); ++} ++ ++static void show_sem_owner(char *str, struct rw_semaphore *sem) ++{ ++ show_rwm_owner(str, &sem->owners); ++} ++ ++void print_owned_read_locks(struct task_struct *tsk) ++{ ++ int i; ++ ++ if (!tsk->reader_lock_count) ++ return; ++ ++ oops_in_progress++; ++ printk(" %s:%d owns:\n", tsk->comm, tsk->pid); ++ for (i = 0; i < tsk->reader_lock_count; i++) { ++ printk(" %p\n", tsk->owned_read_locks[i].lock); ++ } ++ oops_in_progress--; ++} ++ ++#else ++# define show_sem_owner(x...) do { } while (0) ++# define show_rwlock_owner(x...) do { } while (0) ++# define show_mutex_owner(x...) do { } while (0) ++#endif ++ ++static int do_read(int read) ++{ ++ unsigned long x; ++ int ret; ++ ++ x = random32(); ++ ++ /* rwlock can not schedule */ ++ if (!(read & ~1)) { ++ ret = LOCK_READ; ++ goto out; ++ } ++ ++ /* every other time pick a mutex */ ++ if (x & 0x1000) ++ return MUTEX; /* do mutex */ ++ ++ /* alternate between locks and semaphores */ ++ if (x & 0x10) ++ ret = LOCK_READ; ++ else ++ ret = SEM_READ; ++ ++ out: ++ /* Do write 1 in 16 times */ ++ return ret | !(x & 0xf); ++} ++ ++static struct locks * ++pick_lock(struct locks *lock, struct locks *sem, struct locks *mutex, int read) ++{ ++ switch (read) { ++ case LOCK_READ: ++ case LOCK_WRITE: ++ return lock; ++ case SEM_READ: ++ case SEM_WRITE: ++ return sem; ++ case MUTEX: ++ return mutex; ++ } ++ return NULL; ++} ++ ++static void do_lock(struct locks *lock, int read) ++{ ++ switch (read) { ++ case LOCK_READ: ++ if (unlikely(lock->type != LOCK_TYPE_LOCK)) { ++ printk("FAILED expected lock but got %d\n", ++ lock->type); ++ return; ++ } ++ lfcnprint("read lock %s %p count=%d owners=%d", ++ lock->name, lock, atomic_read(&lock->lock->owners.count), ++ atomic_read(&lock->lock->owners.owners)); ++ read_lock(lock->lock); ++ break; ++ case LOCK_WRITE: ++ if (unlikely(lock->type != LOCK_TYPE_LOCK)) { ++ printk("FAILED expected lock but got %d\n", ++ lock->type); ++ return; ++ } ++ lfcnprint("write lock %s %p", lock->name, lock); ++ write_lock(lock->lock); ++ break; ++ case SEM_READ: ++ if (unlikely(lock->type != LOCK_TYPE_SEM)) { ++ printk("FAILED expected sem but got %d\n", ++ lock->type); ++ return; ++ } ++ lfcnprint("read sem %s %p count=%d owners=%d", ++ lock->name, lock, ++ atomic_read(&lock->sem->owners.count), ++ atomic_read(&lock->sem->owners.owners)); ++ down_read(lock->sem); ++ break; ++ case SEM_WRITE: ++ if (unlikely(lock->type != LOCK_TYPE_SEM)) { ++ printk("FAILED expected sem but got %d\n", ++ lock->type); ++ return; ++ } ++ lfcnprint("write sem %s %p", lock->name, lock); ++ down_write(lock->sem); ++ break; ++ case MUTEX: ++ if (unlikely(lock->type != LOCK_TYPE_MUTEX)) { ++ printk("FAILED expected mutex but got %d\n", ++ lock->type); ++ return; ++ } ++ lfcnprint("mutex %s %p", lock->name, lock); ++ mutex_lock(lock->mutex); ++ break; ++ default: ++ printk("bad lock value %d!!!\n", read); ++ } ++ lfcnprint("taken %s %p", lock->name, lock); ++} ++ ++static void do_unlock(struct locks *lock, int read) ++{ ++ switch (read) { ++ case LOCK_READ: ++ if (unlikely(lock->type != LOCK_TYPE_LOCK)) { ++ printk("FAILED expected lock but got %d\n", ++ lock->type); ++ return; ++ } ++ lfcnprint("read lock %s %p count=%d owners=%d", ++ lock->name, lock, atomic_read(&lock->lock->owners.count), ++ atomic_read(&lock->lock->owners.owners)); ++ read_unlock(lock->lock); ++ break; ++ case LOCK_WRITE: ++ if (unlikely(lock->type != LOCK_TYPE_LOCK)) { ++ printk("FAILED expected lock but got %d\n", ++ lock->type); ++ return; ++ } ++ lfcnprint("write lock %s %p", lock->name, lock); ++ write_unlock(lock->lock); ++ break; ++ case SEM_READ: ++ if (unlikely(lock->type != LOCK_TYPE_SEM)) { ++ printk("FAILED expected sem but got %d\n", ++ lock->type); ++ return; ++ } ++ lfcnprint("read sem %s, %p count=%d owners=%d", ++ lock->name, lock, atomic_read(&lock->sem->owners.count), ++ atomic_read(&lock->sem->owners.owners)); ++ up_read(lock->sem); ++ break; ++ case SEM_WRITE: ++ if (unlikely(lock->type != LOCK_TYPE_SEM)) { ++ printk("FAILED expected sem but got %d\n", ++ lock->type); ++ return; ++ } ++ lfcnprint("write sem %s %p", lock->name, lock); ++ up_write(lock->sem); ++ break; ++ case MUTEX: ++ if (unlikely(lock->type != LOCK_TYPE_MUTEX)) { ++ printk("FAILED expected mutex but got %d\n", ++ lock->type); ++ return; ++ } ++ lfcnprint("mutex %s %p", lock->name, lock); ++ mutex_unlock(lock->mutex); ++ break; ++ default: ++ printk("bad lock value %d!!!\n", read); ++ } ++ lfcnprint("unlocked"); ++} ++ ++static void do_something(unsigned long time, int ignore) ++{ ++ lmark(); ++ if (test_done) ++ return; ++ if (time > TIME_MAX) ++ time = TIME_MAX; ++ udelay(time); ++} ++ ++static void do_downgrade(unsigned long time, struct locks *lock, int *read) ++{ ++ struct rw_semaphore *sem = lock->sem; ++ unsigned long x; ++ ++ if (!perform_downgrade_write) ++ return; ++ ++ if (test_done) ++ return; ++ ++ if (*read == SEM_WRITE) { ++ x = random32(); ++ ++ /* Do downgrade write 1 in 16 times of a write */ ++ if (!(x & 0xf)) { ++ lfcnprint("downgrade %p", sem); ++ lock->downgrade++; ++ downgrade_write(sem); ++ do_something(time, 0); ++ /* need to do unlock read */ ++ *read = SEM_READ; ++ } ++ } ++} ++ ++static void update_stats(int read, struct locks *lock) ++{ ++ switch (read) { ++ case LOCK_READ: ++ case SEM_READ: ++ lock->read_cnt++; ++ break; ++ case LOCK_WRITE: ++ case SEM_WRITE: ++ lock->write_cnt++; ++ break; ++ } ++ lock->taken++; ++} ++ ++#define MAX_DEPTH 10 ++ ++static void run_lock(void (*func)(unsigned long time, int read), ++ struct locks *lock, unsigned long time, int read, int depth); ++ ++static void do_again(void (*func)(unsigned long time, int read), ++ struct locks *lock, unsigned long time, int read, int depth) ++{ ++ unsigned long x; ++ ++ if (test_done) ++ return; ++ ++ /* If this was grabbed for read via rwlock, do again */ ++ if (likely(read != LOCK_READ) || depth >= MAX_DEPTH) ++ return; ++ ++ x = random32(); ++ if (x & 1) { ++ lfcnprint("read lock again"); ++ run_lock(func, lock, time, read, depth+1); ++ } ++} ++ ++static void run_lock(void (*func)(unsigned long time, int read), ++ struct locks *lock, unsigned long time, int read, int depth) ++{ ++ if (test_done) ++ return; ++ ++ update_stats(read, lock); ++ if (depth) ++ lock->retaken++; ++ do_lock(lock, read); ++ if (!test_done) { ++ func(time, do_read(read)); ++ do_again(func, lock, time, read, depth); ++ } ++ do_downgrade(time, lock, &read); ++ do_unlock(lock, read); ++ ++} ++ ++static void run_one_lock(unsigned long time, int read) ++{ ++ struct locks *lock; ++ ++ lmark(); ++ lock = pick_lock(&test_lock1, &test_sem1, &test_mutex1, read); ++ run_lock(do_something, lock, time, read, 0); ++} ++ ++static void run_two_locks(unsigned long time, int read) ++{ ++ struct locks *lock; ++ ++ lmark(); ++ lock = pick_lock(&test_lock2, &test_sem2, &test_mutex2, read); ++ run_lock(run_one_lock, lock, time, read, 0); ++} ++ ++static void run_three_locks(unsigned long time, int read) ++{ ++ struct locks *lock; ++ ++ lmark(); ++ lock = pick_lock(&test_lock3, &test_sem3, &test_mutex3, read); ++ run_lock(run_two_locks, lock, time, read, 0); ++} ++ ++static int run_test(unsigned long time) ++{ ++ unsigned long long start; ++ int read; ++ int ret; ++ ++ if (test_done) ++ return 0; ++ ++ start = random32(); ++ ++ read = do_read(MUTEX); ++ ++ switch (ret = (start & 3)) { ++ case 0: ++ run_one_lock(time, read); ++ break; ++ case 1: ++ run_two_locks(time, read); ++ break; ++ case 2: ++ run_three_locks(time, read); ++ break; ++ default: ++ ret = 1; ++ run_two_locks(time, read); ++ } ++ ++ WARN_ON_ONCE(current->reader_lock_count); ++ ++ return ret; ++} ++ ++static int rwlock_thread(void *arg) ++{ ++ long prio = (long)arg; ++ unsigned long time; ++ unsigned long run; ++ struct sched_param param; ++ ++ time = sched_fifo_time_usecs; ++ if (prio) { ++ param.sched_priority = prio; ++ sched_setscheduler(current, SCHED_FIFO, ¶m); ++ time = sched_fifo_time_usecs; ++ } ++ ++ while (!kthread_should_stop()) { ++ run = run_test(time); ++ ++ if (prio) ++ msleep(sched_fifo_sleep_ms); ++ else ++ msleep(sched_other_sleep_ms); ++ } ++ ++ return 0; ++} ++ ++static void print_lock_stat(struct locks *lock) ++{ ++ switch (lock->type) { ++ case LOCK_TYPE_LOCK: ++ case LOCK_TYPE_SEM: ++ printk("%8s taken for read: %9d\n", lock->name, lock->read_cnt); ++ printk("%8s taken for write: %8d\n", lock->name, lock->write_cnt); ++ if (lock->type == LOCK_TYPE_LOCK) { ++ printk("%8s retaken: %9d\n", ++ lock->name, lock->retaken); ++ } else if (perform_downgrade_write) { ++ printk("%8s downgraded: %9d\n", ++ lock->name, lock->downgrade); ++ } ++ } ++ printk("%8s taken: %8d\n\n", lock->name, lock->taken); ++} ++ ++static int __init mutex_stress_init(void) ++{ ++ long i; ++ ++ tsks = kmalloc(sizeof(*tsks) * (thread_count + rt_thread_count), GFP_KERNEL); ++ if (!tsks) { ++ printk("failed to allocate tasks\n"); ++ return -1; ++ } ++ ++ printk("create threads and run for %d seconds\n", test_time); ++ ++ for (i=0; i < thread_count; i++) ++ tsks[i] = kthread_run(rwlock_thread, NULL, "mtest%d", i); ++ for (i=0; i < rt_thread_count; i++) { ++ long prio = rt_thread_prio + i; ++ tsks[thread_count + i] = ++ kthread_run(rwlock_thread, (void*)prio, ++ "mtest%d", thread_count + i); ++ } ++ ++ ++ set_current_state(TASK_INTERRUPTIBLE); ++ schedule_timeout(test_time * HZ); ++ ++ printk("kill threads\n"); ++ test_done = 1; ++ ++ set_current_state(TASK_INTERRUPTIBLE); ++ /* sleep some to allow all tasks to finish */ ++ schedule_timeout(3 * HZ); ++ ++ lfcnprint("Done"); ++ ++ show_rwlock_owner("lock1: ", &lock1); ++ show_rwlock_owner("lock2: ", &lock2); ++ show_rwlock_owner("lock3: ", &lock3); ++ ++ show_sem_owner("sem1: ", &sem1); ++ show_sem_owner("sem2: ", &sem2); ++ show_sem_owner("sem3: ", &sem3); ++ ++ show_mutex_owner("mutex1: ", &mutex1); ++ show_mutex_owner("mutex2: ", &mutex2); ++ show_mutex_owner("mutex3: ", &mutex3); ++ ++ oops_in_progress++; ++// logdev_dump(); ++ oops_in_progress--; ++ ++#ifdef CONFIG_PREEMPT_RT ++ for (i=0; i < (thread_count + rt_thread_count); i++) { ++ if (tsks[i]) { ++ struct rt_mutex *mtx; ++ unsigned long own; ++ struct rt_mutex_waiter *w; ++ ++ spin_lock_irq(&tsks[i]->pi_lock); ++ ++ print_owned_read_locks(tsks[i]); ++ ++ if (tsks[i]->pi_blocked_on) { ++ w = (void *)tsks[i]->pi_blocked_on; ++ mtx = w->lock; ++ spin_unlock_irq(&tsks[i]->pi_lock); ++ spin_lock_irq(&mtx->wait_lock); ++ spin_lock(&tsks[i]->pi_lock); ++ own = (unsigned long)mtx->owner & ~3UL; ++ oops_in_progress++; ++ printk("%s:%d is blocked on ", ++ tsks[i]->comm, tsks[i]->pid); ++ __print_symbol("%s", (unsigned long)mtx); ++ if (own == 0x100) ++ printk(" owner is READER\n"); ++ else if (!(own & ~300)) ++ printk(" owner is ILLEGAL!!\n"); ++ else if (!own) ++ printk(" has no owner!\n"); ++ else { ++ struct task_struct *owner = (void*)own; ++ ++ printk(" owner is %s:%d\n", ++ owner->comm, owner->pid); ++ } ++ oops_in_progress--; ++ ++ spin_unlock(&tsks[i]->pi_lock); ++ spin_unlock_irq(&mtx->wait_lock); ++ } else { ++ print_owned_read_locks(tsks[i]); ++ spin_unlock_irq(&tsks[i]->pi_lock); ++ } ++ } ++ } ++#endif ++ for (i=0; i < (thread_count + rt_thread_count); i++) { ++ if (tsks[i]) ++ kthread_stop(tsks[i]); ++ } ++ ++ print_lock_stat(&test_lock1); ++ print_lock_stat(&test_lock2); ++ print_lock_stat(&test_lock3); ++ print_lock_stat(&test_sem1); ++ print_lock_stat(&test_sem2); ++ print_lock_stat(&test_sem3); ++ print_lock_stat(&test_mutex1); ++ print_lock_stat(&test_mutex2); ++ print_lock_stat(&test_mutex3); ++ ++ if (!perform_downgrade_write) { ++ printk("No downgrade writes performed.\n" ++ " To enable it, pass in perform_downgrade_write=1 to the module\n"); ++ } ++ ++ return 0; ++} ++ ++static void mutex_stress_exit(void) ++{ ++} ++ ++module_init(mutex_stress_init); ++module_exit(mutex_stress_exit); ++ ++module_param(perform_downgrade_write, int, 0644); ++MODULE_PARM_DESC(perform_downgrade_write, ++ "Perform downgrade_write in the test"); ++ ++module_param(sched_other_time_usecs, ulong, 0644); ++MODULE_PARM_DESC(sched_other_time_usecs, ++ "Number of usecs to \"do something\""); ++ ++module_param(sched_fifo_time_usecs, ulong, 0644); ++MODULE_PARM_DESC(sched_fifo_time_usecs, ++ "Number of usecs for rt tasks to \"do something\""); ++ ++module_param(sched_other_sleep_ms, uint, 0644); ++MODULE_PARM_DESC(sched_other_sleep_ms, ++ "Number of usecs for tasks to sleep"); ++ ++module_param(sched_fifo_sleep_ms, uint, 0644); ++MODULE_PARM_DESC(sched_fifo_sleep_ms, ++ "Number of usecs for rt tasks to sleep"); ++ ++module_param(rt_thread_prio, long, 0644); ++MODULE_PARM_DESC(rt_thread_prio, "priority if FIFO tasks"); ++ ++module_param(thread_count, uint, 0644); ++MODULE_PARM_DESC(thread_count, "Number of threads to run"); ++ ++module_param(rt_thread_count, uint, 0644); ++MODULE_PARM_DESC(rt_thread_count, "Number of RT threads to run"); ++ ++module_param(test_time, uint, 0644); ++MODULE_PARM_DESC(test_time, "Number of seconds to run the test"); ++ ++MODULE_AUTHOR("Steven Rostedt"); ++MODULE_DESCRIPTION("Mutex Stress"); ++MODULE_LICENSE("GPL"); +Index: linux-2.6.24.7-rt21/lib/Kconfig.debug +=================================================================== +--- linux-2.6.24.7-rt21.orig/lib/Kconfig.debug 2008-10-08 22:23:59.000000000 -0400 ++++ linux-2.6.24.7-rt21/lib/Kconfig.debug 2008-10-08 22:25:02.000000000 -0400 +@@ -229,6 +229,17 @@ config DEBUG_SEMAPHORE + verbose debugging messages. If you suspect a semaphore problem or a + kernel hacker asks for this option then say Y. Otherwise say N. + ++config RWLOCK_TORTURE_TEST ++ tristate "torture tests for Priority Inheritance RW locks" ++ depends on DEBUG_KERNEL ++ depends on m ++ default n ++ help ++ This option provides a kernel modules that runs a torture test ++ of several threads that try to grab mutexes, rwlocks and rwsems. ++ ++ Say N if you are unsure. ++ + config DEBUG_LOCK_ALLOC + bool "Lock debugging: detect incorrect freeing of live locks" + depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0331-RT_utsname.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0331-RT_utsname.patch @@ -0,0 +1,37 @@ +--- + init/Makefile | 2 +- + scripts/mkcompile_h | 4 +++- + 2 files changed, 4 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/init/Makefile +=================================================================== +--- linux-2.6.24.7-rt21.orig/init/Makefile 2008-10-08 22:22:22.000000000 -0400 ++++ linux-2.6.24.7-rt21/init/Makefile 2008-10-08 22:24:23.000000000 -0400 +@@ -30,4 +30,4 @@ $(obj)/version.o: include/linux/compile. + include/linux/compile.h: FORCE + @echo ' CHK $@' + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkcompile_h $@ \ +- "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT)" "$(CC) $(KBUILD_CFLAGS)" ++ "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT)" "$(CONFIG_PREEMPT_RT)" "$(CC) $(KBUILD_CFLAGS)" +Index: linux-2.6.24.7-rt21/scripts/mkcompile_h +=================================================================== +--- linux-2.6.24.7-rt21.orig/scripts/mkcompile_h 2008-10-08 22:22:22.000000000 -0400 ++++ linux-2.6.24.7-rt21/scripts/mkcompile_h 2008-10-08 22:24:23.000000000 -0400 +@@ -2,7 +2,8 @@ TARGET=$1 + ARCH=$2 + SMP=$3 + PREEMPT=$4 +-CC=$5 ++PREEMPT_RT=$5 ++CC=$6 + + # If compile.h exists already and we don't own autoconf.h + # (i.e. we're not the same user who did make *config), don't +@@ -43,6 +44,7 @@ UTS_VERSION="#$VERSION" + CONFIG_FLAGS="" + if [ -n "$SMP" ] ; then CONFIG_FLAGS="SMP"; fi + if [ -n "$PREEMPT" ] ; then CONFIG_FLAGS="$CONFIG_FLAGS PREEMPT"; fi ++if [ -n "$PREEMPT_RT" ] ; then CONFIG_FLAGS="$CONFIG_FLAGS RT"; fi + UTS_VERSION="$UTS_VERSION $CONFIG_FLAGS $TIMESTAMP" + + # Truncate to maximum length --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0500-rwlock-pi-lock-reader.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0500-rwlock-pi-lock-reader.patch @@ -0,0 +1,105 @@ +From: Steven Rostedt +Subject: rwlock: pi_lock fixes + +When waking up multiple readers we need to hold the pi_lock to +modify the pending lists. This patch also localizes the locks a bit more. + +Signed-off-by: Steven Rostedt +--- + kernel/rtmutex.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/rtmutex.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rtmutex.c 2008-10-08 22:25:02.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rtmutex.c 2008-10-08 22:25:04.000000000 -0400 +@@ -1918,7 +1918,6 @@ rt_write_slowunlock(struct rw_mutex *rwm + if (!rt_mutex_has_waiters(mutex)) + goto out; + +- spin_lock(&pendowner->pi_lock); + /* + * Wake up all readers. + * This gets a bit more complex. More than one reader can't +@@ -1933,13 +1932,17 @@ rt_write_slowunlock(struct rw_mutex *rwm + while (waiter && !waiter->write_lock) { + struct task_struct *reader = waiter->task; + ++ spin_lock(&pendowner->pi_lock); + plist_del(&waiter->list_entry, &mutex->wait_list); + + /* nop if not on a list */ + plist_del(&waiter->pi_list_entry, &pendowner->pi_waiters); ++ spin_unlock(&pendowner->pi_lock); + ++ spin_lock(&reader->pi_lock); + waiter->task = NULL; + reader->pi_blocked_on = NULL; ++ spin_unlock(&reader->pi_lock); + + if (savestate) + wake_up_process_mutex(reader); +@@ -1957,6 +1960,8 @@ rt_write_slowunlock(struct rw_mutex *rwm + struct rt_mutex_waiter *next; + + next = rt_mutex_top_waiter(mutex); ++ ++ spin_lock(&pendowner->pi_lock); + /* delete incase we didn't go through the loop */ + plist_del(&next->pi_list_entry, &pendowner->pi_waiters); + +@@ -1964,13 +1969,12 @@ rt_write_slowunlock(struct rw_mutex *rwm + if (next->write_lock) + /* add back in as top waiter */ + plist_add(&next->pi_list_entry, &pendowner->pi_waiters); ++ spin_unlock(&pendowner->pi_lock); + + rwm->prio = next->task->prio; + } else + rwm->prio = MAX_PRIO; + +- spin_unlock(&pendowner->pi_lock); +- + out: + + spin_unlock_irqrestore(&mutex->wait_lock, flags); +@@ -2052,18 +2056,21 @@ rt_mutex_downgrade_write(struct rw_mutex + * waiting, until we hit the reader limit, or a writer. + */ + +- spin_lock(¤t->pi_lock); + waiter = rt_mutex_top_waiter(mutex); + while (waiter && !waiter->write_lock) { + struct task_struct *reader = waiter->task; + ++ spin_lock(¤t->pi_lock); + plist_del(&waiter->list_entry, &mutex->wait_list); + + /* nop if not on a list */ + plist_del(&waiter->pi_list_entry, ¤t->pi_waiters); ++ spin_unlock(¤t->pi_lock); + ++ spin_lock(&reader->pi_lock); + waiter->task = NULL; + reader->pi_blocked_on = NULL; ++ spin_unlock(&reader->pi_lock); + + /* downgrade is only for mutexes */ + wake_up_process(reader); +@@ -2083,14 +2090,14 @@ rt_mutex_downgrade_write(struct rw_mutex + /* setup this mutex prio for read */ + rwm->prio = next->task->prio; + ++ spin_lock(¤t->pi_lock); + /* delete incase we didn't go through the loop */ + plist_del(&next->pi_list_entry, ¤t->pi_waiters); ++ spin_unlock(¤t->pi_lock); + /* No need to add back since readers don't have PI waiters */ + } else + rwm->prio = MAX_PRIO; + +- spin_unlock(¤t->pi_lock); +- + rt_mutex_set_owner(mutex, RT_RW_READER, 0); + + spin_unlock_irqrestore(&mutex->wait_lock, flags); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0315-x86-64-tscless-vgettimeofday.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0315-x86-64-tscless-vgettimeofday.patch @@ -0,0 +1,44 @@ +Subject: [patch] x86_64 GTOD: offer scalable vgettimeofday +From: Ingo Molnar + +offer scalable vgettimeofday independently of whether the TSC +is synchronous or not. Off by default. + +this patch also fixes an SMP bug in sys_vtime(): we should read +__vsyscall_gtod_data.wall_time_tv.tv_sec only once. + +Signed-off-by: Ingo Molnar +--- + arch/x86/kernel/vsyscall_64.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/vsyscall_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/vsyscall_64.c 2008-10-08 22:23:40.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/vsyscall_64.c 2008-10-08 22:24:19.000000000 -0400 +@@ -119,6 +119,25 @@ static __always_inline void do_vgettimeo + unsigned seq; + unsigned long mult, shift, nsec; + cycle_t (*vread)(void); ++ ++ if (likely(__vsyscall_gtod_data.sysctl_enabled == 2)) { ++ struct timeval tmp; ++ ++ do { ++ barrier(); ++ tv->tv_sec = __vsyscall_gtod_data.wall_time_sec; ++ tv->tv_usec = __vsyscall_gtod_data.wall_time_nsec; ++ barrier(); ++ tmp.tv_sec = __vsyscall_gtod_data.wall_time_sec; ++ tmp.tv_usec = __vsyscall_gtod_data.wall_time_nsec; ++ ++ } while (tmp.tv_usec != tv->tv_usec || ++ tmp.tv_sec != tv->tv_sec); ++ ++ tv->tv_usec /= NSEC_PER_USEC; ++ return; ++ } ++ + do { + seq = read_seqbegin(&__vsyscall_gtod_data.lock); + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0144-preempt-irqs-hrtimer.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0144-preempt-irqs-hrtimer.patch @@ -0,0 +1,148 @@ + include/linux/hrtimer.h | 10 ++++++++++ + kernel/hrtimer.c | 35 ++++++++++++++++++++++++++++++++++- + kernel/itimer.c | 1 + + kernel/posix-timers.c | 3 +++ + 4 files changed, 48 insertions(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/include/linux/hrtimer.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/hrtimer.h 2008-10-08 22:23:19.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/hrtimer.h 2008-10-08 22:23:31.000000000 -0400 +@@ -200,6 +200,9 @@ struct hrtimer_cpu_base { + struct list_head cb_pending; + unsigned long nr_events; + #endif ++#ifdef CONFIG_PREEMPT_SOFTIRQS ++ wait_queue_head_t wait; ++#endif + }; + + #ifdef CONFIG_HIGH_RES_TIMERS +@@ -270,6 +273,13 @@ static inline int hrtimer_restart(struct + return hrtimer_start(timer, timer->expires, HRTIMER_MODE_ABS); + } + ++/* Softirq preemption could deadlock timer removal */ ++#ifdef CONFIG_PREEMPT_SOFTIRQS ++ extern void hrtimer_wait_for_timer(const struct hrtimer *timer); ++#else ++# define hrtimer_wait_for_timer(timer) do { cpu_relax(); } while (0) ++#endif ++ + /* Query timers: */ + extern ktime_t hrtimer_get_remaining(const struct hrtimer *timer); + extern int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp); +Index: linux-2.6.24.7-rt21/kernel/hrtimer.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/hrtimer.c 2008-10-08 22:23:19.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/hrtimer.c 2008-10-08 22:23:31.000000000 -0400 +@@ -989,7 +989,7 @@ int hrtimer_cancel(struct hrtimer *timer + + if (ret >= 0) + return ret; +- cpu_relax(); ++ hrtimer_wait_for_timer(timer); + } + } + EXPORT_SYMBOL_GPL(hrtimer_cancel); +@@ -1100,6 +1100,32 @@ int hrtimer_get_res(const clockid_t whic + } + EXPORT_SYMBOL_GPL(hrtimer_get_res); + ++#ifdef CONFIG_PREEMPT_SOFTIRQS ++# define wake_up_timer_waiters(b) wake_up(&(b)->wait) ++ ++/** ++ * hrtimer_wait_for_timer - Wait for a running timer ++ * ++ * @timer: timer to wait for ++ * ++ * The function waits in case the timers callback function is ++ * currently executed on the waitqueue of the timer base. The ++ * waitqueue is woken up after the timer callback function has ++ * finished execution. ++ */ ++void hrtimer_wait_for_timer(const struct hrtimer *timer) ++{ ++ struct hrtimer_clock_base *base = timer->base; ++ ++ if (base && base->cpu_base) ++ wait_event(base->cpu_base->wait, ++ !(timer->state & HRTIMER_STATE_CALLBACK)); ++} ++ ++#else ++# define wake_up_timer_waiters(b) do { } while (0) ++#endif ++ + #ifdef CONFIG_HIGH_RES_TIMERS + + /* +@@ -1246,6 +1272,8 @@ static void run_hrtimer_softirq(struct s + } + } + spin_unlock_irq(&cpu_base->lock); ++ ++ wake_up_timer_waiters(cpu_base); + } + + #endif /* CONFIG_HIGH_RES_TIMERS */ +@@ -1296,6 +1324,8 @@ static inline void run_hrtimer_queue(str + } + } + spin_unlock_irq(&cpu_base->lock); ++ ++ wake_up_timer_waiters(cpu_base); + } + + /* +@@ -1477,6 +1507,9 @@ static void __cpuinit init_hrtimers_cpu( + cpu_base->clock_base[i].cpu_base = cpu_base; + + hrtimer_init_hres(cpu_base); ++#ifdef CONFIG_PREEMPT_SOFTIRQS ++ init_waitqueue_head(&cpu_base->wait); ++#endif + } + + #ifdef CONFIG_HOTPLUG_CPU +Index: linux-2.6.24.7-rt21/kernel/itimer.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/itimer.c 2008-10-08 22:22:38.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/itimer.c 2008-10-08 22:23:31.000000000 -0400 +@@ -170,6 +170,7 @@ again: + /* We are sharing ->siglock with it_real_fn() */ + if (hrtimer_try_to_cancel(timer) < 0) { + spin_unlock_irq(&tsk->sighand->siglock); ++ hrtimer_wait_for_timer(&tsk->signal->real_timer); + goto again; + } + expires = timeval_to_ktime(value->it_value); +Index: linux-2.6.24.7-rt21/kernel/posix-timers.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/posix-timers.c 2008-10-08 22:22:38.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/posix-timers.c 2008-10-08 22:23:31.000000000 -0400 +@@ -809,6 +809,7 @@ retry: + + unlock_timer(timr, flag); + if (error == TIMER_RETRY) { ++ hrtimer_wait_for_timer(&timr->it.real.timer); + rtn = NULL; // We already got the old time... + goto retry; + } +@@ -848,6 +849,7 @@ retry_delete: + + if (timer_delete_hook(timer) == TIMER_RETRY) { + unlock_timer(timer, flags); ++ hrtimer_wait_for_timer(&timer->it.real.timer); + goto retry_delete; + } + +@@ -880,6 +882,7 @@ retry_delete: + + if (timer_delete_hook(timer) == TIMER_RETRY) { + unlock_timer(timer, flags); ++ hrtimer_wait_for_timer(&timer->it.real.timer); + goto retry_delete; + } + list_del(&timer->list); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0543-futex-trivial-fix.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0543-futex-trivial-fix.patch @@ -0,0 +1,50 @@ +From ankita@in.ibm.com Wed Sep 10 02:10:05 2008 +Date: Wed, 10 Sep 2008 11:36:24 +0530 +From: Ankita Garg +To: Steven Rostedt +Cc: LKML , RT , Ingo Molnar , Thomas Gleixner +Subject: Re: 2.6.24.7-rt18 + +Hi Steven, + +On Tue, Sep 09, 2008 at 11:44:42PM -0400, Steven Rostedt wrote: +> We are pleased to announce the 2.6.24.7-rt18 tree, which can be +> downloaded from the location: +> +> http://rt.et.redhat.com/download/ +> +> Information on the RT patch can be found at: +> +> http://rt.wiki.kernel.org/index.php/Main_Page +> +> Changes since 2.6.24.7-rt17 +> +> - seqlock serialize writes (Gregory Haskins) +> +> - Fix above patch that broke non PREEMPT_RT (Steven Rostedt) +> +> - Add sysctl to warn on RT task using non PI futex (Steven Rostedt) +> + +A trivial patch to remove the hard coded value of MAX_RT_PRIO in the +above patch. + +Signed-off-by: Ankita Garg + +--- + kernel/futex.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/kernel/futex.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/futex.c 2008-10-08 22:25:14.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/futex.c 2008-10-08 22:25:14.000000000 -0400 +@@ -1250,7 +1250,7 @@ static int futex_wait(u32 __user *uaddr, + "RT task %s:%d with priority %d" + " using non PI futex\n", + current->comm, current->pid, +- 100 - current->prio); ++ MAX_RT_PRIO - current->prio); + } + } + /* --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0145-preempt-irqs-i386.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0145-preempt-irqs-i386.patch @@ -0,0 +1,148 @@ +--- + arch/x86/kernel/i8259_32.c | 9 ++++++--- + arch/x86/kernel/io_apic_32.c | 20 +++++--------------- + arch/x86/mach-default/setup.c | 3 ++- + arch/x86/mach-visws/visws_apic.c | 2 ++ + arch/x86/mach-voyager/setup.c | 3 ++- + 5 files changed, 17 insertions(+), 20 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/i8259_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/i8259_32.c 2008-10-08 22:22:38.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/i8259_32.c 2008-10-08 22:23:31.000000000 -0400 +@@ -169,6 +169,8 @@ static void mask_and_ack_8259A(unsigned + */ + if (cached_irq_mask & irqmask) + goto spurious_8259A_irq; ++ if (irq & 8) ++ outb(0x60+(irq&7),PIC_SLAVE_CMD); /* 'Specific EOI' to slave */ + cached_irq_mask |= irqmask; + + handle_real_irq: +@@ -296,10 +298,10 @@ void init_8259A(int auto_eoi) + outb_p(0x11, PIC_MASTER_CMD); /* ICW1: select 8259A-1 init */ + outb_p(0x20 + 0, PIC_MASTER_IMR); /* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */ + outb_p(1U << PIC_CASCADE_IR, PIC_MASTER_IMR); /* 8259A-1 (the master) has a slave on IR2 */ +- if (auto_eoi) /* master does Auto EOI */ +- outb_p(MASTER_ICW4_DEFAULT | PIC_ICW4_AEOI, PIC_MASTER_IMR); +- else /* master expects normal EOI */ ++ if (!auto_eoi) /* master expects normal EOI */ + outb_p(MASTER_ICW4_DEFAULT, PIC_MASTER_IMR); ++ else /* master does Auto EOI */ ++ outb_p(MASTER_ICW4_DEFAULT | PIC_ICW4_AEOI, PIC_MASTER_IMR); + + outb_p(0x11, PIC_SLAVE_CMD); /* ICW1: select 8259A-2 init */ + outb_p(0x20 + 8, PIC_SLAVE_IMR); /* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */ +@@ -351,6 +353,7 @@ static irqreturn_t math_error_irq(int cp + */ + static struct irqaction fpu_irq = { + .handler = math_error_irq, ++ .flags = IRQF_NODELAY, + .mask = CPU_MASK_NONE, + .name = "fpu", + }; +Index: linux-2.6.24.7-rt21/arch/x86/kernel/io_apic_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/io_apic_32.c 2008-10-08 22:23:20.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/io_apic_32.c 2008-10-08 22:23:31.000000000 -0400 +@@ -261,18 +261,6 @@ static void __unmask_IO_APIC_irq (unsign + __modify_IO_APIC_irq(irq, 0, 0x00010000); + } + +-/* mask = 1, trigger = 0 */ +-static void __mask_and_edge_IO_APIC_irq (unsigned int irq) +-{ +- __modify_IO_APIC_irq(irq, 0x00010000, 0x00008000); +-} +- +-/* mask = 0, trigger = 1 */ +-static void __unmask_and_level_IO_APIC_irq (unsigned int irq) +-{ +- __modify_IO_APIC_irq(irq, 0x00008000, 0x00010000); +-} +- + static void mask_IO_APIC_irq (unsigned int irq) + { + unsigned long flags; +@@ -1493,7 +1481,7 @@ void __init print_IO_APIC(void) + return; + } + +-#if 0 ++#if 1 + + static void print_APIC_bitfield (int base) + { +@@ -1989,8 +1977,10 @@ static void ack_ioapic_quirk_irq(unsigne + if (!(v & (1 << (i & 0x1f)))) { + atomic_inc(&irq_mis_count); + spin_lock(&ioapic_lock); +- __mask_and_edge_IO_APIC_irq(irq); +- __unmask_and_level_IO_APIC_irq(irq); ++ /* mask = 1, trigger = 0 */ ++ __modify_IO_APIC_irq(irq, 0x00010000, 0x00008000); ++ /* mask = 0, trigger = 1 */ ++ __modify_IO_APIC_irq(irq, 0x00008000, 0x00010000); + spin_unlock(&ioapic_lock); + } + } +Index: linux-2.6.24.7-rt21/arch/x86/mach-default/setup.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/mach-default/setup.c 2008-10-08 22:22:38.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/mach-default/setup.c 2008-10-08 22:23:31.000000000 -0400 +@@ -37,6 +37,7 @@ void __init pre_intr_init_hook(void) + */ + static struct irqaction irq2 = { + .handler = no_action, ++ .flags = IRQF_NODELAY, + .mask = CPU_MASK_NONE, + .name = "cascade", + }; +@@ -85,7 +86,7 @@ void __init trap_init_hook(void) + + static struct irqaction irq0 = { + .handler = timer_interrupt, +- .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL, ++ .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_NODELAY, + .mask = CPU_MASK_NONE, + .name = "timer" + }; +Index: linux-2.6.24.7-rt21/arch/x86/mach-visws/visws_apic.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/mach-visws/visws_apic.c 2008-10-08 22:22:38.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/mach-visws/visws_apic.c 2008-10-08 22:23:31.000000000 -0400 +@@ -257,11 +257,13 @@ out_unlock: + static struct irqaction master_action = { + .handler = piix4_master_intr, + .name = "PIIX4-8259", ++ .flags = IRQF_NODELAY, + }; + + static struct irqaction cascade_action = { + .handler = no_action, + .name = "cascade", ++ .flags = IRQF_NODELAY, + }; + + +Index: linux-2.6.24.7-rt21/arch/x86/mach-voyager/setup.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/mach-voyager/setup.c 2008-10-08 22:22:38.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/mach-voyager/setup.c 2008-10-08 22:23:31.000000000 -0400 +@@ -20,6 +20,7 @@ void __init pre_intr_init_hook(void) + */ + static struct irqaction irq2 = { + .handler = no_action, ++ .flags = IRQF_NODELAY, + .mask = CPU_MASK_NONE, + .name = "cascade", + }; +@@ -46,7 +47,7 @@ void __init trap_init_hook(void) + + static struct irqaction irq0 = { + .handler = timer_interrupt, +- .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL, ++ .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_NODELAY, + .mask = CPU_MASK_NONE, + .name = "timer" + }; --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0274-nmi-watchdog-disable.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0274-nmi-watchdog-disable.patch @@ -0,0 +1,97 @@ +Subject: [patch] x86_64: do not enable the NMI watchdog by default +From: Ingo Molnar + +do not enable the NMI watchdog by default. Now that we have +lockdep i cannot remember the last time it caught a real bug, +but the NMI watchdog can /cause/ problems. Furthermore, to the +typical user, an NMI watchdog assert results in a total lockup +anyway (if under X). In that sense, all that the NMI watchdog +does is that it makes the system /less/ stable and /less/ +debuggable. + +people can still enable it either after bootup via: + + echo 1 > /proc/sys/kernel/nmi + +or via the nmi_watchdog=1 or nmi_watchdog=2 boot options. + +build and boot tested on an Athlon64 box. + +Signed-off-by: Ingo Molnar +--- + arch/x86/kernel/apic_64.c | 1 - + arch/x86/kernel/io_apic_64.c | 2 -- + arch/x86/kernel/nmi_64.c | 2 +- + arch/x86/kernel/smpboot_64.c | 1 - + include/asm-x86/nmi_64.h | 1 - + 5 files changed, 1 insertion(+), 6 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/apic_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/apic_64.c 2008-10-08 22:22:26.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/apic_64.c 2008-10-08 22:24:09.000000000 -0400 +@@ -535,7 +535,6 @@ void __cpuinit setup_local_APIC (void) + oldvalue, value); + } + +- nmi_watchdog_default(); + setup_apic_nmi_watchdog(NULL); + apic_pm_activate(); + } +Index: linux-2.6.24.7-rt21/arch/x86/kernel/io_apic_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/io_apic_64.c 2008-10-08 22:23:51.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/io_apic_64.c 2008-10-08 22:24:09.000000000 -0400 +@@ -1732,7 +1732,6 @@ static inline void __init check_timer(vo + */ + unmask_IO_APIC_irq(0); + if (!no_timer_check && timer_irq_works()) { +- nmi_watchdog_default(); + if (nmi_watchdog == NMI_IO_APIC) { + disable_8259A_irq(0); + setup_nmi(); +@@ -1758,7 +1757,6 @@ static inline void __init check_timer(vo + setup_ExtINT_IRQ0_pin(apic2, pin2, cfg->vector); + if (timer_irq_works()) { + apic_printk(APIC_VERBOSE," works.\n"); +- nmi_watchdog_default(); + if (nmi_watchdog == NMI_IO_APIC) { + setup_nmi(); + } +Index: linux-2.6.24.7-rt21/arch/x86/kernel/nmi_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/nmi_64.c 2008-10-08 22:24:08.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/nmi_64.c 2008-10-08 22:24:09.000000000 -0400 +@@ -52,7 +52,7 @@ static DEFINE_PER_CPU(short, wd_enabled) + static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu); + + /* Run after command line and cpu_init init, but before all other checks */ +-void nmi_watchdog_default(void) ++static inline void nmi_watchdog_default(void) + { + if (nmi_watchdog != NMI_DEFAULT) + return; +Index: linux-2.6.24.7-rt21/arch/x86/kernel/smpboot_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/smpboot_64.c 2008-10-08 22:22:26.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/smpboot_64.c 2008-10-08 22:24:09.000000000 -0400 +@@ -867,7 +867,6 @@ void __init smp_set_apicids(void) + */ + void __init smp_prepare_cpus(unsigned int max_cpus) + { +- nmi_watchdog_default(); + current_cpu_data = boot_cpu_data; + current_thread_info()->cpu = 0; /* needed? */ + smp_set_apicids(); +Index: linux-2.6.24.7-rt21/include/asm-x86/nmi_64.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/nmi_64.h 2008-10-08 22:22:26.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/nmi_64.h 2008-10-08 22:24:09.000000000 -0400 +@@ -59,7 +59,6 @@ extern void disable_timer_nmi_watchdog(v + extern void enable_timer_nmi_watchdog(void); + extern int nmi_watchdog_tick (struct pt_regs * regs, unsigned reason); + +-extern void nmi_watchdog_default(void); + extern int setup_nmi_watchdog(char *); + + extern atomic_t nmi_active; --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0030-0014-sched-optimize-RT-affinity.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0030-0014-sched-optimize-RT-affinity.patch @@ -0,0 +1,152 @@ +From ed30a37a14cdeac811d99baaa8039ecad9527ace Mon Sep 17 00:00:00 2001 +From: Gregory Haskins +Date: Tue, 11 Dec 2007 10:02:38 +0100 +Subject: [PATCH] sched: optimize RT affinity + +The current code base assumes a relatively flat CPU/core topology and will +route RT tasks to any CPU fairly equally. In the real world, there are +various toplogies and affinities that govern where a task is best suited to +run with the smallest amount of overhead. NUMA and multi-core CPUs are +prime examples of topologies that can impact cache performance. + +Fortunately, linux is already structured to represent these topologies via +the sched_domains interface. So we change our RT router to consult a +combination of topology and affinity policy to best place tasks during +migration. + +Signed-off-by: Gregory Haskins +Signed-off-by: Steven Rostedt +Signed-off-by: Ingo Molnar + +--- + kernel/sched_rt.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 88 insertions(+), 12 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/sched_rt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched_rt.c 2008-10-08 22:22:59.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched_rt.c 2008-10-08 22:22:59.000000000 -0400 +@@ -277,35 +277,111 @@ static struct task_struct *pick_next_hig + } + + static DEFINE_PER_CPU(cpumask_t, local_cpu_mask); ++static DEFINE_PER_CPU(cpumask_t, valid_cpu_mask); + +-static int find_lowest_rq(struct task_struct *task) ++static int find_lowest_cpus(struct task_struct *task, cpumask_t *lowest_mask) + { +- int cpu; +- cpumask_t *cpu_mask = &__get_cpu_var(local_cpu_mask); +- struct rq *lowest_rq = NULL; ++ int cpu; ++ cpumask_t *valid_mask = &__get_cpu_var(valid_cpu_mask); ++ int lowest_prio = -1; ++ int ret = 0; + +- cpus_and(*cpu_mask, cpu_online_map, task->cpus_allowed); ++ cpus_clear(*lowest_mask); ++ cpus_and(*valid_mask, cpu_online_map, task->cpus_allowed); + + /* + * Scan each rq for the lowest prio. + */ +- for_each_cpu_mask(cpu, *cpu_mask) { ++ for_each_cpu_mask(cpu, *valid_mask) { + struct rq *rq = cpu_rq(cpu); + + /* We look for lowest RT prio or non-rt CPU */ + if (rq->rt.highest_prio >= MAX_RT_PRIO) { +- lowest_rq = rq; +- break; ++ if (ret) ++ cpus_clear(*lowest_mask); ++ cpu_set(rq->cpu, *lowest_mask); ++ return 1; + } + + /* no locking for now */ +- if (rq->rt.highest_prio > task->prio && +- (!lowest_rq || rq->rt.highest_prio > lowest_rq->rt.highest_prio)) { +- lowest_rq = rq; ++ if ((rq->rt.highest_prio > task->prio) ++ && (rq->rt.highest_prio >= lowest_prio)) { ++ if (rq->rt.highest_prio > lowest_prio) { ++ /* new low - clear old data */ ++ lowest_prio = rq->rt.highest_prio; ++ cpus_clear(*lowest_mask); ++ } ++ cpu_set(rq->cpu, *lowest_mask); ++ ret = 1; ++ } ++ } ++ ++ return ret; ++} ++ ++static inline int pick_optimal_cpu(int this_cpu, cpumask_t *mask) ++{ ++ int first; ++ ++ /* "this_cpu" is cheaper to preempt than a remote processor */ ++ if ((this_cpu != -1) && cpu_isset(this_cpu, *mask)) ++ return this_cpu; ++ ++ first = first_cpu(*mask); ++ if (first != NR_CPUS) ++ return first; ++ ++ return -1; ++} ++ ++static int find_lowest_rq(struct task_struct *task) ++{ ++ struct sched_domain *sd; ++ cpumask_t *lowest_mask = &__get_cpu_var(local_cpu_mask); ++ int this_cpu = smp_processor_id(); ++ int cpu = task_cpu(task); ++ ++ if (!find_lowest_cpus(task, lowest_mask)) ++ return -1; ++ ++ /* ++ * At this point we have built a mask of cpus representing the ++ * lowest priority tasks in the system. Now we want to elect ++ * the best one based on our affinity and topology. ++ * ++ * We prioritize the last cpu that the task executed on since ++ * it is most likely cache-hot in that location. ++ */ ++ if (cpu_isset(cpu, *lowest_mask)) ++ return cpu; ++ ++ /* ++ * Otherwise, we consult the sched_domains span maps to figure ++ * out which cpu is logically closest to our hot cache data. ++ */ ++ if (this_cpu == cpu) ++ this_cpu = -1; /* Skip this_cpu opt if the same */ ++ ++ for_each_domain(cpu, sd) { ++ if (sd->flags & SD_WAKE_AFFINE) { ++ cpumask_t domain_mask; ++ int best_cpu; ++ ++ cpus_and(domain_mask, sd->span, *lowest_mask); ++ ++ best_cpu = pick_optimal_cpu(this_cpu, ++ &domain_mask); ++ if (best_cpu != -1) ++ return best_cpu; + } + } + +- return lowest_rq ? lowest_rq->cpu : -1; ++ /* ++ * And finally, if there were no matches within the domains ++ * just give the caller *something* to work with from the compatible ++ * locations. ++ */ ++ return pick_optimal_cpu(this_cpu, lowest_mask); + } + + /* Will lock the rq it finds */ --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0425-printk-in-atomic-hack-fix.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0425-printk-in-atomic-hack-fix.patch @@ -0,0 +1,45 @@ +From: Steven Rostedt +Subject: fix printk in atomic hack + +The printk in atomic hack had a slight bug. This but was triggered +by debug locking options. The hack prevents grabbing sleeping spin +locks in printk console drivers if we are in atomic (can't sleep). +But the unlock had a bug where it incorrectely assumed that if +we are in printk and atomic, that we didn't grab the lock. The debug +locking can encapsulate these options and cause unlocks to be in atomic +when the lock was not. This means we would not release the lock after +it was taken. + +The patch only skips releasing the lock if in printk - atomic *and* +not the lock owner. + +Special thanks goes to Jon Masters for digging his head deep into +this crap and narrowing it down to a problem with printks and locks. + +Signed-off-by: Steven Rostedt +--- + kernel/rtmutex.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/rtmutex.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rtmutex.c 2008-10-08 22:24:38.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rtmutex.c 2008-10-08 22:24:45.000000000 -0400 +@@ -634,7 +634,7 @@ rt_spin_lock_fastlock(struct rt_mutex *l + void fastcall (*slowfn)(struct rt_mutex *lock)) + { + /* Temporary HACK! */ +- if (!current->in_printk) ++ if (likely(!current->in_printk)) + might_sleep(); + else if (in_atomic() || irqs_disabled()) + /* don't grab locks for printk in atomic */ +@@ -651,7 +651,7 @@ rt_spin_lock_fastunlock(struct rt_mutex + void fastcall (*slowfn)(struct rt_mutex *lock)) + { + /* Temporary HACK! */ +- if (current->in_printk && (in_atomic() || irqs_disabled())) ++ if (unlikely(rt_mutex_owner(lock) != current) && current->in_printk) + /* don't grab locks for printk in atomic */ + return; + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0118-loopback-revert.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0118-loopback-revert.patch @@ -0,0 +1,38 @@ + +revert this commit: + +commit 58f539740b1ccfc5ef4e509ec2efe82621b546e3 +Author: Eric Dumazet +Date: Fri Oct 20 00:32:41 2006 -0700 + + [NET]: Can use __get_cpu_var() instead of per_cpu() in loopback driver. + + As BHs are off in loopback_xmit(), preemption cannot occurs, so we can + use __get_cpu_var() instead of per_cpu() (and avoid a + preempt_enable()/preempt_disable() pair) + + Signed-off-by: Eric Dumazet + Signed-off-by: David S. Miller + +--- + drivers/net/loopback.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/drivers/net/loopback.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/net/loopback.c 2008-10-08 22:22:40.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/net/loopback.c 2008-10-08 22:23:24.000000000 -0400 +@@ -154,11 +154,11 @@ static int loopback_xmit(struct sk_buff + #endif + dev->last_rx = jiffies; + +- /* it's OK to use per_cpu_ptr() because BHs are off */ + pcpu_lstats = netdev_priv(dev); +- lb_stats = per_cpu_ptr(pcpu_lstats, smp_processor_id()); ++ lb_stats = per_cpu_ptr(pcpu_lstats, get_cpu()); + lb_stats->bytes += skb->len; + lb_stats->packets++; ++ put_cpu(); + + netif_rx(skb); + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0130-rcu-hrt-fixups.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0130-rcu-hrt-fixups.patch @@ -0,0 +1,85 @@ + include/linux/rcuclassic.h | 3 +++ + include/linux/rcupreempt.h | 2 ++ + kernel/rcuclassic.c | 19 ++++++++++++++++--- + 3 files changed, 21 insertions(+), 3 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/rcuclassic.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/rcuclassic.h 2008-10-08 22:23:27.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/rcuclassic.h 2008-10-08 22:23:28.000000000 -0400 +@@ -92,5 +92,8 @@ static inline void rcu_bh_qsctr_inc(int + extern void FASTCALL(call_rcu_classic(struct rcu_head *head, + void (*func)(struct rcu_head *head))); + ++struct softirq_action; ++extern void rcu_process_callbacks(struct softirq_action *unused); ++ + #endif /* __KERNEL__ */ + #endif /* __LINUX_RCUCLASSIC_H */ +Index: linux-2.6.24.7-rt21/include/linux/rcupreempt.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/rcupreempt.h 2008-10-08 22:23:27.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/rcupreempt.h 2008-10-08 22:23:28.000000000 -0400 +@@ -99,5 +99,7 @@ static inline void rcu_exit_nohz(void) + #define rcu_exit_nohz() do { } while (0) + #endif /* CONFIG_NO_HZ */ + ++extern void rcu_process_callbacks(struct softirq_action *unused); ++ + #endif /* __KERNEL__ */ + #endif /* __LINUX_RCUPREEMPT_H */ +Index: linux-2.6.24.7-rt21/kernel/rcuclassic.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rcuclassic.c 2008-10-08 22:23:26.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rcuclassic.c 2008-10-08 22:23:28.000000000 -0400 +@@ -443,6 +443,8 @@ static void rcu_offline_cpu(int cpu) + static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp, + struct rcu_data *rdp) + { ++ unsigned long flags; ++ + if (rdp->curlist && !rcu_batch_before(rcp->completed, rdp->batch)) { + *rdp->donetail = rdp->curlist; + rdp->donetail = rdp->curtail; +@@ -451,12 +453,12 @@ static void __rcu_process_callbacks(stru + } + + if (rdp->nxtlist && !rdp->curlist) { +- local_irq_disable(); ++ local_irq_save(flags); + rdp->curlist = rdp->nxtlist; + rdp->curtail = rdp->nxttail; + rdp->nxtlist = NULL; + rdp->nxttail = &rdp->nxtlist; +- local_irq_enable(); ++ local_irq_restore(flags); + + /* + * start the next batch of callbacks +@@ -483,7 +485,7 @@ static void __rcu_process_callbacks(stru + rcu_do_batch(rdp); + } + +-static void rcu_process_callbacks(struct softirq_action *unused) ++void rcu_process_callbacks(struct softirq_action *unused) + { + __rcu_process_callbacks(&rcu_ctrlblk, &__get_cpu_var(rcu_data)); + __rcu_process_callbacks(&rcu_bh_ctrlblk, &__get_cpu_var(rcu_bh_data)); +@@ -541,6 +543,17 @@ int rcu_needs_cpu(int cpu) + rcu_needs_cpu_rt(cpu)); + } + ++void rcu_advance_callbacks(int cpu, int user) ++{ ++ if (user || ++ (idle_cpu(cpu) && !in_softirq() && ++ hardirq_count() <= (1 << HARDIRQ_SHIFT))) { ++ rcu_qsctr_inc(cpu); ++ rcu_bh_qsctr_inc(cpu); ++ } else if (!in_softirq()) ++ rcu_bh_qsctr_inc(cpu); ++} ++ + void rcu_check_callbacks(int cpu, int user) + { + if (user || --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0559-ftrace-mcount-record.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0559-ftrace-mcount-record.patch @@ -0,0 +1,912 @@ +From: Steven Rostedt +Subject: ftrace: backport mcount record to 2.6.24.7-rt + +Signed-off-by: Steven Rostedt +--- + arch/x86/Kconfig | 1 + arch/x86/kernel/entry_32.S | 13 - + arch/x86/kernel/entry_64.S | 25 --- + arch/x86/kernel/ftrace.c | 43 +---- + arch/x86/kernel/vmlinux_32.lds.S | 5 + arch/x86/kernel/vmlinux_64.lds.S | 5 + include/asm-generic/vmlinux.lds.h | 8 + + include/linux/ftrace.h | 26 +++ + include/linux/kernel.h | 5 + init/main.c | 7 + kernel/module.c | 11 + + kernel/trace/Kconfig | 8 + + kernel/trace/ftrace.c | 160 ++++++++++++++------- + scripts/Makefile.build | 6 + scripts/recordmcount.pl | 280 ++++++++++++++++++++++++++++++++++++++ + 15 files changed, 477 insertions(+), 126 deletions(-) + +Index: linux-2.6.24.7-rt21/include/asm-generic/vmlinux.lds.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-generic/vmlinux.lds.h 2008-10-08 22:22:55.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-generic/vmlinux.lds.h 2008-10-08 22:25:18.000000000 -0400 +@@ -13,6 +13,14 @@ + /* Align . to a 8 byte boundary equals to maximum function alignment. */ + #define ALIGN_FUNCTION() . = ALIGN(8) + ++#ifdef CONFIG_FTRACE_MCOUNT_RECORD ++#define MCOUNT_REC() VMLINUX_SYMBOL(__start_mcount_loc) = .; \ ++ *(__mcount_loc) \ ++ VMLINUX_SYMBOL(__stop_mcount_loc) = .; ++#else ++#define MCOUNT_REC() ++#endif ++ + /* .data section */ + #define DATA_DATA \ + *(.data) \ +Index: linux-2.6.24.7-rt21/scripts/Makefile.build +=================================================================== +--- linux-2.6.24.7-rt21.orig/scripts/Makefile.build 2008-10-08 22:22:07.000000000 -0400 ++++ linux-2.6.24.7-rt21/scripts/Makefile.build 2008-10-08 22:25:18.000000000 -0400 +@@ -192,10 +192,16 @@ cmd_modversions = \ + fi; + endif + ++ifdef CONFIG_FTRACE_MCOUNT_RECORD ++cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ ++ "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" "$(@)"; ++endif ++ + define rule_cc_o_c + $(call echo-cmd,checksrc) $(cmd_checksrc) \ + $(call echo-cmd,cc_o_c) $(cmd_cc_o_c); \ + $(cmd_modversions) \ ++ $(cmd_record_mcount) \ + scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > \ + $(dot-target).tmp; \ + rm -f $(depfile); \ +Index: linux-2.6.24.7-rt21/scripts/recordmcount.pl +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/scripts/recordmcount.pl 2008-10-08 22:25:18.000000000 -0400 +@@ -0,0 +1,280 @@ ++#!/usr/bin/perl -w ++# (c) 2008, Steven Rostedt ++# Licensed under the terms of the GNU GPL License version 2 ++# ++# recordmcount.pl - makes a section called __mcount_loc that holds ++# all the offsets to the calls to mcount. ++# ++# ++# What we want to end up with is a section in vmlinux called ++# __mcount_loc that contains a list of pointers to all the ++# call sites in the kernel that call mcount. Later on boot up, the kernel ++# will read this list, save the locations and turn them into nops. ++# When tracing or profiling is later enabled, these locations will then ++# be converted back to pointers to some function. ++# ++# This is no easy feat. This script is called just after the original ++# object is compiled and before it is linked. ++# ++# The references to the call sites are offsets from the section of text ++# that the call site is in. Hence, all functions in a section that ++# has a call site to mcount, will have the offset from the beginning of ++# the section and not the beginning of the function. ++# ++# The trick is to find a way to record the beginning of the section. ++# The way we do this is to look at the first function in the section ++# which will also be the location of that section after final link. ++# e.g. ++# ++# .section ".text.sched" ++# .globl my_func ++# my_func: ++# [...] ++# call mcount (offset: 0x5) ++# [...] ++# ret ++# other_func: ++# [...] ++# call mcount (offset: 0x1b) ++# [...] ++# ++# Both relocation offsets for the mcounts in the above example will be ++# offset from .text.sched. If we make another file called tmp.s with: ++# ++# .section __mcount_loc ++# .quad my_func + 0x5 ++# .quad my_func + 0x1b ++# ++# We can then compile this tmp.s into tmp.o, and link it to the original ++# object. ++# ++# But this gets hard if my_func is not globl (a static function). ++# In such a case we have: ++# ++# .section ".text.sched" ++# my_func: ++# [...] ++# call mcount (offset: 0x5) ++# [...] ++# ret ++# .globl my_func ++# other_func: ++# [...] ++# call mcount (offset: 0x1b) ++# [...] ++# ++# If we make the tmp.s the same as above, when we link together with ++# the original object, we will end up with two symbols for my_func: ++# one local, one global. After final compile, we will end up with ++# an undefined reference to my_func. ++# ++# Since local objects can reference local variables, we need to find ++# a way to make tmp.o reference the local objects of the original object ++# file after it is linked together. To do this, we convert the my_func ++# into a global symbol before linking tmp.o. Then after we link tmp.o ++# we will only have a single symbol for my_func that is global. ++# We can convert my_func back into a local symbol and we are done. ++# ++# Here are the steps we take: ++# ++# 1) Record all the local symbols by using 'nm' ++# 2) Use objdump to find all the call site offsets and sections for ++# mcount. ++# 3) Compile the list into its own object. ++# 4) Do we have to deal with local functions? If not, go to step 8. ++# 5) Make an object that converts these local functions to global symbols ++# with objcopy. ++# 6) Link together this new object with the list object. ++# 7) Convert the local functions back to local symbols and rename ++# the result as the original object. ++# End. ++# 8) Link the object with the list object. ++# 9) Move the result back to the original object. ++# End. ++# ++ ++use strict; ++ ++my $P = $0; ++$P =~ s@.*/@@g; ++ ++my $V = '0.1'; ++ ++if ($#ARGV < 6) { ++ print "usage: $P arch objdump objcopy cc ld nm rm mv inputfile\n"; ++ print "version: $V\n"; ++ exit(1); ++} ++ ++my ($arch, $objdump, $objcopy, $cc, $ld, $nm, $rm, $mv, $inputfile) = @ARGV; ++ ++$objdump = "objdump" if ((length $objdump) == 0); ++$objcopy = "objcopy" if ((length $objcopy) == 0); ++$cc = "gcc" if ((length $cc) == 0); ++$ld = "ld" if ((length $ld) == 0); ++$nm = "nm" if ((length $nm) == 0); ++$rm = "rm" if ((length $rm) == 0); ++$mv = "mv" if ((length $mv) == 0); ++ ++#print STDERR "running: $P '$arch' '$objdump' '$objcopy' '$cc' '$ld' " . ++# "'$nm' '$rm' '$mv' '$inputfile'\n"; ++ ++my %locals; ++my %convert; ++ ++my $type; ++my $section_regex; # Find the start of a section ++my $function_regex; # Find the name of a function (return func name) ++my $mcount_regex; # Find the call site to mcount (return offset) ++ ++if ($arch eq "x86_64") { ++ $section_regex = "Disassembly of section"; ++ $function_regex = "<(.*?)>:"; ++ $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount([+-]0x[0-9a-zA-Z]+)?\$"; ++ $type = ".quad"; ++} elsif ($arch eq "i386") { ++ $section_regex = "Disassembly of section"; ++ $function_regex = "<(.*?)>:"; ++ $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$"; ++ $type = ".long"; ++} else { ++ die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD"; ++} ++ ++my $text_found = 0; ++my $read_function = 0; ++my $opened = 0; ++my $text = ""; ++my $mcount_section = "__mcount_loc"; ++ ++my $dirname; ++my $filename; ++my $prefix; ++my $ext; ++ ++if ($inputfile =~ m,^(.*)/([^/]*)$,) { ++ $dirname = $1; ++ $filename = $2; ++} else { ++ $dirname = "."; ++ $filename = $inputfile; ++} ++ ++if ($filename =~ m,^(.*)(\.\S),) { ++ $prefix = $1; ++ $ext = $2; ++} else { ++ $prefix = $filename; ++ $ext = ""; ++} ++ ++my $mcount_s = $dirname . "/.tmp_mc_" . $prefix . ".s"; ++my $mcount_o = $dirname . "/.tmp_mc_" . $prefix . ".o"; ++ ++# ++# Step 1: find all the local symbols (static functions). ++# ++open (IN, "$nm $inputfile|") || die "error running $nm"; ++while () { ++ if (/^[0-9a-fA-F]+\s+t\s+(\S+)/) { ++ $locals{$1} = 1; ++ } ++} ++close(IN); ++ ++# ++# Step 2: find the sections and mcount call sites ++# ++open(IN, "$objdump -dr $inputfile|") || die "error running $objdump"; ++ ++while () { ++ # is it a section? ++ if (/$section_regex/) { ++ $read_function = 1; ++ $text_found = 0; ++ # section found, now is this a start of a function? ++ } elsif ($read_function && /$function_regex/) { ++ $read_function = 0; ++ $text_found = 1; ++ $text = $1; ++ # is this function static? If so, note this fact. ++ if (defined $locals{$text}) { ++ $convert{$text} = 1; ++ } ++ # is this a call site to mcount? If so, print the offset from the section ++ } elsif ($text_found && /$mcount_regex/) { ++ if (!$opened) { ++ open(FILE, ">$mcount_s") || die "can't create $mcount_s\n"; ++ $opened = 1; ++ print FILE "\t.section $mcount_section,\"a\",\@progbits\n"; ++ } ++ print FILE "\t$type $text + 0x$1\n"; ++ } ++} ++ ++# If we did not find any mcount callers, we are done (do nothing). ++if (!$opened) { ++ exit(0); ++} ++ ++close(FILE); ++ ++# ++# Step 3: Compile the file that holds the list of call sites to mcount. ++# ++`$cc -o $mcount_o -c $mcount_s`; ++ ++my @converts = keys %convert; ++ ++# ++# Step 4: Do we have sections that started with local functions? ++# ++if ($#converts >= 0) { ++ my $globallist = ""; ++ my $locallist = ""; ++ ++ foreach my $con (@converts) { ++ $globallist .= " --globalize-symbol $con"; ++ $locallist .= " --localize-symbol $con"; ++ } ++ ++ my $globalobj = $dirname . "/.tmp_gl_" . $filename; ++ my $globalmix = $dirname . "/.tmp_mx_" . $filename; ++ ++ # ++ # Step 5: set up each local function as a global ++ # ++ `$objcopy $globallist $inputfile $globalobj`; ++ ++ # ++ # Step 6: Link the global version to our list. ++ # ++ `$ld -r $globalobj $mcount_o -o $globalmix`; ++ ++ # ++ # Step 7: Convert the local functions back into local symbols ++ # ++ `$objcopy $locallist $globalmix $inputfile`; ++ ++ # Remove the temp files ++ `$rm $globalobj $globalmix`; ++ ++} else { ++ ++ my $mix = $dirname . "/.tmp_mx_" . $filename; ++ ++ # ++ # Step 8: Link the object with our list of call sites object. ++ # ++ `$ld -r $inputfile $mcount_o -o $mix`; ++ ++ # ++ # Step 9: Move the result back to the original object. ++ # ++ `$mv $mix $inputfile`; ++} ++ ++# Clean up the temp files ++`$rm $mcount_o $mcount_s`; ++ ++exit(0); +Index: linux-2.6.24.7-rt21/kernel/trace/Kconfig +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/Kconfig 2008-10-08 22:24:49.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/Kconfig 2008-10-08 22:25:18.000000000 -0400 +@@ -7,6 +7,9 @@ config HAVE_FTRACE + config HAVE_DYNAMIC_FTRACE + bool + ++config HAVE_FTRACE_MCOUNT_RECORD ++ bool ++ + config TRACER_MAX_TRACE + bool + +@@ -122,6 +125,11 @@ config DYNAMIC_FTRACE + were made. If so, it runs stop_machine (stops all CPUS) + and modifies the code to jump over the call to ftrace. + ++config FTRACE_MCOUNT_RECORD ++ def_bool y ++ depends on DYNAMIC_FTRACE ++ depends on HAVE_FTRACE_MCOUNT_RECORD ++ + config FTRACE_SELFTEST + bool + +Index: linux-2.6.24.7-rt21/include/linux/ftrace.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/ftrace.h 2008-10-08 22:25:06.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/ftrace.h 2008-10-08 22:25:18.000000000 -0400 +@@ -203,4 +203,30 @@ static inline void ftrace_event_program_ + # define ftrace_event_program_event(p, d) do { } while (0) + #endif /* CONFIG_TRACE_EVENTS */ + ++#ifdef CONFIG_FTRACE_MCOUNT_RECORD ++extern void ftrace_init(void); ++extern void ftrace_init_module(unsigned long *start, unsigned long *end); ++#else ++static inline void ftrace_init(void) { } ++static inline void ++ftrace_init_module(unsigned long *start, unsigned long *end) { } ++#endif ++ ++/* Upstream has include/asm-x86/ftrace.h, but we'll hack this for now */ ++#ifdef CONFIG_X86 ++static inline unsigned long ftrace_call_adjust(unsigned long addr) ++{ ++ /* ++ * call mcount is "e8 <4 byte offset>" ++ * The addr points to the 4 byte offset and the caller of this ++ * function wants the pointer to e8. Simply subtract one. ++ */ ++ return addr - 1; ++} ++#else ++static inline unsigned long ftrace_call_adjust(unsigned long addr) ++{ ++ return addr; ++} ++#endif + #endif /* _LINUX_FTRACE_H */ +Index: linux-2.6.24.7-rt21/init/main.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/init/main.c 2008-10-08 22:24:59.000000000 -0400 ++++ linux-2.6.24.7-rt21/init/main.c 2008-10-08 22:25:18.000000000 -0400 +@@ -60,6 +60,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -658,6 +659,8 @@ asmlinkage void __init start_kernel(void + + acpi_early_init(); /* before LAPIC and SMP init */ + ++ ftrace_init(); ++ + #ifdef CONFIG_PREEMPT_RT + WARN_ON(irqs_disabled()); + #endif +@@ -878,7 +881,7 @@ static int __init kernel_init(void * unu + WARN_ON(irqs_disabled()); + #endif + +-#define DEBUG_COUNT (defined(CONFIG_DEBUG_RT_MUTEXES) + defined(CONFIG_IRQSOFF_TRACER) + defined(CONFIG_PREEMPT_TRACER) + defined(CONFIG_FTRACE) + defined(CONFIG_WAKEUP_LATENCY_HIST) + defined(CONFIG_DEBUG_SLAB) + defined(CONFIG_DEBUG_PAGEALLOC) + defined(CONFIG_LOCKDEP)) ++#define DEBUG_COUNT (defined(CONFIG_DEBUG_RT_MUTEXES) + defined(CONFIG_IRQSOFF_TRACER) + defined(CONFIG_PREEMPT_TRACER) + (defined(CONFIG_FTRACE) - defined(CONFIG_FTRACE_MCOUNT_RECORD)) + defined(CONFIG_WAKEUP_LATENCY_HIST) + defined(CONFIG_DEBUG_SLAB) + defined(CONFIG_DEBUG_PAGEALLOC) + defined(CONFIG_LOCKDEP)) + + #if DEBUG_COUNT > 0 + printk(KERN_ERR "*****************************************************************************\n"); +@@ -898,7 +901,7 @@ static int __init kernel_init(void * unu + #ifdef CONFIG_PREEMPT_TRACER + printk(KERN_ERR "* CONFIG_PREEMPT_TRACER *\n"); + #endif +-#ifdef CONFIG_FTRACE ++#if defined(CONFIG_FTRACE) - defined(CONFIG_FTRACE_MCOUNT_RECORD) + printk(KERN_ERR "* CONFIG_FTRACE *\n"); + #endif + #ifdef CONFIG_WAKEUP_LATENCY_HIST +Index: linux-2.6.24.7-rt21/kernel/trace/ftrace.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/ftrace.c 2008-10-08 22:25:06.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/ftrace.c 2008-10-08 22:25:18.000000000 -0400 +@@ -324,13 +324,6 @@ ftrace_record_ip(unsigned long ip) + if (ftrace_ip_in_hash(ip, key)) + goto out_unlock; + +- /* +- * There's a slight race that the ftraced will update the +- * hash and reset here. If it is already converted, skip it. +- */ +- if (ftrace_ip_converted(ip)) +- goto out_unlock; +- + node = ftrace_alloc_dyn_node(ip); + if (!node) + goto out_unlock; +@@ -697,47 +690,7 @@ static int ftrace_update_code(void) + return 1; + } + +-static int ftraced(void *ignore) +-{ +- unsigned long usecs; +- +- while (!kthread_should_stop()) { +- +- set_current_state(TASK_INTERRUPTIBLE); +- +- /* check once a second */ +- schedule_timeout(HZ); +- +- if (unlikely(ftrace_disabled)) +- continue; +- +- mutex_lock(&ftrace_sysctl_lock); +- mutex_lock(&ftraced_lock); +- if (!ftraced_suspend && !ftraced_stop && +- ftrace_update_code()) { +- usecs = nsecs_to_usecs(ftrace_update_time); +- if (ftrace_update_tot_cnt > 100000) { +- ftrace_update_tot_cnt = 0; +- pr_info("hm, dftrace overflow: %lu change%s" +- " (%lu total) in %lu usec%s\n", +- ftrace_update_cnt, +- ftrace_update_cnt != 1 ? "s" : "", +- ftrace_update_tot_cnt, +- usecs, usecs != 1 ? "s" : ""); +- ftrace_disabled = 1; +- WARN_ON_ONCE(1); +- } +- } +- mutex_unlock(&ftraced_lock); +- mutex_unlock(&ftrace_sysctl_lock); +- +- ftrace_shutdown_replenish(); +- } +- __set_current_state(TASK_RUNNING); +- return 0; +-} +- +-static int __init ftrace_dyn_table_alloc(void) ++static int __init ftrace_dyn_table_alloc(unsigned long num_to_init) + { + struct ftrace_page *pg; + int cnt; +@@ -764,7 +717,9 @@ static int __init ftrace_dyn_table_alloc + + pg = ftrace_pages = ftrace_pages_start; + +- cnt = NR_TO_INIT / ENTRIES_PER_PAGE; ++ cnt = num_to_init / ENTRIES_PER_PAGE; ++ pr_info("ftrace: allocating %ld hash entries in %d pages\n", ++ num_to_init, cnt); + + for (i = 0; i < cnt; i++) { + pg->next = (void *)get_zeroed_page(GFP_KERNEL); +@@ -1423,6 +1378,109 @@ static __init int ftrace_init_debugfs(vo + + fs_initcall(ftrace_init_debugfs); + ++#ifdef CONFIG_FTRACE_MCOUNT_RECORD ++static int ftrace_convert_nops(unsigned long *start, ++ unsigned long *end) ++{ ++ unsigned long *p; ++ unsigned long addr; ++ unsigned long flags; ++ ++ p = start; ++ while (p < end) { ++ addr = ftrace_call_adjust(*p++); ++ ftrace_record_ip(addr); ++ ftrace_shutdown_replenish(); ++ } ++ ++ /* p is ignored */ ++ local_irq_save(flags); ++ __ftrace_update_code(p); ++ local_irq_restore(flags); ++ ++ return 0; ++} ++ ++void ftrace_init_module(unsigned long *start, unsigned long *end) ++{ ++ ftrace_convert_nops(start, end); ++} ++ ++extern unsigned long __start_mcount_loc[]; ++extern unsigned long __stop_mcount_loc[]; ++ ++void __init ftrace_init(void) ++{ ++ unsigned long count, addr, flags; ++ int ret; ++ ++ /* Keep the ftrace pointer to the stub */ ++ addr = (unsigned long)ftrace_stub; ++ ++ local_irq_save(flags); ++ ftrace_dyn_arch_init(&addr); ++ local_irq_restore(flags); ++ ++ /* ftrace_dyn_arch_init places the return code in addr */ ++ if (addr) ++ goto failed; ++ ++ count = __stop_mcount_loc - __start_mcount_loc; ++ ++ ret = ftrace_dyn_table_alloc(count); ++ if (ret) ++ goto failed; ++ ++ last_ftrace_enabled = ftrace_enabled = 1; ++ ++ ret = ftrace_convert_nops(__start_mcount_loc, ++ __stop_mcount_loc); ++ ++ return; ++ failed: ++ ftrace_disabled = 1; ++} ++#else /* CONFIG_FTRACE_MCOUNT_RECORD */ ++static int ftraced(void *ignore) ++{ ++ unsigned long usecs; ++ ++ while (!kthread_should_stop()) { ++ ++ set_current_state(TASK_INTERRUPTIBLE); ++ ++ /* check once a second */ ++ schedule_timeout(HZ); ++ ++ if (unlikely(ftrace_disabled)) ++ continue; ++ ++ mutex_lock(&ftrace_sysctl_lock); ++ mutex_lock(&ftraced_lock); ++ if (!ftraced_suspend && !ftraced_stop && ++ ftrace_update_code()) { ++ usecs = nsecs_to_usecs(ftrace_update_time); ++ if (ftrace_update_tot_cnt > 100000) { ++ ftrace_update_tot_cnt = 0; ++ pr_info("hm, dftrace overflow: %lu change%s" ++ " (%lu total) in %lu usec%s\n", ++ ftrace_update_cnt, ++ ftrace_update_cnt != 1 ? "s" : "", ++ ftrace_update_tot_cnt, ++ usecs, usecs != 1 ? "s" : ""); ++ ftrace_disabled = 1; ++ WARN_ON_ONCE(1); ++ } ++ } ++ mutex_unlock(&ftraced_lock); ++ mutex_unlock(&ftrace_sysctl_lock); ++ ++ ftrace_shutdown_replenish(); ++ } ++ __set_current_state(TASK_RUNNING); ++ return 0; ++} ++ + static int __init ftrace_dynamic_init(void) + { + struct task_struct *p; +@@ -1439,7 +1497,7 @@ static int __init ftrace_dynamic_init(vo + goto failed; + } + +- ret = ftrace_dyn_table_alloc(); ++ ret = ftrace_dyn_table_alloc(NR_TO_INIT); + if (ret) + goto failed; + +@@ -1460,6 +1518,8 @@ static int __init ftrace_dynamic_init(vo + } + + core_initcall(ftrace_dynamic_init); ++#endif /* CONFIG_FTRACE_MCOUNT_RECORD */ ++ + #else + # define ftrace_startup() do { } while (0) + # define ftrace_shutdown() do { } while (0) +Index: linux-2.6.24.7-rt21/kernel/module.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/module.c 2008-10-08 22:23:05.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/module.c 2008-10-08 22:25:18.000000000 -0400 +@@ -49,6 +49,7 @@ + #include + #include + #include ++#include + + extern int module_sysfs_initialized; + +@@ -1682,6 +1683,7 @@ static struct module *load_module(void _ + unsigned int immediatecondendindex; + unsigned int markersindex; + unsigned int markersstringsindex; ++ unsigned int mcountindex; + struct module *mod; + long err = 0; + void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ +@@ -1965,6 +1967,9 @@ static struct module *load_module(void _ + markersstringsindex = find_sec(hdr, sechdrs, secstrings, + "__markers_strings"); + ++ mcountindex = find_sec(hdr, sechdrs, secstrings, ++ "__mcount_loc"); ++ + /* Now do relocations. */ + for (i = 1; i < hdr->e_shnum; i++) { + const char *strtab = (char *)sechdrs[strindex].sh_addr; +@@ -2020,6 +2025,12 @@ static struct module *load_module(void _ + mod->immediate + mod->num_immediate); + #endif + } ++ ++ if (mcountindex) { ++ void *mseg = (void *)sechdrs[mcountindex].sh_addr; ++ ftrace_init_module(mseg, mseg + sechdrs[mcountindex].sh_size); ++ } ++ + err = module_finalize(hdr, sechdrs, mod); + if (err < 0) + goto cleanup; +Index: linux-2.6.24.7-rt21/include/linux/kernel.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/kernel.h 2008-10-08 22:24:19.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/kernel.h 2008-10-08 22:25:18.000000000 -0400 +@@ -432,4 +432,9 @@ struct sysinfo { + #define NUMA_BUILD 0 + #endif + ++/* Rebuild everything on CONFIG_FTRACE_MCOUNT_RECORD */ ++#ifdef CONFIG_FTRACE_MCOUNT_RECORD ++# define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD ++#endif ++ + #endif +Index: linux-2.6.24.7-rt21/arch/x86/Kconfig +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/Kconfig 2008-10-08 22:24:25.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/Kconfig 2008-10-08 22:25:18.000000000 -0400 +@@ -19,6 +19,7 @@ config X86_64 + config X86 + bool + default y ++ select HAVE_FTRACE_MCOUNT_RECORD + select HAVE_DYNAMIC_FTRACE + select HAVE_FTRACE + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/ftrace.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/ftrace.c 2008-10-08 22:23:06.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/ftrace.c 2008-10-08 22:25:18.000000000 -0400 +@@ -17,6 +17,7 @@ + #include + + #include ++#include + #include + + #define CALL_BACK 5 +@@ -32,16 +33,6 @@ union ftrace_code_union { + } __attribute__((packed)); + }; + +-notrace int ftrace_ip_converted(unsigned long ip) +-{ +- unsigned long save; +- +- ip -= CALL_BACK; +- save = *(long *)ip; +- +- return save == *ftrace_nop; +-} +- + static int notrace ftrace_calc_offset(long ip, long addr) + { + return (int)(addr - ip); +@@ -57,7 +48,7 @@ notrace unsigned char *ftrace_call_repla + static union ftrace_code_union calc; + + calc.e8 = 0xe8; +- calc.offset = ftrace_calc_offset(ip, addr); ++ calc.offset = ftrace_calc_offset(ip + CALL_BACK, addr); + + /* + * No locking needed, this must be called via kstop_machine +@@ -76,9 +67,6 @@ ftrace_modify_code(unsigned long ip, uns + unsigned char newch = new_code[4]; + int faulted = 0; + +- /* move the IP back to the start of the call */ +- ip -= CALL_BACK; +- + /* + * Note: Due to modules and __init, code can + * disappear and change, we need to protect against faulting +@@ -116,8 +104,6 @@ notrace int ftrace_update_ftrace_func(ft + unsigned char old[5], *new; + int ret; + +- ip += CALL_BACK; +- + memcpy(old, &ftrace_call, 5); + new = ftrace_call_replace(ip, (unsigned long)func); + ret = ftrace_modify_code(ip, old, new); +@@ -127,33 +113,22 @@ notrace int ftrace_update_ftrace_func(ft + + notrace int ftrace_mcount_set(unsigned long *data) + { +- unsigned long ip = (long)(&mcount_call); +- unsigned long *addr = data; +- unsigned char old[5], *new; +- +- /* ip is at the location, but modify code will subtact this */ +- ip += CALL_BACK; +- +- /* +- * Replace the mcount stub with a pointer to the +- * ip recorder function. +- */ +- memcpy(old, &mcount_call, 5); +- new = ftrace_call_replace(ip, *addr); +- *addr = ftrace_modify_code(ip, old, new); +- ++ *data = 0; + return 0; + } + ++asm("\t.section .rodata, \"a\"\nftrace_nop5: " ++ P6_NOP5 ++ "\t.previous"); ++extern const unsigned char ftrace_nop5[]; ++ + int __init ftrace_dyn_arch_init(void *data) + { +- const unsigned char *const *noptable = find_nop_table(); +- + /* This is running in kstop_machine */ + + ftrace_mcount_set(data); + +- ftrace_nop = (unsigned long *)noptable[CALL_BACK]; ++ ftrace_nop = (unsigned long *)ftrace_nop5; + + return 0; + } +Index: linux-2.6.24.7-rt21/arch/x86/kernel/vmlinux_32.lds.S +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/vmlinux_32.lds.S 2008-10-08 22:22:07.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/vmlinux_32.lds.S 2008-10-08 22:25:18.000000000 -0400 +@@ -134,7 +134,10 @@ SECTIONS + *(.init.text) + _einittext = .; + } +- .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) } ++ .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { ++ *(.init.data) ++ MCOUNT_REC() ++ } + . = ALIGN(16); + .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { + __setup_start = .; +Index: linux-2.6.24.7-rt21/arch/x86/kernel/vmlinux_64.lds.S +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/vmlinux_64.lds.S 2008-10-08 22:22:07.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/vmlinux_64.lds.S 2008-10-08 22:25:18.000000000 -0400 +@@ -159,7 +159,10 @@ SECTIONS + _einittext = .; + } + __initdata_begin = .; +- .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) } ++ .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { ++ *(.init.data) ++ MCOUNT_REC() ++ } + __initdata_end = .; + . = ALIGN(16); + __setup_start = .; +Index: linux-2.6.24.7-rt21/arch/x86/kernel/entry_32.S +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/entry_32.S 2008-10-08 22:23:58.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/entry_32.S 2008-10-08 22:25:18.000000000 -0400 +@@ -1132,19 +1132,6 @@ ENDPROC(xen_failsafe_callback) + #ifdef CONFIG_DYNAMIC_FTRACE + + ENTRY(mcount) +- pushl %eax +- pushl %ecx +- pushl %edx +- movl 0xc(%esp), %eax +- +-.globl mcount_call +-mcount_call: +- call ftrace_stub +- +- popl %edx +- popl %ecx +- popl %eax +- + ret + END(mcount) + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/entry_64.S +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/entry_64.S 2008-10-08 22:23:40.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/entry_64.S 2008-10-08 22:25:18.000000000 -0400 +@@ -56,31 +56,6 @@ + #ifdef CONFIG_FTRACE + #ifdef CONFIG_DYNAMIC_FTRACE + ENTRY(mcount) +- +- subq $0x38, %rsp +- movq %rax, (%rsp) +- movq %rcx, 8(%rsp) +- movq %rdx, 16(%rsp) +- movq %rsi, 24(%rsp) +- movq %rdi, 32(%rsp) +- movq %r8, 40(%rsp) +- movq %r9, 48(%rsp) +- +- movq 0x38(%rsp), %rdi +- +-.globl mcount_call +-mcount_call: +- call ftrace_stub +- +- movq 48(%rsp), %r9 +- movq 40(%rsp), %r8 +- movq 32(%rsp), %rdi +- movq 24(%rsp), %rsi +- movq 16(%rsp), %rdx +- movq 8(%rsp), %rcx +- movq (%rsp), %rax +- addq $0x38, %rsp +- + retq + END(mcount) + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0462-sched-load_balance-iterator.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0462-sched-load_balance-iterator.patch @@ -0,0 +1,73 @@ +Subject: sched: fixup the load balancer iterator +From: Peter Zijlstra + +Solve the live-lock from the previous patch by not restarting the load +balance iterator on each go. + +Signed-off-by: Peter Zijlstra +--- + kernel/sched.c | 13 +++++++++++-- + kernel/sched_fair.c | 3 +++ + 2 files changed, 14 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/sched.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched.c 2008-10-08 22:24:54.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched.c 2008-10-08 22:24:54.000000000 -0400 +@@ -2275,6 +2275,7 @@ static void update_cpu_load(struct rq *t + + #define LB_ALL_PINNED 0x01 + #define LB_COMPLETE 0x02 ++#define LB_START 0x03 + + /* + * double_rq_lock - safely lock two runqueues +@@ -2477,7 +2478,11 @@ balance_tasks(struct rq *this_rq, int th + /* + * Start the load-balancing iterator: + */ +- p = iterator->start(iterator->arg); ++ if (*lb_flags & LB_START) ++ p = iterator->start(iterator->arg); ++ else ++ p = iterator->next(iterator->arg); ++ + if (p) + pinned = 1; + next: +@@ -2544,6 +2549,8 @@ static int move_tasks(struct rq *this_rq + unsigned long total_load_moved = 0; + int this_best_prio = this_rq->curr->prio; + ++ *lb_flags |= LB_START; ++ + do { + unsigned long load_moved; + +@@ -2555,9 +2562,11 @@ static int move_tasks(struct rq *this_rq + + total_load_moved += load_moved; + +- if (!load_moved || *lb_flags & LB_COMPLETE) { ++ if (*lb_flags & LB_COMPLETE) { + class = class->next; ++ *lb_flags |= LB_START; + } else if (sched_feat(LB_BREAK)) { ++ *lb_flags &= ~LB_START; + schedstat_inc(this_rq, lb_breaks); + + double_rq_unlock(this_rq, busiest); +Index: linux-2.6.24.7-rt21/kernel/sched_fair.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched_fair.c 2008-10-08 22:24:54.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched_fair.c 2008-10-08 22:24:54.000000000 -0400 +@@ -185,6 +185,9 @@ static void __dequeue_entity(struct cfs_ + if (cfs_rq->rb_leftmost == &se->run_node) + cfs_rq->rb_leftmost = rb_next(&se->run_node); + ++ if (cfs_rq->rb_load_balance_curr == &se->run_node) ++ cfs_rq->rb_load_balance_curr = rb_next(&se->run_node); ++ + rb_erase(&se->run_node, &cfs_rq->tasks_timeline); + } + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0432-migrate-dying.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0432-migrate-dying.patch @@ -0,0 +1,62 @@ +From ghaskins@novell.com Mon Mar 24 17:47:08 2008 +Date: Mon, 10 Mar 2008 12:20:57 -0400 +From: Gregory Haskins +To: rostedt@goodmis.org, mingo@elte.hu, tglx@linutronix.de +Cc: linux-rt-users@vger.kernel.org, ghaskins@novell.com +Subject: [PATCH] keep rd->online and cpu_online_map in sync + + [ The following text is in the "utf-8" character set. ] + [ Your display is set for the "iso-8859-1" character set. ] + [ Some characters may be displayed incorrectly. ] + +Hi Ingo, Steve, Thomas, + Ingo pointed me at an issue on LKML/mainline regarding cpu-hotplug. +It turns out that the issue (I believe) was related to the root-domain +code that I added a few months ago. This code is also in -rt, so the +bug should exist there as well. This may fix the root-cause of that +s2ram bug that Mike Galbraith found and patched a while back as well. +If that is the case, we can probably get rid of the "num_online_cpus()" +in the update_migration code. That will require confirmation from +Mike, however, as I do not have a P4 machine like his that exhibits +the bug. For now, both patches should probably co-exist together. + +This applies to 24.3-rt3 + +Regards, +-Greg + +------------------------------ +keep rd->online and cpu_online_map in sync + +It is possible to allow the root-domain cache of online cpus to +become out of sync with the global cpu_online_map. This is because we +currently trigger removal of cpus too early in the notifier chain. +Other DOWN_PREPARE handlers may in fact run and reconfigure the +root-domain topology, thereby stomping on our own offline handling. + +The end result is that rd->online may become out of sync with +cpu_online_map, which results in potential task misrouting. + +So change the offline handling to be more tightly coupled with the +global offline process by triggering on CPU_DYING intead of +CPU_DOWN_PREPARE. + +Signed-off-by: Gregory Haskins +--- + + kernel/sched.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/kernel/sched.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched.c 2008-10-08 22:24:45.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched.c 2008-10-08 22:24:47.000000000 -0400 +@@ -6120,7 +6120,7 @@ migration_call(struct notifier_block *nf + spin_unlock_irq(&rq->lock); + break; + +- case CPU_DOWN_PREPARE: ++ case CPU_DYING: + /* Update our root-domain */ + rq = cpu_rq(cpu); + spin_lock_irqsave(&rq->lock, flags); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0313-i386-nmi-watchdog-show-regs.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0313-i386-nmi-watchdog-show-regs.patch @@ -0,0 +1,17 @@ +--- + arch/x86/kernel/nmi_32.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/nmi_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/nmi_32.c 2008-10-08 22:24:08.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/nmi_32.c 2008-10-08 22:24:19.000000000 -0400 +@@ -392,7 +392,7 @@ nmi_watchdog_tick(struct pt_regs * regs, + + spin_lock(&lock); + printk("NMI backtrace for cpu %d\n", cpu); +- dump_stack(); ++ show_regs(regs); + spin_unlock(&lock); + cpu_clear(cpu, backtrace_mask); + } --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0326-nf_conntrack-fix-smp-processor-id.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0326-nf_conntrack-fix-smp-processor-id.patch @@ -0,0 +1,17 @@ +--- + include/net/netfilter/nf_conntrack.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/include/net/netfilter/nf_conntrack.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/net/netfilter/nf_conntrack.h 2008-10-08 22:23:42.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/net/netfilter/nf_conntrack.h 2008-10-08 22:24:22.000000000 -0400 +@@ -262,7 +262,7 @@ DECLARE_PER_CPU(struct ip_conntrack_stat + #define NF_CT_STAT_INC_ATOMIC(count) \ + do { \ + local_bh_disable(); \ +- __get_cpu_var(nf_conntrack_stat).count++; \ ++ __raw_get_cpu_var(nf_conntrack_stat).count++; \ + local_bh_enable(); \ + } while (0) + #define NF_CT_STAT_INC(count) (__raw_get_cpu_var(nf_conntrack_stat).count++) --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0026-0010-sched-de-SCHED_OTHER-ize-the-RT-path.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0026-0010-sched-de-SCHED_OTHER-ize-the-RT-path.patch @@ -0,0 +1,480 @@ +From c73997c8271a00a6a2e65c90e817f1093247eb1b Mon Sep 17 00:00:00 2001 +From: Gregory Haskins +Date: Tue, 11 Dec 2007 10:02:38 +0100 +Subject: [PATCH] sched: de-SCHED_OTHER-ize the RT path + +The current wake-up code path tries to determine if it can optimize the +wake-up to "this_cpu" by computing load calculations. The problem is that +these calculations are only relevant to SCHED_OTHER tasks where load is king. +For RT tasks, priority is king. So the load calculation is completely wasted +bandwidth. + +Therefore, we create a new sched_class interface to help with +pre-wakeup routing decisions and move the load calculation as a function +of CFS task's class. + +Signed-off-by: Gregory Haskins +Signed-off-by: Steven Rostedt +Signed-off-by: Ingo Molnar + +--- + include/linux/sched.h | 1 + kernel/sched.c | 167 +++++++----------------------------------------- + kernel/sched_fair.c | 148 ++++++++++++++++++++++++++++++++++++++++++ + kernel/sched_idletask.c | 9 ++ + kernel/sched_rt.c | 10 ++ + 5 files changed, 195 insertions(+), 140 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/sched.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/sched.h 2008-10-08 22:22:57.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/sched.h 2008-10-08 22:22:58.000000000 -0400 +@@ -827,6 +827,7 @@ struct sched_class { + void (*enqueue_task) (struct rq *rq, struct task_struct *p, int wakeup); + void (*dequeue_task) (struct rq *rq, struct task_struct *p, int sleep); + void (*yield_task) (struct rq *rq); ++ int (*select_task_rq)(struct task_struct *p, int sync); + + void (*check_preempt_curr) (struct rq *rq, struct task_struct *p); + +Index: linux-2.6.24.7-rt21/kernel/sched.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched.c 2008-10-08 22:22:57.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched.c 2008-10-08 22:22:58.000000000 -0400 +@@ -918,6 +918,13 @@ static void cpuacct_charge(struct task_s + static inline void cpuacct_charge(struct task_struct *tsk, u64 cputime) {} + #endif + ++#ifdef CONFIG_SMP ++static unsigned long source_load(int cpu, int type); ++static unsigned long target_load(int cpu, int type); ++static unsigned long cpu_avg_load_per_task(int cpu); ++static int task_hot(struct task_struct *p, u64 now, struct sched_domain *sd); ++#endif /* CONFIG_SMP */ ++ + #include "sched_stats.h" + #include "sched_idletask.c" + #include "sched_fair.c" +@@ -1103,7 +1110,7 @@ static inline void __set_task_cpu(struct + /* + * Is this task likely cache-hot: + */ +-static inline int ++static int + task_hot(struct task_struct *p, u64 now, struct sched_domain *sd) + { + s64 delta; +@@ -1328,7 +1335,7 @@ static unsigned long target_load(int cpu + /* + * Return the average load per task on the cpu's run queue + */ +-static inline unsigned long cpu_avg_load_per_task(int cpu) ++static unsigned long cpu_avg_load_per_task(int cpu) + { + struct rq *rq = cpu_rq(cpu); + unsigned long total = weighted_cpuload(cpu); +@@ -1485,58 +1492,6 @@ static int sched_balance_self(int cpu, i + + #endif /* CONFIG_SMP */ + +-/* +- * wake_idle() will wake a task on an idle cpu if task->cpu is +- * not idle and an idle cpu is available. The span of cpus to +- * search starts with cpus closest then further out as needed, +- * so we always favor a closer, idle cpu. +- * +- * Returns the CPU we should wake onto. +- */ +-#if defined(ARCH_HAS_SCHED_WAKE_IDLE) +-static int wake_idle(int cpu, struct task_struct *p) +-{ +- cpumask_t tmp; +- struct sched_domain *sd; +- int i; +- +- /* +- * If it is idle, then it is the best cpu to run this task. +- * +- * This cpu is also the best, if it has more than one task already. +- * Siblings must be also busy(in most cases) as they didn't already +- * pickup the extra load from this cpu and hence we need not check +- * sibling runqueue info. This will avoid the checks and cache miss +- * penalities associated with that. +- */ +- if (idle_cpu(cpu) || cpu_rq(cpu)->nr_running > 1) +- return cpu; +- +- for_each_domain(cpu, sd) { +- if (sd->flags & SD_WAKE_IDLE) { +- cpus_and(tmp, sd->span, p->cpus_allowed); +- for_each_cpu_mask(i, tmp) { +- if (idle_cpu(i)) { +- if (i != task_cpu(p)) { +- schedstat_inc(p, +- se.nr_wakeups_idle); +- } +- return i; +- } +- } +- } else { +- break; +- } +- } +- return cpu; +-} +-#else +-static inline int wake_idle(int cpu, struct task_struct *p) +-{ +- return cpu; +-} +-#endif +- + /*** + * try_to_wake_up - wake up a thread + * @p: the to-be-woken-up thread +@@ -1558,8 +1513,6 @@ static int try_to_wake_up(struct task_st + long old_state; + struct rq *rq; + #ifdef CONFIG_SMP +- struct sched_domain *sd, *this_sd = NULL; +- unsigned long load, this_load; + int new_cpu; + #endif + +@@ -1579,90 +1532,7 @@ static int try_to_wake_up(struct task_st + if (unlikely(task_running(rq, p))) + goto out_activate; + +- new_cpu = cpu; +- +- schedstat_inc(rq, ttwu_count); +- if (cpu == this_cpu) { +- schedstat_inc(rq, ttwu_local); +- goto out_set_cpu; +- } +- +- for_each_domain(this_cpu, sd) { +- if (cpu_isset(cpu, sd->span)) { +- schedstat_inc(sd, ttwu_wake_remote); +- this_sd = sd; +- break; +- } +- } +- +- if (unlikely(!cpu_isset(this_cpu, p->cpus_allowed))) +- goto out_set_cpu; +- +- /* +- * Check for affine wakeup and passive balancing possibilities. +- */ +- if (this_sd) { +- int idx = this_sd->wake_idx; +- unsigned int imbalance; +- +- imbalance = 100 + (this_sd->imbalance_pct - 100) / 2; +- +- load = source_load(cpu, idx); +- this_load = target_load(this_cpu, idx); +- +- new_cpu = this_cpu; /* Wake to this CPU if we can */ +- +- if (this_sd->flags & SD_WAKE_AFFINE) { +- unsigned long tl = this_load; +- unsigned long tl_per_task; +- +- /* +- * Attract cache-cold tasks on sync wakeups: +- */ +- if (sync && !task_hot(p, rq->clock, this_sd)) +- goto out_set_cpu; +- +- schedstat_inc(p, se.nr_wakeups_affine_attempts); +- tl_per_task = cpu_avg_load_per_task(this_cpu); +- +- /* +- * If sync wakeup then subtract the (maximum possible) +- * effect of the currently running task from the load +- * of the current CPU: +- */ +- if (sync) +- tl -= current->se.load.weight; +- +- if ((tl <= load && +- tl + target_load(cpu, idx) <= tl_per_task) || +- 100*(tl + p->se.load.weight) <= imbalance*load) { +- /* +- * This domain has SD_WAKE_AFFINE and +- * p is cache cold in this domain, and +- * there is no bad imbalance. +- */ +- schedstat_inc(this_sd, ttwu_move_affine); +- schedstat_inc(p, se.nr_wakeups_affine); +- goto out_set_cpu; +- } +- } +- +- /* +- * Start passive balancing when half the imbalance_pct +- * limit is reached. +- */ +- if (this_sd->flags & SD_WAKE_BALANCE) { +- if (imbalance*this_load <= 100*load) { +- schedstat_inc(this_sd, ttwu_move_balance); +- schedstat_inc(p, se.nr_wakeups_passive); +- goto out_set_cpu; +- } +- } +- } +- +- new_cpu = cpu; /* Could not wake to this_cpu. Wake to cpu instead */ +-out_set_cpu: +- new_cpu = wake_idle(new_cpu, p); ++ new_cpu = p->sched_class->select_task_rq(p, sync); + if (new_cpu != cpu) { + set_task_cpu(p, new_cpu); + task_rq_unlock(rq, &flags); +@@ -1678,6 +1548,23 @@ out_set_cpu: + cpu = task_cpu(p); + } + ++#ifdef CONFIG_SCHEDSTATS ++ schedstat_inc(rq, ttwu_count); ++ if (cpu == this_cpu) ++ schedstat_inc(rq, ttwu_local); ++ else { ++ struct sched_domain *sd; ++ for_each_domain(this_cpu, sd) { ++ if (cpu_isset(cpu, sd->span)) { ++ schedstat_inc(sd, ttwu_wake_remote); ++ break; ++ } ++ } ++ } ++ ++#endif ++ ++ + out_activate: + #endif /* CONFIG_SMP */ + schedstat_inc(p, se.nr_wakeups); +Index: linux-2.6.24.7-rt21/kernel/sched_fair.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched_fair.c 2008-10-08 22:22:52.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched_fair.c 2008-10-08 22:22:58.000000000 -0400 +@@ -832,6 +832,151 @@ static void yield_task_fair(struct rq *r + } + + /* ++ * wake_idle() will wake a task on an idle cpu if task->cpu is ++ * not idle and an idle cpu is available. The span of cpus to ++ * search starts with cpus closest then further out as needed, ++ * so we always favor a closer, idle cpu. ++ * ++ * Returns the CPU we should wake onto. ++ */ ++#if defined(ARCH_HAS_SCHED_WAKE_IDLE) ++static int wake_idle(int cpu, struct task_struct *p) ++{ ++ cpumask_t tmp; ++ struct sched_domain *sd; ++ int i; ++ ++ /* ++ * If it is idle, then it is the best cpu to run this task. ++ * ++ * This cpu is also the best, if it has more than one task already. ++ * Siblings must be also busy(in most cases) as they didn't already ++ * pickup the extra load from this cpu and hence we need not check ++ * sibling runqueue info. This will avoid the checks and cache miss ++ * penalities associated with that. ++ */ ++ if (idle_cpu(cpu) || cpu_rq(cpu)->nr_running > 1) ++ return cpu; ++ ++ for_each_domain(cpu, sd) { ++ if (sd->flags & SD_WAKE_IDLE) { ++ cpus_and(tmp, sd->span, p->cpus_allowed); ++ for_each_cpu_mask(i, tmp) { ++ if (idle_cpu(i)) { ++ if (i != task_cpu(p)) { ++ schedstat_inc(p, ++ se.nr_wakeups_idle); ++ } ++ return i; ++ } ++ } ++ } else { ++ break; ++ } ++ } ++ return cpu; ++} ++#else ++static inline int wake_idle(int cpu, struct task_struct *p) ++{ ++ return cpu; ++} ++#endif ++ ++#ifdef CONFIG_SMP ++static int select_task_rq_fair(struct task_struct *p, int sync) ++{ ++ int cpu, this_cpu; ++ struct rq *rq; ++ struct sched_domain *sd, *this_sd = NULL; ++ int new_cpu; ++ ++ cpu = task_cpu(p); ++ rq = task_rq(p); ++ this_cpu = smp_processor_id(); ++ new_cpu = cpu; ++ ++ for_each_domain(this_cpu, sd) { ++ if (cpu_isset(cpu, sd->span)) { ++ this_sd = sd; ++ break; ++ } ++ } ++ ++ if (unlikely(!cpu_isset(this_cpu, p->cpus_allowed))) ++ goto out_set_cpu; ++ ++ /* ++ * Check for affine wakeup and passive balancing possibilities. ++ */ ++ if (this_sd) { ++ int idx = this_sd->wake_idx; ++ unsigned int imbalance; ++ unsigned long load, this_load; ++ ++ imbalance = 100 + (this_sd->imbalance_pct - 100) / 2; ++ ++ load = source_load(cpu, idx); ++ this_load = target_load(this_cpu, idx); ++ ++ new_cpu = this_cpu; /* Wake to this CPU if we can */ ++ ++ if (this_sd->flags & SD_WAKE_AFFINE) { ++ unsigned long tl = this_load; ++ unsigned long tl_per_task; ++ ++ /* ++ * Attract cache-cold tasks on sync wakeups: ++ */ ++ if (sync && !task_hot(p, rq->clock, this_sd)) ++ goto out_set_cpu; ++ ++ schedstat_inc(p, se.nr_wakeups_affine_attempts); ++ tl_per_task = cpu_avg_load_per_task(this_cpu); ++ ++ /* ++ * If sync wakeup then subtract the (maximum possible) ++ * effect of the currently running task from the load ++ * of the current CPU: ++ */ ++ if (sync) ++ tl -= current->se.load.weight; ++ ++ if ((tl <= load && ++ tl + target_load(cpu, idx) <= tl_per_task) || ++ 100*(tl + p->se.load.weight) <= imbalance*load) { ++ /* ++ * This domain has SD_WAKE_AFFINE and ++ * p is cache cold in this domain, and ++ * there is no bad imbalance. ++ */ ++ schedstat_inc(this_sd, ttwu_move_affine); ++ schedstat_inc(p, se.nr_wakeups_affine); ++ goto out_set_cpu; ++ } ++ } ++ ++ /* ++ * Start passive balancing when half the imbalance_pct ++ * limit is reached. ++ */ ++ if (this_sd->flags & SD_WAKE_BALANCE) { ++ if (imbalance*this_load <= 100*load) { ++ schedstat_inc(this_sd, ttwu_move_balance); ++ schedstat_inc(p, se.nr_wakeups_passive); ++ goto out_set_cpu; ++ } ++ } ++ } ++ ++ new_cpu = cpu; /* Could not wake to this_cpu. Wake to cpu instead */ ++out_set_cpu: ++ return wake_idle(new_cpu, p); ++} ++#endif /* CONFIG_SMP */ ++ ++ ++/* + * Preempt the current task with a newly woken task if needed: + */ + static void check_preempt_wakeup(struct rq *rq, struct task_struct *p) +@@ -1108,6 +1253,9 @@ static const struct sched_class fair_sch + .enqueue_task = enqueue_task_fair, + .dequeue_task = dequeue_task_fair, + .yield_task = yield_task_fair, ++#ifdef CONFIG_SMP ++ .select_task_rq = select_task_rq_fair, ++#endif /* CONFIG_SMP */ + + .check_preempt_curr = check_preempt_wakeup, + +Index: linux-2.6.24.7-rt21/kernel/sched_idletask.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched_idletask.c 2008-10-08 22:22:47.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched_idletask.c 2008-10-08 22:22:58.000000000 -0400 +@@ -5,6 +5,12 @@ + * handled in sched_fair.c) + */ + ++#ifdef CONFIG_SMP ++static int select_task_rq_idle(struct task_struct *p, int sync) ++{ ++ return task_cpu(p); /* IDLE tasks as never migrated */ ++} ++#endif /* CONFIG_SMP */ + /* + * Idle tasks are unconditionally rescheduled: + */ +@@ -72,6 +78,9 @@ const struct sched_class idle_sched_clas + + /* dequeue is not valid, we print a debug message there: */ + .dequeue_task = dequeue_task_idle, ++#ifdef CONFIG_SMP ++ .select_task_rq = select_task_rq_idle, ++#endif /* CONFIG_SMP */ + + .check_preempt_curr = check_preempt_curr_idle, + +Index: linux-2.6.24.7-rt21/kernel/sched_rt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched_rt.c 2008-10-08 22:22:57.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched_rt.c 2008-10-08 22:22:58.000000000 -0400 +@@ -146,6 +146,13 @@ yield_task_rt(struct rq *rq) + requeue_task_rt(rq, rq->curr); + } + ++#ifdef CONFIG_SMP ++static int select_task_rq_rt(struct task_struct *p, int sync) ++{ ++ return task_cpu(p); ++} ++#endif /* CONFIG_SMP */ ++ + /* + * Preempt the current task with a newly woken task if needed: + */ +@@ -663,6 +670,9 @@ const struct sched_class rt_sched_class + .enqueue_task = enqueue_task_rt, + .dequeue_task = dequeue_task_rt, + .yield_task = yield_task_rt, ++#ifdef CONFIG_SMP ++ .select_task_rq = select_task_rq_rt, ++#endif /* CONFIG_SMP */ + + .check_preempt_curr = check_preempt_curr_rt, + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0056-0044-sched-remove-some-old-cpuset-logic.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0056-0044-sched-remove-some-old-cpuset-logic.patch @@ -0,0 +1,67 @@ +From 4115ceb4075bf6156a26446777eef274de82610e Mon Sep 17 00:00:00 2001 +From: Gregory Haskins +Date: Tue, 11 Dec 2007 10:02:48 +0100 +Subject: [PATCH] sched: remove some old cpuset logic + +We had support for overlapping cpuset based rto logic in early +prototypes that is no longer used, so remove it. + +Signed-off-by: Gregory Haskins +Signed-off-by: Steven Rostedt +Signed-off-by: Ingo Molnar + +--- + kernel/sched_rt.c | 33 --------------------------------- + 1 file changed, 33 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/sched_rt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched_rt.c 2008-10-08 22:23:04.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched_rt.c 2008-10-08 22:23:05.000000000 -0400 +@@ -582,38 +582,6 @@ static int pull_rt_task(struct rq *this_ + continue; + + src_rq = cpu_rq(cpu); +- if (unlikely(src_rq->rt.rt_nr_running <= 1)) { +- /* +- * It is possible that overlapping cpusets +- * will miss clearing a non overloaded runqueue. +- * Clear it now. +- */ +- if (double_lock_balance(this_rq, src_rq)) { +- /* unlocked our runqueue lock */ +- struct task_struct *old_next = next; +- +- next = pick_next_task_rt(this_rq); +- if (next != old_next) +- ret = 1; +- } +- if (likely(src_rq->rt.rt_nr_running <= 1)) { +- /* +- * Small chance that this_rq->curr changed +- * but it's really harmless here. +- */ +- rt_clear_overload(this_rq); +- } else { +- /* +- * Heh, the src_rq is now overloaded, since +- * we already have the src_rq lock, go straight +- * to pulling tasks from it. +- */ +- goto try_pulling; +- } +- spin_unlock(&src_rq->lock); +- continue; +- } +- + /* + * We can potentially drop this_rq's lock in + * double_lock_balance, and another CPU could +@@ -637,7 +605,6 @@ static int pull_rt_task(struct rq *this_ + continue; + } + +- try_pulling: + p = pick_next_highest_task_rt(src_rq, this_cpu); + + /* --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0342-schedule_on_each_cpu-enhance.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0342-schedule_on_each_cpu-enhance.patch @@ -0,0 +1,143 @@ +It always bothered me a bit that on_each_cpu() and +schedule_on_each_cpu() had wildly different interfaces. + +Rectify this and convert the sole in-kernel user to the new interface. + +Signed-off-by: Peter Zijlstra +Acked-by: Ingo Molnar +--- + include/linux/workqueue.h | 2 - + kernel/workqueue.c | 63 ++++++++++++++++++++++++++++++++++++++-------- + mm/swap.c | 4 +- + 3 files changed, 56 insertions(+), 13 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/workqueue.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/workqueue.h 2008-10-08 22:24:10.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/workqueue.h 2008-10-08 22:24:26.000000000 -0400 +@@ -196,7 +196,7 @@ extern int FASTCALL(schedule_delayed_wor + extern int schedule_delayed_work_on(int cpu, struct delayed_work *work, + unsigned long delay); + extern int schedule_on_each_cpu_wq(struct workqueue_struct *wq, work_func_t func); +-extern int schedule_on_each_cpu(work_func_t func); ++extern int schedule_on_each_cpu(void (*func)(void *info), void *info, int retry, int wait); + extern int current_is_keventd(void); + extern int keventd_up(void); + +Index: linux-2.6.24.7-rt21/kernel/workqueue.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/workqueue.c 2008-10-08 22:24:21.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/workqueue.c 2008-10-08 22:24:26.000000000 -0400 +@@ -594,9 +594,28 @@ int schedule_delayed_work_on(int cpu, + } + EXPORT_SYMBOL(schedule_delayed_work_on); + ++struct schedule_on_each_cpu_work { ++ struct work_struct work; ++ void (*func)(void *info); ++ void *info; ++}; ++ ++static void schedule_on_each_cpu_func(struct work_struct *work) ++{ ++ struct schedule_on_each_cpu_work *w; ++ ++ w = container_of(work, typeof(*w), work); ++ w->func(w->info); ++ ++ kfree(w); ++} ++ + /** + * schedule_on_each_cpu - call a function on each online CPU from keventd + * @func: the function to call ++ * @info: data to pass to function ++ * @retry: ignored ++ * @wait: wait for completion + * + * Returns zero on success. + * Returns -ve errno on failure. +@@ -605,27 +624,51 @@ EXPORT_SYMBOL(schedule_delayed_work_on); + * + * schedule_on_each_cpu() is very slow. + */ +-int schedule_on_each_cpu(work_func_t func) ++int schedule_on_each_cpu(void (*func)(void *info), void *info, int retry, int wait) + { + int cpu; +- struct work_struct *works; ++ struct schedule_on_each_cpu_work **works; ++ int err = 0; + +- works = alloc_percpu(struct work_struct); ++ works = kzalloc(sizeof(void *)*nr_cpu_ids, GFP_KERNEL); + if (!works) + return -ENOMEM; + ++ for_each_possible_cpu(cpu) { ++ works[cpu] = kmalloc_node(sizeof(struct schedule_on_each_cpu_work), ++ GFP_KERNEL, cpu_to_node(cpu)); ++ if (!works[cpu]) { ++ err = -ENOMEM; ++ goto out; ++ } ++ } ++ + preempt_disable(); /* CPU hotplug */ + for_each_online_cpu(cpu) { +- struct work_struct *work = per_cpu_ptr(works, cpu); ++ struct schedule_on_each_cpu_work *work; + +- INIT_WORK(work, func); +- set_bit(WORK_STRUCT_PENDING, work_data_bits(work)); +- __queue_work(per_cpu_ptr(keventd_wq->cpu_wq, cpu), work); ++ work = works[cpu]; ++ works[cpu] = NULL; ++ ++ work->func = func; ++ work->info = info; ++ INIT_WORK(&work->work, schedule_on_each_cpu_func); ++ set_bit(WORK_STRUCT_PENDING, work_data_bits(&work->work)); ++ __queue_work(per_cpu_ptr(keventd_wq->cpu_wq, cpu), &work->work); + } + preempt_enable(); +- flush_workqueue(keventd_wq); +- free_percpu(works); +- return 0; ++ ++out: ++ for_each_possible_cpu(cpu) { ++ if (works[cpu]) ++ kfree(works[cpu]); ++ } ++ kfree(works); ++ ++ if (!err && wait) ++ flush_workqueue(keventd_wq); ++ ++ return err; + } + + /** +Index: linux-2.6.24.7-rt21/mm/swap.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/mm/swap.c 2008-10-08 22:23:42.000000000 -0400 ++++ linux-2.6.24.7-rt21/mm/swap.c 2008-10-08 22:24:26.000000000 -0400 +@@ -318,7 +318,7 @@ void lru_add_drain(void) + } + + #ifdef CONFIG_NUMA +-static void lru_add_drain_per_cpu(struct work_struct *dummy) ++static void lru_add_drain_per_cpu(void *info) + { + lru_add_drain(); + } +@@ -328,7 +328,7 @@ static void lru_add_drain_per_cpu(struct + */ + int lru_add_drain_all(void) + { +- return schedule_on_each_cpu(lru_add_drain_per_cpu); ++ return schedule_on_each_cpu(lru_add_drain_per_cpu, NULL, 0, 1); + } + + #else --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0532-acpi-fix-enter-c1.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0532-acpi-fix-enter-c1.patch @@ -0,0 +1,60 @@ +Subject: acpi-fix-enter-c1.patch +From: Thomas Gleixner +Date: Thu, 24 Jul 2008 01:13:43 +0200 + +Signed-off-by: Thomas Gleixner +--- + drivers/acpi/processor_idle.c | 19 ++++++++++++++++--- + 1 file changed, 16 insertions(+), 3 deletions(-) + +Index: linux-2.6.24.7-rt21/drivers/acpi/processor_idle.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/acpi/processor_idle.c 2008-10-08 22:24:00.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/acpi/processor_idle.c 2008-10-08 22:25:12.000000000 -0400 +@@ -209,7 +209,7 @@ static void acpi_safe_halt(void) + * test NEED_RESCHED: + */ + smp_mb(); +- if (!need_resched() || !need_resched_delayed()) ++ if (!need_resched() && !need_resched_delayed()) + safe_halt(); + current_thread_info()->status |= TS_POLLING; + } +@@ -382,7 +382,7 @@ static void acpi_processor_idle(void) + * Check whether we truly need to go idle, or should + * reschedule: + */ +- if (unlikely(need_resched())) { ++ if (need_resched() || need_resched_delayed()) { + local_irq_enable(); + return; + } +@@ -472,7 +472,7 @@ static void acpi_processor_idle(void) + * test NEED_RESCHED: + */ + smp_mb(); +- if (need_resched()) { ++ if (need_resched() || need_resched_delayed()) { + current_thread_info()->status |= TS_POLLING; + local_irq_enable(); + return; +@@ -1378,6 +1378,19 @@ static int acpi_idle_enter_c1(struct cpu + if (unlikely(!pr)) + return 0; + ++ local_irq_disable(); ++ ++ /* Do not access any ACPI IO ports in suspend path */ ++ if (acpi_idle_suspend) { ++ acpi_safe_halt(); ++ return 0; ++ } ++ ++ if (need_resched() || need_resched_delayed()) { ++ local_irq_enable(); ++ return 0; ++ } ++ + if (pr->flags.bm_check) + acpi_idle_update_bm_rld(pr, cx); + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0536-x86-64-fix-compile.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0536-x86-64-fix-compile.patch @@ -0,0 +1,24 @@ +Subject: x86-64-fix-compile.patch +From: Thomas Gleixner +Date: Fri, 25 Jul 2008 15:54:04 +0200 + +Signed-off-by: Thomas Gleixner +--- + kernel/trace/trace.h | 4 ++++ + 1 file changed, 4 insertions(+) + +Index: linux-2.6.24.7-rt21/kernel/trace/trace.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/trace.h 2008-10-08 22:25:02.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/trace.h 2008-10-08 22:25:13.000000000 -0400 +@@ -7,6 +7,10 @@ + #include + #include + ++#ifdef CONFIG_X86_64 ++#include ++#endif ++ + enum trace_type { + __TRACE_FIRST_TYPE = 0, + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0539-seqlock-serialize-against-writers.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0539-seqlock-serialize-against-writers.patch @@ -0,0 +1,191 @@ +From ghaskins@novell.com Tue Sep 2 09:41:54 2008 +Date: Tue, 02 Sep 2008 09:29:18 -0400 +From: Gregory Haskins +To: mingo@elte.hu, rostedt@goodmis.org, tglx@linutronix.de +Cc: linux-kernel@vger.kernel.org, linux-rt-users@vger.kernel.org, gregory.haskins@gmail.com, andi@firstfloor.org, shemminger@vyatta.com +Subject: [RT PATCH v4] seqlock: serialize against writers + + [ The following text is in the "utf-8" character set. ] + [ Your display is set for the "ANSI_X3.4-1968" character set. ] + [ Some characters may be displayed incorrectly. ] + +[ here is the updated prologue rebased against the proper tree (26.3-rt3) ] + +-------------------------- + +seqlock: serialize against writers + +There are currently several problems in -rt w.r.t. seqlock objects. RT +moves mainline seqlock_t to "raw_seqlock_t", and creates a new seqlock_t +object that is fully preemptible. Being preemptible is a great step +towards deterministic behavior, but there are a few areas that need +additional measures to protect new vulnerabilities created by the +preemptible code. For the purposes of demonstration, consider three tasks +of different priority: A, B, and C. A is the logically highest, and C is +the lowest. A is trying to acquire a seqlock read critical section, while +C is involved in write locks. + +Problem 1) If A spins in seqbegin due to writer contention retries, it may +prevent C from running even if C currently holds the write lock. This +is a deadlock. + +Problem 2) B may preempt C, preventing it from releasing the write +critical section. In this case, A becomes inverted behind B. + +Problem 3) Lower priority tasks such as C may continually acquire the write +section which subsequently causes A to continually retry and thus fail to +make forward progress. Since C is lower priority it ideally should not +cause delays in A. E.g. C should block if A is in a read-lock and C is <= A. + +This patch addresses Problems 1 & 2, and leaves 3 for a later time. + +This patch changes the internal seqlock_t implementation to substitute +a rwlock for the basic spinlock previously used, and forces the readers +to serialize with the writers under contention. Blocking on the read_lock +simultaneously sleeps A (preventing problem 1), while boosting C to A's +priority (preventing problem 2). Non reader-to-writer contended +acquisitions, which are the predominant mode, remain free of atomic +operations. Therefore the fast path should not be perturbed by this +change. + +This fixes a real-world deadlock discovered under testing where all +high priority readers were hogging the cpus and preventing a writer +from releasing the lock (i.e. problem 1). + +Signed-off-by: Gregory Haskins +--- + + include/linux/seqlock.h | 55 +++++++++++++++++++++++++++--------------------- + 1 file changed, 31 insertions(+), 24 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/seqlock.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/seqlock.h 2008-10-08 22:24:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/seqlock.h 2008-10-08 22:25:13.000000000 -0400 +@@ -3,9 +3,11 @@ + /* + * Reader/writer consistent mechanism without starving writers. This type of + * lock for data where the reader wants a consistent set of information +- * and is willing to retry if the information changes. Readers never +- * block but they may have to retry if a writer is in +- * progress. Writers do not wait for readers. ++ * and is willing to retry if the information changes. Readers block ++ * on write contention (and where applicable, pi-boost the writer). ++ * Readers without contention on entry acquire the critical section ++ * without any atomic operations, but they may have to retry if a writer ++ * enters before the critical section ends. Writers do not wait for readers. + * + * This is not as cache friendly as brlock. Also, this will not work + * for data that contains pointers, because any writer could +@@ -24,6 +26,8 @@ + * + * Based on x86_64 vsyscall gettimeofday + * by Keith Owens and Andrea Arcangeli ++ * ++ * Priority inheritance and live-lock avoidance by Gregory Haskins + */ + + #include +@@ -31,7 +35,7 @@ + + typedef struct { + unsigned sequence; +- spinlock_t lock; ++ rwlock_t lock; + } __seqlock_t; + + typedef struct { +@@ -57,7 +61,7 @@ typedef __raw_seqlock_t raw_seqlock_t; + { 0, RAW_SPIN_LOCK_UNLOCKED(lockname) } + + #ifdef CONFIG_PREEMPT_RT +-# define __SEQLOCK_UNLOCKED(lockname) { 0, __SPIN_LOCK_UNLOCKED(lockname) } ++# define __SEQLOCK_UNLOCKED(lockname) { 0, __RW_LOCK_UNLOCKED(lockname) } + #else + # define __SEQLOCK_UNLOCKED(lockname) __RAW_SEQLOCK_UNLOCKED(lockname) + #endif +@@ -69,7 +73,7 @@ typedef __raw_seqlock_t raw_seqlock_t; + do { *(x) = (raw_seqlock_t) __RAW_SEQLOCK_UNLOCKED(x); spin_lock_init(&(x)->lock); } while (0) + + #define seqlock_init(x) \ +- do { *(x) = (seqlock_t) __SEQLOCK_UNLOCKED(x); spin_lock_init(&(x)->lock); } while (0) ++ do { *(x) = (seqlock_t) __SEQLOCK_UNLOCKED(x); rwlock_init(&(x)->lock); } while (0) + + #define DEFINE_SEQLOCK(x) \ + seqlock_t x = __SEQLOCK_UNLOCKED(x) +@@ -85,7 +89,7 @@ typedef __raw_seqlock_t raw_seqlock_t; + */ + static inline void __write_seqlock(seqlock_t *sl) + { +- spin_lock(&sl->lock); ++ write_lock(&sl->lock); + ++sl->sequence; + smp_wmb(); + } +@@ -103,14 +107,14 @@ static inline void __write_sequnlock(seq + { + smp_wmb(); + sl->sequence++; +- spin_unlock(&sl->lock); ++ write_unlock(&sl->lock); + } + + #define __write_sequnlock_irqrestore(sl, flags) __write_sequnlock(sl) + + static inline int __write_tryseqlock(seqlock_t *sl) + { +- int ret = spin_trylock(&sl->lock); ++ int ret = write_trylock(&sl->lock); + + if (ret) { + ++sl->sequence; +@@ -120,10 +124,25 @@ static inline int __write_tryseqlock(seq + } + + /* Start of read calculation -- fetch last complete writer token */ +-static __always_inline unsigned __read_seqbegin(const seqlock_t *sl) ++static __always_inline unsigned __read_seqbegin(seqlock_t *sl) + { +- unsigned ret = sl->sequence; ++ unsigned ret; ++ ++ ret = sl->sequence; + smp_rmb(); ++ if (unlikely(ret & 1)) { ++ /* ++ * Serialze with the writer which will ensure they are ++ * pi-boosted if necessary and prevent us from starving ++ * them. ++ */ ++ read_lock(&sl->lock); ++ ret = sl->sequence; ++ read_unlock(&sl->lock); ++ } ++ ++ BUG_ON(ret & 1); ++ + return ret; + } + +@@ -137,20 +156,8 @@ static __always_inline unsigned __read_s + */ + static inline int __read_seqretry(seqlock_t *sl, unsigned iv) + { +- int ret; +- + smp_rmb(); +- ret = (iv & 1) | (sl->sequence ^ iv); +- /* +- * If invalid then serialize with the writer, to make sure we +- * are not livelocking it: +- */ +- if (unlikely(ret)) { +- unsigned long flags; +- spin_lock_irqsave(&sl->lock, flags); +- spin_unlock_irqrestore(&sl->lock, flags); +- } +- return ret; ++ return (sl->sequence != iv); + } + + static __always_inline void __write_seqlock_raw(raw_seqlock_t *sl) --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0561-rwlock-update-torture-test.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0561-rwlock-update-torture-test.patch @@ -0,0 +1,289 @@ +From: Steven Rostedt +Subject: rwlock: update torture test for testing unnested locking + +Signed-off-by: Steven Rostedt +--- + kernel/rwlock_torture.c | 126 +++++++++++++++++++++++++++++++++++------------- + 1 file changed, 94 insertions(+), 32 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/rwlock_torture.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rwlock_torture.c 2008-10-08 22:25:06.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rwlock_torture.c 2008-10-08 22:25:19.000000000 -0400 +@@ -13,7 +13,20 @@ + + #ifdef CONFIG_LOGDEV + #include ++#define LD_WARN_ON_ONCE(cond) \ ++ do { \ ++ static int once; \ ++ if (unlikely(cond) && !once++) { \ ++ lfcnprint("FAILED " #cond); \ ++ logdev_print_off(); \ ++ oops_in_progress++; \ ++ logdev_dump(); \ ++ WARN_ON(1); \ ++ oops_in_progress--; \ ++ } \ ++ } while (0) + #else ++#define LD_WARN_ON_ONCE(cond) WARN_ON_ONCE(cond) + #define lfcnprint(x...) do { } while (0) + #define lmark() do { } while(0) + #define logdev_dump() do { } while (0) +@@ -31,19 +44,30 @@ static DEFINE_MUTEX(mutex1); + static DEFINE_MUTEX(mutex2); + static DEFINE_MUTEX(mutex3); + ++static DEFINE_SPINLOCK(reverse_lock); ++ + struct locks { + union { + struct rw_semaphore *sem; + rwlock_t *lock; + struct mutex *mutex; + }; ++ + int type; + char *name; ++ ++ /* to test unnested locks */ ++ struct locks *reverse_lock; ++ int reverse_read; ++ struct task_struct *who; ++ ++ /* stats */ + int read_cnt; + int write_cnt; + int downgrade; + int taken; + int retaken; ++ int reversed; + }; + + enum { LOCK_TYPE_LOCK = 0, +@@ -306,6 +330,7 @@ pick_lock(struct locks *lock, struct loc + + static void do_lock(struct locks *lock, int read) + { ++ lfcnprint("reader_lock_count=%d", current->reader_lock_count); + switch (read) { + case LOCK_READ: + if (unlikely(lock->type != LOCK_TYPE_LOCK)) { +@@ -363,8 +388,29 @@ static void do_lock(struct locks *lock, + lfcnprint("taken %s %p", lock->name, lock); + } + +-static void do_unlock(struct locks *lock, int read) ++static void do_unlock(struct locks *lock, int read, struct locks *prev_lock) + { ++ if (prev_lock) { ++ spin_lock(&reverse_lock); ++ if (!prev_lock->reverse_lock) { ++ int x; ++ /* test reverse order unlocking */ ++ x = random32(); ++ if (x & 1) { ++ lfcnprint("reverse lock %s %p and %s %p", ++ lock->name, lock, ++ prev_lock->name, prev_lock); ++ prev_lock->reverse_lock = lock; ++ prev_lock->reverse_read = read; ++ prev_lock->who = current; ++ lock->reversed++; ++ spin_unlock(&reverse_lock); ++ return; ++ } ++ } ++ spin_unlock(&reverse_lock); ++ } ++ + switch (read) { + case LOCK_READ: + if (unlikely(lock->type != LOCK_TYPE_LOCK)) { +@@ -418,10 +464,18 @@ static void do_unlock(struct locks *lock + default: + printk("bad lock value %d!!!\n", read); + } +- lfcnprint("unlocked"); ++ lfcnprint("%s unlocked", lock->name); ++ ++ if (lock->reverse_lock && lock->who == current) { ++ lock->who = NULL; ++ lfcnprint("unlock reverse lock %s %p", ++ lock->reverse_lock->name, lock->reverse_lock); ++ do_unlock(lock->reverse_lock, lock->reverse_read, NULL); ++ lock->reverse_lock = NULL; ++ } + } + +-static void do_something(unsigned long time, int ignore) ++static void do_something(unsigned long time, int ignore, struct locks *prev_lock) + { + lmark(); + if (test_done) +@@ -450,7 +504,7 @@ static void do_downgrade(unsigned long t + lfcnprint("downgrade %p", sem); + lock->downgrade++; + downgrade_write(sem); +- do_something(time, 0); ++ do_something(time, 0, NULL); + /* need to do unlock read */ + *read = SEM_READ; + } +@@ -474,10 +528,11 @@ static void update_stats(int read, struc + + #define MAX_DEPTH 10 + +-static void run_lock(void (*func)(unsigned long time, int read), +- struct locks *lock, unsigned long time, int read, int depth); ++static void run_lock(void (*func)(unsigned long time, int read, struct locks *prev_lock), ++ struct locks *lock, unsigned long time, int read, int depth, ++ struct locks *prev_lock); + +-static void do_again(void (*func)(unsigned long time, int read), ++static void do_again(void (*func)(unsigned long time, int read, struct locks *prev_lock), + struct locks *lock, unsigned long time, int read, int depth) + { + unsigned long x; +@@ -485,19 +540,23 @@ static void do_again(void (*func)(unsign + if (test_done) + return; + +- /* If this was grabbed for read via rwlock, do again */ +- if (likely(read != LOCK_READ) || depth >= MAX_DEPTH) ++ /* ++ * If this was grabbed for read via rwlock, do again ++ * (but not if we did a reverse) ++ */ ++ if (likely(read != LOCK_READ) || depth >= MAX_DEPTH || lock->reverse_lock) + return; + + x = random32(); + if (x & 1) { + lfcnprint("read lock again"); +- run_lock(func, lock, time, read, depth+1); ++ run_lock(func, lock, time, read, depth+1, NULL); + } + } + +-static void run_lock(void (*func)(unsigned long time, int read), +- struct locks *lock, unsigned long time, int read, int depth) ++static void run_lock(void (*func)(unsigned long time, int read, struct locks *prev_lock), ++ struct locks *lock, unsigned long time, int read, int depth, ++ struct locks *prev_lock) + { + if (test_done) + return; +@@ -507,39 +566,39 @@ static void run_lock(void (*func)(unsign + lock->retaken++; + do_lock(lock, read); + if (!test_done) { +- func(time, do_read(read)); ++ func(time, do_read(read), lock); + do_again(func, lock, time, read, depth); + } + do_downgrade(time, lock, &read); +- do_unlock(lock, read); ++ do_unlock(lock, read, prev_lock); + + } + +-static void run_one_lock(unsigned long time, int read) ++static void run_one_lock(unsigned long time, int read, struct locks *prev_lock) + { + struct locks *lock; + + lmark(); + lock = pick_lock(&test_lock1, &test_sem1, &test_mutex1, read); +- run_lock(do_something, lock, time, read, 0); ++ run_lock(do_something, lock, time, read, 0, prev_lock); + } + +-static void run_two_locks(unsigned long time, int read) ++static void run_two_locks(unsigned long time, int read, struct locks *prev_lock) + { + struct locks *lock; + + lmark(); + lock = pick_lock(&test_lock2, &test_sem2, &test_mutex2, read); +- run_lock(run_one_lock, lock, time, read, 0); ++ run_lock(run_one_lock, lock, time, read, 0, prev_lock); + } + +-static void run_three_locks(unsigned long time, int read) ++static void run_three_locks(unsigned long time, int read, struct locks *prev_lock) + { + struct locks *lock; + + lmark(); + lock = pick_lock(&test_lock3, &test_sem3, &test_mutex3, read); +- run_lock(run_two_locks, lock, time, read, 0); ++ run_lock(run_two_locks, lock, time, read, 0, prev_lock); + } + + static int run_test(unsigned long time) +@@ -557,22 +616,20 @@ static int run_test(unsigned long time) + + switch (ret = (start & 3)) { + case 0: +- run_one_lock(time, read); ++ run_one_lock(time, read, NULL); + break; + case 1: +- run_two_locks(time, read); ++ run_two_locks(time, read, NULL); + break; + case 2: +- run_three_locks(time, read); ++ run_three_locks(time, read, NULL); + break; + default: + ret = 1; +- run_two_locks(time, read); ++ run_two_locks(time, read, NULL); + } + +-#ifdef CONFIG_PREEMPT_RT +- WARN_ON_ONCE(current->reader_lock_count); +-#endif ++ LD_WARN_ON_ONCE(current->reader_lock_count); + + return ret; + } +@@ -618,7 +675,8 @@ static void print_lock_stat(struct locks + lock->name, lock->downgrade); + } + } +- printk("%8s taken: %8d\n\n", lock->name, lock->taken); ++ printk("%8s taken: %8d\n", lock->name, lock->taken); ++ printk("%8s reversed: %8d\n\n", lock->name, lock->reversed); + } + + static int __init mutex_stress_init(void) +@@ -676,7 +734,12 @@ static int __init mutex_stress_init(void + if (tsks[i]) { + struct rt_mutex *mtx; + unsigned long own; +- struct rt_mutex_waiter *w; ++ struct rt_my_waiter { ++ struct plist_node list_entry; ++ struct plist_node pi_list_entry; ++ struct task_struct *task; ++ struct rt_mutex *lock; ++ } *w; + + spin_lock_irq(&tsks[i]->pi_lock); + +@@ -690,9 +753,8 @@ static int __init mutex_stress_init(void + spin_lock(&tsks[i]->pi_lock); + own = (unsigned long)mtx->owner & ~3UL; + oops_in_progress++; +- printk("%s:%d is blocked on ", +- tsks[i]->comm, tsks[i]->pid); +- __print_symbol("%s", (unsigned long)mtx); ++ printk("%s:%d is blocked on %p ", ++ tsks[i]->comm, tsks[i]->pid, mtx); + if (own == 0x100) + printk(" owner is READER\n"); + else if (!(own & ~300)) --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0475-adaptive-task-oncpu.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0475-adaptive-task-oncpu.patch @@ -0,0 +1,145 @@ +From ghaskins@novell.com Fri May 23 23:32:44 2008 +Date: Tue, 20 May 2008 10:49:20 -0400 +From: Gregory Haskins +To: mingo@elte.hu, tglx@linutronix.de, rostedt@goodmis.org, + linux-rt-users@vger.kernel.org +Cc: linux-kernel@vger.kernel.org, sdietrich@novell.com, pmorreale@novell.com, + mkohari@novell.com, ghaskins@novell.com +Subject: [PATCH 2/5] sched: make task->oncpu available in all configurations + + [ The following text is in the "utf-8" character set. ] + [ Your display is set for the "iso-8859-1" character set. ] + [ Some characters may be displayed incorrectly. ] + +We will use this later in the series to eliminate the need for a function +call. + +[ Steven Rostedt: added task_is_current function ] + +Signed-off-by: Gregory Haskins +--- + + include/linux/sched.h | 9 ++++++--- + kernel/sched.c | 37 ++++++++++++++++++++++++++----------- + 2 files changed, 32 insertions(+), 14 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/sched.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/sched.h 2008-10-08 22:24:55.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/sched.h 2008-10-08 22:24:58.000000000 -0400 +@@ -1027,10 +1027,8 @@ struct task_struct { + int lock_depth; /* BKL lock depth */ + + #ifdef CONFIG_SMP +-#ifdef __ARCH_WANT_UNLOCKED_CTXSW + int oncpu; + #endif +-#endif + + int prio, static_prio, normal_prio; + #ifdef CONFIG_PREEMPT_RCU_BOOST +@@ -2235,7 +2233,12 @@ static inline void migration_init(void) + } + #endif + +-extern int task_is_current(struct task_struct *task); ++#ifdef CONFIG_SMP ++static inline int task_is_current(struct task_struct *task) ++{ ++ return task->oncpu; ++} ++#endif + + #define TASK_STATE_TO_CHAR_STR "RMSDTtZX" + +Index: linux-2.6.24.7-rt21/kernel/sched.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched.c 2008-10-08 22:24:55.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched.c 2008-10-08 22:24:58.000000000 -0400 +@@ -575,10 +575,12 @@ int runqueue_is_locked(void) + return ret; + } + ++#ifndef CONFIG_SMP + int task_is_current(struct task_struct *task) + { + return task_rq(task)->curr == task; + } ++#endif + + /* + * Debugging: various feature bits +@@ -661,18 +663,39 @@ static inline int task_current(struct rq + return rq->curr == p; + } + +-#ifndef __ARCH_WANT_UNLOCKED_CTXSW + static inline int task_running(struct rq *rq, struct task_struct *p) + { ++#ifdef CONFIG_SMP ++ return p->oncpu; ++#else + return task_current(rq, p); ++#endif + } + ++#ifndef __ARCH_WANT_UNLOCKED_CTXSW + static inline void prepare_lock_switch(struct rq *rq, struct task_struct *next) + { ++#ifdef CONFIG_SMP ++ /* ++ * We can optimise this out completely for !SMP, because the ++ * SMP rebalancing from interrupt is the only thing that cares ++ * here. ++ */ ++ next->oncpu = 1; ++#endif + } + + static inline void finish_lock_switch(struct rq *rq, struct task_struct *prev) + { ++#ifdef CONFIG_SMP ++ /* ++ * After ->oncpu is cleared, the task can be moved to a different CPU. ++ * We must ensure this doesn't happen until the switch is completely ++ * finished. ++ */ ++ smp_wmb(); ++ prev->oncpu = 0; ++#endif + #ifdef CONFIG_DEBUG_SPINLOCK + /* this is a valid case when another task releases the spinlock */ + rq->lock.owner = current; +@@ -688,14 +711,6 @@ static inline void finish_lock_switch(st + } + + #else /* __ARCH_WANT_UNLOCKED_CTXSW */ +-static inline int task_running(struct rq *rq, struct task_struct *p) +-{ +-#ifdef CONFIG_SMP +- return p->oncpu; +-#else +- return task_current(rq, p); +-#endif +-} + + static inline void prepare_lock_switch(struct rq *rq, struct task_struct *next) + { +@@ -1863,7 +1878,7 @@ void sched_fork(struct task_struct *p, i + if (likely(sched_info_on())) + memset(&p->sched_info, 0, sizeof(p->sched_info)); + #endif +-#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW) ++#if defined(CONFIG_SMP) + p->oncpu = 0; + #endif + #ifdef CONFIG_PREEMPT +@@ -5507,7 +5522,7 @@ void __cpuinit init_idle(struct task_str + + spin_lock_irqsave(&rq->lock, flags); + rq->curr = rq->idle = idle; +-#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW) ++#if defined(CONFIG_SMP) + idle->oncpu = 1; + #endif + spin_unlock_irqrestore(&rq->lock, flags); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0542-lockdep-debug-type-fix.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0542-lockdep-debug-type-fix.patch @@ -0,0 +1,33 @@ +From: Steven Rostedt +Subject: lockdep: fix debug lock counting + +The change to convert the task count to atomic_t did not take into +consideration debugging. + +Signed-off-by: Steven Rostedt +--- + lib/locking-selftest.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/lib/locking-selftest.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/lib/locking-selftest.c 2008-10-08 22:23:59.000000000 -0400 ++++ linux-2.6.24.7-rt21/lib/locking-selftest.c 2008-10-08 22:25:14.000000000 -0400 +@@ -948,7 +948,7 @@ static void dotest(void (*testcase_fn)(v + unsigned long saved_preempt_count = preempt_count(); + int expected_failure = 0; + #if defined(CONFIG_DEBUG_PREEMPT) && defined(CONFIG_DEBUG_RT_MUTEXES) +- int saved_lock_count = current->lock_count; ++ long saved_lock_count = atomic_read(¤t->lock_count); + #endif + + WARN_ON(irqs_disabled()); +@@ -1000,7 +1000,7 @@ static void dotest(void (*testcase_fn)(v + + reset_locks(); + #if defined(CONFIG_DEBUG_PREEMPT) && defined(CONFIG_DEBUG_RT_MUTEXES) +- current->lock_count = saved_lock_count; ++ atomic_set(¤t->lock_count, saved_lock_count); + #endif + } + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0071-trace-events-handle-syscalls.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0071-trace-events-handle-syscalls.patch @@ -0,0 +1,345 @@ +Add syscall tracing in event trace. + +Signed-off-by: Steven Rostedt +--- + kernel/trace/trace.c | 104 ++++++++++++++++++++++++++++++++++++++++++ + kernel/trace/trace.h | 30 ++++++++++++ + kernel/trace/trace_events.c | 92 +++++++++++++++++++++++++++++++++++++ + kernel/trace/trace_selftest.c | 2 + 4 files changed, 228 insertions(+) + +Index: linux-2.6.24.7-rt21/kernel/trace/trace.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/trace.c 2008-10-08 22:23:08.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/trace.c 2008-10-08 22:23:09.000000000 -0400 +@@ -31,6 +31,9 @@ + + #include + ++#include ++#include ++ + #include "trace.h" + + unsigned long __read_mostly tracing_max_latency = (cycle_t)ULONG_MAX; +@@ -1126,6 +1129,42 @@ void tracing_event_task_deactivate(struc + entry->task.cpu = task_cpu; + } + ++void tracing_event_syscall(struct trace_array *tr, ++ struct trace_array_cpu *data, ++ unsigned long flags, ++ unsigned long ip, ++ unsigned long nr, ++ unsigned long p1, ++ unsigned long p2, ++ unsigned long p3) ++{ ++ struct trace_entry *entry; ++ ++ entry = tracing_get_trace_entry(tr, data); ++ tracing_generic_entry_update(entry, flags); ++ entry->type = TRACE_SYSCALL; ++ entry->syscall.ip = ip; ++ entry->syscall.nr = nr; ++ entry->syscall.p1 = p1; ++ entry->syscall.p2 = p2; ++ entry->syscall.p3 = p3; ++} ++ ++void tracing_event_sysret(struct trace_array *tr, ++ struct trace_array_cpu *data, ++ unsigned long flags, ++ unsigned long ip, ++ unsigned long ret) ++{ ++ struct trace_entry *entry; ++ ++ entry = tracing_get_trace_entry(tr, data); ++ tracing_generic_entry_update(entry, flags); ++ entry->type = TRACE_SYSRET; ++ entry->sysret.ip = ip; ++ entry->sysret.ret = ret; ++} ++ + #ifdef CONFIG_FTRACE + static void + function_trace_call(unsigned long ip, unsigned long parent_ip) +@@ -1559,6 +1598,13 @@ lat_print_timestamp(struct trace_seq *s, + + static const char state_to_char[] = TASK_STATE_TO_CHAR_STR; + ++extern unsigned long sys_call_table[NR_syscalls]; ++ ++#if defined(CONFIG_COMPAT) && defined(CONFIG_X86) ++extern unsigned long ia32_sys_call_table[], ia32_syscall_end[]; ++# define IA32_NR_syscalls (ia32_syscall_end - ia32_sys_call_table) ++#endif ++ + static int + print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) + { +@@ -1569,6 +1615,7 @@ print_lat_fmt(struct trace_iterator *ite + struct trace_entry *entry = iter->ent; + unsigned long abs_usecs; + unsigned long rel_usecs; ++ unsigned long nr; + char *comm; + int S, T; + int i; +@@ -1680,6 +1727,34 @@ print_lat_fmt(struct trace_iterator *ite + comm, entry->task.pid, + entry->task.prio, entry->task.cpu); + break; ++ case TRACE_SYSCALL: ++ seq_print_ip_sym(s, entry->syscall.ip, sym_flags); ++ nr = entry->syscall.nr; ++ trace_seq_putc(s, ' '); ++#if defined(CONFIG_COMPAT) && defined(CONFIG_X86) ++ if (nr & 0x80000000) { ++ nr &= ~0x80000000; ++ if (nr < IA32_NR_syscalls) ++ seq_print_ip_sym(s, ia32_sys_call_table[nr], 0); ++ else ++ trace_seq_printf(s, "", nr); ++ } else ++#endif ++ if (nr < NR_syscalls) ++ seq_print_ip_sym(s, sys_call_table[nr], 0); ++ else ++ trace_seq_printf(s, "", nr); ++ ++ trace_seq_printf(s, " (%lx %lx %lx)\n", ++ entry->syscall.p1, ++ entry->syscall.p2, ++ entry->syscall.p3); ++ break; ++ case TRACE_SYSRET: ++ seq_print_ip_sym(s, entry->sysret.ip, sym_flags); ++ trace_seq_printf(s, " < (%ld)\n", ++ entry->sysret.ret); ++ break; + default: + trace_seq_printf(s, "Unknown type %d\n", entry->type); + } +@@ -1694,6 +1769,7 @@ static int print_trace_fmt(struct trace_ + unsigned long usec_rem; + unsigned long long t; + unsigned long secs; ++ long nr; + char *comm; + int ret; + int S, T; +@@ -1826,6 +1902,34 @@ static int print_trace_fmt(struct trace_ + comm, entry->task.pid, + entry->task.prio, entry->task.cpu); + break; ++ case TRACE_SYSCALL: ++ seq_print_ip_sym(s, entry->syscall.ip, sym_flags); ++ nr = entry->syscall.nr; ++ trace_seq_putc(s, ' '); ++#if defined(CONFIG_COMPAT) && defined(CONFIG_X86) ++ if (nr & 0x80000000) { ++ nr &= ~0x80000000; ++ if (nr < IA32_NR_syscalls) ++ seq_print_ip_sym(s, ia32_sys_call_table[nr], 0); ++ else ++ trace_seq_printf(s, "", nr); ++ } else ++#endif ++ if (nr < NR_syscalls) ++ seq_print_ip_sym(s, sys_call_table[nr], 0); ++ else ++ trace_seq_printf(s, "", nr); ++ ++ trace_seq_printf(s, " (%lx %lx %lx)\n", ++ entry->syscall.p1, ++ entry->syscall.p2, ++ entry->syscall.p3); ++ break; ++ case TRACE_SYSRET: ++ seq_print_ip_sym(s, entry->sysret.ip, sym_flags); ++ trace_seq_printf(s, "< (%ld)\n", ++ entry->sysret.ret); ++ break; + default: + trace_seq_printf(s, "Unknown type %d\n", entry->type); + } +Index: linux-2.6.24.7-rt21/kernel/trace/trace.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/trace.h 2008-10-08 22:23:08.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/trace.h 2008-10-08 22:23:09.000000000 -0400 +@@ -24,6 +24,8 @@ enum trace_type { + TRACE_TIMESTAMP, + TRACE_TASK_ACT, + TRACE_TASK_DEACT, ++ TRACE_SYSCALL, ++ TRACE_SYSRET, + + __TRACE_LAST_TYPE + }; +@@ -96,6 +98,19 @@ struct wakeup_entry { + unsigned curr_prio; + }; + ++struct syscall_entry { ++ unsigned long ip; ++ unsigned long nr; ++ unsigned long p1; ++ unsigned long p2; ++ unsigned long p3; ++}; ++ ++struct sysret_entry { ++ unsigned long ip; ++ unsigned long ret; ++}; ++ + /* + * Stack-trace entry: + */ +@@ -132,6 +147,8 @@ struct trace_entry { + struct timestamp_entry timestamp; + struct task_entry task; + struct wakeup_entry wakeup; ++ struct syscall_entry syscall; ++ struct sysret_entry sysret; + }; + }; + +@@ -320,6 +337,19 @@ void tracing_event_wakeup(struct trace_a + unsigned long ip, + pid_t pid, int prio, + int curr_prio); ++void tracing_event_syscall(struct trace_array *tr, ++ struct trace_array_cpu *data, ++ unsigned long flags, ++ unsigned long ip, ++ unsigned long nr, ++ unsigned long p1, ++ unsigned long p2, ++ unsigned long p3); ++void tracing_event_sysret(struct trace_array *tr, ++ struct trace_array_cpu *data, ++ unsigned long flags, ++ unsigned long ip, ++ unsigned long ret); + + void tracing_start_cmdline_record(void); + void tracing_stop_cmdline_record(void); +Index: linux-2.6.24.7-rt21/kernel/trace/trace_events.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/trace_events.c 2008-10-08 22:23:08.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/trace_events.c 2008-10-08 22:23:09.000000000 -0400 +@@ -34,6 +34,98 @@ static void event_reset(struct trace_arr + tr->time_start = ftrace_now(raw_smp_processor_id()); + } + ++/* HACK */ ++void notrace ++sys_call(unsigned long nr, unsigned long p1, unsigned long p2, unsigned long p3) ++{ ++ struct trace_array *tr; ++ struct trace_array_cpu *data; ++ unsigned long flags; ++ unsigned long ip; ++ int cpu; ++ ++ if (!tracer_enabled) ++ return; ++ ++ tr = events_trace; ++ local_irq_save(flags); ++ cpu = raw_smp_processor_id(); ++ data = tr->data[cpu]; ++ ++ atomic_inc(&data->disabled); ++ if (atomic_read(&data->disabled) != 1) ++ goto out; ++ ++ ip = CALLER_ADDR0; ++ ++ tracing_event_syscall(tr, data, flags, ip, nr, p1, p2, p3); ++ ++ out: ++ atomic_dec(&data->disabled); ++ local_irq_restore(flags); ++} ++ ++#if defined(CONFIG_COMPAT) && defined(CONFIG_X86) ++void notrace ++sys_ia32_call(unsigned long nr, unsigned long p1, unsigned long p2, ++ unsigned long p3) ++{ ++ struct trace_array *tr; ++ struct trace_array_cpu *data; ++ unsigned long flags; ++ unsigned long ip; ++ int cpu; ++ ++ if (!tracer_enabled) ++ return; ++ ++ tr = events_trace; ++ local_irq_save(flags); ++ cpu = raw_smp_processor_id(); ++ data = tr->data[cpu]; ++ ++ atomic_inc(&data->disabled); ++ if (atomic_read(&data->disabled) != 1) ++ goto out; ++ ++ ip = CALLER_ADDR0; ++ tracing_event_syscall(tr, data, flags, ip, nr | 0x80000000, p1, p2, p3); ++ ++ out: ++ atomic_dec(&data->disabled); ++ local_irq_restore(flags); ++} ++#endif ++ ++void notrace ++sys_ret(unsigned long ret) ++{ ++ struct trace_array *tr; ++ struct trace_array_cpu *data; ++ unsigned long flags; ++ unsigned long ip; ++ int cpu; ++ ++ if (!tracer_enabled) ++ return; ++ ++ tr = events_trace; ++ local_irq_save(flags); ++ cpu = raw_smp_processor_id(); ++ data = tr->data[cpu]; ++ ++ atomic_inc(&data->disabled); ++ if (atomic_read(&data->disabled) != 1) ++ goto out; ++ ++ ip = CALLER_ADDR0; ++ tracing_event_sysret(tr, data, flags, ip, ret); ++ ++ out: ++ atomic_dec(&data->disabled); ++ local_irq_restore(flags); ++} ++ + #define getarg(arg, ap) arg = va_arg(ap, typeof(arg)); + + static void +Index: linux-2.6.24.7-rt21/kernel/trace/trace_selftest.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/trace_selftest.c 2008-10-08 22:23:08.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/trace_selftest.c 2008-10-08 22:23:09.000000000 -0400 +@@ -18,6 +18,8 @@ static inline int trace_valid_entry(stru + case TRACE_TIMESTAMP: + case TRACE_TASK_ACT: + case TRACE_TASK_DEACT: ++ case TRACE_SYSCALL: ++ case TRACE_SYSRET: + return 1; + } + return 0; --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0210-preempt-realtime-arm-footbridge.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0210-preempt-realtime-arm-footbridge.patch @@ -0,0 +1,31 @@ +--- + arch/arm/mach-footbridge/netwinder-hw.c | 2 +- + arch/arm/mach-footbridge/netwinder-leds.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/arm/mach-footbridge/netwinder-hw.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/arm/mach-footbridge/netwinder-hw.c 2008-10-08 22:22:32.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/arm/mach-footbridge/netwinder-hw.c 2008-10-08 22:23:50.000000000 -0400 +@@ -67,7 +67,7 @@ static inline void wb977_ww(int reg, int + /* + * This is a lock for accessing ports GP1_IO_BASE and GP2_IO_BASE + */ +-DEFINE_SPINLOCK(gpio_lock); ++DEFINE_RAW_SPINLOCK(gpio_lock); + + static unsigned int current_gpio_op; + static unsigned int current_gpio_io; +Index: linux-2.6.24.7-rt21/arch/arm/mach-footbridge/netwinder-leds.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/arm/mach-footbridge/netwinder-leds.c 2008-10-08 22:22:32.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/arm/mach-footbridge/netwinder-leds.c 2008-10-08 22:23:50.000000000 -0400 +@@ -32,7 +32,7 @@ static char led_state; + static char hw_led_state; + + static DEFINE_SPINLOCK(leds_lock); +-extern spinlock_t gpio_lock; ++extern raw_spinlock_t gpio_lock; + + static void netwinder_leds_event(led_event_t evt) + { --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0276-gtod-optimize.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0276-gtod-optimize.patch @@ -0,0 +1,22 @@ +--- + kernel/timer.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +Index: linux-2.6.24.7-rt21/kernel/timer.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/timer.c 2008-10-08 22:24:04.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/timer.c 2008-10-08 22:24:09.000000000 -0400 +@@ -1012,6 +1012,13 @@ static inline void update_times(void) + static unsigned long last_tick = INITIAL_JIFFIES; + unsigned long ticks, flags; + ++ /* ++ * Dont take the xtime_lock from every CPU in ++ * every tick - only when needed: ++ */ ++ if (jiffies == last_tick) ++ return; ++ + write_seqlock_irqsave(&xtime_lock, flags); + ticks = jiffies - last_tick; + if (ticks) { --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0168-rt-mutex-delayed-resched.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0168-rt-mutex-delayed-resched.patch @@ -0,0 +1,131 @@ +--- + drivers/acpi/processor_idle.c | 6 +++--- + include/linux/preempt.h | 16 ++++++++++++++++ + include/linux/sched.h | 22 +++++++++++++++++++++- + kernel/sched.c | 4 +++- + 4 files changed, 43 insertions(+), 5 deletions(-) + +Index: linux-2.6.24.7-rt21/drivers/acpi/processor_idle.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/acpi/processor_idle.c 2008-10-08 22:22:36.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/acpi/processor_idle.c 2008-10-08 22:23:37.000000000 -0400 +@@ -209,7 +209,7 @@ static void acpi_safe_halt(void) + * test NEED_RESCHED: + */ + smp_mb(); +- if (!need_resched()) ++ if (!need_resched() || !need_resched_delayed()) + safe_halt(); + current_thread_info()->status |= TS_POLLING; + } +@@ -1417,7 +1417,7 @@ static int acpi_idle_enter_simple(struct + */ + smp_mb(); + +- if (unlikely(need_resched())) { ++ if (unlikely(need_resched() || need_resched_delayed())) { + current_thread_info()->status |= TS_POLLING; + local_irq_enable(); + return 0; +@@ -1503,7 +1503,7 @@ static int acpi_idle_enter_bm(struct cpu + */ + smp_mb(); + +- if (unlikely(need_resched())) { ++ if (unlikely(need_resched() || need_resched_delayed())) { + current_thread_info()->status |= TS_POLLING; + local_irq_enable(); + return 0; +Index: linux-2.6.24.7-rt21/include/linux/preempt.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/preempt.h 2008-10-08 22:23:36.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/preempt.h 2008-10-08 22:23:37.000000000 -0400 +@@ -55,6 +55,21 @@ do { \ + preempt_schedule(); \ + } while (0) + ++ ++/* ++ * If the architecture doens't have TIF_NEED_RESCHED_DELAYED ++ * help it out and define it back to TIF_NEED_RESCHED ++ */ ++#ifndef TIF_NEED_RESCHED_DELAYED ++# define TIF_NEED_RESCHED_DELAYED TIF_NEED_RESCHED ++#endif ++ ++#define preempt_check_resched_delayed() \ ++do { \ ++ if (unlikely(test_thread_flag(TIF_NEED_RESCHED_DELAYED))) \ ++ preempt_schedule(); \ ++} while (0) ++ + #define preempt_enable() \ + do { \ + __preempt_enable_no_resched(); \ +@@ -97,6 +112,7 @@ do { \ + #define __preempt_enable_no_resched() do { } while (0) + #define preempt_enable() do { } while (0) + #define preempt_check_resched() do { } while (0) ++#define preempt_check_resched_delayed() do { } while (0) + + #define preempt_disable_notrace() do { } while (0) + #define preempt_enable_no_resched_notrace() do { } while (0) +Index: linux-2.6.24.7-rt21/include/linux/sched.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/sched.h 2008-10-08 22:23:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/sched.h 2008-10-08 22:23:37.000000000 -0400 +@@ -1893,11 +1893,31 @@ static inline int signal_pending(struct + return unlikely(test_tsk_thread_flag(p,TIF_SIGPENDING)); + } + +-static inline int need_resched(void) ++static inline int _need_resched(void) + { + return unlikely(test_thread_flag(TIF_NEED_RESCHED)); + } + ++static inline int need_resched(void) ++{ ++ return _need_resched(); ++} ++ ++static inline void set_tsk_need_resched_delayed(struct task_struct *tsk) ++{ ++ set_tsk_thread_flag(tsk,TIF_NEED_RESCHED_DELAYED); ++} ++ ++static inline void clear_tsk_need_resched_delayed(struct task_struct *tsk) ++{ ++ clear_tsk_thread_flag(tsk,TIF_NEED_RESCHED_DELAYED); ++} ++ ++static inline int need_resched_delayed(void) ++{ ++ return unlikely(test_thread_flag(TIF_NEED_RESCHED_DELAYED)); ++} ++ + /* + * cond_resched() and cond_resched_lock(): latency reduction via + * explicit rescheduling in places that are safe. The return +Index: linux-2.6.24.7-rt21/kernel/sched.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched.c 2008-10-08 22:23:36.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched.c 2008-10-08 22:23:37.000000000 -0400 +@@ -3735,6 +3735,7 @@ need_resched_nonpreemptible: + __update_rq_clock(rq); + spin_lock(&rq->lock); + clear_tsk_need_resched(prev); ++ clear_tsk_need_resched_delayed(prev); + + if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) { + if (unlikely((prev->state & TASK_INTERRUPTIBLE) && +@@ -3774,7 +3775,8 @@ need_resched_nonpreemptible: + goto need_resched_nonpreemptible; + } + __preempt_enable_no_resched(); +- if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) ++ if (unlikely(test_thread_flag(TIF_NEED_RESCHED) || ++ test_thread_flag(TIF_NEED_RESCHED_DELAYED))) + goto need_resched; + } + EXPORT_SYMBOL(schedule); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0557-61c22c34c6f80a8e89cff5ff717627c54cc14fd4.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0557-61c22c34c6f80a8e89cff5ff717627c54cc14fd4.patch @@ -0,0 +1,55 @@ +commit 61c22c34c6f80a8e89cff5ff717627c54cc14fd4 +Author: Thomas Gleixner +Date: Tue Sep 9 21:38:57 2008 +0200 + + clockevents: remove WARN_ON which was used to gather information + + The issue of the endless reprogramming loop due to a too small + min_delta_ns was fixed with the previous updates of the clock events + code, but we had no information about the spread of this problem. I + added a WARN_ON to get automated information via kerneloops.org and to + get some direct reports, which allowed me to analyse the affected + machines. + + The WARN_ON has served its purpose and would be annoying for a release + kernel. Remove it and just keep the information about the increase of + the min_delta_ns value. + + Signed-off-by: Thomas Gleixner + +--- + kernel/time/tick-oneshot.c | 18 ++++++++---------- + 1 file changed, 8 insertions(+), 10 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/time/tick-oneshot.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/time/tick-oneshot.c 2008-10-08 22:25:16.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/time/tick-oneshot.c 2008-10-08 22:25:18.000000000 -0400 +@@ -43,19 +43,17 @@ int tick_dev_program_event(struct clock_ + * and emit a warning. + */ + if (++i > 2) { +- printk(KERN_WARNING "CE: __tick_program_event of %s is " +- "stuck %llx %llx\n", dev->name ? dev->name : "?", +- now.tv64, expires.tv64); +- printk(KERN_WARNING +- "CE: increasing min_delta_ns %ld to %ld nsec\n", +- dev->min_delta_ns, dev->min_delta_ns << 1); +- WARN_ON(1); +- +- /* Double the min. delta and try again */ ++ /* Increase the min. delta and try again */ + if (!dev->min_delta_ns) + dev->min_delta_ns = 5000; + else +- dev->min_delta_ns <<= 1; ++ dev->min_delta_ns += dev->min_delta_ns >> 1; ++ ++ printk(KERN_WARNING ++ "CE: %s increasing min_delta_ns to %lu nsec\n", ++ dev->name ? dev->name : "?", ++ dev->min_delta_ns << 1); ++ + i = 0; + } + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0327-print-might-sleep-hack.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0327-print-might-sleep-hack.patch @@ -0,0 +1,79 @@ +Temporary HACK!!!! + +PREEMPT_RT suffers from the on going problem of running +printk in atomic operations. It is very advantageous to do so +but with PREEMPT_RT making spin_locks sleep, it can also be +devastating. + +This patch does not solve the problem of printk sleeping in +an atomic operation. This patch just makes printk not report +that it is. Of course if printk does report that it's sleeping +in an atomic operation, then that printing of the report will +also print a report, and you go into recursive hell. + +We need to really sit down and solve the real issue here. + +--- + include/linux/sched.h | 13 +++++++++++++ + kernel/printk.c | 5 ++++- + kernel/rtmutex.c | 4 +++- + 3 files changed, 20 insertions(+), 2 deletions(-) + +Index: hardy/include/linux/sched.h +=================================================================== +--- hardy.orig/include/linux/sched.h 2008-11-21 17:13:33.000000000 +0100 ++++ hardy/include/linux/sched.h 2008-11-21 17:14:13.000000000 +0100 +@@ -1300,8 +1300,21 @@ + struct latency_record latency_record[LT_SAVECOUNT]; + #endif + struct list_head *scm_work_list; ++#ifdef CONFIG_PREEMPT_RT ++ /* ++ * Temporary hack, until we find a solution to ++ * handle printk in atomic operations. ++ */ ++ int in_printk; ++#endif + }; + ++#ifdef CONFIG_PREEMPT_RT ++# define set_printk_might_sleep(x) do { current->in_printk = x; } while(0) ++#else ++# define set_printk_might_sleep(x) do { } while(0) ++#endif ++ + /* + * Priority of a process goes from 0..MAX_PRIO-1, valid RT + * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH +Index: hardy/kernel/printk.c +=================================================================== +--- hardy.orig/kernel/printk.c 2008-11-21 17:13:31.000000000 +0100 ++++ hardy/kernel/printk.c 2008-11-21 17:13:37.000000000 +0100 +@@ -436,8 +436,11 @@ + for (con = console_drivers; con; con = con->next) { + if ((con->flags & CON_ENABLED) && con->write && + (cpu_online(raw_smp_processor_id()) || +- (con->flags & CON_ANYTIME))) ++ (con->flags & CON_ANYTIME))) { ++ set_printk_might_sleep(1); + con->write(con, &LOG_BUF(start), end - start); ++ set_printk_might_sleep(0); ++ } + } + } + +Index: hardy/kernel/rtmutex.c +=================================================================== +--- hardy.orig/kernel/rtmutex.c 2008-11-21 17:13:28.000000000 +0100 ++++ hardy/kernel/rtmutex.c 2008-11-21 17:13:37.000000000 +0100 +@@ -631,7 +631,9 @@ + rt_spin_lock_fastlock(struct rt_mutex *lock, + void fastcall (*slowfn)(struct rt_mutex *lock)) + { +- might_sleep(); ++ /* Temporary HACK! */ ++ if (!current->in_printk) ++ might_sleep(); + + if (likely(rt_mutex_cmpxchg(lock, NULL, current))) + rt_mutex_deadlock_account_lock(lock, current); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0553-7300711e8c6824fcfbd42a126980ff50439d8dd0-fix.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0553-7300711e8c6824fcfbd42a126980ff50439d8dd0-fix.patch @@ -0,0 +1,17 @@ +--- + kernel/time/tick-broadcast.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/kernel/time/tick-broadcast.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/time/tick-broadcast.c 2008-10-08 22:25:16.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/time/tick-broadcast.c 2008-10-08 22:25:17.000000000 -0400 +@@ -498,7 +498,7 @@ static void tick_broadcast_init_next_eve + struct tick_device *td; + int cpu; + +- for_each_cpu_mask_nr(cpu, *mask) { ++ for_each_cpu_mask(cpu, *mask) { + td = &per_cpu(tick_cpu_device, cpu); + if (td->evtdev) + td->evtdev->next_event = expires; --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0059-markers-upstream.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0059-markers-upstream.patch @@ -0,0 +1,1513 @@ +--- + include/linux/immediate.h | 97 ++++++ + include/linux/marker.h | 117 +++++-- + include/linux/module.h | 30 + + kernel/marker.c | 709 ++++++++++++++++++++++++++++++++++------------ + kernel/module.c | 91 +++++ + 5 files changed, 817 insertions(+), 227 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/immediate.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/include/linux/immediate.h 2008-10-08 22:23:05.000000000 -0400 +@@ -0,0 +1,97 @@ ++#ifndef _LINUX_IMMEDIATE_H ++#define _LINUX_IMMEDIATE_H ++ ++/* ++ * Immediate values, can be updated at runtime and save cache lines. ++ * ++ * (C) Copyright 2007 Mathieu Desnoyers ++ * ++ * This file is released under the GPLv2. ++ * See the file COPYING for more details. ++ */ ++ ++#ifdef CONFIG_IMMEDIATE ++ ++#include ++ ++/** ++ * imv_set - set immediate variable (with locking) ++ * @name: immediate value name ++ * @i: required value ++ * ++ * Sets the value of @name, taking the module_mutex if required by ++ * the architecture. ++ */ ++#define imv_set(name, i) \ ++ do { \ ++ name##__imv = (i); \ ++ core_imv_update(); \ ++ module_imv_update(); \ ++ } while (0) ++ ++/* ++ * Internal update functions. ++ */ ++extern void core_imv_update(void); ++extern void imv_update_range(struct __imv *begin, struct __imv *end); ++extern void imv_unref_core_init(void); ++extern void imv_unref(struct __imv *begin, struct __imv *end, void *start, ++ unsigned long size); ++extern int _is_imv_cond_end(unsigned long *begin, unsigned long *end, ++ unsigned long addr1, unsigned long addr2); ++extern int is_imv_cond_end(unsigned long addr1, unsigned long addr2); ++ ++#else ++ ++/* ++ * Generic immediate values: a simple, standard, memory load. ++ */ ++ ++/** ++ * imv_read - read immediate variable ++ * @name: immediate value name ++ * ++ * Reads the value of @name. ++ */ ++#define imv_read(name) _imv_read(name) ++ ++/** ++ * imv_cond - read immediate variable use as condition for if() ++ * @name: immediate value name ++ * ++ * Reads the value of @name. ++ */ ++#define imv_cond(name) _imv_read(name) ++#define imv_cond_end() ++ ++/** ++ * imv_set - set immediate variable (with locking) ++ * @name: immediate value name ++ * @i: required value ++ * ++ * Sets the value of @name, taking the module_mutex if required by ++ * the architecture. ++ */ ++#define imv_set(name, i) (name##__imv = (i)) ++ ++static inline void core_imv_update(void) { } ++static inline void imv_unref_core_init(void) { } ++ ++#endif ++ ++#define DECLARE_IMV(type, name) extern __typeof__(type) name##__imv ++#define DEFINE_IMV(type, name) __typeof__(type) name##__imv ++ ++#define EXPORT_IMV_SYMBOL(name) EXPORT_SYMBOL(name##__imv) ++#define EXPORT_IMV_SYMBOL_GPL(name) EXPORT_SYMBOL_GPL(name##__imv) ++ ++/** ++ * _imv_read - Read immediate value with standard memory load. ++ * @name: immediate value name ++ * ++ * Force a data read of the immediate value instead of the immediate value ++ * based mechanism. Useful for __init and __exit section data read. ++ */ ++#define _imv_read(name) (name##__imv) ++ ++#endif +Index: linux-2.6.24.7-rt21/include/linux/marker.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/marker.h 2008-10-08 22:22:45.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/marker.h 2008-10-08 22:23:05.000000000 -0400 +@@ -12,6 +12,7 @@ + * See the file COPYING for more details. + */ + ++#include + #include + + struct module; +@@ -19,25 +20,35 @@ struct marker; + + /** + * marker_probe_func - Type of a marker probe function +- * @mdata: pointer of type struct marker +- * @private_data: caller site private data ++ * @probe_private: probe private data ++ * @call_private: call site private data + * @fmt: format string +- * @...: variable argument list ++ * @args: variable argument list pointer. Use a pointer to overcome C's ++ * inability to pass this around as a pointer in a portable manner in ++ * the callee otherwise. + * + * Type of marker probe functions. They receive the mdata and need to parse the + * format string to recover the variable argument list. + */ +-typedef void marker_probe_func(const struct marker *mdata, +- void *private_data, const char *fmt, ...); ++typedef void marker_probe_func(void *probe_private, void *call_private, ++ const char *fmt, va_list *args); ++ ++struct marker_probe_closure { ++ marker_probe_func *func; /* Callback */ ++ void *probe_private; /* Private probe data */ ++}; + + struct marker { + const char *name; /* Marker name */ + const char *format; /* Marker format string, describing the + * variable argument list. + */ +- char state; /* Marker state. */ +- marker_probe_func *call;/* Probe handler function pointer */ +- void *private; /* Private probe data */ ++ DEFINE_IMV(char, state);/* Immediate value state. */ ++ char ptype; /* probe type : 0 : single, 1 : multi */ ++ /* Probe wrapper */ ++ void (*call)(const struct marker *mdata, void *call_private, ...); ++ struct marker_probe_closure single; ++ struct marker_probe_closure *multi; + } __attribute__((aligned(8))); + + #ifdef CONFIG_MARKERS +@@ -48,51 +59,73 @@ struct marker { + * Make sure the alignment of the structure in the __markers section will + * not add unwanted padding between the beginning of the section and the + * structure. Force alignment to the same alignment as the section start. ++ * ++ * The "generic" argument controls which marker enabling mechanism must be used. ++ * If generic is true, a variable read is used. ++ * If generic is false, immediate values are used. + */ +-#define __trace_mark(name, call_data, format, args...) \ ++#define __trace_mark(generic, name, call_private, format, args...) \ + do { \ +- static const char __mstrtab_name_##name[] \ ++ static const char __mstrtab_##name[] \ + __attribute__((section("__markers_strings"))) \ +- = #name; \ +- static const char __mstrtab_format_##name[] \ +- __attribute__((section("__markers_strings"))) \ +- = format; \ ++ = #name "\0" format; \ + static struct marker __mark_##name \ + __attribute__((section("__markers"), aligned(8))) = \ +- { __mstrtab_name_##name, __mstrtab_format_##name, \ +- 0, __mark_empty_function, NULL }; \ ++ { __mstrtab_##name, &__mstrtab_##name[sizeof(#name)], \ ++ 0, 0, marker_probe_cb, \ ++ { __mark_empty_function, NULL}, NULL }; \ + __mark_check_format(format, ## args); \ +- if (unlikely(__mark_##name.state)) { \ +- preempt_disable(); \ +- (*__mark_##name.call) \ +- (&__mark_##name, call_data, \ +- format, ## args); \ +- preempt_enable(); \ ++ if (!generic) { \ ++ if (unlikely(imv_cond(__mark_##name.state))) { \ ++ imv_cond_end(); \ ++ (*__mark_##name.call) \ ++ (&__mark_##name, call_private, \ ++ ## args); \ ++ } else \ ++ imv_cond_end(); \ ++ } else { \ ++ if (unlikely(_imv_read(__mark_##name.state))) \ ++ (*__mark_##name.call) \ ++ (&__mark_##name, call_private, \ ++ ## args); \ + } \ + } while (0) + + extern void marker_update_probe_range(struct marker *begin, +- struct marker *end, struct module *probe_module, int *refcount); ++ struct marker *end); + #else /* !CONFIG_MARKERS */ +-#define __trace_mark(name, call_data, format, args...) \ ++#define __trace_mark(generic, name, call_private, format, args...) \ + __mark_check_format(format, ## args) + static inline void marker_update_probe_range(struct marker *begin, +- struct marker *end, struct module *probe_module, int *refcount) ++ struct marker *end) + { } + #endif /* CONFIG_MARKERS */ + + /** +- * trace_mark - Marker ++ * trace_mark - Marker using code patching + * @name: marker name, not quoted. + * @format: format string + * @args...: variable argument list + * +- * Places a marker. ++ * Places a marker using optimized code patching technique (imv_read()) ++ * to be enabled when immediate values are present. + */ + #define trace_mark(name, format, args...) \ +- __trace_mark(name, NULL, format, ## args) ++ __trace_mark(0, name, NULL, format, ## args) + +-#define MARK_MAX_FORMAT_LEN 1024 ++/** ++ * _trace_mark - Marker using variable read ++ * @name: marker name, not quoted. ++ * @format: format string ++ * @args...: variable argument list ++ * ++ * Places a marker using a standard memory read (_imv_read()) to be ++ * enabled. Should be used for markers in code paths where instruction ++ * modification based enabling is not welcome. (__init and __exit functions, ++ * lockdep, some traps, printk). ++ */ ++#define _trace_mark(name, format, args...) \ ++ __trace_mark(1, name, NULL, format, ## args) + + /** + * MARK_NOARGS - Format string for a marker with no argument. +@@ -100,30 +133,42 @@ static inline void marker_update_probe_r + #define MARK_NOARGS " " + + /* To be used for string format validity checking with gcc */ +-static inline void __printf(1, 2) __mark_check_format(const char *fmt, ...) ++static inline void __printf(1, 2) ___mark_check_format(const char *fmt, ...) + { + } + ++#define __mark_check_format(format, args...) \ ++ do { \ ++ if (0) \ ++ ___mark_check_format(format, ## args); \ ++ } while (0) ++ + extern marker_probe_func __mark_empty_function; + ++extern void marker_probe_cb(const struct marker *mdata, ++ void *call_private, ...); ++extern void marker_probe_cb_noarg(const struct marker *mdata, ++ void *call_private, ...); ++ + /* + * Connect a probe to a marker. + * private data pointer must be a valid allocated memory address, or NULL. + */ + extern int marker_probe_register(const char *name, const char *format, +- marker_probe_func *probe, void *private); ++ marker_probe_func *probe, void *probe_private); + + /* + * Returns the private data given to marker_probe_register. + */ +-extern void *marker_probe_unregister(const char *name); ++extern int marker_probe_unregister(const char *name, ++ marker_probe_func *probe, void *probe_private); + /* + * Unregister a marker by providing the registered private data. + */ +-extern void *marker_probe_unregister_private_data(void *private); ++extern int marker_probe_unregister_private_data(marker_probe_func *probe, ++ void *probe_private); + +-extern int marker_arm(const char *name); +-extern int marker_disarm(const char *name); +-extern void *marker_get_private_data(const char *name); ++extern void *marker_get_private_data(const char *name, marker_probe_func *probe, ++ int num); + + #endif +Index: linux-2.6.24.7-rt21/include/linux/module.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/module.h 2008-10-08 22:22:45.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/module.h 2008-10-08 22:23:05.000000000 -0400 +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -355,6 +356,12 @@ struct module + /* The command line arguments (may be mangled). People like + keeping pointers to this stuff */ + char *args; ++#ifdef CONFIG_IMMEDIATE ++ struct __imv *immediate; ++ unsigned int num_immediate; ++ unsigned long *immediate_cond_end; ++ unsigned int num_immediate_cond_end; ++#endif + #ifdef CONFIG_MARKERS + struct marker *markers; + unsigned int num_markers; +@@ -462,7 +469,7 @@ int unregister_module_notifier(struct no + + extern void print_modules(void); + +-extern void module_update_markers(struct module *probe_module, int *refcount); ++extern void module_update_markers(void); + + #else /* !CONFIG_MODULES... */ + #define EXPORT_SYMBOL(sym) +@@ -563,13 +570,30 @@ static inline void print_modules(void) + { + } + +-static inline void module_update_markers(struct module *probe_module, +- int *refcount) ++static inline void module_update_markers(void) + { + } + + #endif /* CONFIG_MODULES */ + ++#if defined(CONFIG_MODULES) && defined(CONFIG_IMMEDIATE) ++extern void _module_imv_update(void); ++extern void module_imv_update(void); ++extern int is_imv_cond_end_module(unsigned long addr1, unsigned long addr2); ++#else ++static inline void _module_imv_update(void) ++{ ++} ++static inline void module_imv_update(void) ++{ ++} ++static inline int is_imv_cond_end_module(unsigned long addr1, ++ unsigned long addr2) ++{ ++ return 0; ++} ++#endif ++ + struct device_driver; + #ifdef CONFIG_SYSFS + struct module; +Index: linux-2.6.24.7-rt21/kernel/marker.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/marker.c 2008-10-08 22:22:45.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/marker.c 2008-10-08 22:23:05.000000000 -0400 +@@ -23,39 +23,48 @@ + #include + #include + #include ++#include ++#include + + extern struct marker __start___markers[]; + extern struct marker __stop___markers[]; + ++/* Set to 1 to enable marker debug output */ ++static const int marker_debug; ++ + /* + * markers_mutex nests inside module_mutex. Markers mutex protects the builtin +- * and module markers, the hash table and deferred_sync. ++ * and module markers and the hash table. + */ + static DEFINE_MUTEX(markers_mutex); + + /* +- * Marker deferred synchronization. +- * Upon marker probe_unregister, we delay call to synchronize_sched() to +- * accelerate mass unregistration (only when there is no more reference to a +- * given module do we call synchronize_sched()). However, we need to make sure +- * every critical region has ended before we re-arm a marker that has been +- * unregistered and then registered back with a different probe data. +- */ +-static int deferred_sync; +- +-/* + * Marker hash table, containing the active markers. + * Protected by module_mutex. + */ + #define MARKER_HASH_BITS 6 + #define MARKER_TABLE_SIZE (1 << MARKER_HASH_BITS) + ++/* ++ * Note about RCU : ++ * It is used to make sure every handler has finished using its private data ++ * between two consecutive operation (add or remove) on a given marker. It is ++ * also used to delay the free of multiple probes array until a quiescent state ++ * is reached. ++ * marker entries modifications are protected by the markers_mutex. ++ */ + struct marker_entry { + struct hlist_node hlist; + char *format; +- marker_probe_func *probe; +- void *private; ++ /* Probe wrapper */ ++ void (*call)(const struct marker *mdata, void *call_private, ...); ++ struct marker_probe_closure single; ++ struct marker_probe_closure *multi; + int refcount; /* Number of times armed. 0 if disarmed. */ ++ struct rcu_head rcu; ++ void *oldptr; ++ unsigned char rcu_pending:1; ++ unsigned char ptype:1; + char name[0]; /* Contains name'\0'format'\0' */ + }; + +@@ -63,7 +72,8 @@ static struct hlist_head marker_table[MA + + /** + * __mark_empty_function - Empty probe callback +- * @mdata: pointer of type const struct marker ++ * @probe_private: probe private data ++ * @call_private: call site private data + * @fmt: format string + * @...: variable argument list + * +@@ -72,13 +82,265 @@ static struct hlist_head marker_table[MA + * though the function pointer change and the marker enabling are two distinct + * operations that modifies the execution flow of preemptible code. + */ +-void __mark_empty_function(const struct marker *mdata, void *private, +- const char *fmt, ...) ++void __mark_empty_function(void *probe_private, void *call_private, ++ const char *fmt, va_list *args) + { + } + EXPORT_SYMBOL_GPL(__mark_empty_function); + + /* ++ * marker_probe_cb Callback that prepares the variable argument list for probes. ++ * @mdata: pointer of type struct marker ++ * @call_private: caller site private data ++ * @...: Variable argument list. ++ * ++ * Since we do not use "typical" pointer based RCU in the 1 argument case, we ++ * need to put a full smp_rmb() in this branch. This is why we do not use ++ * rcu_dereference() for the pointer read. ++ */ ++void marker_probe_cb(const struct marker *mdata, void *call_private, ...) ++{ ++ va_list args; ++ char ptype; ++ ++ /* ++ * preempt_disable does two things : disabling preemption to make sure ++ * the teardown of the callbacks can be done correctly when they are in ++ * modules and they insure RCU read coherency. ++ */ ++ preempt_disable(); ++ ptype = mdata->ptype; ++ if (likely(!ptype)) { ++ marker_probe_func *func; ++ /* Must read the ptype before ptr. They are not data dependant, ++ * so we put an explicit smp_rmb() here. */ ++ smp_rmb(); ++ func = mdata->single.func; ++ /* Must read the ptr before private data. They are not data ++ * dependant, so we put an explicit smp_rmb() here. */ ++ smp_rmb(); ++ va_start(args, call_private); ++ func(mdata->single.probe_private, call_private, mdata->format, ++ &args); ++ va_end(args); ++ } else { ++ struct marker_probe_closure *multi; ++ int i; ++ /* ++ * multi points to an array, therefore accessing the array ++ * depends on reading multi. However, even in this case, ++ * we must insure that the pointer is read _before_ the array ++ * data. Same as rcu_dereference, but we need a full smp_rmb() ++ * in the fast path, so put the explicit barrier here. ++ */ ++ smp_read_barrier_depends(); ++ multi = mdata->multi; ++ for (i = 0; multi[i].func; i++) { ++ va_start(args, call_private); ++ multi[i].func(multi[i].probe_private, call_private, ++ mdata->format, &args); ++ va_end(args); ++ } ++ } ++ preempt_enable(); ++} ++EXPORT_SYMBOL_GPL(marker_probe_cb); ++ ++/* ++ * marker_probe_cb Callback that does not prepare the variable argument list. ++ * @mdata: pointer of type struct marker ++ * @call_private: caller site private data ++ * @...: Variable argument list. ++ * ++ * Should be connected to markers "MARK_NOARGS". ++ */ ++void marker_probe_cb_noarg(const struct marker *mdata, void *call_private, ...) ++{ ++ va_list args; /* not initialized */ ++ char ptype; ++ ++ preempt_disable(); ++ ptype = mdata->ptype; ++ if (likely(!ptype)) { ++ marker_probe_func *func; ++ /* Must read the ptype before ptr. They are not data dependant, ++ * so we put an explicit smp_rmb() here. */ ++ smp_rmb(); ++ func = mdata->single.func; ++ /* Must read the ptr before private data. They are not data ++ * dependant, so we put an explicit smp_rmb() here. */ ++ smp_rmb(); ++ func(mdata->single.probe_private, call_private, mdata->format, ++ &args); ++ } else { ++ struct marker_probe_closure *multi; ++ int i; ++ /* ++ * multi points to an array, therefore accessing the array ++ * depends on reading multi. However, even in this case, ++ * we must insure that the pointer is read _before_ the array ++ * data. Same as rcu_dereference, but we need a full smp_rmb() ++ * in the fast path, so put the explicit barrier here. ++ */ ++ smp_read_barrier_depends(); ++ multi = mdata->multi; ++ for (i = 0; multi[i].func; i++) ++ multi[i].func(multi[i].probe_private, call_private, ++ mdata->format, &args); ++ } ++ preempt_enable(); ++} ++EXPORT_SYMBOL_GPL(marker_probe_cb_noarg); ++ ++static void free_old_closure(struct rcu_head *head) ++{ ++ struct marker_entry *entry = container_of(head, ++ struct marker_entry, rcu); ++ kfree(entry->oldptr); ++ /* Make sure we free the data before setting the pending flag to 0 */ ++ smp_wmb(); ++ entry->rcu_pending = 0; ++} ++ ++static void debug_print_probes(struct marker_entry *entry) ++{ ++ int i; ++ ++ if (!marker_debug) ++ return; ++ ++ if (!entry->ptype) { ++ printk(KERN_DEBUG "Single probe : %p %p\n", ++ entry->single.func, ++ entry->single.probe_private); ++ } else { ++ for (i = 0; entry->multi[i].func; i++) ++ printk(KERN_DEBUG "Multi probe %d : %p %p\n", i, ++ entry->multi[i].func, ++ entry->multi[i].probe_private); ++ } ++} ++ ++static struct marker_probe_closure * ++marker_entry_add_probe(struct marker_entry *entry, ++ marker_probe_func *probe, void *probe_private) ++{ ++ int nr_probes = 0; ++ struct marker_probe_closure *old, *new; ++ ++ WARN_ON(!probe); ++ ++ debug_print_probes(entry); ++ old = entry->multi; ++ if (!entry->ptype) { ++ if (entry->single.func == probe && ++ entry->single.probe_private == probe_private) ++ return ERR_PTR(-EBUSY); ++ if (entry->single.func == __mark_empty_function) { ++ /* 0 -> 1 probes */ ++ entry->single.func = probe; ++ entry->single.probe_private = probe_private; ++ entry->refcount = 1; ++ entry->ptype = 0; ++ debug_print_probes(entry); ++ return NULL; ++ } else { ++ /* 1 -> 2 probes */ ++ nr_probes = 1; ++ old = NULL; ++ } ++ } else { ++ /* (N -> N+1), (N != 0, 1) probes */ ++ for (nr_probes = 0; old[nr_probes].func; nr_probes++) ++ if (old[nr_probes].func == probe ++ && old[nr_probes].probe_private ++ == probe_private) ++ return ERR_PTR(-EBUSY); ++ } ++ /* + 2 : one for new probe, one for NULL func */ ++ new = kzalloc((nr_probes + 2) * sizeof(struct marker_probe_closure), ++ GFP_KERNEL); ++ if (new == NULL) ++ return ERR_PTR(-ENOMEM); ++ if (!old) ++ new[0] = entry->single; ++ else ++ memcpy(new, old, ++ nr_probes * sizeof(struct marker_probe_closure)); ++ new[nr_probes].func = probe; ++ new[nr_probes].probe_private = probe_private; ++ entry->refcount = nr_probes + 1; ++ entry->multi = new; ++ entry->ptype = 1; ++ debug_print_probes(entry); ++ return old; ++} ++ ++static struct marker_probe_closure * ++marker_entry_remove_probe(struct marker_entry *entry, ++ marker_probe_func *probe, void *probe_private) ++{ ++ int nr_probes = 0, nr_del = 0, i; ++ struct marker_probe_closure *old, *new; ++ ++ old = entry->multi; ++ ++ debug_print_probes(entry); ++ if (!entry->ptype) { ++ /* 0 -> N is an error */ ++ WARN_ON(entry->single.func == __mark_empty_function); ++ /* 1 -> 0 probes */ ++ WARN_ON(probe && entry->single.func != probe); ++ WARN_ON(entry->single.probe_private != probe_private); ++ entry->single.func = __mark_empty_function; ++ entry->refcount = 0; ++ entry->ptype = 0; ++ debug_print_probes(entry); ++ return NULL; ++ } else { ++ /* (N -> M), (N > 1, M >= 0) probes */ ++ for (nr_probes = 0; old[nr_probes].func; nr_probes++) { ++ if ((!probe || old[nr_probes].func == probe) ++ && old[nr_probes].probe_private ++ == probe_private) ++ nr_del++; ++ } ++ } ++ ++ if (nr_probes - nr_del == 0) { ++ /* N -> 0, (N > 1) */ ++ entry->single.func = __mark_empty_function; ++ entry->refcount = 0; ++ entry->ptype = 0; ++ } else if (nr_probes - nr_del == 1) { ++ /* N -> 1, (N > 1) */ ++ for (i = 0; old[i].func; i++) ++ if ((probe && old[i].func != probe) || ++ old[i].probe_private != probe_private) ++ entry->single = old[i]; ++ entry->refcount = 1; ++ entry->ptype = 0; ++ } else { ++ int j = 0; ++ /* N -> M, (N > 1, M > 1) */ ++ /* + 1 for NULL */ ++ new = kzalloc((nr_probes - nr_del + 1) ++ * sizeof(struct marker_probe_closure), GFP_KERNEL); ++ if (new == NULL) ++ return ERR_PTR(-ENOMEM); ++ for (i = 0; old[i].func; i++) ++ if ((probe && old[i].func != probe) || ++ old[i].probe_private != probe_private) ++ new[j++] = old[i]; ++ entry->refcount = nr_probes - nr_del; ++ entry->ptype = 1; ++ entry->multi = new; ++ } ++ debug_print_probes(entry); ++ return old; ++} ++ ++/* + * Get marker if the marker is present in the marker hash table. + * Must be called with markers_mutex held. + * Returns NULL if not present. +@@ -102,8 +364,7 @@ static struct marker_entry *get_marker(c + * Add the marker to the marker hash table. Must be called with markers_mutex + * held. + */ +-static int add_marker(const char *name, const char *format, +- marker_probe_func *probe, void *private) ++static struct marker_entry *add_marker(const char *name, const char *format) + { + struct hlist_head *head; + struct hlist_node *node; +@@ -118,9 +379,8 @@ static int add_marker(const char *name, + hlist_for_each_entry(e, node, head, hlist) { + if (!strcmp(name, e->name)) { + printk(KERN_NOTICE +- "Marker %s busy, probe %p already installed\n", +- name, e->probe); +- return -EBUSY; /* Already there */ ++ "Marker %s busy\n", name); ++ return ERR_PTR(-EBUSY); /* Already there */ + } + } + /* +@@ -130,34 +390,42 @@ static int add_marker(const char *name, + e = kmalloc(sizeof(struct marker_entry) + name_len + format_len, + GFP_KERNEL); + if (!e) +- return -ENOMEM; ++ return ERR_PTR(-ENOMEM); + memcpy(&e->name[0], name, name_len); + if (format) { + e->format = &e->name[name_len]; + memcpy(e->format, format, format_len); ++ if (strcmp(e->format, MARK_NOARGS) == 0) ++ e->call = marker_probe_cb_noarg; ++ else ++ e->call = marker_probe_cb; + trace_mark(core_marker_format, "name %s format %s", + e->name, e->format); +- } else ++ } else { + e->format = NULL; +- e->probe = probe; +- e->private = private; ++ e->call = marker_probe_cb; ++ } ++ e->single.func = __mark_empty_function; ++ e->single.probe_private = NULL; ++ e->multi = NULL; ++ e->ptype = 0; + e->refcount = 0; ++ e->rcu_pending = 0; + hlist_add_head(&e->hlist, head); +- return 0; ++ return e; + } + + /* + * Remove the marker from the marker hash table. Must be called with mutex_lock + * held. + */ +-static void *remove_marker(const char *name) ++static int remove_marker(const char *name) + { + struct hlist_head *head; + struct hlist_node *node; + struct marker_entry *e; + int found = 0; + size_t len = strlen(name) + 1; +- void *private = NULL; + u32 hash = jhash(name, len-1, 0); + + head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)]; +@@ -167,12 +435,16 @@ static void *remove_marker(const char *n + break; + } + } +- if (found) { +- private = e->private; +- hlist_del(&e->hlist); +- kfree(e); +- } +- return private; ++ if (!found) ++ return -ENOENT; ++ if (e->single.func != __mark_empty_function) ++ return -EBUSY; ++ hlist_del(&e->hlist); ++ /* Make sure the call_rcu has been executed */ ++ if (e->rcu_pending) ++ rcu_barrier(); ++ kfree(e); ++ return 0; + } + + /* +@@ -184,6 +456,7 @@ static int marker_set_format(struct mark + size_t name_len = strlen((*entry)->name) + 1; + size_t format_len = strlen(format) + 1; + ++ + e = kmalloc(sizeof(struct marker_entry) + name_len + format_len, + GFP_KERNEL); + if (!e) +@@ -191,11 +464,20 @@ static int marker_set_format(struct mark + memcpy(&e->name[0], (*entry)->name, name_len); + e->format = &e->name[name_len]; + memcpy(e->format, format, format_len); +- e->probe = (*entry)->probe; +- e->private = (*entry)->private; ++ if (strcmp(e->format, MARK_NOARGS) == 0) ++ e->call = marker_probe_cb_noarg; ++ else ++ e->call = marker_probe_cb; ++ e->single = (*entry)->single; ++ e->multi = (*entry)->multi; ++ e->ptype = (*entry)->ptype; + e->refcount = (*entry)->refcount; ++ e->rcu_pending = 0; + hlist_add_before(&e->hlist, &(*entry)->hlist); + hlist_del(&(*entry)->hlist); ++ /* Make sure the call_rcu has been executed */ ++ if ((*entry)->rcu_pending) ++ rcu_barrier(); + kfree(*entry); + *entry = e; + trace_mark(core_marker_format, "name %s format %s", +@@ -206,7 +488,8 @@ static int marker_set_format(struct mark + /* + * Sets the probe callback corresponding to one marker. + */ +-static int set_marker(struct marker_entry **entry, struct marker *elem) ++static int set_marker(struct marker_entry **entry, struct marker *elem, ++ int active) + { + int ret; + WARN_ON(strcmp((*entry)->name, elem->name) != 0); +@@ -226,26 +509,64 @@ static int set_marker(struct marker_entr + if (ret) + return ret; + } +- elem->call = (*entry)->probe; +- elem->private = (*entry)->private; +- elem->state = 1; ++ ++ /* ++ * probe_cb setup (statically known) is done here. It is ++ * asynchronous with the rest of execution, therefore we only ++ * pass from a "safe" callback (with argument) to an "unsafe" ++ * callback (does not set arguments). ++ */ ++ elem->call = (*entry)->call; ++ /* ++ * Sanity check : ++ * We only update the single probe private data when the ptr is ++ * set to a _non_ single probe! (0 -> 1 and N -> 1, N != 1) ++ */ ++ WARN_ON(elem->single.func != __mark_empty_function ++ && elem->single.probe_private ++ != (*entry)->single.probe_private && ++ !elem->ptype); ++ elem->single.probe_private = (*entry)->single.probe_private; ++ /* ++ * Make sure the private data is valid when we update the ++ * single probe ptr. ++ */ ++ smp_wmb(); ++ elem->single.func = (*entry)->single.func; ++ /* ++ * We also make sure that the new probe callbacks array is consistent ++ * before setting a pointer to it. ++ */ ++ rcu_assign_pointer(elem->multi, (*entry)->multi); ++ /* ++ * Update the function or multi probe array pointer before setting the ++ * ptype. ++ */ ++ smp_wmb(); ++ elem->ptype = (*entry)->ptype; ++ elem->state__imv = active; ++ + return 0; + } + + /* + * Disable a marker and its probe callback. +- * Note: only after a synchronize_sched() issued after setting elem->call to the +- * empty function insures that the original callback is not used anymore. This +- * insured by preemption disabling around the call site. ++ * Note: only waiting an RCU period after setting elem->call to the empty ++ * function insures that the original callback is not used anymore. This insured ++ * by preempt_disable around the call site. + */ + static void disable_marker(struct marker *elem) + { +- elem->state = 0; +- elem->call = __mark_empty_function; ++ /* leave "call" as is. It is known statically. */ ++ elem->state__imv = 0; ++ elem->single.func = __mark_empty_function; ++ /* Update the function before setting the ptype */ ++ smp_wmb(); ++ elem->ptype = 0; /* single probe */ + /* + * Leave the private data and id there, because removal is racy and +- * should be done only after a synchronize_sched(). These are never used +- * until the next initialization anyway. ++ * should be done only after an RCU period. These are never used until ++ * the next initialization anyway. + */ + } + +@@ -253,14 +574,11 @@ static void disable_marker(struct marker + * marker_update_probe_range - Update a probe range + * @begin: beginning of the range + * @end: end of the range +- * @probe_module: module address of the probe being updated +- * @refcount: number of references left to the given probe_module (out) + * + * Updates the probe callback corresponding to a range of markers. + */ + void marker_update_probe_range(struct marker *begin, +- struct marker *end, struct module *probe_module, +- int *refcount) ++ struct marker *end) + { + struct marker *iter; + struct marker_entry *mark_entry; +@@ -268,15 +586,12 @@ void marker_update_probe_range(struct ma + mutex_lock(&markers_mutex); + for (iter = begin; iter < end; iter++) { + mark_entry = get_marker(iter->name); +- if (mark_entry && mark_entry->refcount) { +- set_marker(&mark_entry, iter); ++ if (mark_entry) { ++ set_marker(&mark_entry, iter, ++ !!mark_entry->refcount); + /* + * ignore error, continue + */ +- if (probe_module) +- if (probe_module == +- __module_text_address((unsigned long)mark_entry->probe)) +- (*refcount)++; + } else { + disable_marker(iter); + } +@@ -286,23 +601,30 @@ void marker_update_probe_range(struct ma + + /* + * Update probes, removing the faulty probes. +- * Issues a synchronize_sched() when no reference to the module passed +- * as parameter is found in the probes so the probe module can be +- * safely unloaded from now on. ++ * ++ * Internal callback only changed before the first probe is connected to it. ++ * Single probe private data can only be changed on 0 -> 1 and 2 -> 1 ++ * transitions. All other transitions will leave the old private data valid. ++ * This makes the non-atomicity of the callback/private data updates valid. ++ * ++ * "special case" updates : ++ * 0 -> 1 callback ++ * 1 -> 0 callback ++ * 1 -> 2 callbacks ++ * 2 -> 1 callbacks ++ * Other updates all behave the same, just like the 2 -> 3 or 3 -> 2 updates. ++ * Site effect : marker_set_format may delete the marker entry (creating a ++ * replacement). + */ +-static void marker_update_probes(struct module *probe_module) ++static void marker_update_probes(void) + { +- int refcount = 0; +- + /* Core kernel markers */ +- marker_update_probe_range(__start___markers, +- __stop___markers, probe_module, &refcount); ++ marker_update_probe_range(__start___markers, __stop___markers); + /* Markers in modules. */ +- module_update_markers(probe_module, &refcount); +- if (probe_module && refcount == 0) { +- synchronize_sched(); +- deferred_sync = 0; +- } ++ module_update_markers(); ++ /* Update immediate values */ ++ core_imv_update(); ++ module_imv_update(); + } + + /** +@@ -310,33 +632,52 @@ static void marker_update_probes(struct + * @name: marker name + * @format: format string + * @probe: probe handler +- * @private: probe private data ++ * @probe_private: probe private data + * + * private data must be a valid allocated memory address, or NULL. + * Returns 0 if ok, error value on error. ++ * The probe address must at least be aligned on the architecture pointer size. + */ + int marker_probe_register(const char *name, const char *format, +- marker_probe_func *probe, void *private) ++ marker_probe_func *probe, void *probe_private) + { + struct marker_entry *entry; + int ret = 0; ++ struct marker_probe_closure *old; + + mutex_lock(&markers_mutex); + entry = get_marker(name); +- if (entry && entry->refcount) { +- ret = -EBUSY; +- goto end; +- } +- if (deferred_sync) { +- synchronize_sched(); +- deferred_sync = 0; ++ if (!entry) { ++ entry = add_marker(name, format); ++ if (IS_ERR(entry)) { ++ ret = PTR_ERR(entry); ++ goto end; ++ } + } +- ret = add_marker(name, format, probe, private); +- if (ret) ++ /* ++ * If we detect that a call_rcu is pending for this marker, ++ * make sure it's executed now. ++ */ ++ if (entry->rcu_pending) ++ rcu_barrier(); ++ old = marker_entry_add_probe(entry, probe, probe_private); ++ if (IS_ERR(old)) { ++ ret = PTR_ERR(old); + goto end; ++ } + mutex_unlock(&markers_mutex); +- marker_update_probes(NULL); +- return ret; ++ marker_update_probes(); /* may update entry */ ++ mutex_lock(&markers_mutex); ++ entry = get_marker(name); ++ WARN_ON(!entry); ++ entry->oldptr = old; ++ entry->rcu_pending = 1; ++ /* write rcu_pending before calling the RCU callback */ ++ smp_wmb(); ++#ifdef CONFIG_PREEMPT_RCU ++ synchronize_sched(); /* Until we have the call_rcu_sched() */ ++#endif ++ call_rcu(&entry->rcu, free_old_closure); + end: + mutex_unlock(&markers_mutex); + return ret; +@@ -346,171 +687,173 @@ EXPORT_SYMBOL_GPL(marker_probe_register) + /** + * marker_probe_unregister - Disconnect a probe from a marker + * @name: marker name ++ * @probe: probe function pointer ++ * @probe_private: probe private data + * + * Returns the private data given to marker_probe_register, or an ERR_PTR(). ++ * We do not need to call a synchronize_sched to make sure the probes have ++ * finished running before doing a module unload, because the module unload ++ * itself uses stop_machine(), which insures that every preempt disabled section ++ * have finished. + */ +-void *marker_probe_unregister(const char *name) ++int marker_probe_unregister(const char *name, ++ marker_probe_func *probe, void *probe_private) + { +- struct module *probe_module; + struct marker_entry *entry; +- void *private; ++ struct marker_probe_closure *old; ++ int ret = -ENOENT; + + mutex_lock(&markers_mutex); + entry = get_marker(name); +- if (!entry) { +- private = ERR_PTR(-ENOENT); ++ if (!entry) + goto end; +- } +- entry->refcount = 0; +- /* In what module is the probe handler ? */ +- probe_module = __module_text_address((unsigned long)entry->probe); +- private = remove_marker(name); +- deferred_sync = 1; ++ if (entry->rcu_pending) ++ rcu_barrier(); ++ old = marker_entry_remove_probe(entry, probe, probe_private); + mutex_unlock(&markers_mutex); +- marker_update_probes(probe_module); +- return private; ++ marker_update_probes(); /* may update entry */ ++ mutex_lock(&markers_mutex); ++ entry = get_marker(name); ++ if (!entry) ++ goto end; ++ entry->oldptr = old; ++ entry->rcu_pending = 1; ++ /* write rcu_pending before calling the RCU callback */ ++ smp_wmb(); ++#ifdef CONFIG_PREEMPT_RCU ++ synchronize_sched(); /* Until we have the call_rcu_sched() */ ++#endif ++ call_rcu(&entry->rcu, free_old_closure); ++ remove_marker(name); /* Ignore busy error message */ ++ ret = 0; + end: + mutex_unlock(&markers_mutex); +- return private; ++ return ret; + } + EXPORT_SYMBOL_GPL(marker_probe_unregister); + +-/** +- * marker_probe_unregister_private_data - Disconnect a probe from a marker +- * @private: probe private data +- * +- * Unregister a marker by providing the registered private data. +- * Returns the private data given to marker_probe_register, or an ERR_PTR(). +- */ +-void *marker_probe_unregister_private_data(void *private) ++static struct marker_entry * ++get_marker_from_private_data(marker_probe_func *probe, void *probe_private) + { +- struct module *probe_module; +- struct hlist_head *head; +- struct hlist_node *node; + struct marker_entry *entry; +- int found = 0; + unsigned int i; ++ struct hlist_head *head; ++ struct hlist_node *node; + +- mutex_lock(&markers_mutex); + for (i = 0; i < MARKER_TABLE_SIZE; i++) { + head = &marker_table[i]; + hlist_for_each_entry(entry, node, head, hlist) { +- if (entry->private == private) { +- found = 1; +- goto iter_end; ++ if (!entry->ptype) { ++ if (entry->single.func == probe ++ && entry->single.probe_private ++ == probe_private) ++ return entry; ++ } else { ++ struct marker_probe_closure *closure; ++ closure = entry->multi; ++ for (i = 0; closure[i].func; i++) { ++ if (closure[i].func == probe && ++ closure[i].probe_private ++ == probe_private) ++ return entry; ++ } + } + } + } +-iter_end: +- if (!found) { +- private = ERR_PTR(-ENOENT); +- goto end; +- } +- entry->refcount = 0; +- /* In what module is the probe handler ? */ +- 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; +-end: +- mutex_unlock(&markers_mutex); +- return private; ++ return NULL; + } +-EXPORT_SYMBOL_GPL(marker_probe_unregister_private_data); + + /** +- * marker_arm - Arm a marker +- * @name: marker name ++ * marker_probe_unregister_private_data - Disconnect a probe from a marker ++ * @probe: probe function ++ * @probe_private: probe private data + * +- * Activate a marker. It keeps a reference count of the number of +- * arming/disarming done. +- * Returns 0 if ok, error value on error. ++ * Unregister a probe by providing the registered private data. ++ * Only removes the first marker found in hash table. ++ * Return 0 on success or error value. ++ * We do not need to call a synchronize_sched to make sure the probes have ++ * finished running before doing a module unload, because the module unload ++ * itself uses stop_machine(), which insures that every preempt disabled section ++ * have finished. + */ +-int marker_arm(const char *name) ++int marker_probe_unregister_private_data(marker_probe_func *probe, ++ void *probe_private) + { + struct marker_entry *entry; + int ret = 0; ++ struct marker_probe_closure *old; + + mutex_lock(&markers_mutex); +- entry = get_marker(name); ++ entry = get_marker_from_private_data(probe, probe_private); + if (!entry) { + ret = -ENOENT; + goto end; + } +- /* +- * Only need to update probes when refcount passes from 0 to 1. +- */ +- if (entry->refcount++) +- goto end; +-end: ++ if (entry->rcu_pending) ++ rcu_barrier(); ++ old = marker_entry_remove_probe(entry, NULL, probe_private); + mutex_unlock(&markers_mutex); +- marker_update_probes(NULL); +- return ret; +-} +-EXPORT_SYMBOL_GPL(marker_arm); +- +-/** +- * marker_disarm - Disarm a marker +- * @name: marker name +- * +- * Disarm a marker. It keeps a reference count of the number of arming/disarming +- * done. +- * Returns 0 if ok, error value on error. +- */ +-int marker_disarm(const char *name) +-{ +- struct marker_entry *entry; +- int ret = 0; +- ++ marker_update_probes(); /* may update entry */ + mutex_lock(&markers_mutex); +- entry = get_marker(name); +- if (!entry) { +- ret = -ENOENT; +- goto end; +- } +- /* +- * Only permit decrement refcount if higher than 0. +- * Do probe update only on 1 -> 0 transition. +- */ +- if (entry->refcount) { +- if (--entry->refcount) +- goto end; +- } else { +- ret = -EPERM; +- goto end; +- } ++ entry = get_marker_from_private_data(probe, probe_private); ++ WARN_ON(!entry); ++ entry->oldptr = old; ++ entry->rcu_pending = 1; ++ /* write rcu_pending before calling the RCU callback */ ++ smp_wmb(); ++#ifdef CONFIG_PREEMPT_RCU ++ synchronize_sched(); /* Until we have the call_rcu_sched() */ ++#endif ++ call_rcu(&entry->rcu, free_old_closure); ++ remove_marker(entry->name); /* Ignore busy error message */ + end: + mutex_unlock(&markers_mutex); +- marker_update_probes(NULL); + return ret; + } +-EXPORT_SYMBOL_GPL(marker_disarm); ++EXPORT_SYMBOL_GPL(marker_probe_unregister_private_data); + + /** + * marker_get_private_data - Get a marker's probe private data + * @name: marker name ++ * @probe: probe to match ++ * @num: get the nth matching probe's private data + * ++ * Returns the nth private data pointer (starting from 0) matching, or an ++ * ERR_PTR. + * Returns the private data pointer, or an ERR_PTR. + * The private data pointer should _only_ be dereferenced if the caller is the + * owner of the data, or its content could vanish. This is mostly used to + * confirm that a caller is the owner of a registered probe. + */ +-void *marker_get_private_data(const char *name) ++void *marker_get_private_data(const char *name, marker_probe_func *probe, ++ int num) + { + struct hlist_head *head; + struct hlist_node *node; + struct marker_entry *e; + size_t name_len = strlen(name) + 1; + u32 hash = jhash(name, name_len-1, 0); +- int found = 0; ++ int i; + + head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)]; + hlist_for_each_entry(e, node, head, hlist) { + if (!strcmp(name, e->name)) { +- found = 1; +- return e->private; ++ if (!e->ptype) { ++ if (num == 0 && e->single.func == probe) ++ return e->single.probe_private; ++ else ++ break; ++ } else { ++ struct marker_probe_closure *closure; ++ int match = 0; ++ closure = e->multi; ++ for (i = 0; closure[i].func; i++) { ++ if (closure[i].func != probe) ++ continue; ++ if (match++ == num) ++ return closure[i].probe_private; ++ } ++ } + } + } + return ERR_PTR(-ENOENT); +Index: linux-2.6.24.7-rt21/kernel/module.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/module.c 2008-10-08 22:22:45.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/module.c 2008-10-08 22:23:05.000000000 -0400 +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -46,6 +47,8 @@ + #include + #include + #include ++#include ++#include + + extern int module_sysfs_initialized; + +@@ -1675,6 +1678,8 @@ static struct module *load_module(void _ + unsigned int unusedcrcindex; + unsigned int unusedgplindex; + unsigned int unusedgplcrcindex; ++ unsigned int immediateindex; ++ unsigned int immediatecondendindex; + unsigned int markersindex; + unsigned int markersstringsindex; + struct module *mod; +@@ -1773,6 +1778,9 @@ static struct module *load_module(void _ + #ifdef ARCH_UNWIND_SECTION_NAME + unwindex = find_sec(hdr, sechdrs, secstrings, ARCH_UNWIND_SECTION_NAME); + #endif ++ immediateindex = find_sec(hdr, sechdrs, secstrings, "__imv"); ++ immediatecondendindex = find_sec(hdr, sechdrs, secstrings, ++ "__imv_cond_end"); + + /* Don't keep modinfo section */ + sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC; +@@ -1924,6 +1932,16 @@ static struct module *load_module(void _ + mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr; + if (gplfuturecrcindex) + mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr; ++#ifdef CONFIG_IMMEDIATE ++ mod->immediate = (void *)sechdrs[immediateindex].sh_addr; ++ mod->num_immediate = ++ sechdrs[immediateindex].sh_size / sizeof(*mod->immediate); ++ mod->immediate_cond_end = ++ (void *)sechdrs[immediatecondendindex].sh_addr; ++ mod->num_immediate_cond_end = ++ sechdrs[immediatecondendindex].sh_size ++ / sizeof(*mod->immediate_cond_end); ++#endif + + mod->unused_syms = (void *)sechdrs[unusedindex].sh_addr; + if (unusedcrcindex) +@@ -1991,11 +2009,17 @@ static struct module *load_module(void _ + + add_kallsyms(mod, sechdrs, symindex, strindex, secstrings); + ++ if (!(mod->taints & TAINT_FORCED_MODULE)) { + #ifdef CONFIG_MARKERS +- if (!mod->taints) + marker_update_probe_range(mod->markers, +- mod->markers + mod->num_markers, NULL, NULL); ++ mod->markers + mod->num_markers); ++#endif ++#ifdef CONFIG_IMMEDIATE ++ /* Immediate values must be updated after markers */ ++ imv_update_range(mod->immediate, ++ mod->immediate + mod->num_immediate); + #endif ++ } + err = module_finalize(hdr, sechdrs, mod); + if (err < 0) + goto cleanup; +@@ -2142,6 +2166,10 @@ sys_init_module(void __user *umod, + /* Drop initial reference. */ + module_put(mod); + unwind_remove_table(mod->unwind_info, 1); ++#ifdef CONFIG_IMMEDIATE ++ imv_unref(mod->immediate, mod->immediate + mod->num_immediate, ++ mod->module_init, mod->init_size); ++#endif + module_free(mod, mod->module_init); + mod->module_init = NULL; + mod->init_size = 0; +@@ -2596,7 +2624,7 @@ EXPORT_SYMBOL(struct_module); + #endif + + #ifdef CONFIG_MARKERS +-void module_update_markers(struct module *probe_module, int *refcount) ++void module_update_markers(void) + { + struct module *mod; + +@@ -2604,8 +2632,61 @@ void module_update_markers(struct module + list_for_each_entry(mod, &modules, list) + if (!mod->taints) + marker_update_probe_range(mod->markers, +- mod->markers + mod->num_markers, +- probe_module, refcount); ++ mod->markers + mod->num_markers); + mutex_unlock(&module_mutex); + } + #endif ++ ++#ifdef CONFIG_IMMEDIATE ++/** ++ * _module_imv_update - update all immediate values in the kernel ++ * ++ * Iterate on the kernel core and modules to update the immediate values. ++ * Module_mutex must be held be the caller. ++ */ ++void _module_imv_update(void) ++{ ++ struct module *mod; ++ ++ list_for_each_entry(mod, &modules, list) { ++ if (mod->taints) ++ continue; ++ imv_update_range(mod->immediate, ++ mod->immediate + mod->num_immediate); ++ } ++} ++EXPORT_SYMBOL_GPL(_module_imv_update); ++ ++/** ++ * module_imv_update - update all immediate values in the kernel ++ * ++ * Iterate on the kernel core and modules to update the immediate values. ++ * Takes module_mutex. ++ */ ++void module_imv_update(void) ++{ ++ mutex_lock(&module_mutex); ++ _module_imv_update(); ++ mutex_unlock(&module_mutex); ++} ++EXPORT_SYMBOL_GPL(module_imv_update); ++ ++/** ++ * is_imv_cond_end_module ++ * ++ * Check if the two given addresses are located in the immediate value condition ++ * end table. Addresses should be in the same object. ++ * The module mutex should be held. ++ */ ++int is_imv_cond_end_module(unsigned long addr1, unsigned long addr2) ++{ ++ struct module *mod = __module_text_address(addr1); ++ ++ if (!mod) ++ return 0; ++ ++ return _is_imv_cond_end(mod->immediate_cond_end, ++ mod->immediate_cond_end + mod->num_immediate_cond_end, ++ addr1, addr2); ++} ++#endif --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0192-tasklet-redesign.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0192-tasklet-redesign.patch @@ -0,0 +1,297 @@ +From: Ingo Molnar + +tasklet redesign: make it saner and make it easier to thread. + +Signed-off-by: Ingo Molnar + +---- + include/linux/interrupt.h | 39 ++++++----- + kernel/softirq.c | 155 +++++++++++++++++++++++++++++++--------------- + 2 files changed, 128 insertions(+), 66 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/interrupt.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/interrupt.h 2008-10-08 22:23:35.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/interrupt.h 2008-10-08 22:23:45.000000000 -0400 +@@ -310,8 +310,9 @@ extern void wait_for_softirq(int softirq + to be executed on some cpu at least once after this. + * If the tasklet is already scheduled, but its excecution is still not + started, it will be executed only once. +- * If this tasklet is already running on another CPU (or schedule is called +- from tasklet itself), it is rescheduled for later. ++ * If this tasklet is already running on another CPU, it is rescheduled ++ for later. ++ * Schedule must not be called from the tasklet itself (a lockup occurs) + * Tasklet is strictly serialized wrt itself, but not + wrt another tasklets. If client needs some intertask synchronization, + he makes it with spinlocks. +@@ -336,15 +337,25 @@ struct tasklet_struct name = { NULL, 0, + enum + { + TASKLET_STATE_SCHED, /* Tasklet is scheduled for execution */ +- TASKLET_STATE_RUN /* Tasklet is running (SMP only) */ ++ TASKLET_STATE_RUN, /* Tasklet is running (SMP only) */ ++ TASKLET_STATE_PENDING /* Tasklet is pending */ + }; + +-#ifdef CONFIG_SMP ++#define TASKLET_STATEF_SCHED (1 << TASKLET_STATE_SCHED) ++#define TASKLET_STATEF_RUN (1 << TASKLET_STATE_RUN) ++#define TASKLET_STATEF_PENDING (1 << TASKLET_STATE_PENDING) ++ ++#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT) + static inline int tasklet_trylock(struct tasklet_struct *t) + { + return !test_and_set_bit(TASKLET_STATE_RUN, &(t)->state); + } + ++static inline int tasklet_tryunlock(struct tasklet_struct *t) ++{ ++ return cmpxchg(&t->state, TASKLET_STATEF_RUN, 0) == TASKLET_STATEF_RUN; ++} ++ + static inline void tasklet_unlock(struct tasklet_struct *t) + { + smp_mb__before_clear_bit(); +@@ -356,9 +367,10 @@ static inline void tasklet_unlock_wait(s + while (test_bit(TASKLET_STATE_RUN, &(t)->state)) { barrier(); } + } + #else +-#define tasklet_trylock(t) 1 +-#define tasklet_unlock_wait(t) do { } while (0) +-#define tasklet_unlock(t) do { } while (0) ++# define tasklet_trylock(t) 1 ++# define tasklet_tryunlock(t) 1 ++# define tasklet_unlock_wait(t) do { } while (0) ++# define tasklet_unlock(t) do { } while (0) + #endif + + extern void FASTCALL(__tasklet_schedule(struct tasklet_struct *t)); +@@ -391,17 +403,8 @@ static inline void tasklet_disable(struc + smp_mb(); + } + +-static inline void tasklet_enable(struct tasklet_struct *t) +-{ +- smp_mb__before_atomic_dec(); +- atomic_dec(&t->count); +-} +- +-static inline void tasklet_hi_enable(struct tasklet_struct *t) +-{ +- smp_mb__before_atomic_dec(); +- atomic_dec(&t->count); +-} ++extern fastcall void tasklet_enable(struct tasklet_struct *t); ++extern fastcall void tasklet_hi_enable(struct tasklet_struct *t); + + extern void tasklet_kill(struct tasklet_struct *t); + extern void tasklet_kill_immediate(struct tasklet_struct *t, unsigned int cpu); +Index: linux-2.6.24.7-rt21/kernel/softirq.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/softirq.c 2008-10-08 22:23:36.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/softirq.c 2008-10-08 22:23:45.000000000 -0400 +@@ -454,14 +454,24 @@ struct tasklet_head + static DEFINE_PER_CPU(struct tasklet_head, tasklet_vec) = { NULL }; + static DEFINE_PER_CPU(struct tasklet_head, tasklet_hi_vec) = { NULL }; + ++static void inline ++__tasklet_common_schedule(struct tasklet_struct *t, struct tasklet_head *head, unsigned int nr) ++{ ++ if (tasklet_trylock(t)) { ++ WARN_ON(t->next != NULL); ++ t->next = head->list; ++ head->list = t; ++ raise_softirq_irqoff(nr); ++ tasklet_unlock(t); ++ } ++} ++ + void fastcall __tasklet_schedule(struct tasklet_struct *t) + { + unsigned long flags; + + local_irq_save(flags); +- t->next = __get_cpu_var(tasklet_vec).list; +- __get_cpu_var(tasklet_vec).list = t; +- raise_softirq_irqoff(TASKLET_SOFTIRQ); ++ __tasklet_common_schedule(t, &__get_cpu_var(tasklet_vec), TASKLET_SOFTIRQ); + local_irq_restore(flags); + } + +@@ -472,81 +482,130 @@ void fastcall __tasklet_hi_schedule(stru + unsigned long flags; + + local_irq_save(flags); +- t->next = __get_cpu_var(tasklet_hi_vec).list; +- __get_cpu_var(tasklet_hi_vec).list = t; +- raise_softirq_irqoff(HI_SOFTIRQ); ++ __tasklet_common_schedule(t, &__get_cpu_var(tasklet_hi_vec), HI_SOFTIRQ); + local_irq_restore(flags); + } + + EXPORT_SYMBOL(__tasklet_hi_schedule); + +-static void tasklet_action(struct softirq_action *a) ++void fastcall tasklet_enable(struct tasklet_struct *t) + { +- struct tasklet_struct *list; ++ if (!atomic_dec_and_test(&t->count)) ++ return; ++ if (test_and_clear_bit(TASKLET_STATE_PENDING, &t->state)) ++ tasklet_schedule(t); ++} + +- local_irq_disable(); +- list = __get_cpu_var(tasklet_vec).list; +- __get_cpu_var(tasklet_vec).list = NULL; +- local_irq_enable(); ++EXPORT_SYMBOL(tasklet_enable); ++ ++void fastcall tasklet_hi_enable(struct tasklet_struct *t) ++{ ++ if (!atomic_dec_and_test(&t->count)) ++ return; ++ if (test_and_clear_bit(TASKLET_STATE_PENDING, &t->state)) ++ tasklet_hi_schedule(t); ++} ++ ++EXPORT_SYMBOL(tasklet_hi_enable); ++ ++static void ++__tasklet_action(struct softirq_action *a, struct tasklet_struct *list) ++{ ++ int loops = 1000000; + + while (list) { + struct tasklet_struct *t = list; + + list = list->next; ++ /* ++ * Should always succeed - after a tasklist got on the ++ * list (after getting the SCHED bit set from 0 to 1), ++ * nothing but the tasklet softirq it got queued to can ++ * lock it: ++ */ ++ if (!tasklet_trylock(t)) { ++ WARN_ON(1); ++ continue; ++ } ++ ++ t->next = NULL; ++ ++ /* ++ * If we cannot handle the tasklet because it's disabled, ++ * mark it as pending. tasklet_enable() will later ++ * re-schedule the tasklet. ++ */ ++ if (unlikely(atomic_read(&t->count))) { ++out_disabled: ++ /* implicit unlock: */ ++ wmb(); ++ t->state = TASKLET_STATEF_PENDING; ++ continue; ++ } + +- if (tasklet_trylock(t)) { +- if (!atomic_read(&t->count)) { +- if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state)) +- BUG(); +- t->func(t->data); ++ /* ++ * After this point on the tasklet might be rescheduled ++ * on another CPU, but it can only be added to another ++ * CPU's tasklet list if we unlock the tasklet (which we ++ * dont do yet). ++ */ ++ if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state)) ++ WARN_ON(1); ++ ++again: ++ t->func(t->data); ++ ++ /* ++ * Try to unlock the tasklet. We must use cmpxchg, because ++ * another CPU might have scheduled or disabled the tasklet. ++ * We only allow the STATE_RUN -> 0 transition here. ++ */ ++ while (!tasklet_tryunlock(t)) { ++ /* ++ * If it got disabled meanwhile, bail out: ++ */ ++ if (atomic_read(&t->count)) ++ goto out_disabled; ++ /* ++ * If it got scheduled meanwhile, re-execute ++ * the tasklet function: ++ */ ++ if (test_and_clear_bit(TASKLET_STATE_SCHED, &t->state)) ++ goto again; ++ if (!--loops) { ++ printk("hm, tasklet state: %08lx\n", t->state); ++ WARN_ON(1); + tasklet_unlock(t); +- continue; ++ break; + } +- tasklet_unlock(t); + } +- +- local_irq_disable(); +- t->next = __get_cpu_var(tasklet_vec).list; +- __get_cpu_var(tasklet_vec).list = t; +- __do_raise_softirq_irqoff(TASKLET_SOFTIRQ); +- local_irq_enable(); + } + } + +-static void tasklet_hi_action(struct softirq_action *a) ++static void tasklet_action(struct softirq_action *a) + { + struct tasklet_struct *list; + + local_irq_disable(); +- list = __get_cpu_var(tasklet_hi_vec).list; +- __get_cpu_var(tasklet_hi_vec).list = NULL; ++ list = __get_cpu_var(tasklet_vec).list; ++ __get_cpu_var(tasklet_vec).list = NULL; + local_irq_enable(); + +- while (list) { +- struct tasklet_struct *t = list; ++ __tasklet_action(a, list); ++} + +- list = list->next; ++static void tasklet_hi_action(struct softirq_action *a) ++{ ++ struct tasklet_struct *list; + +- if (tasklet_trylock(t)) { +- if (!atomic_read(&t->count)) { +- if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state)) +- BUG(); +- t->func(t->data); +- tasklet_unlock(t); +- continue; +- } +- tasklet_unlock(t); +- } ++ local_irq_disable(); ++ list = __get_cpu_var(tasklet_hi_vec).list; ++ __get_cpu_var(tasklet_hi_vec).list = NULL; ++ local_irq_enable(); + +- local_irq_disable(); +- t->next = __get_cpu_var(tasklet_hi_vec).list; +- __get_cpu_var(tasklet_hi_vec).list = t; +- __do_raise_softirq_irqoff(HI_SOFTIRQ); +- local_irq_enable(); +- } ++ __tasklet_action(a, list); + } + +- + void tasklet_init(struct tasklet_struct *t, + void (*func)(unsigned long), unsigned long data) + { --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0123-rcu-new-4.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0123-rcu-new-4.patch @@ -0,0 +1,677 @@ +From paulmck@linux.vnet.ibm.com Thu Sep 27 00:09:37 2007 +Date: Mon, 10 Sep 2007 11:35:25 -0700 +From: Paul E. McKenney +To: linux-kernel@vger.kernel.org +Cc: linux-rt-users@vger.kernel.org, mingo@elte.hu, akpm@linux-foundation.org, + dipankar@in.ibm.com, josht@linux.vnet.ibm.com, tytso@us.ibm.com, + dvhltc@us.ibm.com, tglx@linutronix.de, a.p.zijlstra@chello.nl, + bunk@kernel.org, ego@in.ibm.com, oleg@tv-sign.ru, srostedt@redhat.com +Subject: [PATCH RFC 4/9] RCU: synchronize_sched() workaround for CPU hotplug + +Work in progress, not for inclusion. + +The combination of CPU hotplug and PREEMPT_RCU has resulted in deadlocks +due to the migration-based implementation of synchronize_sched() in -rt. +This experimental patch maps synchronize_sched() back onto Classic RCU, +eliminating the migration, thus hopefully also eliminating the deadlocks. +It is not clear that this is a good long-term approach, but it will at +least permit people doing CPU hotplug in -rt kernels additional wiggle +room in their design and implementation. + +The basic approach is to cause the -rt kernel to incorporate rcuclassic.c +as well as rcupreempt.c, but to #ifdef out the conflicting portions of +rcuclassic.c so that only the code needed to implement synchronize_sched() +remains in a PREEMPT_RT build. Invocations of grace-period detection from +the scheduling-clock interrupt go to rcuclassic.c, which then invokes +the corresponding functions in rcupreempt.c (with _rt suffix added to +keep the linker happy). Also applies the RCU_SOFTIRQ to classic RCU. +The bulk of this patch just moves code around, but likely increases +scheduling-clock latency. + +If this patch does turn out to be the right approach, the #ifdefs in +kernel/rcuclassic.c might be dealt with. ;-) At current writing, Gautham +Shenoy's most recent CPU-hotplug fixes seem likely to obsolete this patch +(which would be a very good thing indeed!). If this really pans out, +this portion of the patch will vanish during the forward-porting process. + +Signed-off-by: Steven Rostedt (for RCU_SOFTIRQ) +Signed-off-by: Paul E. McKenney +--- + + include/linux/rcuclassic.h | 79 +++++-------------------------------- + include/linux/rcupdate.h | 30 ++++++++++++-- + include/linux/rcupreempt.h | 27 ++++++------ + kernel/Makefile | 2 + kernel/rcuclassic.c | 95 ++++++++++++++++++++++++++++++++++++--------- + kernel/rcupdate.c | 22 ++++++++-- + kernel/rcupreempt.c | 50 +++++------------------ + 7 files changed, 158 insertions(+), 147 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/rcuclassic.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/rcuclassic.h 2008-10-08 22:23:25.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/rcuclassic.h 2008-10-08 22:23:26.000000000 -0400 +@@ -42,80 +42,19 @@ + #include + #include + +- +-/* Global control variables for rcupdate callback mechanism. */ +-struct rcu_ctrlblk { +- long cur; /* Current batch number. */ +- long completed; /* Number of the last completed batch */ +- int next_pending; /* Is the next batch already waiting? */ +- +- int signaled; +- +- spinlock_t lock ____cacheline_internodealigned_in_smp; +- cpumask_t cpumask; /* CPUs that need to switch in order */ +- /* for current batch to proceed. */ +-} ____cacheline_internodealigned_in_smp; +- +-/* Is batch a before batch b ? */ +-static inline int rcu_batch_before(long a, long b) +-{ +- return (a - b) < 0; +-} +- +-/* Is batch a after batch b ? */ +-static inline int rcu_batch_after(long a, long b) +-{ +- return (a - b) > 0; +-} ++DECLARE_PER_CPU(int, rcu_data_bh_passed_quiesc); + + /* +- * Per-CPU data for Read-Copy UPdate. +- * nxtlist - new callbacks are added here +- * curlist - current batch for which quiescent cycle started if any +- */ +-struct rcu_data { +- /* 1) quiescent state handling : */ +- long quiescbatch; /* Batch # for grace period */ +- int passed_quiesc; /* User-mode/idle loop etc. */ +- int qs_pending; /* core waits for quiesc state */ +- +- /* 2) batch handling */ +- long batch; /* Batch # for current RCU batch */ +- struct rcu_head *nxtlist; +- struct rcu_head **nxttail; +- long qlen; /* # of queued callbacks */ +- struct rcu_head *curlist; +- struct rcu_head **curtail; +- struct rcu_head *donelist; +- struct rcu_head **donetail; +- long blimit; /* Upper limit on a processed batch */ +- int cpu; +- struct rcu_head barrier; +-}; +- +-DECLARE_PER_CPU(struct rcu_data, rcu_data); +-DECLARE_PER_CPU(struct rcu_data, rcu_bh_data); +- +-/* +- * Increment the quiescent state counter. ++ * Increment the bottom-half quiescent state counter. + * The counter is a bit degenerated: We do not need to know + * how many quiescent states passed, just if there was at least + * one since the start of the grace period. Thus just a flag. + */ +-static inline void rcu_qsctr_inc(int cpu) +-{ +- struct rcu_data *rdp = &per_cpu(rcu_data, cpu); +- rdp->passed_quiesc = 1; +-} + static inline void rcu_bh_qsctr_inc(int cpu) + { +- struct rcu_data *rdp = &per_cpu(rcu_bh_data, cpu); +- rdp->passed_quiesc = 1; ++ per_cpu(rcu_data_bh_passed_quiesc, cpu) = 1; + } + +-extern int rcu_pending(int cpu); +-extern int rcu_needs_cpu(int cpu); +- + #define __rcu_read_lock() \ + do { \ + preempt_disable(); \ +@@ -139,9 +78,15 @@ extern int rcu_needs_cpu(int cpu); + + #define __synchronize_sched() synchronize_rcu() + +-extern void __rcu_init(void); +-extern void rcu_check_callbacks(int cpu, int user); +-extern void rcu_restart_cpu(int cpu); ++#define rcu_advance_callbacks_rt(cpu, user) do { } while (0) ++#define rcu_check_callbacks_rt(cpu, user) do { } while (0) ++#define rcu_init_rt() do { } while (0) ++#define rcu_needs_cpu_rt(cpu) 0 ++#define rcu_pending_rt(cpu) 0 ++#define rcu_process_callbacks_rt(unused) do { } while (0) ++ ++extern void FASTCALL(call_rcu_classic(struct rcu_head *head, ++ void (*func)(struct rcu_head *head))); + + #endif /* __KERNEL__ */ + #endif /* __LINUX_RCUCLASSIC_H */ +Index: linux-2.6.24.7-rt21/include/linux/rcupdate.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/rcupdate.h 2008-10-08 22:23:25.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/rcupdate.h 2008-10-08 22:23:26.000000000 -0400 +@@ -220,8 +220,11 @@ extern struct lockdep_map rcu_lock_map; + * delimited by rcu_read_lock() and rcu_read_unlock(), + * and may be nested. + */ +-extern void FASTCALL(call_rcu(struct rcu_head *head, +- void (*func)(struct rcu_head *head))); ++#ifdef CONFIG_CLASSIC_RCU ++#define call_rcu(head, func) call_rcu_classic(head, func) ++#else /* #ifdef CONFIG_CLASSIC_RCU */ ++#define call_rcu(head, func) call_rcu_preempt(head, func) ++#endif /* #else #ifdef CONFIG_CLASSIC_RCU */ + + /** + * call_rcu_bh - Queue an RCU for invocation after a quicker grace period. +@@ -249,9 +252,28 @@ extern long rcu_batches_completed(void); + extern long rcu_batches_completed_bh(void); + + /* Internal to kernel */ +-extern void rcu_init(void); + extern void rcu_check_callbacks(int cpu, int user); +-extern int rcu_needs_cpu(int cpu); ++extern long rcu_batches_completed(void); ++extern long rcu_batches_completed_bh(void); ++extern void rcu_check_callbacks(int cpu, int user); ++extern void rcu_init(void); ++extern int rcu_needs_cpu(int cpu); ++extern int rcu_pending(int cpu); ++struct softirq_action; ++extern void rcu_restart_cpu(int cpu); ++ ++DECLARE_PER_CPU(int, rcu_data_passed_quiesc); ++ ++/* ++ * Increment the quiescent state counter. ++ * The counter is a bit degenerated: We do not need to know ++ * how many quiescent states passed, just if there was at least ++ * one since the start of the grace period. Thus just a flag. ++ */ ++static inline void rcu_qsctr_inc(int cpu) ++{ ++ per_cpu(rcu_data_passed_quiesc, cpu) = 1; ++} + + #endif /* __KERNEL__ */ + #endif /* __LINUX_RCUPDATE_H */ +Index: linux-2.6.24.7-rt21/include/linux/rcupreempt.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/rcupreempt.h 2008-10-08 22:23:25.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/rcupreempt.h 2008-10-08 22:23:26.000000000 -0400 +@@ -42,25 +42,26 @@ + #include + #include + +-#define rcu_qsctr_inc(cpu) +-#define rcu_bh_qsctr_inc(cpu) + #define call_rcu_bh(head, rcu) call_rcu(head, rcu) +- +-extern void __rcu_read_lock(void); +-extern void __rcu_read_unlock(void); +-extern int rcu_pending(int cpu); +-extern int rcu_needs_cpu(int cpu); +- ++#define rcu_bh_qsctr_inc(cpu) do { } while (0) + #define __rcu_read_lock_bh() { rcu_read_lock(); local_bh_disable(); } + #define __rcu_read_unlock_bh() { local_bh_enable(); rcu_read_unlock(); } +- + #define __rcu_read_lock_nesting() (current->rcu_read_lock_nesting) + ++extern void FASTCALL(call_rcu_classic(struct rcu_head *head, ++ void (*func)(struct rcu_head *head))); ++extern void FASTCALL(call_rcu_preempt(struct rcu_head *head, ++ void (*func)(struct rcu_head *head))); ++extern void __rcu_read_lock(void); ++extern void __rcu_read_unlock(void); + extern void __synchronize_sched(void); +- +-extern void __rcu_init(void); +-extern void rcu_check_callbacks(int cpu, int user); +-extern void rcu_restart_cpu(int cpu); ++extern void rcu_advance_callbacks_rt(int cpu, int user); ++extern void rcu_check_callbacks_rt(int cpu, int user); ++extern void rcu_init_rt(void); ++extern int rcu_needs_cpu_rt(int cpu); ++extern int rcu_pending_rt(int cpu); ++struct softirq_action; ++extern void rcu_process_callbacks_rt(struct softirq_action *unused); + + #ifdef CONFIG_RCU_TRACE + struct rcupreempt_trace; +Index: linux-2.6.24.7-rt21/kernel/Makefile +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/Makefile 2008-10-08 22:23:25.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/Makefile 2008-10-08 22:23:26.000000000 -0400 +@@ -65,7 +65,7 @@ obj-$(CONFIG_GENERIC_HARDIRQS) += irq/ + obj-$(CONFIG_SECCOMP) += seccomp.o + obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o + obj-$(CONFIG_CLASSIC_RCU) += rcuclassic.o +-obj-$(CONFIG_PREEMPT_RCU) += rcupreempt.o ++obj-$(CONFIG_PREEMPT_RCU) += rcuclassic.o rcupreempt.o + ifeq ($(CONFIG_PREEMPT_RCU),y) + obj-$(CONFIG_RCU_TRACE) += rcupreempt_trace.o + endif +Index: linux-2.6.24.7-rt21/kernel/rcuclassic.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rcuclassic.c 2008-10-08 22:23:25.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rcuclassic.c 2008-10-08 22:23:26.000000000 -0400 +@@ -45,10 +45,53 @@ + #include + #include + #include +-/* #include @@@ */ + #include + #include + ++ ++/* Global control variables for rcupdate callback mechanism. */ ++struct rcu_ctrlblk { ++ long cur; /* Current batch number. */ ++ long completed; /* Number of the last completed batch */ ++ int next_pending; /* Is the next batch already waiting? */ ++ ++ int signaled; ++ ++ spinlock_t lock ____cacheline_internodealigned_in_smp; ++ cpumask_t cpumask; /* CPUs that need to switch in order */ ++ /* for current batch to proceed. */ ++} ____cacheline_internodealigned_in_smp; ++ ++/* Is batch a before batch b ? */ ++static inline int rcu_batch_before(long a, long b) ++{ ++ return (a - b) < 0; ++} ++ ++/* ++ * Per-CPU data for Read-Copy UPdate. ++ * nxtlist - new callbacks are added here ++ * curlist - current batch for which quiescent cycle started if any ++ */ ++struct rcu_data { ++ /* 1) quiescent state handling : */ ++ long quiescbatch; /* Batch # for grace period */ ++ int *passed_quiesc; /* User-mode/idle loop etc. */ ++ int qs_pending; /* core waits for quiesc state */ ++ ++ /* 2) batch handling */ ++ long batch; /* Batch # for current RCU batch */ ++ struct rcu_head *nxtlist; ++ struct rcu_head **nxttail; ++ long qlen; /* # of queued callbacks */ ++ struct rcu_head *curlist; ++ struct rcu_head **curtail; ++ struct rcu_head *donelist; ++ struct rcu_head **donetail; ++ long blimit; /* Upper limit on a processed batch */ ++ int cpu; ++}; ++ + /* Definition for rcupdate control block. */ + static struct rcu_ctrlblk rcu_ctrlblk = { + .cur = -300, +@@ -63,11 +106,11 @@ static struct rcu_ctrlblk rcu_bh_ctrlblk + .cpumask = CPU_MASK_NONE, + }; + +-DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L }; +-DEFINE_PER_CPU(struct rcu_data, rcu_bh_data) = { 0L }; ++static DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L }; ++static DEFINE_PER_CPU(struct rcu_data, rcu_bh_data) = { 0L }; ++DEFINE_PER_CPU(int, rcu_data_bh_passed_quiesc); + + /* Fake initialization required by compiler */ +-static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL}; + static int blimit = 10; + static int qhimark = 10000; + static int qlowmark = 100; +@@ -110,8 +153,8 @@ static inline void force_quiescent_state + * sections are delimited by rcu_read_lock() and rcu_read_unlock(), + * and may be nested. + */ +-void fastcall call_rcu(struct rcu_head *head, +- void (*func)(struct rcu_head *rcu)) ++void fastcall call_rcu_classic(struct rcu_head *head, ++ void (*func)(struct rcu_head *rcu)) + { + unsigned long flags; + struct rcu_data *rdp; +@@ -128,7 +171,9 @@ void fastcall call_rcu(struct rcu_head * + } + local_irq_restore(flags); + } +-EXPORT_SYMBOL_GPL(call_rcu); ++EXPORT_SYMBOL_GPL(call_rcu_classic); ++ ++#ifdef CONFIG_CLASSIC_RCU + + /** + * call_rcu_bh - Queue an RCU for invocation after a quicker grace period. +@@ -166,7 +211,9 @@ void fastcall call_rcu_bh(struct rcu_hea + + local_irq_restore(flags); + } ++#ifdef CONFIG_CLASSIC_RCU + EXPORT_SYMBOL_GPL(call_rcu_bh); ++#endif /* #ifdef CONFIG_CLASSIC_RCU */ + + /* + * Return the number of RCU batches processed thus far. Useful +@@ -176,7 +223,9 @@ long rcu_batches_completed(void) + { + return rcu_ctrlblk.completed; + } ++#ifdef CONFIG_CLASSIC_RCU + EXPORT_SYMBOL_GPL(rcu_batches_completed); ++#endif /* #ifdef CONFIG_CLASSIC_RCU */ + + /* + * Return the number of RCU batches processed thus far. Useful +@@ -186,7 +235,11 @@ long rcu_batches_completed_bh(void) + { + return rcu_bh_ctrlblk.completed; + } ++#ifdef CONFIG_CLASSIC_RCU + EXPORT_SYMBOL_GPL(rcu_batches_completed_bh); ++#endif /* #ifdef CONFIG_CLASSIC_RCU */ ++ ++#endif /* #ifdef CONFIG_CLASSIC_RCU */ + + /* + * Invoke the completed RCU callbacks. They are expected to be in +@@ -217,7 +270,7 @@ static void rcu_do_batch(struct rcu_data + if (!rdp->donelist) + rdp->donetail = &rdp->donelist; + else +- tasklet_schedule(&per_cpu(rcu_tasklet, rdp->cpu)); ++ raise_softirq(RCU_SOFTIRQ); + } + + /* +@@ -294,7 +347,7 @@ static void rcu_check_quiescent_state(st + if (rdp->quiescbatch != rcp->cur) { + /* start new grace period: */ + rdp->qs_pending = 1; +- rdp->passed_quiesc = 0; ++ *rdp->passed_quiesc = 0; + rdp->quiescbatch = rcp->cur; + return; + } +@@ -310,7 +363,7 @@ static void rcu_check_quiescent_state(st + * Was there a quiescent state since the beginning of the grace + * period? If no, then exit and wait for the next call. + */ +- if (!rdp->passed_quiesc) ++ if (!*rdp->passed_quiesc) + return; + rdp->qs_pending = 0; + +@@ -369,7 +422,6 @@ static void rcu_offline_cpu(int cpu) + &per_cpu(rcu_bh_data, cpu)); + put_cpu_var(rcu_data); + put_cpu_var(rcu_bh_data); +- tasklet_kill_immediate(&per_cpu(rcu_tasklet, cpu), cpu); + } + + #else +@@ -381,7 +433,7 @@ static void rcu_offline_cpu(int cpu) + #endif + + /* +- * This does the RCU processing work from tasklet context. ++ * This does the RCU processing work from softirq context. + */ + static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp, + struct rcu_data *rdp) +@@ -426,10 +478,11 @@ static void __rcu_process_callbacks(stru + rcu_do_batch(rdp); + } + +-static void rcu_process_callbacks(unsigned long unused) ++static void rcu_process_callbacks(struct softirq_action *unused) + { + __rcu_process_callbacks(&rcu_ctrlblk, &__get_cpu_var(rcu_data)); + __rcu_process_callbacks(&rcu_bh_ctrlblk, &__get_cpu_var(rcu_bh_data)); ++ rcu_process_callbacks_rt(unused); + } + + static int __rcu_pending(struct rcu_ctrlblk *rcp, struct rcu_data *rdp) +@@ -464,7 +517,8 @@ static int __rcu_pending(struct rcu_ctrl + int rcu_pending(int cpu) + { + return __rcu_pending(&rcu_ctrlblk, &per_cpu(rcu_data, cpu)) || +- __rcu_pending(&rcu_bh_ctrlblk, &per_cpu(rcu_bh_data, cpu)); ++ __rcu_pending(&rcu_bh_ctrlblk, &per_cpu(rcu_bh_data, cpu)) || ++ rcu_pending_rt(cpu); + } + + /* +@@ -478,7 +532,8 @@ int rcu_needs_cpu(int cpu) + struct rcu_data *rdp = &per_cpu(rcu_data, cpu); + struct rcu_data *rdp_bh = &per_cpu(rcu_bh_data, cpu); + +- return (!!rdp->curlist || !!rdp_bh->curlist || rcu_pending(cpu)); ++ return (!!rdp->curlist || !!rdp_bh->curlist || rcu_pending(cpu) || ++ rcu_needs_cpu_rt(cpu)); + } + + void rcu_check_callbacks(int cpu, int user) +@@ -490,7 +545,8 @@ void rcu_check_callbacks(int cpu, int us + rcu_bh_qsctr_inc(cpu); + } else if (!in_softirq()) + rcu_bh_qsctr_inc(cpu); +- tasklet_schedule(&per_cpu(rcu_tasklet, cpu)); ++ rcu_check_callbacks_rt(cpu, user); ++ raise_softirq(RCU_SOFTIRQ); + } + + static void rcu_init_percpu_data(int cpu, struct rcu_ctrlblk *rcp, +@@ -512,8 +568,9 @@ static void __cpuinit rcu_online_cpu(int + struct rcu_data *bh_rdp = &per_cpu(rcu_bh_data, cpu); + + rcu_init_percpu_data(cpu, &rcu_ctrlblk, rdp); ++ rdp->passed_quiesc = &per_cpu(rcu_data_passed_quiesc, cpu); + rcu_init_percpu_data(cpu, &rcu_bh_ctrlblk, bh_rdp); +- tasklet_init(&per_cpu(rcu_tasklet, cpu), rcu_process_callbacks, 0UL); ++ bh_rdp->passed_quiesc = &per_cpu(rcu_data_bh_passed_quiesc, cpu); + } + + static int __cpuinit rcu_cpu_notify(struct notifier_block *self, +@@ -545,12 +602,14 @@ static struct notifier_block __cpuinitda + * Note that rcu_qsctr and friends are implicitly + * initialized due to the choice of ``0'' for RCU_CTR_INVALID. + */ +-void __init __rcu_init(void) ++void __init rcu_init(void) + { + rcu_cpu_notify(&rcu_nb, CPU_UP_PREPARE, + (void *)(long)smp_processor_id()); + /* Register notifier for non-boot CPUs */ + register_cpu_notifier(&rcu_nb); ++ rcu_init_rt(); ++ open_softirq(RCU_SOFTIRQ, rcu_process_callbacks, NULL); + } + + module_param(blimit, int, 0); +Index: linux-2.6.24.7-rt21/kernel/rcupdate.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rcupdate.c 2008-10-08 22:23:25.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rcupdate.c 2008-10-08 22:23:26.000000000 -0400 +@@ -59,6 +59,7 @@ struct rcu_synchronize { + struct completion completion; + }; + ++DEFINE_PER_CPU(int, rcu_data_passed_quiesc); + static DEFINE_PER_CPU(struct rcu_head, rcu_barrier_head) = {NULL}; + static atomic_t rcu_barrier_cpu_count; + static DEFINE_MUTEX(rcu_barrier_mutex); +@@ -95,6 +96,22 @@ void synchronize_rcu(void) + } + EXPORT_SYMBOL_GPL(synchronize_rcu); + ++#ifdef CONFIG_PREEMPT_RCU ++ ++/* ++ * Map synchronize_sched() to the classic RCU implementation. ++ */ ++void __synchronize_sched(void) ++{ ++ struct rcu_synchronize rcu; ++ ++ init_completion(&rcu.completion); ++ call_rcu_classic(&rcu.head, wakeme_after_rcu); ++ wait_for_completion(&rcu.completion); ++} ++EXPORT_SYMBOL_GPL(__synchronize_sched); ++#endif /* #ifdef CONFIG_PREEMPT_RCU */ ++ + static void rcu_barrier_callback(struct rcu_head *notused) + { + if (atomic_dec_and_test(&rcu_barrier_cpu_count)) +@@ -138,8 +155,3 @@ void rcu_barrier(void) + mutex_unlock(&rcu_barrier_mutex); + } + EXPORT_SYMBOL_GPL(rcu_barrier); +- +-void __init rcu_init(void) +-{ +- __rcu_init(); +-} +Index: linux-2.6.24.7-rt21/kernel/rcupreempt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rcupreempt.c 2008-10-08 22:23:25.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rcupreempt.c 2008-10-08 22:23:26.000000000 -0400 +@@ -61,7 +61,6 @@ struct rcu_data { + spinlock_t lock; /* Protect rcu_data fields. */ + long completed; /* Number of last completed batch. */ + int waitlistcount; +- struct tasklet_struct rcu_tasklet; + struct rcu_head *nextlist; + struct rcu_head **nexttail; + struct rcu_head *waitlist[GP_STAGES]; +@@ -550,7 +549,7 @@ static void rcu_check_mb(int cpu) + } + } + +-void rcu_check_callbacks(int cpu, int user) ++void rcu_check_callbacks_rt(int cpu, int user) + { + unsigned long oldirq; + struct rcu_data *rdp = RCU_DATA_CPU(cpu); +@@ -561,19 +560,14 @@ void rcu_check_callbacks(int cpu, int us + spin_lock_irqsave(&rdp->lock, oldirq); + RCU_TRACE_RDP(rcupreempt_trace_check_callbacks, rdp); + __rcu_advance_callbacks(rdp); +- if (rdp->donelist == NULL) { +- spin_unlock_irqrestore(&rdp->lock, oldirq); +- } else { +- spin_unlock_irqrestore(&rdp->lock, oldirq); +- raise_softirq(RCU_SOFTIRQ); +- } ++ spin_unlock_irqrestore(&rdp->lock, oldirq); + } + + /* + * Needed by dynticks, to make sure all RCU processing has finished +- * when we go idle: ++ * when we go idle. (Currently unused, needed?) + */ +-void rcu_advance_callbacks(int cpu, int user) ++void rcu_advance_callbacks_rt(int cpu, int user) + { + unsigned long oldirq; + struct rcu_data *rdp = RCU_DATA_CPU(cpu); +@@ -589,7 +583,7 @@ void rcu_advance_callbacks(int cpu, int + spin_unlock_irqrestore(&rdp->lock, oldirq); + } + +-static void rcu_process_callbacks(struct softirq_action *unused) ++void rcu_process_callbacks_rt(struct softirq_action *unused) + { + unsigned long flags; + struct rcu_head *next, *list; +@@ -613,8 +607,8 @@ static void rcu_process_callbacks(struct + } + } + +-void fastcall call_rcu(struct rcu_head *head, +- void (*func)(struct rcu_head *rcu)) ++void fastcall call_rcu_preempt(struct rcu_head *head, ++ void (*func)(struct rcu_head *rcu)) + { + unsigned long oldirq; + struct rcu_data *rdp; +@@ -631,28 +625,7 @@ void fastcall call_rcu(struct rcu_head * + spin_unlock(&rdp->lock); + local_irq_restore(oldirq); + } +-EXPORT_SYMBOL_GPL(call_rcu); +- +-/* +- * Wait until all currently running preempt_disable() code segments +- * (including hardware-irq-disable segments) complete. Note that +- * in -rt this does -not- necessarily result in all currently executing +- * interrupt -handlers- having completed. +- */ +-void __synchronize_sched(void) +-{ +- cpumask_t oldmask; +- int cpu; +- +- if (sched_getaffinity(0, &oldmask) < 0) +- oldmask = cpu_possible_map; +- for_each_online_cpu(cpu) { +- sched_setaffinity(0, cpumask_of_cpu(cpu)); +- schedule(); +- } +- sched_setaffinity(0, oldmask); +-} +-EXPORT_SYMBOL_GPL(__synchronize_sched); ++EXPORT_SYMBOL_GPL(call_rcu_preempt); + + /* + * Check to see if any future RCU-related work will need to be done +@@ -663,7 +636,7 @@ EXPORT_SYMBOL_GPL(__synchronize_sched); + * This function is part of the RCU implementation; it is -not- + * an exported member of the RCU API. + */ +-int rcu_needs_cpu(int cpu) ++int rcu_needs_cpu_rt(int cpu) + { + struct rcu_data *rdp = RCU_DATA_CPU(cpu); + +@@ -672,7 +645,7 @@ int rcu_needs_cpu(int cpu) + rdp->nextlist != NULL); + } + +-int rcu_pending(int cpu) ++int rcu_pending_rt(int cpu) + { + struct rcu_data *rdp = RCU_DATA_CPU(cpu); + +@@ -699,7 +672,7 @@ int rcu_pending(int cpu) + return 0; + } + +-void __init __rcu_init(void) ++void __init rcu_init_rt(void) + { + int cpu; + int i; +@@ -719,7 +692,6 @@ void __init __rcu_init(void) + rdp->donelist = NULL; + rdp->donetail = &rdp->donelist; + } +- open_softirq(RCU_SOFTIRQ, rcu_process_callbacks, NULL); + } + + /* --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0275-softlockup-add-irq-regs-h.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0275-softlockup-add-irq-regs-h.patch @@ -0,0 +1,20 @@ +Subject: core: make asm/irq_regs.h available on every platform +From: Ingo Molnar + +the softlockup detector would like to use get_irq_regs(), so generalize +the availability on every Linux architecture. + +(it is fine for an architecture to always return NULL to get_irq_regs(), +which it does by default.) + +Signed-off-by: Ingo Molnar +--- + include/asm-arm26/irq_regs.h | 1 + + 1 file changed, 1 insertion(+) + +Index: linux-2.6.24.7-rt21/include/asm-arm26/irq_regs.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/include/asm-arm26/irq_regs.h 2008-10-08 22:24:09.000000000 -0400 +@@ -0,0 +1 @@ ++#include --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0125-rcu-new-7.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0125-rcu-new-7.patch @@ -0,0 +1,253 @@ +From paulmck@linux.vnet.ibm.com Thu Sep 27 15:32:09 2007 +Date: Mon, 10 Sep 2007 11:39:46 -0700 +From: Paul E. McKenney +To: linux-kernel@vger.kernel.org +Cc: linux-rt-users@vger.kernel.org, mingo@elte.hu, akpm@linux-foundation.org, + dipankar@in.ibm.com, josht@linux.vnet.ibm.com, tytso@us.ibm.com, + dvhltc@us.ibm.com, tglx@linutronix.de, a.p.zijlstra@chello.nl, + bunk@kernel.org, ego@in.ibm.com, oleg@tv-sign.ru, srostedt@redhat.com +Subject: [PATCH RFC 7/9] RCU: rcutorture testing for RCU priority boosting + +Work in progress, not for inclusion. Still uses xtime because this +patch is still against 2.6.22. + +This patch modifies rcutorture to also torture RCU priority boosting. +The torturing involves forcing RCU read-side critical sections (already +performed as part of the torturing of RCU) to run for extremely long +time periods, increasing the probability of their being preempted and +thus needing priority boosting. The fact that rcutorture's "nreaders" +module parameter defaults to twice the number of CPUs helps ensure lots +of the needed preemption. + +To cause the torturing to be fully effective in -mm, run in presence +of CPU-hotplug operations. + +Signed-off-by: Paul E. McKenney +--- + + kernel/rcutorture.c | 91 ++++++++++++++++++++++++++++++++++++++-------- + kernel/time/timekeeping.c | 2 + + 2 files changed, 79 insertions(+), 14 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/rcutorture.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rcutorture.c 2008-10-08 22:22:39.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rcutorture.c 2008-10-08 22:23:26.000000000 -0400 +@@ -57,6 +57,7 @@ static int stat_interval; /* Interval be + static int verbose; /* Print more debug info. */ + static int test_no_idle_hz; /* Test RCU's support for tickless idle CPUs. */ + static int shuffle_interval = 5; /* Interval between shuffles (in sec)*/ ++static int preempt_torture; /* Realtime task preempts torture readers. */ + static char *torture_type = "rcu"; /* What RCU implementation to torture. */ + + module_param(nreaders, int, 0444); +@@ -71,6 +72,8 @@ module_param(test_no_idle_hz, bool, 0444 + MODULE_PARM_DESC(test_no_idle_hz, "Test support for tickless idle CPUs"); + module_param(shuffle_interval, int, 0444); + MODULE_PARM_DESC(shuffle_interval, "Number of seconds between shuffles"); ++module_param(preempt_torture, bool, 0444); ++MODULE_PARM_DESC(preempt_torture, "Enable realtime preemption torture"); + module_param(torture_type, charp, 0444); + MODULE_PARM_DESC(torture_type, "Type of RCU to torture (rcu, rcu_bh, srcu)"); + +@@ -191,6 +194,8 @@ struct rcu_torture_ops { + int (*completed)(void); + void (*deferredfree)(struct rcu_torture *p); + void (*sync)(void); ++ long (*preemptstart)(void); ++ void (*preemptend)(void); + int (*stats)(char *page); + char *name; + }; +@@ -255,16 +260,75 @@ static void rcu_torture_deferred_free(st + call_rcu(&p->rtort_rcu, rcu_torture_cb); + } + ++static struct task_struct *rcu_preeempt_task; ++static unsigned long rcu_torture_preempt_errors; ++ ++static int rcu_torture_preempt(void *arg) ++{ ++ int completedstart; ++ int err; ++ time_t gcstart; ++ struct sched_param sp; ++ ++ sp.sched_priority = MAX_RT_PRIO - 1; ++ err = sched_setscheduler(current, SCHED_RR, &sp); ++ if (err != 0) ++ printk(KERN_ALERT "rcu_torture_preempt() priority err: %d\n", ++ err); ++ current->flags |= PF_NOFREEZE; ++ ++ do { ++ completedstart = rcu_torture_completed(); ++ gcstart = xtime.tv_sec; ++ while ((xtime.tv_sec - gcstart < 10) && ++ (rcu_torture_completed() == completedstart)) ++ cond_resched(); ++ if (rcu_torture_completed() == completedstart) ++ rcu_torture_preempt_errors++; ++ schedule_timeout_interruptible(1); ++ } while (!kthread_should_stop()); ++ return 0; ++} ++ ++static long rcu_preempt_start(void) ++{ ++ long retval = 0; ++ ++ rcu_preeempt_task = kthread_run(rcu_torture_preempt, NULL, ++ "rcu_torture_preempt"); ++ if (IS_ERR(rcu_preeempt_task)) { ++ VERBOSE_PRINTK_ERRSTRING("Failed to create preempter"); ++ retval = PTR_ERR(rcu_preeempt_task); ++ rcu_preeempt_task = NULL; ++ } ++ return retval; ++} ++ ++static void rcu_preempt_end(void) ++{ ++ if (rcu_preeempt_task != NULL) { ++ VERBOSE_PRINTK_STRING("Stopping rcu_preempt task"); ++ kthread_stop(rcu_preeempt_task); ++ } ++ rcu_preeempt_task = NULL; ++} ++ ++static int rcu_preempt_stats(char *page) ++{ ++ return sprintf(page, ++ "Preemption stalls: %lu\n", rcu_torture_preempt_errors); ++} ++ + static struct rcu_torture_ops rcu_ops = { +- .init = NULL, +- .cleanup = NULL, + .readlock = rcu_torture_read_lock, + .readdelay = rcu_read_delay, + .readunlock = rcu_torture_read_unlock, + .completed = rcu_torture_completed, + .deferredfree = rcu_torture_deferred_free, + .sync = synchronize_rcu, +- .stats = NULL, ++ .preemptstart = rcu_preempt_start, ++ .preemptend = rcu_preempt_end, ++ .stats = rcu_preempt_stats, + .name = "rcu" + }; + +@@ -296,14 +360,12 @@ static void rcu_sync_torture_init(void) + + static struct rcu_torture_ops rcu_sync_ops = { + .init = rcu_sync_torture_init, +- .cleanup = NULL, + .readlock = rcu_torture_read_lock, + .readdelay = rcu_read_delay, + .readunlock = rcu_torture_read_unlock, + .completed = rcu_torture_completed, + .deferredfree = rcu_sync_torture_deferred_free, + .sync = synchronize_rcu, +- .stats = NULL, + .name = "rcu_sync" + }; + +@@ -355,28 +417,23 @@ static void rcu_bh_torture_synchronize(v + } + + static struct rcu_torture_ops rcu_bh_ops = { +- .init = NULL, +- .cleanup = NULL, + .readlock = rcu_bh_torture_read_lock, + .readdelay = rcu_read_delay, /* just reuse rcu's version. */ + .readunlock = rcu_bh_torture_read_unlock, + .completed = rcu_bh_torture_completed, + .deferredfree = rcu_bh_torture_deferred_free, + .sync = rcu_bh_torture_synchronize, +- .stats = NULL, + .name = "rcu_bh" + }; + + static struct rcu_torture_ops rcu_bh_sync_ops = { + .init = rcu_sync_torture_init, +- .cleanup = NULL, + .readlock = rcu_bh_torture_read_lock, + .readdelay = rcu_read_delay, /* just reuse rcu's version. */ + .readunlock = rcu_bh_torture_read_unlock, + .completed = rcu_bh_torture_completed, + .deferredfree = rcu_sync_torture_deferred_free, + .sync = rcu_bh_torture_synchronize, +- .stats = NULL, + .name = "rcu_bh_sync" + }; + +@@ -488,14 +545,12 @@ static void sched_torture_synchronize(vo + + static struct rcu_torture_ops sched_ops = { + .init = rcu_sync_torture_init, +- .cleanup = NULL, + .readlock = sched_torture_read_lock, + .readdelay = rcu_read_delay, /* just reuse rcu's version. */ + .readunlock = sched_torture_read_unlock, + .completed = sched_torture_completed, + .deferredfree = rcu_sync_torture_deferred_free, + .sync = sched_torture_synchronize, +- .stats = NULL, + .name = "sched" + }; + +@@ -787,9 +842,10 @@ rcu_torture_print_module_parms(char *tag + printk(KERN_ALERT "%s" TORTURE_FLAG + "--- %s: nreaders=%d nfakewriters=%d " + "stat_interval=%d verbose=%d test_no_idle_hz=%d " +- "shuffle_interval = %d\n", ++ "shuffle_interval=%d preempt_torture=%d\n", + torture_type, tag, nrealreaders, nfakewriters, +- stat_interval, verbose, test_no_idle_hz, shuffle_interval); ++ stat_interval, verbose, test_no_idle_hz, shuffle_interval, ++ preempt_torture); + } + + static void +@@ -842,6 +898,8 @@ rcu_torture_cleanup(void) + kthread_stop(stats_task); + } + stats_task = NULL; ++ if (preempt_torture && (cur_ops->preemptend != NULL)) ++ cur_ops->preemptend(); + + /* Wait for all RCU callbacks to fire. */ + rcu_barrier(); +@@ -984,6 +1042,11 @@ rcu_torture_init(void) + goto unwind; + } + } ++ if (preempt_torture && (cur_ops->preemptstart != NULL)) { ++ firsterr = cur_ops->preemptstart(); ++ if (firsterr != 0) ++ goto unwind; ++ } + return 0; + + unwind: +Index: linux-2.6.24.7-rt21/kernel/time/timekeeping.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/time/timekeeping.c 2008-10-08 22:22:39.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/time/timekeeping.c 2008-10-08 22:23:26.000000000 -0400 +@@ -26,6 +26,7 @@ + */ + __cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock); + ++EXPORT_SYMBOL_GPL(xtime_lock); + + /* + * The current time +@@ -45,6 +46,7 @@ __cacheline_aligned_in_smp DEFINE_SEQLOC + struct timespec xtime __attribute__ ((aligned (16))); + struct timespec wall_to_monotonic __attribute__ ((aligned (16))); + static unsigned long total_sleep_time; /* seconds */ ++EXPORT_SYMBOL_GPL(xtime); + + static struct timespec xtime_cache __attribute__ ((aligned (16))); + static inline void update_xtime_cache(u64 nsec) --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0156-preempt-irqs-ppc-celleb-beatic-eoi.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0156-preempt-irqs-ppc-celleb-beatic-eoi.patch @@ -0,0 +1,110 @@ +From tsutomu.owa@toshiba.co.jp Tue May 15 17:44:07 2007 +Date: Tue, 15 May 2007 17:44:07 +0900 +From: Tsutomu OWA +To: linuxppc-dev@ozlabs.org +Cc: mingo@elte.hu, tglx@linutronix.de +Subject: Re: [RFC] [patch 1/2] powerpc 2.6.21-rt1: fix kernel hang and/or panic + + +> It occurs on 2.6.21 + patch-2.6.21-rt1 + series of patches that I posted +> yesterday. + +When doing 'hdparm -t /dev/hda' several times, it silently hangs. +I think it freezes since It does not response to ping as well. +On the other hand, PREEMPT_NONE kernel works just fine. + +After looking into the rt interrupt handling code, I noticed +that code path differs between PREEMPT_NONE and PREEMPT_RT; + NONE: mask() -> unmask() -> eoi() + RT: mask() -> eoi() -> unmask() + +The hypervisor underlying the linux on Celleb wants to be called +in this "mask() -> unmask() -> eoi()" order. This patch mimics +the behavior of PREEPT_NONE even if PREEMPT_RT is specified. + +Or, would it be better to create/add a new (threaded) irq handler? + +Any comments? + +Thanks in advance + +Signed-off-by: Tsutomu OWA +-- owa + +--- + arch/powerpc/platforms/celleb/interrupt.c | 39 +++++++++++++++++++++++++----- + 1 file changed, 33 insertions(+), 6 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/powerpc/platforms/celleb/interrupt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/platforms/celleb/interrupt.c 2008-10-08 22:22:37.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/platforms/celleb/interrupt.c 2008-10-08 22:23:34.000000000 -0400 +@@ -29,6 +29,10 @@ + #include "interrupt.h" + #include "beat_wrapper.h" + ++#ifdef CONFIG_PREEMPT_HARDIRQS ++extern int hardirq_preemption; ++#endif /* CONFIG_PREEMPT_HARDIRQS */ ++ + #define MAX_IRQS NR_IRQS + static DEFINE_SPINLOCK(beatic_irq_mask_lock); + static uint64_t beatic_irq_mask_enable[(MAX_IRQS+255)/64]; +@@ -71,12 +75,35 @@ static void beatic_mask_irq(unsigned int + spin_unlock_irqrestore(&beatic_irq_mask_lock, flags); + } + ++static void __beatic_eoi_irq(unsigned int irq_plug) ++{ ++ s64 err; ++ ++ if ((err = beat_downcount_of_interrupt(irq_plug)) != 0) { ++ if ((err & 0xFFFFFFFF) != 0xFFFFFFF5) /* -11: wrong state */ ++ panic("Failed to downcount IRQ! Error = %16lx", err); ++ ++ printk(KERN_ERR "IRQ over-downcounted, plug %d\n", irq_plug); ++ } ++} ++ + static void beatic_unmask_irq(unsigned int irq_plug) + { + unsigned long flags; + ++#ifdef CONFIG_PREEMPT_HARDIRQS ++ if (hardirq_preemption) ++ __beatic_eoi_irq(irq_plug); ++#endif /* CONFIG_PREEMPT_HARDIRQS */ ++ + spin_lock_irqsave(&beatic_irq_mask_lock, flags); + beatic_irq_mask_enable[irq_plug/64] |= 1UL << (63 - (irq_plug%64)); ++ ++#ifdef CONFIG_PREEMPT_HARDIRQS ++ if (hardirq_preemption) ++ beatic_irq_mask_ack[irq_plug/64] |= 1UL << (63 - (irq_plug%64)); ++#endif /* CONFIG_PREEMPT_HARDIRQS */ ++ + beatic_update_irq_mask(irq_plug); + spin_unlock_irqrestore(&beatic_irq_mask_lock, flags); + } +@@ -93,15 +120,15 @@ static void beatic_ack_irq(unsigned int + + static void beatic_end_irq(unsigned int irq_plug) + { +- s64 err; + unsigned long flags; + +- if ((err = beat_downcount_of_interrupt(irq_plug)) != 0) { +- if ((err & 0xFFFFFFFF) != 0xFFFFFFF5) /* -11: wrong state */ +- panic("Failed to downcount IRQ! Error = %16lx", err); ++#ifdef CONFIG_PREEMPT_HARDIRQS ++ if (hardirq_preemption) ++ return; ++#endif /* CONFIG_PREEMPT_HARDIRQS */ ++ ++ __beatic_eoi_irq(irq_plug); + +- printk(KERN_ERR "IRQ over-downcounted, plug %d\n", irq_plug); +- } + spin_lock_irqsave(&beatic_irq_mask_lock, flags); + beatic_irq_mask_ack[irq_plug/64] |= 1UL << (63 - (irq_plug%64)); + beatic_update_irq_mask(irq_plug); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0254-preempt-realtime-irqs.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0254-preempt-realtime-irqs.patch @@ -0,0 +1,157 @@ +--- + include/linux/irq.h | 10 ++++------ + kernel/irq/handle.c | 10 +++++++++- + kernel/irq/manage.c | 22 ++++++++++++++++------ + kernel/irq/spurious.c | 3 +-- + 4 files changed, 30 insertions(+), 15 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/irq.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/irq.h 2008-10-08 22:23:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/irq.h 2008-10-08 22:24:03.000000000 -0400 +@@ -146,7 +146,6 @@ struct irq_chip { + * @last_unhandled: aging timer for unhandled count + * @thread: Thread pointer for threaded preemptible irq handling + * @wait_for_handler: Waitqueue to wait for a running preemptible handler +- * @cycles: Timestamp for stats and debugging + * @lock: locking for SMP + * @affinity: IRQ affinity on SMP + * @cpu: cpu index useful for balancing +@@ -169,10 +168,10 @@ struct irq_desc { + unsigned int irq_count; /* For detecting broken IRQs */ + unsigned int irqs_unhandled; + unsigned long last_unhandled; /* Aging timer for unhandled count */ +- struct task_struct *thread; +- wait_queue_head_t wait_for_handler; +- cycles_t timestamp; +- spinlock_t lock; ++ struct task_struct *thread; ++ wait_queue_head_t wait_for_handler; ++ cycles_t timestamp; ++ raw_spinlock_t lock; + #ifdef CONFIG_SMP + cpumask_t affinity; + unsigned int cpu; +@@ -408,7 +407,6 @@ extern int set_irq_msi(unsigned int irq, + + /* Early initialization of irqs */ + extern void early_init_hardirqs(void); +-extern cycles_t irq_timestamp(unsigned int irq); + + #if defined(CONFIG_PREEMPT_HARDIRQS) + extern void init_hardirqs(void); +Index: linux-2.6.24.7-rt21/kernel/irq/handle.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/irq/handle.c 2008-10-08 22:23:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/irq/handle.c 2008-10-08 22:24:03.000000000 -0400 +@@ -54,12 +54,13 @@ struct irq_desc irq_desc[NR_IRQS] __cach + .chip = &no_irq_chip, + .handle_irq = handle_bad_irq, + .depth = 1, +- .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock), ++ .lock = RAW_SPIN_LOCK_UNLOCKED(irq_desc), + #ifdef CONFIG_SMP + .affinity = CPU_MASK_ALL + #endif + } + }; ++EXPORT_SYMBOL_GPL(irq_desc); + + /* + * What should we do if we get a hw irq event on an illegal vector? +@@ -248,6 +249,13 @@ fastcall unsigned int __do_IRQ(unsigned + desc->chip->end(irq); + return 1; + } ++ /* ++ * If the task is currently running in user mode, don't ++ * detect soft lockups. If CONFIG_DETECT_SOFTLOCKUP is not ++ * configured, this should be optimized out. ++ */ ++ if (user_mode(get_irq_regs())) ++ touch_softlockup_watchdog(); + + spin_lock(&desc->lock); + if (desc->chip->ack) +Index: linux-2.6.24.7-rt21/kernel/irq/manage.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/irq/manage.c 2008-10-08 22:23:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/irq/manage.c 2008-10-08 22:24:03.000000000 -0400 +@@ -500,9 +500,9 @@ void free_irq(unsigned int irq, void *de + * parallel with our fake + */ + if (action->flags & IRQF_SHARED) { +- local_irq_save(flags); ++ local_irq_save_nort(flags); + action->handler(irq, dev_id); +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + } + #endif + kfree(action); +@@ -594,9 +594,9 @@ int request_irq(unsigned int irq, irq_ha + */ + unsigned long flags; + +- local_irq_save(flags); ++ local_irq_save_nort(flags); + handler(irq, dev_id); +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + } + #endif + +@@ -614,6 +614,11 @@ int hardirq_preemption = 1; + + EXPORT_SYMBOL(hardirq_preemption); + ++/* ++ * Real-Time Preemption depends on hardirq threading: ++ */ ++#ifndef CONFIG_PREEMPT_RT ++ + static int __init hardirq_preempt_setup (char *str) + { + if (!strncmp(str, "off", 3)) +@@ -628,6 +633,7 @@ static int __init hardirq_preempt_setup + + __setup("hardirq-preempt=", hardirq_preempt_setup); + ++#endif + + /* + * threaded simple handler +@@ -787,12 +793,16 @@ static int do_irqd(void * __desc) + sys_sched_setscheduler(current->pid, SCHED_FIFO, ¶m); + + while (!kthread_should_stop()) { +- local_irq_disable(); ++ local_irq_disable_nort(); + set_current_state(TASK_INTERRUPTIBLE); ++#ifndef CONFIG_PREEMPT_RT + irq_enter(); ++#endif + do_hardirq(desc); ++#ifndef CONFIG_PREEMPT_RT + irq_exit(); +- local_irq_enable(); ++#endif ++ local_irq_enable_nort(); + cond_resched(); + #ifdef CONFIG_SMP + /* +Index: linux-2.6.24.7-rt21/kernel/irq/spurious.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/irq/spurious.c 2008-10-08 22:23:46.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/irq/spurious.c 2008-10-08 22:24:03.000000000 -0400 +@@ -59,9 +59,8 @@ static int misrouted_irq(int irq) + } + action = action->next; + } +- local_irq_disable(); + /* Now clean up the flags */ +- spin_lock(&desc->lock); ++ spin_lock_irq(&desc->lock); + action = desc->action; + + /* --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0240-schedule-tail-balance-disable-irqs.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0240-schedule-tail-balance-disable-irqs.patch @@ -0,0 +1,21 @@ +--- + kernel/sched_rt.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/sched_rt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched_rt.c 2008-10-08 22:23:58.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched_rt.c 2008-10-08 22:23:59.000000000 -0400 +@@ -684,10 +684,10 @@ static void post_schedule_rt(struct rq * + * first via finish_lock_switch and then reaquire it here. + */ + if (unlikely(rq->rt.overloaded)) { +- spin_lock_irq(&rq->lock); ++ spin_lock(&rq->lock); + push_rt_tasks(rq); + schedstat_inc(rq, rto_schedule_tail); +- spin_unlock_irq(&rq->lock); ++ spin_unlock(&rq->lock); + } + } + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0234-preempt-realtime-ftrace.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0234-preempt-realtime-ftrace.patch @@ -0,0 +1,118 @@ +--- + kernel/trace/ftrace.c | 4 ++-- + kernel/trace/trace.c | 10 +++++----- + kernel/trace/trace.h | 2 +- + kernel/trace/trace_hist.c | 2 +- + kernel/trace/trace_irqsoff.c | 2 +- + kernel/trace/trace_sched_wakeup.c | 2 +- + 6 files changed, 11 insertions(+), 11 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/trace/ftrace.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/ftrace.c 2008-10-08 22:23:07.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/ftrace.c 2008-10-08 22:23:57.000000000 -0400 +@@ -39,7 +39,7 @@ static int last_ftrace_enabled; + */ + static int ftrace_disabled __read_mostly; + +-static DEFINE_SPINLOCK(ftrace_lock); ++static DEFINE_RAW_SPINLOCK(ftrace_lock); + static DEFINE_MUTEX(ftrace_sysctl_lock); + + static struct ftrace_ops ftrace_list_end __read_mostly = +@@ -166,7 +166,7 @@ static struct hlist_head ftrace_hash[FTR + + static DEFINE_PER_CPU(int, ftrace_shutdown_disable_cpu); + +-static DEFINE_SPINLOCK(ftrace_shutdown_lock); ++static DEFINE_RAW_SPINLOCK(ftrace_shutdown_lock); + static DEFINE_MUTEX(ftraced_lock); + static DEFINE_MUTEX(ftrace_regex_lock); + +Index: linux-2.6.24.7-rt21/kernel/trace/trace.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/trace.c 2008-10-08 22:23:11.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/trace.c 2008-10-08 22:23:57.000000000 -0400 +@@ -223,8 +223,8 @@ static const char *trace_options[] = { + * This is defined as a raw_spinlock_t in order to help + * with performance when lockdep debugging is enabled. + */ +-static raw_spinlock_t ftrace_max_lock = +- (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; ++static __raw_spinlock_t ftrace_max_lock = ++ (__raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; + + /* + * Copy the new maximum trace into the separate maximum-trace +@@ -654,7 +654,7 @@ static unsigned map_pid_to_cmdline[PID_M + static unsigned map_cmdline_to_pid[SAVED_CMDLINES]; + static char saved_cmdlines[SAVED_CMDLINES][TASK_COMM_LEN]; + static int cmdline_idx; +-static DEFINE_SPINLOCK(trace_cmdline_lock); ++static DEFINE_RAW_SPINLOCK(trace_cmdline_lock); + + /* temporary disable recording */ + atomic_t trace_record_cmdline_disabled __read_mostly; +@@ -3355,8 +3355,8 @@ __init static int tracer_alloc_buffers(v + /* use the LRU flag to differentiate the two buffers */ + ClearPageLRU(page); + +- data->lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; +- max_tr.data[i]->lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; ++ data->lock = (__raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; ++ max_tr.data[i]->lock = (__raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; + + /* Only allocate if we are actually using the max trace */ + #ifdef CONFIG_TRACER_MAX_TRACE +Index: linux-2.6.24.7-rt21/kernel/trace/trace.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/trace.h 2008-10-08 22:23:09.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/trace.h 2008-10-08 22:23:57.000000000 -0400 +@@ -162,7 +162,7 @@ struct trace_entry { + struct trace_array_cpu { + struct list_head trace_pages; + atomic_t disabled; +- raw_spinlock_t lock; ++ __raw_spinlock_t lock; + struct lock_class_key lock_key; + + /* these fields get copied into max-trace: */ +Index: linux-2.6.24.7-rt21/kernel/trace/trace_hist.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/trace_hist.c 2008-10-08 22:23:08.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/trace_hist.c 2008-10-08 22:23:57.000000000 -0400 +@@ -412,7 +412,7 @@ int tracing_wakeup_hist __read_mostly = + static unsigned wakeup_prio = (unsigned)-1 ; + static struct task_struct *wakeup_task; + static cycle_t wakeup_start; +-static DEFINE_SPINLOCK(wakeup_lock); ++static DEFINE_RAW_SPINLOCK(wakeup_lock); + + notrace void tracing_hist_wakeup_start(struct task_struct *p, + struct task_struct *curr) +Index: linux-2.6.24.7-rt21/kernel/trace/trace_irqsoff.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/trace_irqsoff.c 2008-10-08 22:23:08.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/trace_irqsoff.c 2008-10-08 22:23:57.000000000 -0400 +@@ -24,7 +24,7 @@ static int tracer_enabled __read_most + + static DEFINE_PER_CPU(int, tracing_cpu); + +-static DEFINE_SPINLOCK(max_trace_lock); ++static DEFINE_RAW_SPINLOCK(max_trace_lock); + + enum { + TRACER_IRQS_OFF = (1 << 1), +Index: linux-2.6.24.7-rt21/kernel/trace/trace_sched_wakeup.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/trace_sched_wakeup.c 2008-10-08 22:23:06.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/trace_sched_wakeup.c 2008-10-08 22:23:57.000000000 -0400 +@@ -26,7 +26,7 @@ static struct task_struct *wakeup_task; + static int wakeup_cpu; + static unsigned wakeup_prio = -1; + +-static DEFINE_SPINLOCK(wakeup_lock); ++static DEFINE_RAW_SPINLOCK(wakeup_lock); + + static void __wakeup_reset(struct trace_array *tr); + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0065-tracer-add-event-markers.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0065-tracer-add-event-markers.patch @@ -0,0 +1,306 @@ +Add markers to various events + +This patch adds markers to various events in the kernel. +(interrupts, task activation and hrtimers) + +Signed-off-by: Steven Rostedt +--- + arch/x86/kernel/apic_32.c | 3 ++ + arch/x86/kernel/irq_32.c | 3 ++ + arch/x86/kernel/irq_64.c | 4 +++ + arch/x86/kernel/traps_32.c | 4 +++ + arch/x86/kernel/traps_64.c | 4 +++ + arch/x86/mm/fault_32.c | 4 +++ + arch/x86/mm/fault_64.c | 4 +++ + include/linux/ftrace.h | 49 +++++++++++++++++++++++++++++++++++++++++++++ + kernel/hrtimer.c | 6 +++++ + kernel/sched.c | 7 ++++++ + 10 files changed, 88 insertions(+) + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/apic_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/apic_32.c 2008-10-08 22:22:44.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/apic_32.c 2008-10-08 22:23:08.000000000 -0400 +@@ -45,6 +45,8 @@ + + #include "io_ports.h" + ++#include ++ + /* + * Sanity check + */ +@@ -581,6 +583,7 @@ void fastcall smp_apic_timer_interrupt(s + { + struct pt_regs *old_regs = set_irq_regs(regs); + ++ ftrace_event_irq(-1, user_mode(regs), regs->eip); + /* + * NOTE! We'd better ACK the irq immediately, + * because timer handling can be slow. +Index: linux-2.6.24.7-rt21/arch/x86/kernel/irq_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/irq_32.c 2008-10-08 22:22:44.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/irq_32.c 2008-10-08 22:23:08.000000000 -0400 +@@ -16,6 +16,8 @@ + #include + #include + ++#include ++ + #include + #include + +@@ -85,6 +87,7 @@ fastcall unsigned int do_IRQ(struct pt_r + + old_regs = set_irq_regs(regs); + irq_enter(); ++ ftrace_event_irq(irq, user_mode(regs), regs->eip); + #ifdef CONFIG_DEBUG_STACKOVERFLOW + /* Debugging check for stack overflow: is there less than 1KB free? */ + { +Index: linux-2.6.24.7-rt21/arch/x86/kernel/irq_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/irq_64.c 2008-10-08 22:22:44.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/irq_64.c 2008-10-08 22:23:08.000000000 -0400 +@@ -18,6 +18,8 @@ + #include + #include + ++#include ++ + atomic_t irq_err_count; + + #ifdef CONFIG_DEBUG_STACKOVERFLOW +@@ -149,6 +151,8 @@ asmlinkage unsigned int do_IRQ(struct pt + irq_enter(); + irq = __get_cpu_var(vector_irq)[vector]; + ++ ftrace_event_irq(irq, user_mode(regs), regs->rip); ++ + #ifdef CONFIG_DEBUG_STACKOVERFLOW + stack_overflow_check(regs); + #endif +Index: linux-2.6.24.7-rt21/arch/x86/kernel/traps_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/traps_32.c 2008-10-08 22:22:44.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/traps_32.c 2008-10-08 22:23:08.000000000 -0400 +@@ -30,6 +30,8 @@ + #include + #include + ++#include ++ + #ifdef CONFIG_EISA + #include + #include +@@ -769,6 +771,8 @@ fastcall __kprobes void do_nmi(struct pt + + nmi_enter(); + ++ ftrace_event_irq(-1, user_mode(regs), regs->eip); ++ + cpu = smp_processor_id(); + + ++nmi_count(cpu); +Index: linux-2.6.24.7-rt21/arch/x86/kernel/traps_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/traps_64.c 2008-10-08 22:22:44.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/traps_64.c 2008-10-08 22:23:08.000000000 -0400 +@@ -33,6 +33,8 @@ + #include + #include + ++#include ++ + #if defined(CONFIG_EDAC) + #include + #endif +@@ -782,6 +784,8 @@ asmlinkage __kprobes void default_do_nmi + + cpu = smp_processor_id(); + ++ ftrace_event_irq(-1, user_mode(regs), regs->rip); ++ + /* Only the BSP gets external NMIs from the system. */ + if (!cpu) + reason = get_nmi_reason(); +Index: linux-2.6.24.7-rt21/arch/x86/mm/fault_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/mm/fault_32.c 2008-10-08 22:22:44.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/mm/fault_32.c 2008-10-08 22:23:08.000000000 -0400 +@@ -27,6 +27,8 @@ + #include + #include + ++#include ++ + #include + #include + #include +@@ -311,6 +313,8 @@ fastcall void __kprobes do_page_fault(st + /* get the address */ + address = read_cr2(); + ++ ftrace_event_fault(regs->eip, error_code, address); ++ + tsk = current; + + si_code = SEGV_MAPERR; +Index: linux-2.6.24.7-rt21/arch/x86/mm/fault_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/mm/fault_64.c 2008-10-08 22:22:44.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/mm/fault_64.c 2008-10-08 22:23:08.000000000 -0400 +@@ -27,6 +27,8 @@ + #include + #include + ++#include ++ + #include + #include + #include +@@ -316,6 +318,8 @@ asmlinkage void __kprobes do_page_fault( + /* get the address */ + address = read_cr2(); + ++ ftrace_event_fault(regs->rip, error_code, address); ++ + info.si_code = SEGV_MAPERR; + + +Index: linux-2.6.24.7-rt21/include/linux/ftrace.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/ftrace.h 2008-10-08 22:23:07.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/ftrace.h 2008-10-08 22:23:08.000000000 -0400 +@@ -4,6 +4,7 @@ + #ifdef CONFIG_FTRACE + + #include ++#include + #include + + extern int ftrace_enabled; +@@ -136,4 +137,52 @@ static inline void + ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { } + #endif + ++#ifdef CONFIG_EVENT_TRACER ++#include ++ ++static inline void ftrace_event_irq(int irq, int user, unsigned long ip) ++{ ++ trace_mark(ftrace_event_irq, "%d %d %ld", irq, user, ip); ++} ++ ++static inline void ftrace_event_fault(unsigned long ip, unsigned long error, ++ unsigned long addr) ++{ ++ trace_mark(ftrace_event_fault, "%ld %ld %ld", ip, error, addr); ++} ++ ++static inline void ftrace_event_timer_set(void *p1, void *p2) ++{ ++ trace_mark(ftrace_event_timer_set, "%p %p", p1, p2); ++} ++ ++static inline void ftrace_event_timer_triggered(void *p1, void *p2) ++{ ++ trace_mark(ftrace_event_timer_triggered, "%p %p", p1, p2); ++} ++ ++static inline void ftrace_event_timestamp(ktime_t *time) ++{ ++ trace_mark(ftrace_event_hrtimer, "%p", time); ++} ++ ++static inline void ftrace_event_task_activate(struct task_struct *p, int cpu) ++{ ++ trace_mark(ftrace_event_task_activate, "%p %d", p, cpu); ++} ++ ++static inline void ftrace_event_task_deactivate(struct task_struct *p, int cpu) ++{ ++ trace_mark(ftrace_event_task_deactivate, "%p %d", p, cpu); ++} ++#else ++# define ftrace_event_irq(irq, user, ip) do { } while (0) ++# define ftrace_event_fault(ip, error, addr) do { } while (0) ++# define ftrace_event_timer_set(p1, p2) do { } while (0) ++# define ftrace_event_timer_triggered(p1, p2) do { } while (0) ++# define ftrace_event_timestamp(now) do { } while (0) ++# define ftrace_event_task_activate(p, cpu) do { } while (0) ++# define ftrace_event_task_deactivate(p, cpu) do { } while (0) ++#endif /* CONFIG_TRACE_EVENTS */ ++ + #endif /* _LINUX_FTRACE_H */ +Index: linux-2.6.24.7-rt21/kernel/hrtimer.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/hrtimer.c 2008-10-08 22:22:51.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/hrtimer.c 2008-10-08 22:23:08.000000000 -0400 +@@ -44,6 +44,8 @@ + #include + #include + ++#include ++ + #include + + /** +@@ -742,6 +744,7 @@ static void enqueue_hrtimer(struct hrtim + struct hrtimer *entry; + int leftmost = 1; + ++ ftrace_event_timer_set(&timer->expires, timer); + /* + * Find the right place in the rbtree: + */ +@@ -1094,6 +1097,7 @@ void hrtimer_interrupt(struct clock_even + + retry: + now = ktime_get(); ++ ftrace_event_timestamp(&now); + + expires_next.tv64 = KTIME_MAX; + +@@ -1122,6 +1126,8 @@ void hrtimer_interrupt(struct clock_even + break; + } + ++ ftrace_event_timer_triggered(&timer->expires, timer); ++ + /* Move softirq callbacks to the pending list */ + if (timer->cb_mode == HRTIMER_CB_SOFTIRQ) { + __remove_hrtimer(timer, base, +Index: linux-2.6.24.7-rt21/kernel/sched.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched.c 2008-10-08 22:23:06.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched.c 2008-10-08 22:23:08.000000000 -0400 +@@ -91,6 +91,11 @@ unsigned long long __attribute__((weak)) + #define PRIO_TO_NICE(prio) ((prio) - MAX_RT_PRIO - 20) + #define TASK_NICE(p) PRIO_TO_NICE((p)->static_prio) + ++#define __PRIO(prio) \ ++ ((prio) <= 99 ? 199 - (prio) : (prio) - 120) ++ ++#define PRIO(p) __PRIO((p)->prio) ++ + /* + * 'User priority' is the nice value converted to something we + * can work with better when scaling various scheduler parameters, +@@ -1119,6 +1124,7 @@ static void activate_task(struct rq *rq, + if (p->state == TASK_UNINTERRUPTIBLE) + rq->nr_uninterruptible--; + ++ ftrace_event_task_activate(p, cpu_of(rq)); + enqueue_task(rq, p, wakeup); + inc_nr_running(p, rq); + } +@@ -1131,6 +1137,7 @@ static void deactivate_task(struct rq *r + if (p->state == TASK_UNINTERRUPTIBLE) + rq->nr_uninterruptible++; + ++ ftrace_event_task_deactivate(p, cpu_of(rq)); + dequeue_task(rq, p, sleep); + dec_nr_running(p, rq); + } --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0454-rwlocks-default-nr-readers-nr-cpus.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0454-rwlocks-default-nr-readers-nr-cpus.patch @@ -0,0 +1,23 @@ +From: Steven Rostedt + +Limit the number of readers to number of CPUS by default. + +Signed-off-by: Steven Rostedt + +--- + kernel/rtmutex.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/kernel/rtmutex.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rtmutex.c 2008-10-08 22:24:52.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rtmutex.c 2008-10-08 22:24:52.000000000 -0400 +@@ -1015,7 +1015,7 @@ __rt_spin_lock_init(spinlock_t *lock, ch + } + EXPORT_SYMBOL(__rt_spin_lock_init); + +-int rt_rwlock_limit; ++int rt_rwlock_limit = NR_CPUS; + + static inline int rt_release_bkl(struct rt_mutex *lock, unsigned long flags); + static inline void rt_reacquire_bkl(int saved_lock_depth); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0484-ftrace-fix-header.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0484-ftrace-fix-header.patch @@ -0,0 +1,63 @@ +From clark.williams@gmail.com Sat May 24 20:47:58 2008 +Date: Sat, 24 May 2008 14:49:40 -0500 +From: Clark Williams +To: Steven Rostedt +Cc: Steven Rostedt , LKML , + RT +Subject: [PATCH -rt] fix for compiling 2.6.24.7-rt10 without CONFIG_FTRACE + + [ The following text is in the "UTF-8" character set. ] + [ Your display is set for the "iso-8859-1" character set. ] + [ Some characters may be displayed incorrectly. ] + +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +Steven, + +If you build a debugging kernel and don't have CONFIG_FTRACE turned on, -rt10 dies +when compiling arch/x86/kernel/x8664_ksyms_64.c, because ktime_t isn't defined in the +prototypes at the bottom of include/linux/ftrace.h. Patch to fix attached. + +Clark + + +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.9 (GNU/Linux) +Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org + +iEYEARECAAYFAkg4cVQACgkQqA4JVb61b9d0gQCffgzXgm2qaftlj5Q3fjjtyolD +J2MAnAoy4j9s2AUhZjwagT6OXzJ3Plgq +=9Ypr +-----END PGP SIGNATURE----- + + [ Part 2: "Attached Text" ] + +fix to handle compiling debugging without CONFIG_FTRACE + +From: Clark Williams + +Signed-off-by: Clark Williams +--- + + include/linux/ftrace.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + + +Index: linux-2.6.24.7-rt21/include/linux/ftrace.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/ftrace.h 2008-10-08 22:23:08.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/ftrace.h 2008-10-08 22:25:00.000000000 -0400 +@@ -1,10 +1,11 @@ + #ifndef _LINUX_FTRACE_H + #define _LINUX_FTRACE_H + ++#include ++ + #ifdef CONFIG_FTRACE + + #include +-#include + #include + + extern int ftrace_enabled; --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0513-cpu-hotplug-cpu-up-vs-preempt-rt.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0513-cpu-hotplug-cpu-up-vs-preempt-rt.patch @@ -0,0 +1,189 @@ +Subject: cpu-hotplug: cpu_up vs preempt-rt +From: Peter Zijlstra +Date: Tue, 10 Jun 2008 13:13:02 +0200 + +On PREEMPT_RT the allocators use preemptible locks, cpu bootstrap must have IRQs +disabled because there are no IRQ/exception stacks yet, these we allocate +atomically, which is not possible on -rt. + +Solve this by allocating these stacks on the boot cpu (which already has its +stacks). + +This also allows cpu-up to fail instead of panic on OOM scenarios. + +I suspect it also fixes a memory leak, as I cannot find the place where +cpu_down frees these cpu stacks, but each cpu_up used to allocate new ones. + +Signed-off-by: Peter Zijlstra +Cc: Steven Rostedt +Cc: Clark Williams +Cc: Gregory Haskins +Cc: "Paul E. McKenney" +Cc: Gautham R Shenoy +Cc: Pekka Enberg +Cc: Arnaldo Carvalho de Melo +Cc: Peter Zijlstra +Signed-off-by: Thomas Gleixner +--- + arch/x86/kernel/setup64.c | 31 ++-------------------- + arch/x86/kernel/smpboot_64.c | 57 +++++++++++++++++++++++++++++++++++++++++ + include/asm-x86/processor_64.h | 4 ++ + 3 files changed, 65 insertions(+), 27 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/setup64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/setup64.c 2008-10-08 22:24:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/setup64.c 2008-10-08 22:25:07.000000000 -0400 +@@ -137,19 +137,12 @@ void pda_init(int cpu) + pda->pcurrent = &init_task; + pda->irqstackptr = boot_cpu_stack; + } else { +- pda->irqstackptr = (char *) +- __get_free_pages(GFP_ATOMIC, IRQSTACK_ORDER); +- if (!pda->irqstackptr) +- panic("cannot allocate irqstack for cpu %d", cpu); ++ pda->irqstackptr = (char *)per_cpu(init_tss, cpu).irqstack; + } + +- + pda->irqstackptr += IRQSTACKSIZE-64; + } + +-char boot_exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ] +-__attribute__((section(".bss.page_aligned"))); +- + extern asmlinkage void ignore_sysret(void); + + /* May not be marked __init: used by software suspend */ +@@ -203,15 +196,13 @@ void __cpuinit cpu_init (void) + struct tss_struct *t = &per_cpu(init_tss, cpu); + struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu); + unsigned long v; +- char *estacks = NULL; + struct task_struct *me; + int i; + + /* CPU 0 is initialised in head64.c */ + if (cpu != 0) { + pda_init(cpu); +- } else +- estacks = boot_exception_stacks; ++ } + + me = current; + +@@ -245,22 +236,8 @@ void __cpuinit cpu_init (void) + /* + * set up and load the per-CPU TSS + */ +- for (v = 0; v < N_EXCEPTION_STACKS; v++) { +- static const unsigned int order[N_EXCEPTION_STACKS] = { +- [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STACK_ORDER, +-#if DEBUG_STACK > 0 +- [DEBUG_STACK - 1] = DEBUG_STACK_ORDER +-#endif +- }; +- if (cpu) { +- estacks = (char *)__get_free_pages(GFP_ATOMIC, order[v]); +- if (!estacks) +- panic("Cannot allocate exception stack %ld %d\n", +- v, cpu); +- } +- estacks += PAGE_SIZE << order[v]; +- orig_ist->ist[v] = t->ist[v] = (unsigned long)estacks; +- } ++ for (v = 0; v < N_EXCEPTION_STACKS; v++) ++ orig_ist->ist[v] = t->ist[v] = (unsigned long)t->estacks[v]; + + t->io_bitmap_base = offsetof(struct tss_struct, io_bitmap); + /* +Index: linux-2.6.24.7-rt21/arch/x86/kernel/smpboot_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/smpboot_64.c 2008-10-08 22:24:09.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/smpboot_64.c 2008-10-08 22:25:07.000000000 -0400 +@@ -535,6 +535,60 @@ static void __cpuinit do_fork_idle(struc + complete(&c_idle->done); + } + ++static char boot_exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ] ++__attribute__((section(".bss.page_aligned"))); ++ ++static int __cpuinit allocate_stacks(int cpu) ++{ ++ static const unsigned int order[N_EXCEPTION_STACKS] = { ++ [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STACK_ORDER, ++#if DEBUG_STACK > 0 ++ [DEBUG_STACK - 1] = DEBUG_STACK_ORDER ++#endif ++ }; ++ struct tss_struct *t = &per_cpu(init_tss, cpu); ++ int node = cpu_to_node(cpu); ++ struct page *page; ++ char *estack; ++ int v; ++ ++ if (cpu && !t->irqstack) { ++ page = alloc_pages_node(node, GFP_KERNEL, ++ IRQSTACK_ORDER); ++ if (!page) ++ goto fail_oom; ++ t->irqstack = page_address(page); ++ } ++ ++ if (!cpu) ++ estack = boot_exception_stacks; ++ ++ for (v = 0; v < N_EXCEPTION_STACKS; v++) { ++ if (t->estacks[v]) ++ continue; ++ ++ if (cpu) { ++ page = alloc_pages_node(node, GFP_KERNEL, order[v]); ++ if (!page) ++ goto fail_oom; ++ estack = page_address(page); ++ } ++ estack += PAGE_SIZE << order[v]; ++ /* ++ * XXX: can we set t->isr[v] here directly, or will that be ++ * modified later? - the existance of orig_ist seems to suggest ++ * it _can_ be modified, which would imply we'd need to reset ++ * it. ++ */ ++ t->estacks[v] = estack; ++ } ++ ++ return 0; ++ ++fail_oom: ++ return -ENOMEM; ++} ++ + /* + * Boot one CPU. + */ +@@ -605,6 +659,9 @@ static int __cpuinit do_boot_cpu(int cpu + return PTR_ERR(c_idle.idle); + } + ++ if (allocate_stacks(cpu)) ++ return -ENOMEM; ++ + set_idle_for_cpu(cpu, c_idle.idle); + + do_rest: +Index: linux-2.6.24.7-rt21/include/asm-x86/processor_64.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/processor_64.h 2008-10-08 22:22:10.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/processor_64.h 2008-10-08 22:25:07.000000000 -0400 +@@ -197,6 +197,10 @@ struct tss_struct { + * 8 bytes, for an extra "long" of ~0UL + */ + unsigned long io_bitmap[IO_BITMAP_LONGS + 1]; ++ ++ void *irqstack; ++ void *estacks[N_EXCEPTION_STACKS]; ++ + } __attribute__((packed)) ____cacheline_aligned; + + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0319-softirq-per-cpu-assumptions-fixes.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0319-softirq-per-cpu-assumptions-fixes.patch @@ -0,0 +1,180 @@ +--- + kernel/hrtimer.c | 38 +++++++++++++++++++++----------------- + kernel/sched.c | 2 +- + kernel/softirq.c | 5 +++-- + kernel/timer.c | 2 +- + 4 files changed, 26 insertions(+), 21 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/hrtimer.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/hrtimer.c 2008-10-08 22:24:08.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/hrtimer.c 2008-10-08 22:24:20.000000000 -0400 +@@ -380,9 +380,9 @@ static inline int hrtimer_is_hres_enable + /* + * Is the high resolution mode active ? + */ +-static inline int hrtimer_hres_active(void) ++static inline int hrtimer_hres_active(struct hrtimer_cpu_base *cpu_base) + { +- return __get_cpu_var(hrtimer_bases).hres_active; ++ return cpu_base->hres_active; + } + + /* +@@ -470,11 +470,12 @@ static int hrtimer_reprogram(struct hrti + */ + static void retrigger_next_event(void *arg) + { +- struct hrtimer_cpu_base *base; ++ struct hrtimer_cpu_base *base = &__get_cpu_var(hrtimer_bases); ++ + struct timespec realtime_offset; + unsigned long seq; + +- if (!hrtimer_hres_active()) ++ if (!hrtimer_hres_active(base)) + return; + + do { +@@ -484,8 +485,6 @@ static void retrigger_next_event(void *a + -wall_to_monotonic.tv_nsec); + } while (read_seqretry(&xtime_lock, seq)); + +- base = &__get_cpu_var(hrtimer_bases); +- + /* Adjust CLOCK_REALTIME offset */ + spin_lock(&base->lock); + base->clock_base[CLOCK_REALTIME].offset = +@@ -606,10 +605,8 @@ static inline int hrtimer_enqueue_reprog + /* + * Switch to high resolution mode + */ +-static int hrtimer_switch_to_hres(void) ++static int hrtimer_switch_to_hres(struct hrtimer_cpu_base *base) + { +- int cpu = smp_processor_id(); +- struct hrtimer_cpu_base *base = &per_cpu(hrtimer_bases, cpu); + unsigned long flags; + + if (base->hres_active) +@@ -620,7 +617,7 @@ static int hrtimer_switch_to_hres(void) + if (tick_init_highres()) { + local_irq_restore(flags); + printk(KERN_WARNING "Could not switch to high resolution " +- "mode on CPU %d\n", cpu); ++ "mode on CPU %d\n", raw_smp_processor_id()); + return 0; + } + base->hres_active = 1; +@@ -642,9 +639,15 @@ static inline void hrtimer_raise_softirq + + #else + +-static inline int hrtimer_hres_active(void) { return 0; } ++static inline int hrtimer_hres_active(struct hrtimer_cpu_base *base) ++{ ++ return 0; ++} + static inline int hrtimer_is_hres_enabled(void) { return 0; } +-static inline int hrtimer_switch_to_hres(void) { return 0; } ++static inline int hrtimer_switch_to_hres(struct hrtimer_cpu_base *base) ++{ ++ return 0; ++} + static inline void hrtimer_force_reprogram(struct hrtimer_cpu_base *base) { } + static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer, + struct hrtimer_clock_base *base) +@@ -836,7 +839,7 @@ static void __remove_hrtimer(struct hrti + if (base->first == &timer->node) { + base->first = rb_next(&timer->node); + /* Reprogram the clock event device. if enabled */ +- if (reprogram && hrtimer_hres_active()) ++ if (reprogram && hrtimer_hres_active(base->cpu_base)) + hrtimer_force_reprogram(base->cpu_base); + } + rb_erase(&timer->node, &base->active); +@@ -1027,7 +1030,7 @@ ktime_t hrtimer_get_next_event(void) + + spin_lock_irqsave(&cpu_base->lock, flags); + +- if (!hrtimer_hres_active()) { ++ if (!hrtimer_hres_active(cpu_base)) { + for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++, base++) { + struct hrtimer *timer; + +@@ -1335,10 +1338,11 @@ static inline void run_hrtimer_queue(str + */ + void hrtimer_run_queues(void) + { +- struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases); ++ struct hrtimer_cpu_base *cpu_base; + int i; + +- if (hrtimer_hres_active()) ++ cpu_base = &per_cpu(hrtimer_bases, raw_smp_processor_id()); ++ if (hrtimer_hres_active(cpu_base)) + return; + + /* +@@ -1350,7 +1354,7 @@ void hrtimer_run_queues(void) + * deadlock vs. xtime_lock. + */ + if (tick_check_oneshot_change(!hrtimer_is_hres_enabled())) +- if (hrtimer_switch_to_hres()) ++ if (hrtimer_switch_to_hres(cpu_base)) + return; + + hrtimer_get_softirq_time(cpu_base); +Index: linux-2.6.24.7-rt21/kernel/sched.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched.c 2008-10-08 22:23:58.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched.c 2008-10-08 22:24:20.000000000 -0400 +@@ -3392,7 +3392,7 @@ out: + */ + static void run_rebalance_domains(struct softirq_action *h) + { +- int this_cpu = smp_processor_id(); ++ int this_cpu = raw_smp_processor_id(); + struct rq *this_rq = cpu_rq(this_cpu); + enum cpu_idle_type idle = this_rq->idle_at_tick ? + CPU_IDLE : CPU_NOT_IDLE; +Index: linux-2.6.24.7-rt21/kernel/softirq.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/softirq.c 2008-10-08 22:24:20.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/softirq.c 2008-10-08 22:24:20.000000000 -0400 +@@ -411,12 +411,12 @@ void do_softirq_from_hardirq(void) + { + unsigned long p_flags; + +- if (!local_softirq_pending()) +- return; + /* + * 'immediate' softirq execution, from hardirq context: + */ + local_irq_disable(); ++ if (!local_softirq_pending()) ++ goto out; + __local_bh_disable((unsigned long)__builtin_return_address(0)); + #ifndef CONFIG_PREEMPT_SOFTIRQS + trace_softirq_enter(); +@@ -436,6 +436,7 @@ void do_softirq_from_hardirq(void) + current->flags &= ~PF_SOFTIRQ; + + _local_bh_enable(); ++out: + local_irq_enable(); + } + +Index: linux-2.6.24.7-rt21/kernel/timer.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/timer.c 2008-10-08 22:24:09.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/timer.c 2008-10-08 22:24:20.000000000 -0400 +@@ -1035,7 +1035,7 @@ static inline void update_times(void) + */ + static void run_timer_softirq(struct softirq_action *h) + { +- tvec_base_t *base = __get_cpu_var(tvec_bases); ++ tvec_base_t *base = per_cpu(tvec_bases, raw_smp_processor_id()); + + update_times(); + hrtimer_run_queues(); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0510-fix-config-debug-rt-mutex-lock-underflow-warnings.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0510-fix-config-debug-rt-mutex-lock-underflow-warnings.patch @@ -0,0 +1,131 @@ +Subject: Fix CONFIG_DEBUG_RT_MUTEX lock underflow warnings +From: john stultz +Date: Wed, 02 Jul 2008 17:57:32 -0700 +All, + +So if I enable CONFIG_DEBUG_RT_MUTEXES with 2.6.24.7-rt14, I tend to +quickly see a number of BUG warnings when running Java tests: + +BUG: jxeinajar/3383: lock count underflow! +Pid: 3383, comm: jxeinajar Not tainted 2.6.24-ibmrt2.5john #3 + +Call Trace: + [] rt_mutex_deadlock_account_unlock+0x5d/0x70 + [] rt_read_slowunlock+0x35/0x550 + [] rt_mutex_up_read+0x3d/0xc0 + [] rt_up_read+0x29/0x30 + [] do_futex+0x32e/0xd40 + [] ? rt_mutex_up_read+0x3d/0xc0 + [] ? rt_up_read+0x29/0x30 + [] compat_sys_futex+0xa0/0x110 + [] ? syscall_trace_enter+0x86/0xb0 + [] cstar_do_call+0x1b/0x65 + +INFO: lockdep is turned off. +--------------------------- +| preempt count: 00000001 ] +| 1-level deep critical section nesting: +---------------------------------------- +... [] .... __spin_lock_irqsave+0x22/0x60 +......[] .. ( <= rt_read_slowunlock+0x23/0x550) + + + +After some debugging and with Steven's help, we realized that with +rwlocks, rt_mutex_deadlock_account_lock can be called multiple times in +parallel (where as in most cases the mutex must be held by the caller to +to call the function). This can cause integer lock_count value being +used to be non-atomically incremented. + +The following patch converts lock_count to a atomic_t and resolves the +warnings. + +Let me know if you have any feedback or comments! + +thanks +-john + + +Signed-off-by: John Stultz +Cc: Steven Rostedt +Cc: Clark Williams +Cc: dvhltc +Signed-off-by: Thomas Gleixner + +--- + include/linux/sched.h | 2 +- + kernel/fork.c | 2 +- + kernel/rtmutex-debug.c | 12 ++++++------ + 3 files changed, 8 insertions(+), 8 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/sched.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/sched.h 2008-10-08 22:25:03.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/sched.h 2008-10-08 22:25:06.000000000 -0400 +@@ -1250,7 +1250,7 @@ struct task_struct { + + #define MAX_LOCK_STACK MAX_PREEMPT_TRACE + #ifdef CONFIG_DEBUG_PREEMPT +- int lock_count; ++ atomic_t lock_count; + # ifdef CONFIG_PREEMPT_RT + struct rt_mutex *owned_lock[MAX_LOCK_STACK]; + # endif +Index: linux-2.6.24.7-rt21/kernel/fork.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/fork.c 2008-10-08 22:24:55.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/fork.c 2008-10-08 22:25:06.000000000 -0400 +@@ -1203,7 +1203,7 @@ static struct task_struct *copy_process( + if (retval) + goto bad_fork_cleanup_namespaces; + #ifdef CONFIG_DEBUG_PREEMPT +- p->lock_count = 0; ++ atomic_set(&p->lock_count, 0); + #endif + + #ifdef CONFIG_PREEMPT_RT +Index: linux-2.6.24.7-rt21/kernel/rtmutex-debug.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rtmutex-debug.c 2008-10-08 22:25:05.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rtmutex-debug.c 2008-10-08 22:25:06.000000000 -0400 +@@ -176,7 +176,7 @@ void + rt_mutex_deadlock_account_lock(struct rt_mutex *lock, struct task_struct *task) + { + #ifdef CONFIG_DEBUG_PREEMPT +- if (task->lock_count >= MAX_LOCK_STACK) { ++ if (atomic_read(&task->lock_count) >= MAX_LOCK_STACK) { + if (!debug_locks_off()) + return; + printk("BUG: %s/%d: lock count overflow!\n", +@@ -185,16 +185,16 @@ rt_mutex_deadlock_account_lock(struct rt + return; + } + #ifdef CONFIG_PREEMPT_RT +- task->owned_lock[task->lock_count] = lock; ++ task->owned_lock[atomic_read(&task->lock_count)] = lock; + #endif +- task->lock_count++; ++ atomic_inc(&task->lock_count); + #endif + } + + void rt_mutex_deadlock_account_unlock(struct task_struct *task) + { + #ifdef CONFIG_DEBUG_PREEMPT +- if (!task->lock_count) { ++ if (!atomic_read(&task->lock_count)) { + if (!debug_locks_off()) + return; + printk("BUG: %s/%d: lock count underflow!\n", +@@ -202,9 +202,9 @@ void rt_mutex_deadlock_account_unlock(st + dump_stack(); + return; + } +- task->lock_count--; ++ atomic_dec(&task->lock_count); + #ifdef CONFIG_PREEMPT_RT +- task->owned_lock[task->lock_count] = NULL; ++ task->owned_lock[atomic_read(&task->lock_count)] = NULL; + #endif + #endif + } --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0365-fork-desched_thread-comment-rework.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0365-fork-desched_thread-comment-rework.patch @@ -0,0 +1,33 @@ +From dwalker@mvista.com Wed Sep 26 22:18:23 2007 +Date: Tue, 28 Aug 2007 14:37:52 -0700 +From: Daniel Walker +To: mingo@elte.hu +Cc: mingo@redhat.com, linux-kernel@vger.kernel.org, + linux-rt-users@vger.kernel.org +Subject: [PATCH -rt 4/8] fork: desched_thread comment rework. + +Lines are too long.. + +Signed-off-by: Daniel Walker + +--- + kernel/fork.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/fork.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/fork.c 2008-10-08 22:24:16.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/fork.c 2008-10-08 22:24:31.000000000 -0400 +@@ -1839,8 +1839,10 @@ static int desched_thread(void * __bind_ + continue; + schedule(); + +- /* This must be called from time to time on ia64, and is a no-op on other archs. +- * Used to be in cpu_idle(), but with the new -rt semantics it can't stay there. ++ /* ++ * This must be called from time to time on ia64, and is a ++ * no-op on other archs. Used to be in cpu_idle(), but with ++ * the new -rt semantics it can't stay there. + */ + check_pgt_cache(); + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0037-0021-sched-clean-up-pick_next_highest_task_rt.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0037-0021-sched-clean-up-pick_next_highest_task_rt.patch @@ -0,0 +1,37 @@ +From f5e7fef1687db918dab55b3196bd5c0c7b3060b0 Mon Sep 17 00:00:00 2001 +From: Ingo Molnar +Date: Tue, 11 Dec 2007 10:02:39 +0100 +Subject: [PATCH] sched: clean up pick_next_highest_task_rt() + +clean up pick_next_highest_task_rt(). + +Signed-off-by: Ingo Molnar + +--- + kernel/sched_rt.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/sched_rt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched_rt.c 2008-10-08 22:23:00.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched_rt.c 2008-10-08 22:23:00.000000000 -0400 +@@ -238,8 +238,7 @@ static int pick_rt_task(struct rq *rq, s + } + + /* Return the second highest RT task, NULL otherwise */ +-static struct task_struct *pick_next_highest_task_rt(struct rq *rq, +- int cpu) ++static struct task_struct *pick_next_highest_task_rt(struct rq *rq, int cpu) + { + struct rt_prio_array *array = &rq->rt.active; + struct task_struct *next; +@@ -266,7 +265,8 @@ static struct task_struct *pick_next_hig + + if (queue->next->next != queue) { + /* same prio task */ +- next = list_entry(queue->next->next, struct task_struct, run_list); ++ next = list_entry(queue->next->next, struct task_struct, ++ run_list); + if (pick_rt_task(rq, next, cpu)) + goto out; + } --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0027-0011-sched-break-out-search-for-RT-tasks.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0027-0011-sched-break-out-search-for-RT-tasks.patch @@ -0,0 +1,114 @@ +From 34addd81b2d8c437daf1f295b924459a6bc34f5e Mon Sep 17 00:00:00 2001 +From: Gregory Haskins +Date: Tue, 11 Dec 2007 10:02:38 +0100 +Subject: [PATCH] sched: break out search for RT tasks + +Isolate the search logic into a function so that it can be used later +in places other than find_locked_lowest_rq(). + +Signed-off-by: Gregory Haskins +Signed-off-by: Steven Rostedt +Signed-off-by: Ingo Molnar + +--- + kernel/sched_rt.c | 66 +++++++++++++++++++++++++++++++----------------------- + 1 file changed, 39 insertions(+), 27 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/sched_rt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched_rt.c 2008-10-08 22:22:58.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched_rt.c 2008-10-08 22:22:58.000000000 -0400 +@@ -259,54 +259,66 @@ static struct task_struct *pick_next_hig + + static DEFINE_PER_CPU(cpumask_t, local_cpu_mask); + +-/* Will lock the rq it finds */ +-static struct rq *find_lock_lowest_rq(struct task_struct *task, +- struct rq *this_rq) ++static int find_lowest_rq(struct task_struct *task) + { +- struct rq *lowest_rq = NULL; + int cpu; +- int tries; + cpumask_t *cpu_mask = &__get_cpu_var(local_cpu_mask); ++ struct rq *lowest_rq = NULL; + + cpus_and(*cpu_mask, cpu_online_map, task->cpus_allowed); + +- for (tries = 0; tries < RT_MAX_TRIES; tries++) { +- /* +- * Scan each rq for the lowest prio. +- */ +- for_each_cpu_mask(cpu, *cpu_mask) { +- struct rq *rq = &per_cpu(runqueues, cpu); ++ /* ++ * Scan each rq for the lowest prio. ++ */ ++ for_each_cpu_mask(cpu, *cpu_mask) { ++ struct rq *rq = cpu_rq(cpu); + +- if (cpu == this_rq->cpu) +- continue; ++ if (cpu == rq->cpu) ++ continue; + +- /* We look for lowest RT prio or non-rt CPU */ +- if (rq->rt.highest_prio >= MAX_RT_PRIO) { +- lowest_rq = rq; +- break; +- } ++ /* We look for lowest RT prio or non-rt CPU */ ++ if (rq->rt.highest_prio >= MAX_RT_PRIO) { ++ lowest_rq = rq; ++ break; ++ } + +- /* no locking for now */ +- if (rq->rt.highest_prio > task->prio && +- (!lowest_rq || rq->rt.highest_prio > lowest_rq->rt.highest_prio)) { +- lowest_rq = rq; +- } ++ /* no locking for now */ ++ if (rq->rt.highest_prio > task->prio && ++ (!lowest_rq || rq->rt.highest_prio > lowest_rq->rt.highest_prio)) { ++ lowest_rq = rq; + } ++ } ++ ++ return lowest_rq ? lowest_rq->cpu : -1; ++} ++ ++/* Will lock the rq it finds */ ++static struct rq *find_lock_lowest_rq(struct task_struct *task, ++ struct rq *rq) ++{ ++ struct rq *lowest_rq = NULL; ++ int cpu; ++ int tries; + +- if (!lowest_rq) ++ for (tries = 0; tries < RT_MAX_TRIES; tries++) { ++ cpu = find_lowest_rq(task); ++ ++ if (cpu == -1) + break; + ++ lowest_rq = cpu_rq(cpu); ++ + /* if the prio of this runqueue changed, try again */ +- if (double_lock_balance(this_rq, lowest_rq)) { ++ if (double_lock_balance(rq, lowest_rq)) { + /* + * We had to unlock the run queue. In + * the mean time, task could have + * migrated already or had its affinity changed. + * Also make sure that it wasn't scheduled on its rq. + */ +- if (unlikely(task_rq(task) != this_rq || ++ if (unlikely(task_rq(task) != rq || + !cpu_isset(lowest_rq->cpu, task->cpus_allowed) || +- task_running(this_rq, task) || ++ task_running(rq, task) || + !task->se.on_rq)) { + spin_unlock(&lowest_rq->lock); + lowest_rq = NULL; --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0420-apic-level-smp-affinity.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0420-apic-level-smp-affinity.patch @@ -0,0 +1,24 @@ +--- + arch/x86/kernel/io_apic_64.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/io_apic_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/io_apic_64.c 2008-10-08 22:24:09.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/io_apic_64.c 2008-10-08 22:24:44.000000000 -0400 +@@ -1509,6 +1509,15 @@ static void ack_apic_level(unsigned int + move_masked_irq(irq); + unmask_IO_APIC_irq(irq); + } ++#if (defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE)) && \ ++ defined(CONFIG_PREEMPT_HARDIRQS) ++ /* ++ * With threaded interrupts, we always have IRQ_INPROGRESS ++ * when acking. ++ */ ++ else if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) ++ move_masked_irq(irq); ++#endif + } + + static struct irq_chip ioapic_chip __read_mostly = { --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0459-sched-wake_up_idle_cpu-rt.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0459-sched-wake_up_idle_cpu-rt.patch @@ -0,0 +1,17 @@ +--- + kernel/sched.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/kernel/sched.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched.c 2008-10-08 22:24:53.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched.c 2008-10-08 22:24:54.000000000 -0400 +@@ -887,7 +887,7 @@ void wake_up_idle_cpu(int cpu) + { + struct rq *rq = cpu_rq(cpu); + +- if (cpu == smp_processor_id()) ++ if (cpu == raw_smp_processor_id()) + return; + + /* --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0463-sched-load_balance-stop.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0463-sched-load_balance-stop.patch @@ -0,0 +1,26 @@ +Subject: sched: one is enough to not be idle +From: Peter Zijlstra + +Cap the load balancing on new_idle - you only need one task to run, +no need to bring the whole machine in balance again - let the softirq +balancer do that. + +Signed-off-by: Peter Zijlstra +--- + kernel/sched.c | 3 +++ + 1 file changed, 3 insertions(+) + +Index: linux-2.6.24.7-rt21/kernel/sched.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched.c 2008-10-08 22:24:54.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched.c 2008-10-08 22:24:55.000000000 -0400 +@@ -2569,6 +2569,9 @@ static int move_tasks(struct rq *this_rq + *lb_flags &= ~LB_START; + schedstat_inc(this_rq, lb_breaks); + ++ if (idle == CPU_NEWLY_IDLE && total_load_moved) ++ break; ++ + double_rq_unlock(this_rq, busiest); + local_irq_enable(); + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0563-toshiba-mutex.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0563-toshiba-mutex.patch @@ -0,0 +1,14 @@ +Index: ubuntu-hardy/drivers/acpi/toshiba_acpi.c +=================================================================== +--- ubuntu-hardy.orig/drivers/acpi/toshiba_acpi.c 2008-04-18 20:01:51.000000000 +0200 ++++ ubuntu-hardy/drivers/acpi/toshiba_acpi.c 2008-04-18 20:02:27.000000000 +0200 +@@ -968,7 +968,8 @@ + printk(MY_INFO "ktoshkeyd will check %d time%s per second\n", + hotkeys_check_per_sec, hotkeys_check_per_sec==1?"":"s"); + if (init_threaded_acpi() >= 0) { +- init_MUTEX_LOCKED(&thread_sem); ++ init_MUTEX(&thread_sem); ++ down(&thread_sem); + kernel_thread(toshiba_acpi_thread, NULL, CLONE_KERNEL); + down(&thread_sem); + } else { --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0267-preempt-realtime-net-softirq-fixups.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0267-preempt-realtime-net-softirq-fixups.patch @@ -0,0 +1,42 @@ +Subject: NOHZ: local_softirq_pending with tickless + +From: Mikulas Patocka + +On one of my machines with tickless kernel and plip I get messages : + +NOHZ: local_softirq_pending 08 + +always when using plip (on other machine with tickless kernel and plip I +get no errors). Thebug happens both on 2.6.21 and 2.6.22-rc1 + +This patch fixes that. Note that plip calls netif_rx neither from hardware +interrupt nor from ksoftirqd, so there is no one who would wake +ksoftirqd then. netif_tx calls only +__raise_softirq_irqoff(NET_RX_SOFTIRQ), which sets softirq bit, but +doesn't wake ksoftirqd. + +Mikulas + +Signed-off-by: Mikulas Patocka + +Removed the remaining users of __raise_softirq_irqoff() as well. + + tglx + +--- + net/core/dev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/net/core/dev.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/net/core/dev.c 2008-10-08 22:24:07.000000000 -0400 ++++ linux-2.6.24.7-rt21/net/core/dev.c 2008-10-08 22:24:07.000000000 -0400 +@@ -2267,7 +2267,7 @@ out: + + softnet_break: + __get_cpu_var(netdev_rx_stat).time_squeeze++; +- __raise_softirq_irqoff(NET_RX_SOFTIRQ); ++ raise_softirq_irqoff(NET_RX_SOFTIRQ); + goto out; + } + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0354-hack-convert-i_alloc_sem-for-direct_io-craziness.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0354-hack-convert-i_alloc_sem-for-direct_io-craziness.patch @@ -0,0 +1,59 @@ +From rostedt@goodmis.org Wed Sep 26 11:12:03 2007 +Date: Mon, 24 Sep 2007 17:14:26 -0400 (EDT) +From: Steven Rostedt +To: LKML +Cc: linux-rt-users , mingo@goodmis.org, + Thomas Gleixner +Subject: [HACK] convert i_alloc_sem for direct_io.c craziness! + + +Hopefully I will get some attention from those that are responsible for +fs/direct_io.c + +Ingo and Thomas, + +This patch converts the i_alloc_sem into a compat_rw_semaphore for the -rt +patch. Seems that the code in fs/direct_io.c does some nasty logic with +the i_alloc_sem. For DIO_LOCKING, I'm assuming that the i_alloc_sem is +used as a reference counter for pending requests. When the request is +made, the down_read is performed. When the request is handled by the block +softirq, then that softirq does an up on the request. So the owner is not +the same between down and up. When all requests are handled, the semaphore +counter should be zero. This keeps away any write access while requests +are pending. + +Now this may all be well and dandy for vanilla Linux, but it breaks +miserbly when converted to -rt. + +1) In RT rw_semaphores must be up'd by the same thread that down's it. + +2) We can't do PI on the correct processes. + +This patch converts (for now) the i_alloc_sem into a compat_rw_semaphore +to give back the old features to the sem. This fixes deadlocks that we've +been having WRT direct_io. But unfortunately, it now opens up +unbonded priority inversion with this semaphore. But really, those that +can be affected by this, shouldn't be doing disk IO anyway. + +The real fix would be to get rid of the read semaphore trickery in +direct_io.c. + +Signed-off-by: Steve Rostedt + +--- + include/linux/fs.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/include/linux/fs.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/fs.h 2008-10-08 22:24:15.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/fs.h 2008-10-08 22:24:29.000000000 -0400 +@@ -635,7 +635,7 @@ struct inode { + umode_t i_mode; + spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */ + struct mutex i_mutex; +- struct rw_semaphore i_alloc_sem; ++ struct compat_rw_semaphore i_alloc_sem; + const struct inode_operations *i_op; + const struct file_operations *i_fop; /* former ->i_op->default_file_ops */ + struct super_block *i_sb; --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0324-irda-fix.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0324-irda-fix.patch @@ -0,0 +1,25 @@ +This was found around the 2.6.10 timeframe when testing with the -rt patch +and I believe is still is an issue. irttp_dup() does a memcpy() of the tsap_cb +structure causing the spinlock protecting various fields in the structure to be +duped. This works OK in the non-RT case but in the RT case we end up with two +mutexes pointing to the same wait_list and leading to an OOPS. Fix is to simply +initialize the spinlock after the memcpy(). + +Signed-off-by: Deepak Saxena + +--- + net/irda/irttp.c | 1 + + 1 file changed, 1 insertion(+) + +Index: linux-2.6.24.7-rt21/net/irda/irttp.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/net/irda/irttp.c 2008-10-08 22:22:22.000000000 -0400 ++++ linux-2.6.24.7-rt21/net/irda/irttp.c 2008-10-08 22:24:22.000000000 -0400 +@@ -1453,6 +1453,7 @@ struct tsap_cb *irttp_dup(struct tsap_cb + } + /* Dup */ + memcpy(new, orig, sizeof(struct tsap_cb)); ++ spin_lock_init(&new->lock); + + /* We don't need the old instance any more */ + spin_unlock_irqrestore(&irttp->tsaps->hb_spinlock, flags); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0388-irq-flags-unsigned-long.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0388-irq-flags-unsigned-long.patch @@ -0,0 +1,35 @@ +--- + drivers/media/video/zoran_driver.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +Index: linux-2.6.24.7-rt21/drivers/media/video/zoran_driver.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/media/video/zoran_driver.c 2008-10-08 22:22:18.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/media/video/zoran_driver.c 2008-10-08 22:24:37.000000000 -0400 +@@ -1174,7 +1174,7 @@ zoran_close_end_session (struct file *fi + + /* v4l capture */ + if (fh->v4l_buffers.active != ZORAN_FREE) { +- long flags; ++ unsigned long flags; + + spin_lock_irqsave(&zr->spinlock, flags); + zr36057_set_memgrab(zr, 0); +@@ -3447,7 +3447,7 @@ zoran_do_ioctl (struct inode *inode, + + /* unload capture */ + if (zr->v4l_memgrab_active) { +- long flags; ++ unsigned long flags; + + spin_lock_irqsave(&zr->spinlock, flags); + zr36057_set_memgrab(zr, 0); +@@ -4387,7 +4387,7 @@ zoran_vm_close (struct vm_area_struct *v + mutex_lock(&zr->resource_lock); + + if (fh->v4l_buffers.active != ZORAN_FREE) { +- long flags; ++ unsigned long flags; + + spin_lock_irqsave(&zr->spinlock, flags); + zr36057_set_memgrab(zr, 0); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0121-rcu-new-2.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0121-rcu-new-2.patch @@ -0,0 +1,61 @@ +From paulmck@linux.vnet.ibm.com Thu Sep 27 00:03:00 2007 +Date: Mon, 10 Sep 2007 11:33:05 -0700 +From: Paul E. McKenney +To: linux-kernel@vger.kernel.org +Cc: linux-rt-users@vger.kernel.org, mingo@elte.hu, akpm@linux-foundation.org, + dipankar@in.ibm.com, josht@linux.vnet.ibm.com, tytso@us.ibm.com, + dvhltc@us.ibm.com, tglx@linutronix.de, a.p.zijlstra@chello.nl, + bunk@kernel.org, ego@in.ibm.com, oleg@tv-sign.ru, srostedt@redhat.com +Subject: [PATCH RFC 2/9] RCU: Fix barriers + +Work in progress, not for inclusion. + +Fix rcu_barrier() to work properly in preemptive kernel environment. +Also, the ordering of callback must be preserved while moving +callbacks to another CPU during CPU hotplug. + +Signed-off-by: Dipankar Sarma +Signed-off-by: Paul E. McKenney +--- + + kernel/rcuclassic.c | 2 +- + kernel/rcupdate.c | 10 ++++++++++ + 2 files changed, 11 insertions(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/kernel/rcuclassic.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rcuclassic.c 2008-10-08 22:23:25.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rcuclassic.c 2008-10-08 22:23:25.000000000 -0400 +@@ -353,9 +353,9 @@ static void __rcu_offline_cpu(struct rcu + if (rcp->cur != rcp->completed) + cpu_quiet(rdp->cpu, rcp); + spin_unlock_bh(&rcp->lock); ++ rcu_move_batch(this_rdp, rdp->donelist, rdp->donetail); + rcu_move_batch(this_rdp, rdp->curlist, rdp->curtail); + rcu_move_batch(this_rdp, rdp->nxtlist, rdp->nxttail); +- rcu_move_batch(this_rdp, rdp->donelist, rdp->donetail); + } + + static void rcu_offline_cpu(int cpu) +Index: linux-2.6.24.7-rt21/kernel/rcupdate.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rcupdate.c 2008-10-08 22:23:25.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rcupdate.c 2008-10-08 22:23:25.000000000 -0400 +@@ -123,7 +123,17 @@ void rcu_barrier(void) + mutex_lock(&rcu_barrier_mutex); + init_completion(&rcu_barrier_completion); + atomic_set(&rcu_barrier_cpu_count, 0); ++ /* ++ * The queueing of callbacks in all CPUs must be atomic with ++ * respect to RCU, otherwise one CPU may queue a callback, ++ * wait for a grace period, decrement barrier count and call ++ * complete(), while other CPUs have not yet queued anything. ++ * So, we need to make sure that grace periods cannot complete ++ * until all the callbacks are queued. ++ */ ++ rcu_read_lock(); + on_each_cpu(rcu_barrier_func, NULL, 0, 1); ++ rcu_read_unlock(); + wait_for_completion(&rcu_barrier_completion); + mutex_unlock(&rcu_barrier_mutex); + } --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0220-preempt-realtime-powerpc.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0220-preempt-realtime-powerpc.patch @@ -0,0 +1,457 @@ +--- + arch/powerpc/kernel/smp.c | 12 ++++++++- + arch/powerpc/kernel/traps.c | 9 +++++- + arch/powerpc/platforms/cell/smp.c | 2 - + arch/powerpc/platforms/chrp/smp.c | 2 - + arch/powerpc/platforms/chrp/time.c | 2 - + arch/powerpc/platforms/powermac/feature.c | 2 - + arch/powerpc/platforms/powermac/nvram.c | 2 - + arch/powerpc/platforms/powermac/pic.c | 2 - + arch/powerpc/platforms/pseries/smp.c | 2 - + arch/ppc/8260_io/enet.c | 2 - + arch/ppc/8260_io/fcc_enet.c | 2 - + arch/ppc/8xx_io/commproc.c | 2 - + arch/ppc/8xx_io/enet.c | 2 - + arch/ppc/8xx_io/fec.c | 2 - + arch/ppc/kernel/smp.c | 12 ++++++++- + arch/ppc/kernel/traps.c | 6 +++- + arch/ppc/platforms/hdpu.c | 2 - + arch/ppc/platforms/sbc82xx.c | 2 - + arch/ppc/syslib/cpm2_common.c | 2 - + arch/ppc/syslib/open_pic.c | 2 - + arch/ppc/syslib/open_pic2.c | 2 - + include/asm-powerpc/hw_irq.h | 40 ++++++++++++++++++------------ + 22 files changed, 76 insertions(+), 37 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/powerpc/kernel/smp.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/kernel/smp.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/kernel/smp.c 2008-10-08 22:23:53.000000000 -0400 +@@ -126,6 +126,16 @@ void smp_send_reschedule(int cpu) + smp_ops->message_pass(cpu, PPC_MSG_RESCHEDULE); + } + ++/* ++ * this function sends a 'reschedule' IPI to all other CPUs. ++ * This is used when RT tasks are starving and other CPUs ++ * might be able to run them: ++ */ ++void smp_send_reschedule_allbutself(void) ++{ ++ smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_RESCHEDULE); ++} ++ + #ifdef CONFIG_DEBUGGER + void smp_send_debugger_break(int cpu) + { +@@ -157,7 +167,7 @@ static void stop_this_cpu(void *dummy) + * static memory requirements. It also looks cleaner. + * Stolen from the i386 version. + */ +-static __cacheline_aligned_in_smp DEFINE_SPINLOCK(call_lock); ++static __cacheline_aligned_in_smp DEFINE_RAW_SPINLOCK(call_lock); + + static struct call_data_struct { + void (*func) (void *info); +Index: linux-2.6.24.7-rt21/arch/powerpc/kernel/traps.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/kernel/traps.c 2008-10-08 22:23:11.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/kernel/traps.c 2008-10-08 22:23:53.000000000 -0400 +@@ -98,11 +98,11 @@ static inline void pmac_backlight_unblan + int die(const char *str, struct pt_regs *regs, long err) + { + static struct { +- spinlock_t lock; ++ raw_spinlock_t lock; + u32 lock_owner; + int lock_owner_depth; + } die = { +- .lock = __SPIN_LOCK_UNLOCKED(die.lock), ++ .lock = _RAW_SPIN_LOCK_UNLOCKED(die.lock), + .lock_owner = -1, + .lock_owner_depth = 0 + }; +@@ -191,6 +191,11 @@ void _exception(int signr, struct pt_reg + addr, regs->nip, regs->link, code); + } + ++#ifdef CONFIG_PREEMPT_RT ++ local_irq_enable(); ++ preempt_check_resched(); ++#endif ++ + memset(&info, 0, sizeof(info)); + info.si_signo = signr; + info.si_code = code; +Index: linux-2.6.24.7-rt21/arch/powerpc/platforms/cell/smp.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/platforms/cell/smp.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/platforms/cell/smp.c 2008-10-08 22:23:53.000000000 -0400 +@@ -134,7 +134,7 @@ static void __devinit smp_iic_setup_cpu( + iic_setup_cpu(); + } + +-static DEFINE_SPINLOCK(timebase_lock); ++static DEFINE_RAW_SPINLOCK(timebase_lock); + static unsigned long timebase = 0; + + static void __devinit cell_give_timebase(void) +Index: linux-2.6.24.7-rt21/arch/powerpc/platforms/chrp/smp.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/platforms/chrp/smp.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/platforms/chrp/smp.c 2008-10-08 22:23:53.000000000 -0400 +@@ -42,7 +42,7 @@ static void __devinit smp_chrp_setup_cpu + mpic_setup_this_cpu(); + } + +-static DEFINE_SPINLOCK(timebase_lock); ++static DEFINE_RAW_SPINLOCK(timebase_lock); + static unsigned int timebase_upper = 0, timebase_lower = 0; + + void __devinit smp_chrp_give_timebase(void) +Index: linux-2.6.24.7-rt21/arch/powerpc/platforms/chrp/time.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/platforms/chrp/time.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/platforms/chrp/time.c 2008-10-08 22:23:53.000000000 -0400 +@@ -27,7 +27,7 @@ + #include + #include + +-extern spinlock_t rtc_lock; ++extern raw_spinlock_t rtc_lock; + + static int nvram_as1 = NVRAM_AS1; + static int nvram_as0 = NVRAM_AS0; +Index: linux-2.6.24.7-rt21/arch/powerpc/platforms/powermac/feature.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/platforms/powermac/feature.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/platforms/powermac/feature.c 2008-10-08 22:23:53.000000000 -0400 +@@ -59,7 +59,7 @@ extern struct device_node *k2_skiplist[2 + * We use a single global lock to protect accesses. Each driver has + * to take care of its own locking + */ +-DEFINE_SPINLOCK(feature_lock); ++DEFINE_RAW_SPINLOCK(feature_lock); + + #define LOCK(flags) spin_lock_irqsave(&feature_lock, flags); + #define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags); +Index: linux-2.6.24.7-rt21/arch/powerpc/platforms/powermac/nvram.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/platforms/powermac/nvram.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/platforms/powermac/nvram.c 2008-10-08 22:23:53.000000000 -0400 +@@ -80,7 +80,7 @@ static int is_core_99; + static int core99_bank = 0; + static int nvram_partitions[3]; + // XXX Turn that into a sem +-static DEFINE_SPINLOCK(nv_lock); ++static DEFINE_RAW_SPINLOCK(nv_lock); + + static int (*core99_write_bank)(int bank, u8* datas); + static int (*core99_erase_bank)(int bank); +Index: linux-2.6.24.7-rt21/arch/powerpc/platforms/powermac/pic.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/platforms/powermac/pic.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/platforms/powermac/pic.c 2008-10-08 22:23:53.000000000 -0400 +@@ -63,7 +63,7 @@ static int max_irqs; + static int max_real_irqs; + static u32 level_mask[4]; + +-static DEFINE_SPINLOCK(pmac_pic_lock); ++static DEFINE_RAW_SPINLOCK(pmac_pic_lock); + + #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) + static unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; +Index: linux-2.6.24.7-rt21/arch/powerpc/platforms/pseries/smp.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/platforms/pseries/smp.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/platforms/pseries/smp.c 2008-10-08 22:23:53.000000000 -0400 +@@ -154,7 +154,7 @@ static void __devinit smp_xics_setup_cpu + } + #endif /* CONFIG_XICS */ + +-static DEFINE_SPINLOCK(timebase_lock); ++static DEFINE_RAW_SPINLOCK(timebase_lock); + static unsigned long timebase = 0; + + static void __devinit pSeries_give_timebase(void) +Index: linux-2.6.24.7-rt21/arch/ppc/8260_io/enet.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ppc/8260_io/enet.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ppc/8260_io/enet.c 2008-10-08 22:23:53.000000000 -0400 +@@ -115,7 +115,7 @@ struct scc_enet_private { + scc_t *sccp; + struct net_device_stats stats; + uint tx_full; +- spinlock_t lock; ++ raw_spinlock_t lock; + }; + + static int scc_enet_open(struct net_device *dev); +Index: linux-2.6.24.7-rt21/arch/ppc/8260_io/fcc_enet.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ppc/8260_io/fcc_enet.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ppc/8260_io/fcc_enet.c 2008-10-08 22:23:53.000000000 -0400 +@@ -375,7 +375,7 @@ struct fcc_enet_private { + volatile fcc_enet_t *ep; + struct net_device_stats stats; + uint tx_free; +- spinlock_t lock; ++ raw_spinlock_t lock; + + #ifdef CONFIG_USE_MDIO + uint phy_id; +Index: linux-2.6.24.7-rt21/arch/ppc/8xx_io/commproc.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ppc/8xx_io/commproc.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ppc/8xx_io/commproc.c 2008-10-08 22:23:53.000000000 -0400 +@@ -370,7 +370,7 @@ cpm_setbrg(uint brg, uint rate) + /* + * dpalloc / dpfree bits. + */ +-static spinlock_t cpm_dpmem_lock; ++static raw_spinlock_t cpm_dpmem_lock; + /* + * 16 blocks should be enough to satisfy all requests + * until the memory subsystem goes up... +Index: linux-2.6.24.7-rt21/arch/ppc/8xx_io/enet.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ppc/8xx_io/enet.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ppc/8xx_io/enet.c 2008-10-08 22:23:53.000000000 -0400 +@@ -143,7 +143,7 @@ struct scc_enet_private { + unsigned char *rx_vaddr[RX_RING_SIZE]; + struct net_device_stats stats; + uint tx_full; +- spinlock_t lock; ++ raw_spinlock_t lock; + }; + + static int scc_enet_open(struct net_device *dev); +Index: linux-2.6.24.7-rt21/arch/ppc/8xx_io/fec.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ppc/8xx_io/fec.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ppc/8xx_io/fec.c 2008-10-08 22:23:53.000000000 -0400 +@@ -164,7 +164,7 @@ struct fec_enet_private { + + struct net_device_stats stats; + uint tx_full; +- spinlock_t lock; ++ raw_spinlock_t lock; + + #ifdef CONFIG_USE_MDIO + uint phy_id; +Index: linux-2.6.24.7-rt21/arch/ppc/kernel/smp.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ppc/kernel/smp.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ppc/kernel/smp.c 2008-10-08 22:23:53.000000000 -0400 +@@ -136,6 +136,16 @@ void smp_send_reschedule(int cpu) + smp_message_pass(cpu, PPC_MSG_RESCHEDULE); + } + ++/* ++ * this function sends a 'reschedule' IPI to all other CPUs. ++ * This is used when RT tasks are starving and other CPUs ++ * might be able to run them: ++ */ ++void smp_send_reschedule_allbutself(void) ++{ ++ smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_RESCHEDULE, 0, 0); ++} ++ + #ifdef CONFIG_XMON + void smp_send_xmon_break(int cpu) + { +@@ -160,7 +170,7 @@ void smp_send_stop(void) + * static memory requirements. It also looks cleaner. + * Stolen from the i386 version. + */ +-static DEFINE_SPINLOCK(call_lock); ++static DEFINE_RAW_SPINLOCK(call_lock); + + static struct call_data_struct { + void (*func) (void *info); +Index: linux-2.6.24.7-rt21/arch/ppc/kernel/traps.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ppc/kernel/traps.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ppc/kernel/traps.c 2008-10-08 22:23:53.000000000 -0400 +@@ -72,7 +72,7 @@ void (*debugger_fault_handler)(struct pt + * Trap & Exception support + */ + +-DEFINE_SPINLOCK(die_lock); ++DEFINE_RAW_SPINLOCK(die_lock); + + int die(const char * str, struct pt_regs * fp, long err) + { +@@ -108,6 +108,10 @@ void _exception(int signr, struct pt_reg + debugger(regs); + die("Exception in kernel mode", regs, signr); + } ++#ifdef CONFIG_PREEMPT_RT ++ local_irq_enable(); ++ preempt_check_resched(); ++#endif + info.si_signo = signr; + info.si_errno = 0; + info.si_code = code; +Index: linux-2.6.24.7-rt21/arch/ppc/platforms/hdpu.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ppc/platforms/hdpu.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ppc/platforms/hdpu.c 2008-10-08 22:23:53.000000000 -0400 +@@ -55,7 +55,7 @@ static void parse_bootinfo(unsigned long + static void hdpu_set_l1pe(void); + static void hdpu_cpustate_set(unsigned char new_state); + #ifdef CONFIG_SMP +-static DEFINE_SPINLOCK(timebase_lock); ++static DEFINE_RAW_SPINLOCK(timebase_lock); + static unsigned int timebase_upper = 0, timebase_lower = 0; + extern int smp_tb_synchronized; + +Index: linux-2.6.24.7-rt21/arch/ppc/platforms/sbc82xx.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ppc/platforms/sbc82xx.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ppc/platforms/sbc82xx.c 2008-10-08 22:23:53.000000000 -0400 +@@ -65,7 +65,7 @@ static void sbc82xx_time_init(void) + + static volatile char *sbc82xx_i8259_map; + static char sbc82xx_i8259_mask = 0xff; +-static DEFINE_SPINLOCK(sbc82xx_i8259_lock); ++static DEFINE_RAW_SPINLOCK(sbc82xx_i8259_lock); + + static void sbc82xx_i8259_mask_and_ack_irq(unsigned int irq_nr) + { +Index: linux-2.6.24.7-rt21/arch/ppc/syslib/cpm2_common.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ppc/syslib/cpm2_common.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ppc/syslib/cpm2_common.c 2008-10-08 22:23:53.000000000 -0400 +@@ -114,7 +114,7 @@ cpm2_fastbrg(uint brg, uint rate, int di + /* + * dpalloc / dpfree bits. + */ +-static spinlock_t cpm_dpmem_lock; ++static raw_spinlock_t cpm_dpmem_lock; + /* 16 blocks should be enough to satisfy all requests + * until the memory subsystem goes up... */ + static rh_block_t cpm_boot_dpmem_rh_block[16]; +Index: linux-2.6.24.7-rt21/arch/ppc/syslib/open_pic.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ppc/syslib/open_pic.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ppc/syslib/open_pic.c 2008-10-08 22:23:53.000000000 -0400 +@@ -526,7 +526,7 @@ void openpic_reset_processor_phys(u_int + } + + #if defined(CONFIG_SMP) || defined(CONFIG_PM) +-static DEFINE_SPINLOCK(openpic_setup_lock); ++static DEFINE_RAW_SPINLOCK(openpic_setup_lock); + #endif + + #ifdef CONFIG_SMP +Index: linux-2.6.24.7-rt21/arch/ppc/syslib/open_pic2.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ppc/syslib/open_pic2.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ppc/syslib/open_pic2.c 2008-10-08 22:23:53.000000000 -0400 +@@ -380,7 +380,7 @@ static void openpic2_set_spurious(u_int + vec); + } + +-static DEFINE_SPINLOCK(openpic2_setup_lock); ++static DEFINE_RAW_SPINLOCK(openpic2_setup_lock); + + /* + * Initialize a timer interrupt (and disable it) +Index: linux-2.6.24.7-rt21/include/asm-powerpc/hw_irq.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-powerpc/hw_irq.h 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-powerpc/hw_irq.h 2008-10-08 22:23:53.000000000 -0400 +@@ -20,8 +20,8 @@ static inline unsigned long local_get_fl + { + unsigned long flags; + +- __asm__ __volatile__("lbz %0,%1(13)" +- : "=r" (flags) ++<<<<<<< delete extern unsigned long local_get_flags(void); ++<<<<<<< delete extern unsigned long local_irq_disable(void); + : "i" (offsetof(struct paca_struct, soft_enabled))); + + return flags; +@@ -39,14 +39,19 @@ static inline unsigned long local_irq_di + return flags; + } + +-extern void local_irq_restore(unsigned long); ++ + extern void iseries_handle_interrupts(void); ++extern unsigned long raw_local_get_flags(void); ++extern unsigned long raw_local_irq_disable(void); ++extern void raw_local_irq_restore(unsigned long); ++ ++#define raw_local_irq_enable() raw_local_irq_restore(1) ++#define raw_local_save_flags(flags) ((flags) = raw_local_get_flags()) ++#define raw_local_irq_save(flags) ((flags) = raw_local_irq_disable()) + +-#define local_irq_enable() local_irq_restore(1) +-#define local_save_flags(flags) ((flags) = local_get_flags()) +-#define local_irq_save(flags) ((flags) = local_irq_disable()) ++#define raw_irqs_disabled() (raw_local_get_flags() == 0) ++#define raw_irqs_disabled_flags(flags) ((flags) == 0) + +-#define irqs_disabled() (local_get_flags() == 0) + + #define __hard_irq_enable() __mtmsrd(mfmsr() | MSR_EE, 1) + #define __hard_irq_disable() __mtmsrd(mfmsr() & ~MSR_EE, 1) +@@ -62,13 +67,15 @@ extern void iseries_handle_interrupts(vo + + #if defined(CONFIG_BOOKE) + #define SET_MSR_EE(x) mtmsr(x) +-#define local_irq_restore(flags) __asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory") ++#define raw_local_irq_restore(flags) __asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory") ++<<<<<<< delete #define local_irq_restore(flags) do { \ ++#define raw_local_irq_restore(flags) do { \ + #else + #define SET_MSR_EE(x) mtmsr(x) +-#define local_irq_restore(flags) mtmsr(flags) ++#define raw_local_irq_restore(flags) mtmsr(flags) + #endif + +-static inline void local_irq_disable(void) ++static inline void raw_local_irq_disable(void) + { + #ifdef CONFIG_BOOKE + __asm__ __volatile__("wrteei 0": : :"memory"); +@@ -80,7 +87,7 @@ static inline void local_irq_disable(voi + #endif + } + +-static inline void local_irq_enable(void) ++static inline void raw_local_irq_enable(void) + { + #ifdef CONFIG_BOOKE + __asm__ __volatile__("wrteei 1": : :"memory"); +@@ -92,7 +99,7 @@ static inline void local_irq_enable(void + #endif + } + +-static inline void local_irq_save_ptr(unsigned long *flags) ++static inline void raw_local_irq_save_ptr(unsigned long *flags) + { + unsigned long msr; + msr = mfmsr(); +@@ -105,13 +112,16 @@ static inline void local_irq_save_ptr(un + __asm__ __volatile__("": : :"memory"); + } + +-#define local_save_flags(flags) ((flags) = mfmsr()) +-#define local_irq_save(flags) local_irq_save_ptr(&flags) +-#define irqs_disabled() ((mfmsr() & MSR_EE) == 0) ++#define raw_local_save_flags(flags) ((flags) = mfmsr()) ++#define raw_local_irq_save(flags) raw_local_irq_save_ptr(&flags) ++#define raw_irqs_disabled() ((mfmsr() & MSR_EE) == 0) ++#define raw_irqs_disabled_flags(flags) ((flags & MSR_EE) == 0) + + #define hard_irq_enable() local_irq_enable() + #define hard_irq_disable() local_irq_disable() + ++#include ++ + #endif /* CONFIG_PPC64 */ + + /* --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0468-ftrace-record-comm-on-ctrl.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0468-ftrace-record-comm-on-ctrl.patch @@ -0,0 +1,28 @@ +From: Steven Rostedt +Subject: ftrace: record comm on function ctrl change + +On stress tests, it is possible for the comm of that disables the +ftracer to be lost. Record it on turning on or off the function tracer. + +Signed-off-by: Steven Rostedt +--- + kernel/trace/trace.c | 2 ++ + 1 file changed, 2 insertions(+) + +Index: linux-2.6.24.7-rt21/kernel/trace/trace.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/trace.c 2008-10-08 22:23:57.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/trace.c 2008-10-08 22:24:56.000000000 -0400 +@@ -1197,10 +1197,12 @@ static struct ftrace_ops trace_ops __rea + void tracing_start_function_trace(void) + { + register_ftrace_function(&trace_ops); ++ tracing_record_cmdline(current); + } + + void tracing_stop_function_trace(void) + { ++ tracing_record_cmdline(current); + unregister_ftrace_function(&trace_ops); + } + #endif --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0428-kthread-cpus-allowed-init.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0428-kthread-cpus-allowed-init.patch @@ -0,0 +1,49 @@ +From ghaskins@novell.com Mon Mar 24 17:40:01 2008 +Date: Fri, 07 Mar 2008 07:11:43 -0500 +From: Gregory Haskins +To: rostedt@goodmis.org, mingo@elte.he +Cc: linux-kernel@vger.kernel.org, linux-rt-users@vger.kernel.org, + ghaskins@novell.com +Subject: [PATCH] RESEND: fix cpus_allowed settings + + [ The following text is in the "utf-8" character set. ] + [ Your display is set for the "iso-8859-1" character set. ] + [ Some characters may be displayed incorrectly. ] + +Hi Ingo, Steve, + I sent this patch a few weeks ago along with the migration_disable +series. I think the controversy with the migration_disable feature +may have resulted in this fix being overlooked. This patch is against +-rt, but the bug theoretically affects both -rt and sched-devel/mainline. +I can also whip up a sched-devel based patch if you like, but I think it +will apply trivially to both places. + +Please consider it for inclusion. + +Regards, +-Greg + +------------------------------- +Subject: fix cpus_allowed settings + +We miss setting nr_cpus_allowed for the kthread case since the normal +set_cpus_allowed() function is not used. + +Signed-off-by: Gregory Haskins +--- + + kernel/kthread.c | 1 + + 1 file changed, 1 insertion(+) + +Index: linux-2.6.24.7-rt21/kernel/kthread.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/kthread.c 2008-10-08 22:22:16.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/kthread.c 2008-10-08 22:24:46.000000000 -0400 +@@ -170,6 +170,7 @@ void kthread_bind(struct task_struct *k, + wait_task_inactive(k); + set_task_cpu(k, cpu); + k->cpus_allowed = cpumask_of_cpu(cpu); ++ k->nr_cpus_allowed = 1; + } + EXPORT_SYMBOL(kthread_bind); + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0103-dont-unmask-io_apic.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0103-dont-unmask-io_apic.patch @@ -0,0 +1,18 @@ +--- + arch/x86/kernel/io_apic_64.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/io_apic_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/io_apic_64.c 2008-10-08 22:22:41.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/io_apic_64.c 2008-10-08 22:23:21.000000000 -0400 +@@ -1440,7 +1440,8 @@ static void ack_apic_level(unsigned int + irq_complete_move(irq); + #if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE) + /* If we are moving the irq we need to mask it */ +- if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) { ++ if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING) && ++ !(irq_desc[irq].status & IRQ_INPROGRESS)) { + do_unmask_irq = 1; + mask_IO_APIC_irq(irq); + } --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0492-rwlock-fixes.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0492-rwlock-fixes.patch @@ -0,0 +1,176 @@ +From: Steven Rostedt +Subject: rwlock: fix pi_list race conditions + +Found a few pi_list problems, this patch fixes. + +Signed-off-by: Steven Rostedt +--- + kernel/rtmutex.c | 56 ++++++++++++++++++++++++++++++++++++++++--------------- + 1 file changed, 41 insertions(+), 15 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/rtmutex.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rtmutex.c 2008-10-08 22:25:02.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rtmutex.c 2008-10-08 22:25:02.000000000 -0400 +@@ -1108,6 +1108,23 @@ update_rw_mutex_owner(struct rw_mutex *r + rt_mutex_set_owner(mutex, mtxowner, 0); + } + ++#ifdef CONFIG_DEBUG_RT_MUTEXES ++/* ++ * A rw lock is about to be added or has already been ++ * removed from current. Make sure it doesn't exist still. ++ */ ++static void rw_check_held(struct rw_mutex *rwm) ++{ ++ int reader_count = current->reader_lock_count; ++ int i; ++ ++ for (i = 0; i < reader_count; i++) ++ WARN_ON_ONCE(current->owned_read_locks[i].lock == rwm); ++} ++#else ++# define rw_check_held(rwm) do { } while (0) ++#endif ++ + /* + * The fast path does not add itself to the reader list to keep + * from needing to grab the spinlock. We need to add the owner +@@ -1122,16 +1139,14 @@ update_rw_mutex_owner(struct rw_mutex *r + */ + + static inline void +-rt_rwlock_update_owner(struct rw_mutex *rwm, unsigned owners) ++rt_rwlock_update_owner(struct rw_mutex *rwm, struct task_struct *own) + { + struct reader_lock_struct *rls; +- struct task_struct *own; + int i; + +- if (!owners || rt_rwlock_pending(rwm)) ++ if (!own || rt_rwlock_pending(rwm)) + return; + +- own = rt_rwlock_owner(rwm); + if (own == RT_RW_READER) + return; + +@@ -1201,7 +1216,7 @@ static int try_to_take_rw_read(struct rw + } + + owners = atomic_read(&rwm->owners); +- rt_rwlock_update_owner(rwm, owners); ++ rt_rwlock_update_owner(rwm, rt_rwlock_owner(rwm)); + + /* Check for rwlock limits */ + if (rt_rwlock_limit && owners >= rt_rwlock_limit) +@@ -1253,6 +1268,7 @@ static int try_to_take_rw_read(struct rw + taken: + if (incr) { + atomic_inc(&rwm->owners); ++ rw_check_held(rwm); + reader_count = current->reader_lock_count++; + if (likely(reader_count < MAX_RWLOCK_DEPTH)) { + rls = ¤t->owned_read_locks[reader_count]; +@@ -1280,11 +1296,12 @@ try_to_take_rw_write(struct rw_mutex *rw + own = rt_rwlock_owner(rwm); + + /* owners must be zero for writer */ +- rt_rwlock_update_owner(rwm, atomic_read(&rwm->owners)); ++ if (own) { ++ rt_rwlock_update_owner(rwm, own); + +- /* readers or writers? */ +- if ((own && !rt_rwlock_pending(rwm))) +- return 0; ++ if (!rt_rwlock_pending(rwm)) ++ return 0; ++ } + + /* + * RT_RW_PENDING means that the lock is free, but there are +@@ -1431,6 +1448,7 @@ __rt_read_fasttrylock(struct rw_mutex *r + } + + atomic_inc(&rwm->owners); ++ rw_check_held(rwm); + reader_count = current->reader_lock_count; + if (likely(reader_count < MAX_RWLOCK_DEPTH)) { + current->owned_read_locks[reader_count].lock = rwm; +@@ -1713,6 +1731,7 @@ rt_read_slowunlock(struct rw_mutex *rwm, + WARN_ON(!rls->list.prev || list_empty(&rls->list)); + list_del_init(&rls->list); + rls->lock = NULL; ++ rw_check_held(rwm); + } + break; + } +@@ -1729,7 +1748,7 @@ rt_read_slowunlock(struct rw_mutex *rwm, + if (unlikely(rt_rwlock_owner(rwm) != current && + rt_rwlock_owner(rwm) != RT_RW_READER)) { + /* Update the owner if necessary */ +- rt_rwlock_update_owner(rwm, atomic_read(&rwm->owners)); ++ rt_rwlock_update_owner(rwm, rt_rwlock_owner(rwm)); + goto out; + } + +@@ -1786,7 +1805,8 @@ rt_read_slowunlock(struct rw_mutex *rwm, + if (rt_rwlock_limit && + unlikely(atomic_read(&rwm->owners) >= rt_rwlock_limit)) + goto out; +- rwm->owner = RT_RW_PENDING_READ; ++ if (!reader_count) ++ rwm->owner = RT_RW_PENDING_READ; + } + + wakeup_next_waiter(mutex, savestate); +@@ -1812,6 +1832,7 @@ rt_read_fastunlock(struct rw_mutex *rwm, + WARN_ON(!atomic_read(&rwm->count)); + WARN_ON(!atomic_read(&rwm->owners)); + WARN_ON(!rwm->owner); ++ smp_mb(); + atomic_dec(&rwm->count); + if (likely(rt_rwlock_cmpxchg(rwm, current, NULL))) { + struct reader_lock_struct *rls; +@@ -1830,7 +1851,9 @@ rt_read_fastunlock(struct rw_mutex *rwm, + rls = ¤t->owned_read_locks[reader_count]; + WARN_ON_ONCE(rls->lock != rwm); + WARN_ON(rls->list.prev && !list_empty(&rls->list)); ++ WARN_ON(rls->count != 1); + rls->lock = NULL; ++ rw_check_held(rwm); + } else + slowfn(rwm, mtx); + } +@@ -1936,8 +1959,11 @@ rt_write_slowunlock(struct rw_mutex *rwm + next = rt_mutex_top_waiter(mutex); + /* delete incase we didn't go through the loop */ + plist_del(&next->pi_list_entry, &pendowner->pi_waiters); +- /* add back in as top waiter */ +- plist_add(&next->pi_list_entry, &pendowner->pi_waiters); ++ ++ /* This could also be a reader (if reader_limit is set) */ ++ if (next->write_lock) ++ /* add back in as top waiter */ ++ plist_add(&next->pi_list_entry, &pendowner->pi_waiters); + + rwm->prio = next->task->prio; + } else +@@ -1997,6 +2023,7 @@ rt_mutex_downgrade_write(struct rw_mutex + /* we have the lock and are sole owner, then update the accounting */ + atomic_inc(&rwm->count); + atomic_inc(&rwm->owners); ++ rw_check_held(rwm); + reader_count = current->reader_lock_count++; + rls = ¤t->owned_read_locks[reader_count]; + if (likely(reader_count < MAX_RWLOCK_DEPTH)) { +@@ -2058,8 +2085,7 @@ rt_mutex_downgrade_write(struct rw_mutex + + /* delete incase we didn't go through the loop */ + plist_del(&next->pi_list_entry, ¤t->pi_waiters); +- /* add back in as top waiter */ +- plist_add(&next->pi_list_entry, ¤t->pi_waiters); ++ /* No need to add back since readers don't have PI waiters */ + } else + rwm->prio = MAX_PRIO; + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0430-swap-spinlock-fix.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0430-swap-spinlock-fix.patch @@ -0,0 +1,212 @@ +From h-shimamoto@ct.jp.nec.com Mon Mar 24 17:44:11 2008 +Date: Mon, 17 Mar 2008 17:14:51 -0700 +From: Hiroshi Shimamoto +To: linux-rt-users@vger.kernel.org, Ingo Molnar , + Steven Rostedt , Thomas Gleixner +Subject: Re: deadlock on 2.6.24.3-rt3 + +Hiroshi Shimamoto wrote: +> Hi, +> +> I got a soft lockup message on 2.6.24.3-rt3. +> I attached the .config. +> +> I think there is a deadlock scenario, I explain later. +> +> Here is the console log; +> BUG: soft lockup - CPU#2 stuck for 11s! [bash:2175] +> CPU 2: +> Modules linked in: +> Pid: 2175, comm: bash Not tainted 2.6.24.3-rt3 #1 +> RIP: 0010:[] [] __spin_lock+0x57/0x67 +> RSP: 0000:ffff8100c52a1d48 EFLAGS: 00000202 +> RAX: 0000000000000000 RBX: 0000000000004bc5 RCX: 0000000000004bc5 +> RDX: 0000000000000002 RSI: 00000000006c3208 RDI: 0000000000000001 +> RBP: 000000000000000d R08: ffff8100cbc28018 R09: ffff810007c95458 +> R10: 00000000006c3208 R11: 0000000000000246 R12: ffffffff808246e8 +> R13: 000284d000000002 R14: ffffffff80387277 R15: 00000000ffffffff +> FS: 00002b28926a2ef0(0000) GS:ffff8100cf8a3940(0000) knlGS:0000000000000000 +> CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b +> CR2: 00000000006c3208 CR3: 00000000c3cac000 CR4: 00000000000006e0 +> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +> DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 +> Call Trace: +> [] __spin_lock+0x29/0x67 +> [] swap_info_get+0x65/0xdd +> [] can_share_swap_page+0x39/0x84 +> [] do_wp_page+0x2f9/0x519 +> [] handle_mm_fault+0x615/0x7cf +> [] proc_flush_task+0x171/0x29c +> [] recalc_sigpending+0xe/0x3c +> [] do_page_fault+0x162/0x754 +> [] audit_syscall_exit+0x31c/0x37a +> [] error_exit+0x0/0x51 +> --------------------------- +> | preempt count: 00010002 ] +> | 2-level deep critical section nesting: +> ---------------------------------------- +> .. [] .... __spin_lock+0xe/0x67 +> .....[<00000000>] .. ( <= 0x0) +> .. [] .... __spin_lock+0xe/0x67 +> .....[<00000000>] .. ( <= 0x0) +> BUG: soft lockup - CPU#3 stuck for 11s! [stress:9460] +> CPU 3: +> Modules linked in: +> Pid: 9460, comm: stress Not tainted 2.6.24.3-rt3 #1 +> RIP: 0010:[] [] find_get_page+0xad/0xbe +> RSP: 0018:ffff8100cbf25b88 EFLAGS: 00000202 +> 0000000000002009 RBX: ffffffff80824bc8 RCX: 0000000000000002 +> RDX: 0000000000000002 RSI: ffff8100cbfcf298 RDI: ffff810005ad8910 +> RBP: ffffffff80383a57 R08: ffff810005ad8918 R09: 0000000000000003 +> R10: ffff810005ad88d8 R11: 0000000000000001 R12: ffffffff80822880 +> R13: ffff81000799ce48 R14: ffffffff8028921c R15: ffffffff80822880 +> FS: 00002acaa373bb00(0000) GS:ffff8100cf8a32c0(0000) knlGS:0000000000000000 +> CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b +> CR2: 00002b9b2827c530 CR3: 000000006cc90000 CR4: 00000000000006e0 +> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +> DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 +> Call Trace: +> [] find_get_page+0x23/0xbe +> [] free_swap_and_cache+0x46/0xdd +> [] unmap_vmas+0x626/0x8ce +> [] exit_mmap+0xac/0x147 +> [] mmput+0x32/0xae +> [] do_exit+0x199/0x914 +> [] __dequeue_signal+0x19/0x1b7 +> [] do_group_exit+0x2c/0x7e +> [] get_signal_to_deliver+0x2ef/0x4aa +> [] do_notify_resume+0xa8/0x7cd +> [] add_preempt_count+0x14/0x111 +> [] __up_read+0x13/0x8d +> [] do_page_fault+0x187/0x754 +> [] __dequeue_entity+0x2d/0x34 +> [] __switch_to+0x27/0x2c9 +> [] do_page_fault+0x1f4/0x754 +> [] retint_signal+0x3d/0x7f +> --------------------------- +> | preempt count: 00010005 ] +> | 5-level deep critical section nesting: +> ---------------------------------------- +> .. [] .... __spin_lock+0xe/0x67 +> .....[<00000000>] .. ( <= 0x0) +> .. [] .... __spin_lock+0xe/0x67 +> .....[<00000000>] .. ( <= 0x0) +> .. [] .... __spin_lock+0xe/0x67 +> .....[<00000000>] .. ( <= 0x0) +> .. [] .... find_get_page+0x14/0xbe +> .....[<00000000>] .. ( <= 0x0) +> .. [] .... __spin_lock+0xe/0x67 +> .....[<00000000>] .. ( <= 0x0) +> +> +> I also got a kernel core. +> (gdb) info thr +> 4 process 9460 0xffffffff8027c974 in find_get_page (mapping=, +> offset=18446744071570598016) at include/asm/processor_64.h:385 +> 3 process 2175 __spin_lock (lock=0xffffffff80893f80) at kernel/spinlock.c:333 +> 2 process 9132 __spin_lock (lock=0xffffffff80893f80) at include/asm/spinlock_64.h:22 +> * 1 process 9478 __spin_lock (lock=0xffffffff80893f80) at kernel/spinlock.c:333 +> +> CPU3(thread 4) is in find_get_page(), and the others in __spin_lock(). +> The thread 4 is waiting to turn PG_nonewrefs bit off in wait_on_page_ref() which is +> called from page_cache_get_speculative(), and the thread 4 holds the swap_lock. +> The other threads waiting the swap_lock. +> On the other hand, the thread 1 turned PG_nonewrefs bit on by calling +> lock_page_ref_irq() in remove_mapping(), and then waiting the swap_lock. +> So if the target page of remove_mapping() is in the exiting process memory, +> the kernel is deadlock. +> +> (gdb) bt +> #0 __spin_lock (lock=0xffffffff80893f80) at kernel/spinlock.c:333 +> #1 0xffffffff80296597 in swap_info_get (entry=) +> at mm/swapfile.c:253 +> #2 0xffffffff80296618 in swap_free (entry={val = 1}) at mm/swapfile.c:300 +> #3 0xffffffff80286acd in remove_mapping (mapping=, +> page=0xffff810005ad8910) at mm/vmscan.c:423 +> ... +> +> (gdb) thr 2 +> (gdb) bt +> #0 __spin_lock (lock=0xffffffff80893f80) at include/asm/spinlock_64.h:22 +> #1 0xffffffff80296374 in valid_swaphandles (entry=, +> offset=0xffff81001e22bc78) at mm/swapfile.c:1783 +> #2 0xffffffff8028b0af in swapin_readahead (entry={val = 1}, addr=0, vma=0x1) +> at mm/memory.c:2054 +> #3 0xffffffff8029a6af in shmem_getpage (inode=0xffff8100cdf4fd48, idx=0, +> pagep=0xffff81001e22bd80, sgp=SGP_FAULT, type=0xffff81001e22bd34) at mm/shmem.c:1089 +> ... +> +> (gdb) thr 3 +> (gdb) bt +> #0 __spin_lock (lock=0xffffffff80893f80) at kernel/spinlock.c:333 +> #1 0xffffffff80296597 in swap_info_get (entry=) +> at mm/swapfile.c:253 +> #2 0xffffffff80296c0c in can_share_swap_page (page=) +> at mm/swapfile.c:317 +> #3 0xffffffff8028ae6e in do_wp_page (mm=0xffff8100ce772f40, vma=0xffff8100cd212f00, +> address=7090696, page_table=0xffff8100cbcef618, pmd=0xffff8100cbc28018, +> ptl=0xffff810007c95458, orig_pte=) at mm/memory.c:1606 +> ... +> +> (gdb) thr 4 +> (gdb) bt +> #0 0xffffffff8027c974 in find_get_page (mapping=, +> offset=18446744071570598016) at include/asm/processor_64.h:385 +> #1 0xffffffff80296f83 in free_swap_and_cache (entry={val = 4032}) at mm/swapfile.c:403 +> #2 0xffffffff8028b9b7 in unmap_vmas (tlbp=0xffff8100cbf25cd8, vma=0xffff8100cde5c678, +> start_addr=0, end_addr=18446744073709551615, nr_accounted=0xffff8100cbf25cd0, +> details=0x0) at mm/memory.c:728 +> #3 0xffffffff8028fa4c in exit_mmap (mm=0xffff8100cd093600) at mm/mmap.c:2048 +> #4 0xffffffff8023ced7 in mmput (mm=0xffff8100cd093600) at kernel/fork.c:443 +> #5 0xffffffff80242f00 in do_exit (code=14) at kernel/exit.c:997 +> ... +> +> +> I think it came from the lockless speculative get page patch. +> I found the newer version of this patch in linux-mm. +> http://marc.info/?l=linux-mm&m=119477111927364&w=2 +> +> I haven't tested it because it looks big change and hard to apply. +> But it seems to fix this deadlock issue. +> Any other patch to fix this issue is welcome. +> + +Is this patch good? + +--- +From: Hiroshi Shimamoto +Subject: [PATCH] avoid deadlock related with PG_nonewrefs and swap_lock + +There is a deadlock scenario; remove_mapping() vs free_swap_and_cache(). +remove_mapping() turns PG_nonewrefs bit on, then locks swap_lock. +free_swap_and_cache() locks swap_lock, then wait to turn PG_nonewrefs bit +off in find_get_page(). + +swap_lock can be unlocked before calling find_get_page(). + +Signed-off-by: Hiroshi Shimamoto +--- + mm/swapfile.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/mm/swapfile.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/mm/swapfile.c 2008-10-08 22:24:15.000000000 -0400 ++++ linux-2.6.24.7-rt21/mm/swapfile.c 2008-10-08 22:24:47.000000000 -0400 +@@ -400,13 +400,14 @@ void free_swap_and_cache(swp_entry_t ent + p = swap_info_get(entry); + if (p) { + if (swap_entry_free(p, swp_offset(entry)) == 1) { ++ spin_unlock(&swap_lock); + page = find_get_page(&swapper_space, entry.val); + if (page && unlikely(TestSetPageLocked(page))) { + page_cache_release(page); + page = NULL; + } +- } +- spin_unlock(&swap_lock); ++ } else ++ spin_unlock(&swap_lock); + } + if (page) { + int one_user; --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0512-cpu-hotplug-vs-page-alloc.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0512-cpu-hotplug-vs-page-alloc.patch @@ -0,0 +1,81 @@ +Subject: cpu-hotplug: vs page_alloc +From: Peter Zijlstra +Date: Tue, 10 Jun 2008 13:13:01 +0200 + +On -rt we protect per-cpu state by locks instead of disabling preemption/irqs. +This keeps all the code preemptible at the cost of possible remote memory +access. + +The race was that cpu-hotplug - which assumes to be cpu local and non- +preemptible, didn't take the per-cpu lock. + +This also means that the normal lock acquire needs to be aware of cpus getting +off-lined while its waiting. + +Signed-off-by: Peter Zijlstra +Cc: Steven Rostedt +Cc: Clark Williams +Cc: Gregory Haskins +Cc: "Paul E. McKenney" +Cc: Gautham R Shenoy +Cc: Pekka Enberg +Cc: Arnaldo Carvalho de Melo +Cc: Peter Zijlstra +Signed-off-by: Thomas Gleixner +--- + mm/page_alloc.c | 24 +++++++++++++++++++++--- + 1 file changed, 21 insertions(+), 3 deletions(-) + +Index: linux-2.6.24.7-rt21/mm/page_alloc.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/mm/page_alloc.c 2008-10-08 22:24:39.000000000 -0400 ++++ linux-2.6.24.7-rt21/mm/page_alloc.c 2008-10-08 22:25:07.000000000 -0400 +@@ -176,7 +176,19 @@ static inline void __lock_cpu_pcp(unsign + static inline void lock_cpu_pcp(unsigned long *flags, int *this_cpu) + { + #ifdef CONFIG_PREEMPT_RT +- (void)get_cpu_var_locked(pcp_locks, this_cpu); ++ spinlock_t *lock; ++ int cpu; ++ ++again: ++ cpu = raw_smp_processor_id(); ++ lock = &__get_cpu_lock(pcp_locks, cpu); ++ ++ spin_lock(lock); ++ if (unlikely(!cpu_online(cpu))) { ++ spin_unlock(lock); ++ goto again; ++ } ++ *this_cpu = cpu; + flags = 0; + #else + local_irq_save(*flags); +@@ -2781,12 +2793,17 @@ static inline void free_zone_pagesets(in + struct zone *zone; + + for_each_zone(zone) { +- struct per_cpu_pageset *pset = zone_pcp(zone, cpu); ++ struct per_cpu_pageset *pset; ++ unsigned long flags; ++ ++ __lock_cpu_pcp(&flags, cpu); ++ pset = zone_pcp(zone, cpu); ++ zone_pcp(zone, cpu) = NULL; ++ unlock_cpu_pcp(flags, cpu); + + /* Free per_cpu_pageset if it is slab allocated */ + if (pset != &boot_pageset[cpu]) + kfree(pset); +- zone_pcp(zone, cpu) = NULL; + } + } + +@@ -2812,6 +2829,7 @@ static int __cpuinit pageset_cpuup_callb + default: + break; + } ++ + return ret; + } + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0135-arm-preempt-config.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0135-arm-preempt-config.patch @@ -0,0 +1,27 @@ + arch/arm/Kconfig | 13 +------------ + 1 file changed, 1 insertion(+), 12 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/arm/Kconfig +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/arm/Kconfig 2008-10-08 22:23:23.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/arm/Kconfig 2008-10-08 22:23:29.000000000 -0400 +@@ -622,18 +622,7 @@ config LOCAL_TIMERS + accounting to be spread across the timer interval, preventing a + "thundering herd" at every timer tick. + +-config PREEMPT +- bool "Preemptible Kernel (EXPERIMENTAL)" +- depends on EXPERIMENTAL +- help +- This option reduces the latency of the kernel when reacting to +- real-time or interactive events by allowing a low priority process to +- be preempted even if it is in kernel mode executing a system call. +- This allows applications to run more reliably even when the system is +- under load. +- +- Say Y here if you are building a kernel for a desktop, embedded +- or real-time system. Say N if you are unsure. ++source kernel/Kconfig.preempt + + config NO_IDLE_HZ + bool "Dynamic tick timer" --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0134-arm-futex-atomic-cmpxchg.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0134-arm-futex-atomic-cmpxchg.patch @@ -0,0 +1,156 @@ +Implement futex macros for ARM + +Signed-off-by: Khem Raj +Signed-off-by: Nicolas Pitre +Signed-off-by: George Davis + + arch/arm/kernel/process.c | 2 + include/asm-arm/futex.h | 125 ++++++++++++++++++++++++++++++++++++++++++++-- + 2 files changed, 124 insertions(+), 3 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/arm/kernel/process.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/arm/kernel/process.c 2008-10-08 22:22:39.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/arm/kernel/process.c 2008-10-08 22:23:29.000000000 -0400 +@@ -37,6 +37,8 @@ + #include + #include + ++DEFINE_SPINLOCK(futex_atomic_lock); ++ + static const char *processor_modes[] = { + "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" , + "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26", +Index: linux-2.6.24.7-rt21/include/asm-arm/futex.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-arm/futex.h 2008-10-08 22:22:39.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-arm/futex.h 2008-10-08 22:23:29.000000000 -0400 +@@ -1,6 +1,125 @@ +-#ifndef _ASM_FUTEX_H +-#define _ASM_FUTEX_H ++#ifndef _ASM_ARM_FUTEX_H ++#define _ASM_ARM_FUTEX_H + +-#include ++#ifdef __KERNEL__ + ++#include ++#include ++#include ++ ++extern spinlock_t futex_atomic_lock; ++ ++#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \ ++ __asm__ __volatile__ ( \ ++ "1: ldrt %1, [%2] \n" \ ++ insn \ ++ "2: strt %0, [%2] \n" \ ++ " mov %0, #0 \n" \ ++ "3: \n" \ ++ " .section __ex_table, \"a\" \n" \ ++ " .align 3 \n" \ ++ " .long 1b, 4f, 2b, 4f \n" \ ++ " .previous \n" \ ++ " .section .fixup,\"ax\" \n" \ ++ "4: mov %0, %4 \n" \ ++ " b 3b \n" \ ++ " .previous" \ ++ : "=&r" (ret), "=&r" (oldval) \ ++ : "r" (uaddr), "r" (oparg), "Ir" (-EFAULT) \ ++ : "cc", "memory") ++ ++static inline int ++futex_atomic_op_inuser (int encoded_op, int __user *uaddr) ++{ ++ int op = (encoded_op >> 28) & 7; ++ int cmp = (encoded_op >> 24) & 15; ++ int oparg = (encoded_op << 8) >> 20; ++ int cmparg = (encoded_op << 20) >> 20; ++ int oldval = 0, ret; ++ if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) ++ oparg = 1 << oparg; ++ ++ if (!access_ok (VERIFY_WRITE, uaddr, sizeof(int))) ++ return -EFAULT; ++ ++ pagefault_disable(); ++ ++ spin_lock(&futex_atomic_lock); ++ ++ switch (op) { ++ case FUTEX_OP_SET: ++ __futex_atomic_op(" mov %0, %3\n", ++ ret, oldval, uaddr, oparg); ++ break; ++ case FUTEX_OP_ADD: ++ __futex_atomic_op(" add %0, %1, %3\n", ++ ret, oldval, uaddr, oparg); ++ break; ++ case FUTEX_OP_OR: ++ __futex_atomic_op(" orr %0, %1, %3\n", ++ ret, oldval, uaddr, oparg); ++ break; ++ case FUTEX_OP_ANDN: ++ __futex_atomic_op(" and %0, %1, %3\n", ++ ret, oldval, uaddr, oparg); ++ break; ++ case FUTEX_OP_XOR: ++ __futex_atomic_op(" eor %0, %1, %3\n", ++ ret, oldval, uaddr, oparg); ++ break; ++ default: ++ ret = -ENOSYS; ++ } ++ ++ spin_unlock(&futex_atomic_lock); ++ ++ pagefault_enable(); ++ ++ if (!ret) { ++ switch (cmp) { ++ case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; ++ case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; ++ case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; ++ case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; ++ case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; ++ case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; ++ default: ret = -ENOSYS; ++ } ++ } ++ return ret; ++} ++ ++static inline int ++futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) ++{ ++ int val; ++ ++ if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) ++ return -EFAULT; ++ ++ spin_lock(&futex_atomic_lock); ++ ++ __asm__ __volatile__( "@futex_atomic_cmpxchg_inatomic \n" ++ "1: ldrt %0, [%3] \n" ++ " teq %0, %1 \n" ++ "2: streqt %2, [%3] \n" ++ "3: \n" ++ " .section __ex_table, \"a\" \n" ++ " .align 3 \n" ++ " .long 1b, 4f, 2b, 4f \n" ++ " .previous \n" ++ " .section .fixup,\"ax\" \n" ++ "4: mov %0, %4 \n" ++ " b 3b \n" ++ " .previous" ++ : "=&r" (val) ++ : "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT) ++ : "cc"); ++ ++ spin_unlock(&futex_atomic_lock); ++ ++ return val; ++} ++ ++#endif + #endif --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0321-only-run-softirqs-from-irq-thread-when-irq-affinity-is-set.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0321-only-run-softirqs-from-irq-thread-when-irq-affinity-is-set.patch @@ -0,0 +1,168 @@ +From linux-rt-users-owner@vger.kernel.org Wed Aug 8 22:43:28 2007 +Return-Path: +X-Spam-Checker-Version: SpamAssassin 3.1.7-deb (2006-10-05) on debian +X-Spam-Level: +X-Spam-Status: No, score=0.0 required=5.0 tests=AWL autolearn=unavailable + version=3.1.7-deb +Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by + mail.tglx.de (Postfix) with ESMTP id 6193665C3D9; Wed, 8 Aug 2007 22:43:28 + +0200 (CEST) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id + S1755519AbXHHUn0 (ORCPT + 1 other); + Wed, 8 Aug 2007 16:43:26 -0400 +Received: (majordomo@vger.kernel.org) by vger.kernel.org id + S1755399AbXHHUn0 (ORCPT ); Wed, 8 Aug 2007 + 16:43:26 -0400 +Received: from ms-smtp-03.nyroc.rr.com ([24.24.2.57]:59763 "EHLO + ms-smtp-03.nyroc.rr.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with + ESMTP id S1754194AbXHHUnY (ORCPT ); + Wed, 8 Aug 2007 16:43:24 -0400 +Received: from gandalf.stny.rr.com (cpe-24-94-51-176.stny.res.rr.com + [24.94.51.176]) by ms-smtp-03.nyroc.rr.com (8.13.6/8.13.6) with ESMTP id + l78KgX4S011873; Wed, 8 Aug 2007 16:42:33 -0400 (EDT) +Received: from localhost ([127.0.0.1] ident=rostedt) by gandalf.stny.rr.com + with esmtp (Exim 4.67) (envelope-from ) id + 1IIsMT-0003mx-ET; Wed, 08 Aug 2007 16:42:33 -0400 +Subject: [PATCH RT] Only run softirqs from the irq thread if the irq + affinity is set to 1 CPU +From: Steven Rostedt +To: Ingo Molnar +Cc: RT , LKML , Thomas Gleixner , john stultz +Content-Type: text/plain +Date: Wed, 08 Aug 2007 16:42:32 -0400 +Message-Id: <1186605752.29097.18.camel@localhost.localdomain> +Mime-Version: 1.0 +X-Mailer: Evolution 2.10.2 +X-Virus-Scanned: Symantec AntiVirus Scan Engine +Sender: linux-rt-users-owner@vger.kernel.org +Precedence: bulk +X-Mailing-List: linux-rt-users@vger.kernel.org +X-Filter-To: .Kernel.rt-users +X-Evolution-Source: imap://tglx%40linutronix.de@localhost:8993/ +Content-Transfer-Encoding: 8bit + +Ingo and Thomas, + +John and I have been discussing all the "run softirq from IRQ thread" +lately and discovered something nasty. + +Now it is a nice optimization to run softirqs from the IRQ thread, but +it may not be feasible because of the semantics of the IRQ thread +compared with the softirq thread. Namely, the softirq thread is bound to +a single CPU and the IRQ thread is not. + +We use to think that it would be fine to simply bind an IRQ thread to a +single CPU, either at the start of the IRQ thread code, or just while it +is running the softirq code. But this has a major flaw as John Stultz +discovered. + +If a RT hog that is of higher priority than the IRQ thread preempts the +IRQ thread while it is bound to the CPU (more likely with the latest +code that always binds the IRQ thread to 1 CPU), then that IRQ is, in +essence, masked. That means no more actions will be taken place by that +IRQ while the RT thread is running. Normally, one would expect, that if +the IRQ has its affinity set to all CPUS, if a RT thread were to preempt +the IRQ thread and run for a long time, it would be expected that the +IRQ thread would migrate to another CPU and finish. Letting more +interrupts from the IRQ line in (remember that the IRQ line is masked +until the IRQ finishes its handler). + +This patch will only run the softirq functions if the IRQ thread and the +softirq thread have the same priority **and** the IRQ thread is already +bound to a single CPU. If we are running on UP or the IRQ thread is +bound to a single CPU, we already have the possibility of having a RT +hog starve the IRQ. But we should not add that scenario when the IRQ +thread has its affinity set to run on other CPUS that don't have RT hogs +on them. + +Signed-off-by: Steven Rostedt + +--- + kernel/irq/manage.c | 32 +++++++++++++++++++++----------- + kernel/softirq.c | 9 ++++++++- + 2 files changed, 29 insertions(+), 12 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/irq/manage.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/irq/manage.c 2008-10-08 22:24:21.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/irq/manage.c 2008-10-08 22:24:21.000000000 -0400 +@@ -775,17 +775,28 @@ static int do_irqd(void * __desc) + { + struct sched_param param = { 0, }; + struct irq_desc *desc = __desc; ++ int run_softirq = 1; + + #ifdef CONFIG_SMP +- cpumask_t cpus_allowed, mask; ++ cpumask_t cpus_allowed; + + cpus_allowed = desc->affinity; + /* +- * Restrict it to one cpu so we avoid being migrated inside of +- * do_softirq_from_hardirq() ++ * If the irqd is bound to one CPU we let it run softirqs ++ * that have the same priority as the irqd thread. We do ++ * not run it if the irqd is bound to more than one CPU ++ * due to the fact that it can ++ * 1) migrate to other CPUS while running the softirqd ++ * 2) if we pin the irqd to a CPU to run the softirqd, then ++ * we risk a high priority process from waking up and ++ * preempting the irqd. Although the irqd may be able to ++ * run on other CPUS due to its irq affinity, it will not ++ * be able to since we bound it to a CPU to run softirqs. ++ * So a RT hog could starve the irqd from running on ++ * other CPUS that it's allowed to run on. + */ +- mask = cpumask_of_cpu(first_cpu(desc->affinity)); +- set_cpus_allowed(current, mask); ++ if (cpus_weight(cpus_allowed) != 1) ++ run_softirq = 0; /* turn it off */ + #endif + current->flags |= PF_NOFREEZE | PF_HARDIRQ; + +@@ -801,7 +812,8 @@ static int do_irqd(void * __desc) + do { + set_current_state(TASK_INTERRUPTIBLE); + do_hardirq(desc); +- do_softirq_from_hardirq(); ++ if (run_softirq) ++ do_softirq_from_hardirq(); + } while (current->state == TASK_RUNNING); + + local_irq_enable_nort(); +@@ -812,12 +824,10 @@ static int do_irqd(void * __desc) + if (!cpus_equal(cpus_allowed, desc->affinity)) { + cpus_allowed = desc->affinity; + /* +- * Restrict it to one cpu so we avoid being +- * migrated inside of +- * do_softirq_from_hardirq() ++ * Only allow the irq thread to run the softirqs ++ * if it is bound to a single CPU. + */ +- mask = cpumask_of_cpu(first_cpu(desc->affinity)); +- set_cpus_allowed(current, mask); ++ run_softirq = (cpus_weight(cpus_allowed) == 1); + } + #endif + schedule(); +Index: linux-2.6.24.7-rt21/kernel/softirq.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/softirq.c 2008-10-08 22:24:20.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/softirq.c 2008-10-08 22:24:21.000000000 -0400 +@@ -114,7 +114,14 @@ static void wakeup_softirqd(int softirq) + * context processing it later on. + */ + if ((current->flags & PF_HARDIRQ) && !hardirq_count() && +- (tsk->normal_prio == current->normal_prio)) ++ (tsk->normal_prio == current->normal_prio) && ++ /* ++ * The hard irq thread must be bound to a single CPU to run ++ * a softirq. Don't worry about locking, the irq thread ++ * should be the only one to modify the cpus_allowed, when ++ * the irq affinity changes. ++ */ ++ (cpus_weight(current->cpus_allowed) == 1)) + return; + #endif + /* --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0154-preempt-irqs-ppc-fix-b5.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0154-preempt-irqs-ppc-fix-b5.patch @@ -0,0 +1,42 @@ + + To fix the following boot time error by removing ack member added by +the rt patch. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Processor 1 found. +Brought up 2 CPUs +------------[ cut here ]------------ +kernel BUG at arch/powerpc/platforms/cell/interrupt.c:86! +pu 0x1: Vector: 700 (Program Check) at [c00000000fff3c80] + pc: c000000000033f9c: .iic_eoi+0x58/0x64 + lr: c00000000009add8: .handle_percpu_irq+0xd4/0xf4 + sp: c00000000fff3f00 + msr: 9000000000021032 + current = 0xc000000000fee040 + paca = 0xc000000000509e80 + pid = 0, comm = swapper +kernel BUG at arch/powerpc/platforms/cell/interrupt.c:86! +enter ? for help +[link register ] c00000000009add8 .handle_percpu_irq+0xd4/0xf4 +[c00000000fff3f00] c00000000009ada8 .handle_percpu_irq+0xa4/0xf4 (unreliable) +[c00000000fff3f90] c000000000023bb8 .call_handle_irq+0x1c/0x2c +[c000000000ff7950] c00000000000c910 .do_IRQ+0xf8/0x1b8 +[c000000000ff79f0] c000000000034f34 .cbe_system_reset_exception+0x74/0xb4 +[c000000000ff7a70] c000000000022610 .system_reset_exception+0x40/0xe0 +[c000000000ff7af0] c000000000003378 system_reset_common+0xf8/0x100 +--- + arch/powerpc/platforms/cell/interrupt.c | 1 - + 1 file changed, 1 deletion(-) + +Index: linux-2.6.24.7-rt21/arch/powerpc/platforms/cell/interrupt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/platforms/cell/interrupt.c 2008-10-08 22:23:33.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/platforms/cell/interrupt.c 2008-10-08 22:23:34.000000000 -0400 +@@ -90,7 +90,6 @@ static struct irq_chip iic_chip = { + .typename = " CELL-IIC ", + .mask = iic_mask, + .unmask = iic_unmask, +- .ack = iic_eoi, + .eoi = iic_eoi, + }; + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0535-sched-fix-dequeued-race.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0535-sched-fix-dequeued-race.patch @@ -0,0 +1,22 @@ +Subject: sched-fix-dequeued-race.patch +From: Thomas Gleixner +Date: Thu, 24 Jul 2008 16:14:31 +0200 + +Signed-off-by: Thomas Gleixner +--- + kernel/sched.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/kernel/sched.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched.c 2008-10-08 22:25:10.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched.c 2008-10-08 22:25:12.000000000 -0400 +@@ -3769,7 +3769,7 @@ void scheduler_tick(void) + rq->clock = next_tick; + rq->tick_timestamp = rq->clock; + update_cpu_load(rq); +- if (curr != rq->idle) /* FIXME: needed? */ ++ if (curr != rq->idle && curr->se.on_rq) + curr->sched_class->task_tick(rq, curr); + spin_unlock(&rq->lock); + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0489-sched-fix-sched-fair-wakeup.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0489-sched-fix-sched-fair-wakeup.patch @@ -0,0 +1,48 @@ +From ghaskins@novell.com Tue May 27 21:24:41 2008 +Date: Tue, 27 May 2008 18:59:39 -0600 +From: Gregory Haskins +To: Steven Rostedt , linux-rt-users@vger.kernel.org +Cc: linux-kernel@vger.kernel.org, Ingo Molnar , + Thomas Gleixner , + Gregory Haskins +Subject: [PATCH 2/3] sched: fix SCHED_FAIR wake-idle logic error + + [ The following text is in the "utf-8" character set. ] + [ Your display is set for the "iso-8859-1" character set. ] + [ Some characters may be displayed incorrectly. ] + +We currently use an optimization to skip the overhead of wake-idle + +processing if more than one task is assigned to a run-queue. The +assumption is that the system must already be load-balanced or we +wouldnt be overloaded to begin with. + +The problem is that we are looking at rq->nr_running, which may include +RT tasks in addition to CFS tasks. Since the presence of RT tasks +really has no bearing on the balance status of CFS tasks, this throws +the calculation off. + +This patch changes the logic to only consider the number of CFS tasks +when making the decision to optimze the wake-idle. + +Signed-off-by: Gregory Haskins +CC: Peter Zijlstra +Signed-off-by: Ingo Molnar +--- + + kernel/sched_fair.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/kernel/sched_fair.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched_fair.c 2008-10-08 22:24:55.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched_fair.c 2008-10-08 22:25:01.000000000 -0400 +@@ -858,7 +858,7 @@ static int wake_idle(int cpu, struct tas + * sibling runqueue info. This will avoid the checks and cache miss + * penalities associated with that. + */ +- if (idle_cpu(cpu) || cpu_rq(cpu)->nr_running > 1) ++ if (idle_cpu(cpu) || cpu_rq(cpu)->cfs.nr_running > 1) + return cpu; + + for_each_domain(cpu, sd) { --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0480-x86-fifo-ticket-spinlocks.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0480-x86-fifo-ticket-spinlocks.patch @@ -0,0 +1,686 @@ +x86: FIFO ticket spinlocks + +From: Nick Piggin + +Introduce ticket lock spinlocks for x86 which are FIFO. The implementation +is described in the comments. The straight-line lock/unlock instruction +sequence is slightly slower than the dec based locks on modern x86 CPUs, +however the difference is quite small on Core2 and Opteron when working out of +cache, and becomes almost insignificant even on P4 when the lock misses cache. +trylock is more significantly slower, but they are relatively rare. + +On an 8 core (2 socket) Opteron, spinlock unfairness is extremely noticable, +with a userspace test having a difference of up to 2x runtime per thread, and +some threads are starved or "unfairly" granted the lock up to 1 000 000 (!) +times. After this patch, all threads appear to finish at exactly the same +time. + +The memory ordering of the lock does conform to x86 standards, and the +implementation has been reviewed by Intel and AMD engineers. + +The algorithm also tells us how many CPUs are contending the lock, so +lockbreak becomes trivial and we no longer have to waste 4 bytes per +spinlock for it. + +After this, we can no longer spin on any locks with preempt enabled +and cannot reenable interrupts when spinning on an irq safe lock, because +at that point we have already taken a ticket and the would deadlock if +the same CPU tries to take the lock again. These are questionable anyway: +if the lock happens to be called under a preempt or interrupt disabled section, +then it will just have the same latency problems. The real fix is to keep +critical sections short, and ensure locks are reasonably fair (which this +patch does). + +Signed-off-by: Nick Piggin +--- + + include/asm-x86/spinlock.h | 225 ++++++++++++++++++++++++++++++++++++++- + include/asm-x86/spinlock_32.h | 221 -------------------------------------- + include/asm-x86/spinlock_64.h | 167 ---------------------------- + include/asm-x86/spinlock_types.h | 2 + 4 files changed, 224 insertions(+), 391 deletions(-) + +Index: linux-2.6.24.7-rt21/include/asm-x86/spinlock.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/spinlock.h 2008-10-08 22:22:12.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/spinlock.h 2008-10-08 22:24:59.000000000 -0400 +@@ -1,5 +1,226 @@ ++#ifndef _X86_SPINLOCK_H_ ++#define _X86_SPINLOCK_H_ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * Your basic SMP spinlocks, allowing only a single CPU anywhere ++ * ++ * Simple spin lock operations. There are two variants, one clears IRQ's ++ * on the local processor, one does not. ++ * ++ * These are fair FIFO ticket locks, which are currently limited to 256 ++ * CPUs. ++ * ++ * (the type definitions are in asm/spinlock_types.h) ++ */ ++ + #ifdef CONFIG_X86_32 +-# include "spinlock_32.h" ++typedef char _slock_t; ++# define LOCK_INS_DEC "decb" ++# define LOCK_INS_XCH "xchgb" ++# define LOCK_INS_MOV "movb" ++# define LOCK_INS_CMP "cmpb" ++# define LOCK_PTR_REG "a" + #else +-# include "spinlock_64.h" ++typedef int _slock_t; ++# define LOCK_INS_DEC "decl" ++# define LOCK_INS_XCH "xchgl" ++# define LOCK_INS_MOV "movl" ++# define LOCK_INS_CMP "cmpl" ++# define LOCK_PTR_REG "D" ++#endif ++ ++#if (NR_CPUS > 256) ++#error spinlock supports a maximum of 256 CPUs ++#endif ++ ++static inline int __raw_spin_is_locked(__raw_spinlock_t *lock) ++{ ++ int tmp = *(volatile signed int *)(&(lock)->slock); ++ ++ return (((tmp >> 8) & 0xff) != (tmp & 0xff)); ++} ++ ++static inline int __raw_spin_is_contended(__raw_spinlock_t *lock) ++{ ++ int tmp = *(volatile signed int *)(&(lock)->slock); ++ ++ return (((tmp >> 8) & 0xff) - (tmp & 0xff)) > 1; ++} ++ ++static inline void __raw_spin_lock(__raw_spinlock_t *lock) ++{ ++ short inc = 0x0100; ++ ++ /* ++ * Ticket locks are conceptually two bytes, one indicating the current ++ * head of the queue, and the other indicating the current tail. The ++ * lock is acquired by atomically noting the tail and incrementing it ++ * by one (thus adding ourself to the queue and noting our position), ++ * then waiting until the head becomes equal to the the initial value ++ * of the tail. ++ * ++ * This uses a 16-bit xadd to increment the tail and also load the ++ * position of the head, which takes care of memory ordering issues ++ * and should be optimal for the uncontended case. Note the tail must ++ * be in the high byte, otherwise the 16-bit wide increment of the low ++ * byte would carry up and contaminate the high byte. ++ */ ++ ++ __asm__ __volatile__ ( ++ LOCK_PREFIX "xaddw %w0, %1\n" ++ "1:\t" ++ "cmpb %h0, %b0\n\t" ++ "je 2f\n\t" ++ "rep ; nop\n\t" ++ "movb %1, %b0\n\t" ++ /* don't need lfence here, because loads are in-order */ ++ "jmp 1b\n" ++ "2:" ++ :"+Q" (inc), "+m" (lock->slock) ++ : ++ :"memory", "cc"); ++} ++ ++#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) ++ ++static inline int __raw_spin_trylock(__raw_spinlock_t *lock) ++{ ++ int tmp; ++ short new; ++ ++ asm volatile( ++ "movw %2,%w0\n\t" ++ "cmpb %h0,%b0\n\t" ++ "jne 1f\n\t" ++ "movw %w0,%w1\n\t" ++ "incb %h1\n\t" ++ "lock ; cmpxchgw %w1,%2\n\t" ++ "1:" ++ "sete %b1\n\t" ++ "movzbl %b1,%0\n\t" ++ :"=&a" (tmp), "=Q" (new), "+m" (lock->slock) ++ : ++ : "memory", "cc"); ++ ++ return tmp; ++} ++ ++#if defined(CONFIG_X86_32) && \ ++ (defined(CONFIG_X86_OOSTORE) || defined(CONFIG_X86_PPRO_FENCE)) ++/* ++ * On PPro SMP or if we are using OOSTORE, we use a locked operation to unlock ++ * (PPro errata 66, 92) ++ */ ++# define UNLOCK_LOCK_PREFIX LOCK_PREFIX ++#else ++# define UNLOCK_LOCK_PREFIX ++#endif ++ ++static inline void __raw_spin_unlock(__raw_spinlock_t *lock) ++{ ++ __asm__ __volatile__( ++ UNLOCK_LOCK_PREFIX "incb %0" ++ :"+m" (lock->slock) ++ : ++ :"memory", "cc"); ++} ++ ++static inline void __raw_spin_unlock_wait(__raw_spinlock_t *lock) ++{ ++ while (__raw_spin_is_locked(lock)) ++ cpu_relax(); ++} ++ ++/* ++ * Read-write spinlocks, allowing multiple readers ++ * but only one writer. ++ * ++ * NOTE! it is quite common to have readers in interrupts ++ * but no interrupt writers. For those circumstances we ++ * can "mix" irq-safe locks - any writer needs to get a ++ * irq-safe write-lock, but readers can get non-irqsafe ++ * read-locks. ++ * ++ * On x86, we implement read-write locks as a 32-bit counter ++ * with the high bit (sign) being the "contended" bit. ++ */ ++ ++/** ++ * read_can_lock - would read_trylock() succeed? ++ * @lock: the rwlock in question. ++ */ ++static inline int __raw_read_can_lock(__raw_rwlock_t *lock) ++{ ++ return (int)(lock)->lock > 0; ++} ++ ++/** ++ * write_can_lock - would write_trylock() succeed? ++ * @lock: the rwlock in question. ++ */ ++static inline int __raw_write_can_lock(__raw_rwlock_t *lock) ++{ ++ return (lock)->lock == RW_LOCK_BIAS; ++} ++ ++static inline void __raw_read_lock(__raw_rwlock_t *rw) ++{ ++ asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t" ++ "jns 1f\n" ++ "call __read_lock_failed\n\t" ++ "1:\n" ++ ::LOCK_PTR_REG (rw) : "memory"); ++} ++ ++static inline void __raw_write_lock(__raw_rwlock_t *rw) ++{ ++ asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t" ++ "jz 1f\n" ++ "call __write_lock_failed\n\t" ++ "1:\n" ++ ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory"); ++} ++ ++static inline int __raw_read_trylock(__raw_rwlock_t *lock) ++{ ++ atomic_t *count = (atomic_t *)lock; ++ ++ atomic_dec(count); ++ if (atomic_read(count) >= 0) ++ return 1; ++ atomic_inc(count); ++ return 0; ++} ++ ++static inline int __raw_write_trylock(__raw_rwlock_t *lock) ++{ ++ atomic_t *count = (atomic_t *)lock; ++ ++ if (atomic_sub_and_test(RW_LOCK_BIAS, count)) ++ return 1; ++ atomic_add(RW_LOCK_BIAS, count); ++ return 0; ++} ++ ++static inline void __raw_read_unlock(__raw_rwlock_t *rw) ++{ ++ asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory"); ++} ++ ++static inline void __raw_write_unlock(__raw_rwlock_t *rw) ++{ ++ asm volatile(LOCK_PREFIX "addl %1, %0" ++ : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory"); ++} ++ ++#define _raw_spin_relax(lock) cpu_relax() ++#define _raw_read_relax(lock) cpu_relax() ++#define _raw_write_relax(lock) cpu_relax() ++ + #endif +Index: linux-2.6.24.7-rt21/include/asm-x86/spinlock_32.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/spinlock_32.h 2008-10-08 22:23:38.000000000 -0400 ++++ /dev/null 1970-01-01 00:00:00.000000000 +0000 +@@ -1,221 +0,0 @@ +-#ifndef __ASM_SPINLOCK_H +-#define __ASM_SPINLOCK_H +- +-#include +-#include +-#include +-#include +-#include +- +-#ifdef CONFIG_PARAVIRT +-#include +-#else +-#define CLI_STRING "cli" +-#define STI_STRING "sti" +-#define CLI_STI_CLOBBERS +-#define CLI_STI_INPUT_ARGS +-#endif /* CONFIG_PARAVIRT */ +- +-/* +- * Your basic SMP spinlocks, allowing only a single CPU anywhere +- * +- * Simple spin lock operations. There are two variants, one clears IRQ's +- * on the local processor, one does not. +- * +- * We make no fairness assumptions. They have a cost. +- * +- * (the type definitions are in asm/spinlock_types.h) +- */ +- +-static inline int __raw_spin_is_locked(__raw_spinlock_t *x) +-{ +- return *(volatile signed char *)(&(x)->slock) <= 0; +-} +- +-static inline void __raw_spin_lock(__raw_spinlock_t *lock) +-{ +- asm volatile("\n1:\t" +- LOCK_PREFIX " ; decb %0\n\t" +- "jns 3f\n" +- "2:\t" +- "rep;nop\n\t" +- "cmpb $0,%0\n\t" +- "jle 2b\n\t" +- "jmp 1b\n" +- "3:\n\t" +- : "+m" (lock->slock) : : "memory"); +-} +- +-/* +- * It is easier for the lock validator if interrupts are not re-enabled +- * in the middle of a lock-acquire. This is a performance feature anyway +- * so we turn it off: +- * +- * NOTE: there's an irqs-on section here, which normally would have to be +- * irq-traced, but on CONFIG_TRACE_IRQFLAGS we never use this variant. +- */ +-#ifndef CONFIG_PROVE_LOCKING +-static inline void __raw_spin_lock_flags(__raw_spinlock_t *lock, unsigned long flags) +-{ +- asm volatile( +- "\n1:\t" +- LOCK_PREFIX " ; decb %[slock]\n\t" +- "jns 5f\n" +- "2:\t" +- "testl $0x200, %[flags]\n\t" +- "jz 4f\n\t" +- STI_STRING "\n" +- "3:\t" +- "rep;nop\n\t" +- "cmpb $0, %[slock]\n\t" +- "jle 3b\n\t" +- CLI_STRING "\n\t" +- "jmp 1b\n" +- "4:\t" +- "rep;nop\n\t" +- "cmpb $0, %[slock]\n\t" +- "jg 1b\n\t" +- "jmp 4b\n" +- "5:\n\t" +- : [slock] "+m" (lock->slock) +- : [flags] "r" (flags) +- CLI_STI_INPUT_ARGS +- : "memory" CLI_STI_CLOBBERS); +-} +-#endif +- +-static inline int __raw_spin_trylock(__raw_spinlock_t *lock) +-{ +- char oldval; +- asm volatile( +- "xchgb %b0,%1" +- :"=q" (oldval), "+m" (lock->slock) +- :"0" (0) : "memory"); +- return oldval > 0; +-} +- +-/* +- * __raw_spin_unlock based on writing $1 to the low byte. +- * This method works. Despite all the confusion. +- * (except on PPro SMP or if we are using OOSTORE, so we use xchgb there) +- * (PPro errata 66, 92) +- */ +- +-#if !defined(CONFIG_X86_OOSTORE) && !defined(CONFIG_X86_PPRO_FENCE) +- +-static inline void __raw_spin_unlock(__raw_spinlock_t *lock) +-{ +- asm volatile("movb $1,%0" : "+m" (lock->slock) :: "memory"); +-} +- +-#else +- +-static inline void __raw_spin_unlock(__raw_spinlock_t *lock) +-{ +- char oldval = 1; +- +- asm volatile("xchgb %b0, %1" +- : "=q" (oldval), "+m" (lock->slock) +- : "0" (oldval) : "memory"); +-} +- +-#endif +- +-static inline void __raw_spin_unlock_wait(__raw_spinlock_t *lock) +-{ +- while (__raw_spin_is_locked(lock)) +- cpu_relax(); +-} +- +-/* +- * Read-write spinlocks, allowing multiple readers +- * but only one writer. +- * +- * NOTE! it is quite common to have readers in interrupts +- * but no interrupt writers. For those circumstances we +- * can "mix" irq-safe locks - any writer needs to get a +- * irq-safe write-lock, but readers can get non-irqsafe +- * read-locks. +- * +- * On x86, we implement read-write locks as a 32-bit counter +- * with the high bit (sign) being the "contended" bit. +- * +- * The inline assembly is non-obvious. Think about it. +- * +- * Changed to use the same technique as rw semaphores. See +- * semaphore.h for details. -ben +- * +- * the helpers are in arch/i386/kernel/semaphore.c +- */ +- +-/** +- * read_can_lock - would read_trylock() succeed? +- * @lock: the rwlock in question. +- */ +-static inline int __raw_read_can_lock(__raw_rwlock_t *x) +-{ +- return (int)(x)->lock > 0; +-} +- +-/** +- * write_can_lock - would write_trylock() succeed? +- * @lock: the rwlock in question. +- */ +-static inline int __raw_write_can_lock(__raw_rwlock_t *x) +-{ +- return (x)->lock == RW_LOCK_BIAS; +-} +- +-static inline void __raw_read_lock(__raw_rwlock_t *rw) +-{ +- asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t" +- "jns 1f\n" +- "call __read_lock_failed\n\t" +- "1:\n" +- ::"a" (rw) : "memory"); +-} +- +-static inline void __raw_write_lock(__raw_rwlock_t *rw) +-{ +- asm volatile(LOCK_PREFIX " subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" +- "jz 1f\n" +- "call __write_lock_failed\n\t" +- "1:\n" +- ::"a" (rw) : "memory"); +-} +- +-static inline int __raw_read_trylock(__raw_rwlock_t *lock) +-{ +- atomic_t *count = (atomic_t *)lock; +- atomic_dec(count); +- if (atomic_read(count) >= 0) +- return 1; +- atomic_inc(count); +- return 0; +-} +- +-static inline int __raw_write_trylock(__raw_rwlock_t *lock) +-{ +- atomic_t *count = (atomic_t *)lock; +- if (atomic_sub_and_test(RW_LOCK_BIAS, count)) +- return 1; +- atomic_add(RW_LOCK_BIAS, count); +- return 0; +-} +- +-static inline void __raw_read_unlock(__raw_rwlock_t *rw) +-{ +- asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory"); +-} +- +-static inline void __raw_write_unlock(__raw_rwlock_t *rw) +-{ +- asm volatile(LOCK_PREFIX "addl $" RW_LOCK_BIAS_STR ", %0" +- : "+m" (rw->lock) : : "memory"); +-} +- +-#define __raw_spin_relax(lock) cpu_relax() +-#define __raw_read_relax(lock) cpu_relax() +-#define __raw_write_relax(lock) cpu_relax() +- +-#endif /* __ASM_SPINLOCK_H */ +Index: linux-2.6.24.7-rt21/include/asm-x86/spinlock_64.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/spinlock_64.h 2008-10-08 22:23:51.000000000 -0400 ++++ /dev/null 1970-01-01 00:00:00.000000000 +0000 +@@ -1,167 +0,0 @@ +-#ifndef __ASM_SPINLOCK_H +-#define __ASM_SPINLOCK_H +- +-#include +-#include +-#include +-#include +- +-/* +- * Your basic SMP spinlocks, allowing only a single CPU anywhere +- * +- * Simple spin lock operations. There are two variants, one clears IRQ's +- * on the local processor, one does not. +- * +- * We make no fairness assumptions. They have a cost. +- * +- * (the type definitions are in asm/spinlock_types.h) +- */ +- +-static inline int __raw_spin_is_locked(__raw_spinlock_t *lock) +-{ +- return *(volatile signed int *)(&(lock)->slock) <= 0; +-} +- +-static inline void __raw_spin_lock(__raw_spinlock_t *lock) +-{ +- asm volatile( +- "\n1:\t" +- LOCK_PREFIX " ; decl %0\n\t" +- "jns 2f\n" +- "3:\n" +- "rep;nop\n\t" +- "cmpl $0,%0\n\t" +- "jle 3b\n\t" +- "jmp 1b\n" +- "2:\t" : "=m" (lock->slock) : : "memory"); +-} +- +-/* +- * Same as __raw_spin_lock, but reenable interrupts during spinning. +- */ +-#ifndef CONFIG_PROVE_LOCKING +-static inline void __raw_spin_lock_flags(__raw_spinlock_t *lock, unsigned long flags) +-{ +- asm volatile( +- "\n1:\t" +- LOCK_PREFIX " ; decl %0\n\t" +- "jns 5f\n" +- "testl $0x200, %1\n\t" /* interrupts were disabled? */ +- "jz 4f\n\t" +- "sti\n" +- "3:\t" +- "rep;nop\n\t" +- "cmpl $0, %0\n\t" +- "jle 3b\n\t" +- "cli\n\t" +- "jmp 1b\n" +- "4:\t" +- "rep;nop\n\t" +- "cmpl $0, %0\n\t" +- "jg 1b\n\t" +- "jmp 4b\n" +- "5:\n\t" +- : "+m" (lock->slock) : "r" ((unsigned)flags) : "memory"); +-} +-#endif +- +-static inline int __raw_spin_trylock(__raw_spinlock_t *lock) +-{ +- int oldval; +- +- asm volatile( +- "xchgl %0,%1" +- :"=q" (oldval), "=m" (lock->slock) +- :"0" (0) : "memory"); +- +- return oldval > 0; +-} +- +-static inline void __raw_spin_unlock(__raw_spinlock_t *lock) +-{ +- asm volatile("movl $1,%0" :"=m" (lock->slock) :: "memory"); +-} +- +-static inline void __raw_spin_unlock_wait(__raw_spinlock_t *lock) +-{ +- while (__raw_spin_is_locked(lock)) +- cpu_relax(); +-} +- +-/* +- * Read-write spinlocks, allowing multiple readers +- * but only one writer. +- * +- * NOTE! it is quite common to have readers in interrupts +- * but no interrupt writers. For those circumstances we +- * can "mix" irq-safe locks - any writer needs to get a +- * irq-safe write-lock, but readers can get non-irqsafe +- * read-locks. +- * +- * On x86, we implement read-write locks as a 32-bit counter +- * with the high bit (sign) being the "contended" bit. +- */ +- +-static inline int __raw_read_can_lock(__raw_rwlock_t *lock) +-{ +- return (int)(lock)->lock > 0; +-} +- +-static inline int __raw_write_can_lock(__raw_rwlock_t *lock) +-{ +- return (lock)->lock == RW_LOCK_BIAS; +-} +- +-static inline void __raw_read_lock(__raw_rwlock_t *rw) +-{ +- asm volatile(LOCK_PREFIX "subl $1,(%0)\n\t" +- "jns 1f\n" +- "call __read_lock_failed\n" +- "1:\n" +- ::"D" (rw), "i" (RW_LOCK_BIAS) : "memory"); +-} +- +-static inline void __raw_write_lock(__raw_rwlock_t *rw) +-{ +- asm volatile(LOCK_PREFIX "subl %1,(%0)\n\t" +- "jz 1f\n" +- "\tcall __write_lock_failed\n\t" +- "1:\n" +- ::"D" (rw), "i" (RW_LOCK_BIAS) : "memory"); +-} +- +-static inline int __raw_read_trylock(__raw_rwlock_t *lock) +-{ +- atomic_t *count = (atomic_t *)lock; +- atomic_dec(count); +- if (atomic_read(count) >= 0) +- return 1; +- atomic_inc(count); +- return 0; +-} +- +-static inline int __raw_write_trylock(__raw_rwlock_t *lock) +-{ +- atomic_t *count = (atomic_t *)lock; +- if (atomic_sub_and_test(RW_LOCK_BIAS, count)) +- return 1; +- atomic_add(RW_LOCK_BIAS, count); +- return 0; +-} +- +-static inline void __raw_read_unlock(__raw_rwlock_t *rw) +-{ +- asm volatile(LOCK_PREFIX " ; incl %0" :"=m" (rw->lock) : : "memory"); +-} +- +-static inline void __raw_write_unlock(__raw_rwlock_t *rw) +-{ +- asm volatile(LOCK_PREFIX " ; addl $" RW_LOCK_BIAS_STR ",%0" +- : "=m" (rw->lock) : : "memory"); +-} +- +-#define __raw_spin_relax(lock) cpu_relax() +-#define __raw_read_relax(lock) cpu_relax() +-#define __raw_write_relax(lock) cpu_relax() +- +-#endif /* __ASM_SPINLOCK_H */ +Index: linux-2.6.24.7-rt21/include/asm-x86/spinlock_types.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/spinlock_types.h 2008-10-08 22:23:38.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/spinlock_types.h 2008-10-08 22:24:59.000000000 -0400 +@@ -9,7 +9,7 @@ typedef struct { + unsigned int slock; + } __raw_spinlock_t; + +-#define __RAW_SPIN_LOCK_UNLOCKED { 1 } ++#define __RAW_SPIN_LOCK_UNLOCKED { 0 } + + typedef struct { + unsigned int lock; --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0199-cputimer-thread-rt_A0.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0199-cputimer-thread-rt_A0.patch @@ -0,0 +1,306 @@ +Ingo, + This patch re-adds the posix-cpu-timer functionality by running it from +a per-cpu RT thread. This allows cpu rlimits to be enforced against RT +processes that would otherwise starve the system. + +thanks +-john + +Signed-off-by: John Stultz + + include/linux/init_task.h | 1 + include/linux/posix-timers.h | 2 + include/linux/sched.h | 2 + init/main.c | 2 + kernel/fork.c | 2 + kernel/posix-cpu-timers.c | 176 ++++++++++++++++++++++++++++++++++++++++++- + 6 files changed, 180 insertions(+), 5 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/init_task.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/init_task.h 2008-10-08 22:23:37.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/init_task.h 2008-10-08 22:23:46.000000000 -0400 +@@ -166,6 +166,7 @@ extern struct group_info init_groups; + .journal_info = NULL, \ + .cpu_timers = INIT_CPU_TIMERS(tsk.cpu_timers), \ + .fs_excl = ATOMIC_INIT(0), \ ++ .posix_timer_list = NULL, \ + .pi_lock = RAW_SPIN_LOCK_UNLOCKED(tsk.pi_lock), \ + .pids = { \ + [PIDTYPE_PID] = INIT_PID_LINK(PIDTYPE_PID), \ +Index: linux-2.6.24.7-rt21/include/linux/posix-timers.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/posix-timers.h 2008-10-08 22:22:33.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/posix-timers.h 2008-10-08 22:23:46.000000000 -0400 +@@ -115,4 +115,6 @@ void set_process_cpu_timer(struct task_s + + long clock_nanosleep_restart(struct restart_block *restart_block); + ++int posix_cpu_thread_init(void); ++ + #endif +Index: linux-2.6.24.7-rt21/include/linux/sched.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/sched.h 2008-10-08 22:23:37.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/sched.h 2008-10-08 22:23:46.000000000 -0400 +@@ -1070,6 +1070,8 @@ struct task_struct { + unsigned long long it_sched_expires; + struct list_head cpu_timers[3]; + ++ struct task_struct* posix_timer_list; ++ + /* process credentials */ + uid_t uid,euid,suid,fsuid; + gid_t gid,egid,sgid,fsgid; +Index: linux-2.6.24.7-rt21/init/main.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/init/main.c 2008-10-08 22:23:36.000000000 -0400 ++++ linux-2.6.24.7-rt21/init/main.c 2008-10-08 22:23:46.000000000 -0400 +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -753,6 +754,7 @@ static void __init do_pre_smp_initcalls( + extern int spawn_ksoftirqd(void); + + migration_init(); ++ posix_cpu_thread_init(); + spawn_ksoftirqd(); + if (!nosoftlockup) + spawn_softlockup_task(); +Index: linux-2.6.24.7-rt21/kernel/fork.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/fork.c 2008-10-08 22:23:37.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/fork.c 2008-10-08 22:23:46.000000000 -0400 +@@ -1081,7 +1081,7 @@ static struct task_struct *copy_process( + INIT_LIST_HEAD(&p->cpu_timers[0]); + INIT_LIST_HEAD(&p->cpu_timers[1]); + INIT_LIST_HEAD(&p->cpu_timers[2]); +- ++ p->posix_timer_list = NULL; + p->lock_depth = -1; /* -1 = no lock */ + do_posix_clock_monotonic_gettime(&p->start_time); + p->real_start_time = p->start_time; +Index: linux-2.6.24.7-rt21/kernel/posix-cpu-timers.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/posix-cpu-timers.c 2008-10-08 22:22:33.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/posix-cpu-timers.c 2008-10-08 22:23:46.000000000 -0400 +@@ -578,7 +578,7 @@ static void arm_timer(struct k_itimer *t + p->cpu_timers : p->signal->cpu_timers); + head += CPUCLOCK_WHICH(timer->it_clock); + +- BUG_ON(!irqs_disabled()); ++ BUG_ON_NONRT(!irqs_disabled()); + spin_lock(&p->sighand->siglock); + + listpos = head; +@@ -735,7 +735,7 @@ int posix_cpu_timer_set(struct k_itimer + /* + * Disarm any old timer after extracting its expiry time. + */ +- BUG_ON(!irqs_disabled()); ++ BUG_ON_NONRT(!irqs_disabled()); + + ret = 0; + spin_lock(&p->sighand->siglock); +@@ -1287,12 +1287,11 @@ out: + * already updated our counts. We need to check if any timers fire now. + * Interrupts are disabled. + */ +-void run_posix_cpu_timers(struct task_struct *tsk) ++void __run_posix_cpu_timers(struct task_struct *tsk) + { + LIST_HEAD(firing); + struct k_itimer *timer, *next; + +- BUG_ON(!irqs_disabled()); + + #define UNEXPIRED(clock) \ + (cputime_eq(tsk->it_##clock##_expires, cputime_zero) || \ +@@ -1355,6 +1354,169 @@ void run_posix_cpu_timers(struct task_st + } + } + ++#include ++#include ++DEFINE_PER_CPU(struct task_struct *, posix_timer_task); ++DEFINE_PER_CPU(struct task_struct *, posix_timer_tasklist); ++ ++static int posix_cpu_timers_thread(void *data) ++{ ++ int cpu = (long)data; ++ ++ BUG_ON(per_cpu(posix_timer_task,cpu) != current); ++ ++ ++ while (!kthread_should_stop()) { ++ struct task_struct *tsk = NULL; ++ struct task_struct *next = NULL; ++ ++ if (cpu_is_offline(cpu)) { ++ goto wait_to_die; ++ } ++ ++ /* grab task list */ ++ raw_local_irq_disable(); ++ tsk = per_cpu(posix_timer_tasklist, cpu); ++ per_cpu(posix_timer_tasklist, cpu) = NULL; ++ raw_local_irq_enable(); ++ ++ ++ /* its possible the list is empty, just return */ ++ if (!tsk) { ++ set_current_state(TASK_INTERRUPTIBLE); ++ schedule(); ++ __set_current_state(TASK_RUNNING); ++ continue; ++ } ++ ++ /* Process task list */ ++ while (1) { ++ /* save next */ ++ next = tsk->posix_timer_list; ++ ++ /* run the task timers, clear its ptr and ++ * unreference it ++ */ ++ __run_posix_cpu_timers(tsk); ++ tsk->posix_timer_list = NULL; ++ put_task_struct(tsk); ++ ++ /* check if this is the last on the list */ ++ if (next == tsk) ++ break; ++ tsk = next; ++ } ++ } ++ return 0; ++ ++wait_to_die: ++ /* Wait for kthread_stop */ ++ set_current_state(TASK_INTERRUPTIBLE); ++ while (!kthread_should_stop()) { ++ schedule(); ++ set_current_state(TASK_INTERRUPTIBLE); ++ } ++ __set_current_state(TASK_RUNNING); ++ return 0; ++} ++ ++void run_posix_cpu_timers(struct task_struct *tsk) ++{ ++ unsigned long cpu = smp_processor_id(); ++ struct task_struct *tasklist; ++ ++ BUG_ON(!irqs_disabled()); ++ if(!per_cpu(posix_timer_task, cpu)) ++ return; ++ /* get per-cpu references */ ++ tasklist = per_cpu(posix_timer_tasklist, cpu); ++ ++ /* check to see if we're already queued */ ++ if (!tsk->posix_timer_list) { ++ get_task_struct(tsk); ++ if (tasklist) { ++ tsk->posix_timer_list = tasklist; ++ } else { ++ /* ++ * The list is terminated by a self-pointing ++ * task_struct ++ */ ++ tsk->posix_timer_list = tsk; ++ } ++ per_cpu(posix_timer_tasklist, cpu) = tsk; ++ } ++ /* XXX signal the thread somehow */ ++ wake_up_process(per_cpu(posix_timer_task,cpu)); ++} ++ ++ ++ ++ ++/* ++ * posix_cpu_thread_call - callback that gets triggered when a CPU is added. ++ * Here we can start up the necessary migration thread for the new CPU. ++ */ ++static int posix_cpu_thread_call(struct notifier_block *nfb, unsigned long action, ++ void *hcpu) ++{ ++ int cpu = (long)hcpu; ++ struct task_struct *p; ++ struct sched_param param; ++ ++ switch (action) { ++ case CPU_UP_PREPARE: ++ p = kthread_create(posix_cpu_timers_thread, hcpu, ++ "posix_cpu_timers/%d",cpu); ++ if (IS_ERR(p)) ++ return NOTIFY_BAD; ++ p->flags |= PF_NOFREEZE; ++ kthread_bind(p, cpu); ++ /* Must be high prio to avoid getting starved */ ++ param.sched_priority = MAX_RT_PRIO-1; ++ sched_setscheduler(p, SCHED_FIFO, ¶m); ++ per_cpu(posix_timer_task,cpu) = p; ++ break; ++ case CPU_ONLINE: ++ /* Strictly unneccessary, as first user will wake it. */ ++ wake_up_process(per_cpu(posix_timer_task,cpu)); ++ break; ++#ifdef CONFIG_HOTPLUG_CPU ++ case CPU_UP_CANCELED: ++ /* Unbind it from offline cpu so it can run. Fall thru. */ ++ kthread_bind(per_cpu(posix_timer_task,cpu), ++ any_online_cpu(cpu_online_map)); ++ kthread_stop(per_cpu(posix_timer_task,cpu)); ++ per_cpu(posix_timer_task,cpu) = NULL; ++ break; ++ case CPU_DEAD: ++ kthread_stop(per_cpu(posix_timer_task,cpu)); ++ per_cpu(posix_timer_task,cpu) = NULL; ++ break; ++#endif ++ } ++ return NOTIFY_OK; ++} ++ ++/* Register at highest priority so that task migration (migrate_all_tasks) ++ * happens before everything else. ++ */ ++static struct notifier_block __devinitdata posix_cpu_thread_notifier = { ++ .notifier_call = posix_cpu_thread_call, ++ .priority = 10 ++}; ++ ++int __init posix_cpu_thread_init(void) ++{ ++ void *cpu = (void *)(long)smp_processor_id(); ++ /* Start one for boot CPU. */ ++ posix_cpu_thread_call(&posix_cpu_thread_notifier, CPU_UP_PREPARE, cpu); ++ posix_cpu_thread_call(&posix_cpu_thread_notifier, CPU_ONLINE, cpu); ++ register_cpu_notifier(&posix_cpu_thread_notifier); ++ return 0; ++} ++ ++ ++ + /* + * Set one of the process-wide special case CPU timers. + * The tasklist_lock and tsk->sighand->siglock must be held by the caller. +@@ -1620,6 +1782,12 @@ static __init int init_posix_cpu_timers( + .nsleep = thread_cpu_nsleep, + .nsleep_restart = thread_cpu_nsleep_restart, + }; ++ unsigned long cpu; ++ ++ /* init the per-cpu posix_timer_tasklets */ ++ for_each_cpu_mask(cpu, cpu_possible_map) { ++ per_cpu(posix_timer_tasklist, cpu) = NULL; ++ } + + register_posix_clock(CLOCK_PROCESS_CPUTIME_ID, &process); + register_posix_clock(CLOCK_THREAD_CPUTIME_ID, &thread); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0386-ntfs-local-irq-save-nort.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0386-ntfs-local-irq-save-nort.patch @@ -0,0 +1,63 @@ +From efault@gmx.de Sat Oct 27 10:28:42 2007 +Date: Sat, 27 Oct 2007 12:17:49 +0200 +From: Mike Galbraith +To: Ingo Molnar +Cc: Nick Piggin , Steven Rostedt , + LKML , RT , + Thomas Gleixner +Subject: Re: [2.6.23-rt3] NMI watchdog trace of deadlock + +On Sat, 2007-10-27 at 11:44 +0200, Ingo Molnar wrote: +> * Nick Piggin wrote: +> +> > > [10138.175796] [] show_trace+0x12/0x14 +> > > [10138.180291] [] dump_stack+0x16/0x18 +> > > [10138.184769] [] native_smp_call_function_mask+0x138/0x13d +> > > [10138.191117] [] smp_call_function+0x1e/0x24 +> > > [10138.196210] [] on_each_cpu+0x25/0x50 +> > > [10138.200807] [] flush_tlb_all+0x1e/0x20 +> > > [10138.205553] [] kmap_high+0x1b6/0x417 +> > > [10138.210118] [] kmap+0x4d/0x4f +> > > [10138.214102] [] ntfs_end_buffer_async_read+0x228/0x2f9 +> > > [10138.220163] [] end_bio_bh_io_sync+0x26/0x3f +> > > [10138.225352] [] bio_endio+0x42/0x6d +> > > [10138.229769] [] __end_that_request_first+0x115/0x4ac +> > > [10138.235682] [] end_that_request_chunk+0x8/0xa +> > > [10138.241052] [] ide_end_request+0x55/0x10a +> > > [10138.246058] [] ide_dma_intr+0x6f/0xac +> > > [10138.250727] [] ide_intr+0x93/0x1e0 +> > > [10138.255125] [] handle_IRQ_event+0x5c/0xc9 +> > +> > Looks like ntfs is kmap()ing from interrupt context. Should be using +> > kmap_atomic instead, I think. +> +> it's not atomic interrupt context but irq thread context - and -rt +> remaps kmap_atomic() to kmap() internally. + +Hm. Looking at the change to mm/bounce.c, perhaps I should do this +instead? + +--- + fs/ntfs/aops.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/fs/ntfs/aops.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/ntfs/aops.c 2008-10-08 22:23:44.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/ntfs/aops.c 2008-10-08 22:24:36.000000000 -0400 +@@ -139,13 +139,13 @@ static void ntfs_end_buffer_async_read(s + recs = PAGE_CACHE_SIZE / rec_size; + /* Should have been verified before we got here... */ + BUG_ON(!recs); +- local_irq_save(flags); ++ local_irq_save_nort(flags); + kaddr = kmap_atomic(page, KM_BIO_SRC_IRQ); + for (i = 0; i < recs; i++) + post_read_mst_fixup((NTFS_RECORD*)(kaddr + + i * rec_size), rec_size); + kunmap_atomic(kaddr, KM_BIO_SRC_IRQ); +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + flush_dcache_page(page); + if (likely(page_uptodate && !PageError(page))) + SetPageUptodate(page); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0353-fix-compilation-for-non-RT-in-timer.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0353-fix-compilation-for-non-RT-in-timer.patch @@ -0,0 +1,43 @@ +From ak@suse.de Wed Sep 26 10:39:29 2007 +Date: Mon, 17 Sep 2007 17:52:37 +0200 +From: Andi Kleen +To: mingo@elte.hu, Thomas Gleixner +Cc: linux-rt-users@vger.kernel.org +Subject: [PATCH] Fix compilation of 2.6.23rc4-rt1 without CONFIG_PREEMPT_RT + + +count_active_rt_tasks() is undefined otherwise. + +Signed-off-by: Andi Kleen + +--- + kernel/timer.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/timer.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/timer.c 2008-10-08 22:24:27.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/timer.c 2008-10-08 22:24:28.000000000 -0400 +@@ -939,18 +939,20 @@ static unsigned long count_active_tasks( + #endif + } + +-#ifdef CONFIG_PREEMPT_RT + /* + * Nr of active tasks - counted in fixed-point numbers + */ + static unsigned long count_active_rt_tasks(void) + { ++#ifdef CONFIG_PREEMPT_RT + extern unsigned long rt_nr_running(void); + extern unsigned long rt_nr_uninterruptible(void); + + return (rt_nr_running() + rt_nr_uninterruptible()) * FIXED_1; +-} ++#else ++ return 0; + #endif ++} + + /* + * Hmm.. Changed this, as the GNU make sources (load.c) seems to --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0155-preempt-irqs-ppc-fix-b6.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0155-preempt-irqs-ppc-fix-b6.patch @@ -0,0 +1,44 @@ + + To fix the following boot time warnings by setting soft_enabled and +hard_enabled. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Freeing unused kernel memory: 248k freed +BUG: scheduling with irqs disabled: rc.sysinit/0x00000000/373 +caller is user_work+0x14/0x2c +Call Trace: +[C00000001FEC3D10] [C00000000000FAA0] .show_stack+0x68/0x1b0 (unreliable) +[C00000001FEC3DB0] [C0000000003E78DC] .schedule+0x78/0x128 +[C00000001FEC3E30] [C000000000008C40] user_work+0x14/0x2c +BUG: scheduling with irqs disabled: sed/0x00000000/378 +caller is user_work+0x14/0x2c +Call Trace: +[C00000000FA33D10] [C00000000000FAA0] .show_stack+0x68/0x1b0 (unreliable) +[C00000000FA33DB0] [C0000000003E78DC] .schedule+0x78/0x128 +[C00000000FA33E30] [C000000000008C40] user_work+0x14/0x2c + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +Signed-off-by: Tsutomu Owa +-- owa + +--- + arch/powerpc/kernel/entry_64.S | 5 +++++ + 1 file changed, 5 insertions(+) + +Index: linux-2.6.24.7-rt21/arch/powerpc/kernel/entry_64.S +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/kernel/entry_64.S 2008-10-08 22:23:11.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/kernel/entry_64.S 2008-10-08 22:23:34.000000000 -0400 +@@ -599,6 +599,11 @@ do_work: + + user_work: + #endif ++ /* here we are preempting the current task */ ++ li r0,1 ++ stb r0,PACASOFTIRQEN(r13) ++ stb r0,PACAHARDIRQEN(r13) ++ + /* Enable interrupts */ + ori r10,r10,MSR_EE + mtmsrd r10,1 --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0249-preempt-realtime-compile-fixes.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0249-preempt-realtime-compile-fixes.patch @@ -0,0 +1,17 @@ +--- + drivers/block/paride/pseudo.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/drivers/block/paride/pseudo.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/block/paride/pseudo.h 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/block/paride/pseudo.h 2008-10-08 22:24:01.000000000 -0400 +@@ -43,7 +43,7 @@ static unsigned long ps_timeout; + static int ps_tq_active = 0; + static int ps_nice = 0; + +-static DEFINE_SPINLOCK(ps_spinlock __attribute__((unused))); ++static __attribute__((unused)) DEFINE_SPINLOCK(ps_spinlock); + + static DECLARE_DELAYED_WORK(ps_tq, ps_tq_int); + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0243-preempt-realtime-fs-block.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0243-preempt-realtime-fs-block.patch @@ -0,0 +1,407 @@ +--- + block/ll_rw_blk.c | 6 ++-- + fs/aio.c | 6 +++- + fs/block_dev.c | 34 +++++++++++++++++++++------ + fs/dcache.c | 5 ++-- + fs/dnotify.c | 2 - + fs/exec.c | 8 +++++- + fs/file.c | 5 ++-- + fs/lockd/svc.c | 8 +----- + fs/pipe.c | 12 +++++++++ + fs/proc/proc_misc.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++ + fs/proc/task_mmu.c | 4 ++- + fs/xfs/linux-2.6/mrlock.h | 4 +-- + fs/xfs/xfs_mount.h | 2 - + include/linux/genhd.h | 11 +++++++-- + 14 files changed, 132 insertions(+), 31 deletions(-) + +Index: linux-2.6.24.7-rt21/block/ll_rw_blk.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/block/ll_rw_blk.c 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/block/ll_rw_blk.c 2008-10-08 22:24:00.000000000 -0400 +@@ -1548,7 +1548,7 @@ static int ll_merge_requests_fn(struct r + */ + void blk_plug_device(struct request_queue *q) + { +- WARN_ON(!irqs_disabled()); ++ WARN_ON_NONRT(!irqs_disabled()); + + /* + * don't plug a stopped queue, it must be paired with blk_start_queue() +@@ -1571,7 +1571,7 @@ EXPORT_SYMBOL(blk_plug_device); + */ + int blk_remove_plug(struct request_queue *q) + { +- WARN_ON(!irqs_disabled()); ++ WARN_ON_NONRT(!irqs_disabled()); + + if (!test_and_clear_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags)) + return 0; +@@ -1670,7 +1670,7 @@ EXPORT_SYMBOL(blk_unplug); + **/ + void blk_start_queue(struct request_queue *q) + { +- WARN_ON(!irqs_disabled()); ++ WARN_ON_NONRT(!irqs_disabled()); + + clear_bit(QUEUE_FLAG_STOPPED, &q->queue_flags); + +Index: linux-2.6.24.7-rt21/fs/aio.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/aio.c 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/aio.c 2008-10-08 22:24:00.000000000 -0400 +@@ -582,13 +582,15 @@ static void use_mm(struct mm_struct *mm) + tsk->flags |= PF_BORROWED_MM; + active_mm = tsk->active_mm; + atomic_inc(&mm->mm_count); +- tsk->mm = mm; +- tsk->active_mm = mm; ++ local_irq_disable(); // FIXME + /* + * Note that on UML this *requires* PF_BORROWED_MM to be set, otherwise + * it won't work. Update it accordingly if you change it here + */ + switch_mm(active_mm, mm, tsk); ++ tsk->mm = mm; ++ tsk->active_mm = mm; ++ local_irq_enable(); + task_unlock(tsk); + + mmdrop(active_mm); +Index: linux-2.6.24.7-rt21/fs/block_dev.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/block_dev.c 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/block_dev.c 2008-10-08 22:24:00.000000000 -0400 +@@ -1225,14 +1225,32 @@ static int __blkdev_get(struct block_dev + * For now, block device ->open() routine must _not_ + * examine anything in 'inode' argument except ->i_rdev. + */ +- struct file fake_file = {}; +- struct dentry fake_dentry = {}; +- fake_file.f_mode = mode; +- fake_file.f_flags = flags; +- fake_file.f_path.dentry = &fake_dentry; +- fake_dentry.d_inode = bdev->bd_inode; +- +- return do_open(bdev, &fake_file, for_part); ++ struct file *fake_file; ++ struct dentry *fake_dentry; ++ int err = -ENOMEM; ++ ++ fake_file = kmalloc(sizeof(*fake_file), GFP_KERNEL); ++ if (!fake_file) ++ goto out; ++ memset(fake_file, 0, sizeof(*fake_file)); ++ ++ fake_dentry = kmalloc(sizeof(*fake_dentry), GFP_KERNEL); ++ if (!fake_dentry) ++ goto out_free_file; ++ memset(fake_dentry, 0, sizeof(*fake_dentry)); ++ ++ fake_file->f_mode = mode; ++ fake_file->f_flags = flags; ++ fake_file->f_path.dentry = fake_dentry; ++ fake_dentry->d_inode = bdev->bd_inode; ++ ++ err = do_open(bdev, fake_file, for_part); ++ ++ kfree(fake_dentry); ++out_free_file: ++ kfree(fake_file); ++out: ++ return err; + } + + int blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags) +Index: linux-2.6.24.7-rt21/fs/dcache.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/dcache.c 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/dcache.c 2008-10-08 22:24:00.000000000 -0400 +@@ -704,8 +704,9 @@ void shrink_dcache_for_umount(struct sup + { + struct dentry *dentry; + +- if (down_read_trylock(&sb->s_umount)) +- BUG(); ++// -rt: this might succeed there ... ++// if (down_read_trylock(&sb->s_umount)) ++// BUG(); + + dentry = sb->s_root; + sb->s_root = NULL; +Index: linux-2.6.24.7-rt21/fs/dnotify.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/dnotify.c 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/dnotify.c 2008-10-08 22:24:00.000000000 -0400 +@@ -173,7 +173,7 @@ void dnotify_parent(struct dentry *dentr + + spin_lock(&dentry->d_lock); + parent = dentry->d_parent; +- if (parent->d_inode->i_dnotify_mask & event) { ++ if (unlikely(parent->d_inode->i_dnotify_mask & event)) { + dget(parent); + spin_unlock(&dentry->d_lock); + __inode_dir_notify(parent->d_inode, event); +Index: linux-2.6.24.7-rt21/fs/exec.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/exec.c 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/exec.c 2008-10-08 22:24:00.000000000 -0400 +@@ -48,6 +48,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -721,11 +722,16 @@ static int exec_mmap(struct mm_struct *m + } + } + task_lock(tsk); ++ ++ local_irq_disable(); + active_mm = tsk->active_mm; ++ activate_mm(active_mm, mm); + tsk->mm = mm; + tsk->active_mm = mm; +- activate_mm(active_mm, mm); ++ local_irq_enable(); ++ + task_unlock(tsk); ++ + arch_pick_mmap_layout(mm); + if (old_mm) { + up_read(&old_mm->mmap_sem); +Index: linux-2.6.24.7-rt21/fs/file.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/file.c 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/file.c 2008-10-08 22:24:00.000000000 -0400 +@@ -96,14 +96,15 @@ void free_fdtable_rcu(struct rcu_head *r + kfree(fdt->open_fds); + kfree(fdt); + } else { +- fddef = &get_cpu_var(fdtable_defer_list); ++ ++ fddef = &per_cpu(fdtable_defer_list, raw_smp_processor_id()); ++ + spin_lock(&fddef->lock); + fdt->next = fddef->next; + fddef->next = fdt; + /* vmallocs are handled from the workqueue context */ + schedule_work(&fddef->wq); + spin_unlock(&fddef->lock); +- put_cpu_var(fdtable_defer_list); + } + } + +Index: linux-2.6.24.7-rt21/fs/lockd/svc.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/lockd/svc.c 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/lockd/svc.c 2008-10-08 22:24:00.000000000 -0400 +@@ -349,16 +349,12 @@ lockd_down(void) + * Wait for the lockd process to exit, but since we're holding + * the lockd semaphore, we can't wait around forever ... + */ +- clear_thread_flag(TIF_SIGPENDING); +- interruptible_sleep_on_timeout(&lockd_exit, HZ); +- if (nlmsvc_pid) { ++ if (wait_event_interruptible_timeout(lockd_exit, ++ nlmsvc_pid == 0, HZ) <= 0) { + printk(KERN_WARNING + "lockd_down: lockd failed to exit, clearing pid\n"); + nlmsvc_pid = 0; + } +- spin_lock_irq(¤t->sighand->siglock); +- recalc_sigpending(); +- spin_unlock_irq(¤t->sighand->siglock); + out: + mutex_unlock(&nlmsvc_mutex); + } +Index: linux-2.6.24.7-rt21/fs/pipe.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/pipe.c 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/pipe.c 2008-10-08 22:24:00.000000000 -0400 +@@ -385,8 +385,14 @@ redo: + wake_up_interruptible_sync(&pipe->wait); + kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); + } ++ /* ++ * Hack: we turn off atime updates for -RT kernels. ++ * Who uses them on pipes anyway? ++ */ ++#ifndef CONFIG_PREEMPT_RT + if (ret > 0) + file_accessed(filp); ++#endif + return ret; + } + +@@ -558,8 +564,14 @@ out: + wake_up_interruptible_sync(&pipe->wait); + kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); + } ++ /* ++ * Hack: we turn off atime updates for -RT kernels. ++ * Who uses them on pipes anyway? ++ */ ++#ifndef CONFIG_PREEMPT_RT + if (ret > 0) + file_update_time(filp); ++#endif + return ret; + } + +Index: linux-2.6.24.7-rt21/fs/proc/proc_misc.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/proc/proc_misc.c 2008-10-08 22:23:46.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/proc/proc_misc.c 2008-10-08 22:24:00.000000000 -0400 +@@ -96,6 +96,27 @@ static int loadavg_read_proc(char *page, + return proc_calc_metrics(page, start, off, count, eof, len); + } + ++#ifdef CONFIG_PREEMPT_RT ++static int loadavg_rt_read_proc(char *page, char **start, off_t off, ++ int count, int *eof, void *data) ++{ ++ extern unsigned long avenrun_rt[]; ++ extern unsigned long rt_nr_running(void); ++ int a, b, c; ++ int len; ++ ++ a = avenrun_rt[0] + (FIXED_1/200); ++ b = avenrun_rt[1] + (FIXED_1/200); ++ c = avenrun_rt[2] + (FIXED_1/200); ++ len = sprintf(page,"%d.%02d %d.%02d %d.%02d %ld/%d %d\n", ++ LOAD_INT(a), LOAD_FRAC(a), ++ LOAD_INT(b), LOAD_FRAC(b), ++ LOAD_INT(c), LOAD_FRAC(c), ++ rt_nr_running(), nr_threads, current->nsproxy->pid_ns->last_pid); ++ return proc_calc_metrics(page, start, off, count, eof, len); ++} ++#endif ++ + static int uptime_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) + { +@@ -555,6 +576,38 @@ static int show_stat(struct seq_file *p, + nr_iowait()); + + kfree(per_irq_sum); ++#ifdef CONFIG_PREEMPT_RT ++ { ++ unsigned long nr_uninterruptible_cpu(int cpu); ++ extern int pi_initialized; ++ unsigned long rt_nr_running(void); ++ unsigned long rt_nr_running_cpu(int cpu); ++ unsigned long rt_nr_uninterruptible(void); ++ unsigned long rt_nr_uninterruptible_cpu(int cpu); ++ ++ int i; ++ ++ seq_printf(p, "pi_init: %d\n", pi_initialized); ++ seq_printf(p, "nr_running(): %ld\n", ++ nr_running()); ++ seq_printf(p, "nr_uninterruptible(): %ld\n", ++ nr_uninterruptible()); ++ for_each_online_cpu(i) ++ seq_printf(p, "nr_uninterruptible(%d): %ld\n", ++ i, nr_uninterruptible_cpu(i)); ++ seq_printf(p, "rt_nr_running(): %ld\n", ++ rt_nr_running()); ++ for_each_online_cpu(i) ++ seq_printf(p, "rt_nr_running(%d): %ld\n", ++ i, rt_nr_running_cpu(i)); ++ seq_printf(p, "nr_rt_uninterruptible(): %ld\n", ++ rt_nr_uninterruptible()); ++ for_each_online_cpu(i) ++ seq_printf(p, "nr_rt_uninterruptible(%d): %ld\n", ++ i, rt_nr_uninterruptible_cpu(i)); ++ } ++#endif ++ + return 0; + } + +@@ -704,6 +757,9 @@ void __init proc_misc_init(void) + int (*read_proc)(char*,char**,off_t,int,int*,void*); + } *p, simple_ones[] = { + {"loadavg", loadavg_read_proc}, ++#ifdef CONFIG_PREEMPT_RT ++ {"loadavgrt", loadavg_rt_read_proc}, ++#endif + {"uptime", uptime_read_proc}, + {"meminfo", meminfo_read_proc}, + {"version", version_read_proc}, +Index: linux-2.6.24.7-rt21/fs/proc/task_mmu.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/proc/task_mmu.c 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/proc/task_mmu.c 2008-10-08 22:24:00.000000000 -0400 +@@ -416,8 +416,10 @@ static void *m_start(struct seq_file *m, + vma = NULL; + if ((unsigned long)l < mm->map_count) { + vma = mm->mmap; +- while (l-- && vma) ++ while (l-- && vma) { + vma = vma->vm_next; ++ cond_resched(); ++ } + goto out; + } + +Index: linux-2.6.24.7-rt21/fs/xfs/linux-2.6/mrlock.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/xfs/linux-2.6/mrlock.h 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/xfs/linux-2.6/mrlock.h 2008-10-08 22:24:00.000000000 -0400 +@@ -23,8 +23,8 @@ + enum { MR_NONE, MR_ACCESS, MR_UPDATE }; + + typedef struct { +- struct rw_semaphore mr_lock; +- int mr_writer; ++ struct compat_rw_semaphore mr_lock; ++ int mr_writer; + } mrlock_t; + + #define mrinit(mrp, name) \ +Index: linux-2.6.24.7-rt21/fs/xfs/xfs_mount.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/xfs/xfs_mount.h 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/xfs/xfs_mount.h 2008-10-08 22:24:00.000000000 -0400 +@@ -383,7 +383,7 @@ typedef struct xfs_mount { + uint m_bm_maxlevels[2]; /* XFS_BM_MAXLEVELS */ + uint m_in_maxlevels; /* XFS_IN_MAXLEVELS */ + struct xfs_perag *m_perag; /* per-ag accounting info */ +- struct rw_semaphore m_peraglock; /* lock for m_perag (pointer) */ ++ struct compat_rw_semaphore m_peraglock; /* lock for m_perag (pointer) */ + struct mutex m_growlock; /* growfs mutex */ + int m_fixedfsid[2]; /* unchanged for life of FS */ + uint m_dmevmask; /* DMI events for this FS */ +Index: linux-2.6.24.7-rt21/include/linux/genhd.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/genhd.h 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/genhd.h 2008-10-08 22:24:00.000000000 -0400 +@@ -157,15 +157,22 @@ struct disk_attribute { + * variants disable/enable preemption. + */ + #ifdef CONFIG_SMP +-#define __disk_stat_add(gendiskp, field, addnd) \ +- (per_cpu_ptr(gendiskp->dkstats, smp_processor_id())->field += addnd) ++#define __disk_stat_add(gendiskp, field, addnd) \ ++do { \ ++ preempt_disable(); \ ++ (per_cpu_ptr(gendiskp->dkstats, \ ++ smp_processor_id())->field += addnd); \ ++ preempt_enable(); \ ++} while (0) + + #define disk_stat_read(gendiskp, field) \ + ({ \ + typeof(gendiskp->dkstats->field) res = 0; \ + int i; \ ++ preempt_disable(); \ + for_each_possible_cpu(i) \ + res += per_cpu_ptr(gendiskp->dkstats, i)->field; \ ++ preempt_enable(); \ + res; \ + }) + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0412-disable-run-softirq-from-hardirq-completely.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0412-disable-run-softirq-from-hardirq-completely.patch @@ -0,0 +1,103 @@ +From: Steven Rostedt +Subject: Disable running softirqs from hardirqs completely! + +There's too many problems with running softirqs from the hardirq context. +Softirqs are not allowed to migrate, and hardirqs might. +Perhaps this will be better when softirqs can migrate. + +Signed-off-by: Steven Rostedt +--- + kernel/irq/manage.c | 27 +-------------------------- + kernel/softirq.c | 21 --------------------- + 2 files changed, 1 insertion(+), 47 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/irq/manage.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/irq/manage.c 2008-10-08 22:24:40.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/irq/manage.c 2008-10-08 22:24:42.000000000 -0400 +@@ -786,28 +786,11 @@ static int do_irqd(void * __desc) + { + struct sched_param param = { 0, }; + struct irq_desc *desc = __desc; +- int run_softirq = 1; + + #ifdef CONFIG_SMP + cpumask_t cpus_allowed; + + cpus_allowed = desc->affinity; +- /* +- * If the irqd is bound to one CPU we let it run softirqs +- * that have the same priority as the irqd thread. We do +- * not run it if the irqd is bound to more than one CPU +- * due to the fact that it can +- * 1) migrate to other CPUS while running the softirqd +- * 2) if we pin the irqd to a CPU to run the softirqd, then +- * we risk a high priority process from waking up and +- * preempting the irqd. Although the irqd may be able to +- * run on other CPUS due to its irq affinity, it will not +- * be able to since we bound it to a CPU to run softirqs. +- * So a RT hog could starve the irqd from running on +- * other CPUS that it's allowed to run on. +- */ +- if (cpus_weight(cpus_allowed) != 1) +- run_softirq = 0; /* turn it off */ + #endif + current->flags |= PF_NOFREEZE | PF_HARDIRQ; + +@@ -823,8 +806,6 @@ static int do_irqd(void * __desc) + do { + set_current_state(TASK_INTERRUPTIBLE); + do_hardirq(desc); +- if (run_softirq) +- do_softirq_from_hardirq(); + } while (current->state == TASK_RUNNING); + + local_irq_enable_nort(); +@@ -832,14 +813,8 @@ static int do_irqd(void * __desc) + /* + * Did IRQ affinities change? + */ +- if (!cpus_equal(cpus_allowed, desc->affinity)) { ++ if (!cpus_equal(cpus_allowed, desc->affinity)) + cpus_allowed = desc->affinity; +- /* +- * Only allow the irq thread to run the softirqs +- * if it is bound to a single CPU. +- */ +- run_softirq = (cpus_weight(cpus_allowed) == 1); +- } + #endif + schedule(); + } +Index: linux-2.6.24.7-rt21/kernel/softirq.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/softirq.c 2008-10-08 22:24:39.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/softirq.c 2008-10-08 22:24:42.000000000 -0400 +@@ -103,27 +103,6 @@ static void wakeup_softirqd(int softirq) + + if (unlikely(!tsk)) + return; +-#if defined(CONFIG_PREEMPT_SOFTIRQS) && defined(CONFIG_PREEMPT_HARDIRQS) +- /* +- * Optimization: if we are in a hardirq thread context, and +- * if the priority of the softirq thread is the same as the +- * priority of the hardirq thread, then 'merge' softirq +- * processing into the hardirq context. (it will later on +- * execute softirqs via do_softirq_from_hardirq()). +- * So here we can skip the wakeup and can rely on the hardirq +- * context processing it later on. +- */ +- if ((current->flags & PF_HARDIRQ) && !hardirq_count() && +- (tsk->normal_prio == current->normal_prio) && +- /* +- * The hard irq thread must be bound to a single CPU to run +- * a softirq. Don't worry about locking, the irq thread +- * should be the only one to modify the cpus_allowed, when +- * the irq affinity changes. +- */ +- (cpus_weight(current->cpus_allowed) == 1)) +- return; +-#endif + /* + * Wake up the softirq task: + */ --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0165-rt-mutex-irq-flags-checking.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0165-rt-mutex-irq-flags-checking.patch @@ -0,0 +1,83 @@ +--- + include/linux/irqflags.h | 37 ++++++++++++++++++++++++++++++++----- + 1 file changed, 32 insertions(+), 5 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/irqflags.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/irqflags.h 2008-10-08 22:23:06.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/irqflags.h 2008-10-08 22:23:36.000000000 -0400 +@@ -11,6 +11,12 @@ + #ifndef _LINUX_TRACE_IRQFLAGS_H + #define _LINUX_TRACE_IRQFLAGS_H + ++#define BUILD_CHECK_IRQ_FLAGS(flags) \ ++ do { \ ++ BUILD_BUG_ON(sizeof(flags) != sizeof(unsigned long)); \ ++ typecheck(unsigned long, flags); \ ++ } while (0) ++ + #ifdef CONFIG_TRACE_IRQFLAGS + extern void trace_hardirqs_on(void); + extern void trace_hardirqs_off(void); +@@ -59,10 +65,15 @@ + #define local_irq_disable() \ + do { raw_local_irq_disable(); trace_hardirqs_off(); } while (0) + #define local_irq_save(flags) \ +- do { raw_local_irq_save(flags); trace_hardirqs_off(); } while (0) ++ do { \ ++ BUILD_CHECK_IRQ_FLAGS(flags); \ ++ raw_local_irq_save(flags); \ ++ trace_hardirqs_off(); \ ++ } while (0) + + #define local_irq_restore(flags) \ + do { \ ++ BUILD_CHECK_IRQ_FLAGS(flags); \ + if (raw_irqs_disabled_flags(flags)) { \ + raw_local_irq_restore(flags); \ + trace_hardirqs_off(); \ +@@ -78,8 +89,16 @@ + */ + # define raw_local_irq_disable() local_irq_disable() + # define raw_local_irq_enable() local_irq_enable() +-# define raw_local_irq_save(flags) local_irq_save(flags) +-# define raw_local_irq_restore(flags) local_irq_restore(flags) ++# define raw_local_irq_save(flags) \ ++ do { \ ++ BUILD_CHECK_IRQ_FLAGS(flags); \ ++ local_irq_save(flags); \ ++ } while (0) ++# define raw_local_irq_restore(flags) \ ++ do { \ ++ BUILD_CHECK_IRQ_FLAGS(flags); \ ++ local_irq_restore(flags); \ ++ } while (0) + #endif /* CONFIG_TRACE_IRQFLAGS_SUPPORT */ + + #ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT +@@ -89,7 +108,11 @@ + raw_safe_halt(); \ + } while (0) + +-#define local_save_flags(flags) raw_local_save_flags(flags) ++#define local_save_flags(flags) \ ++ do { \ ++ BUILD_CHECK_IRQ_FLAGS(flags); \ ++ raw_local_save_flags(flags); \ ++ } while (0) + + #define irqs_disabled() \ + ({ \ +@@ -99,7 +122,11 @@ + raw_irqs_disabled_flags(flags); \ + }) + +-#define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags) ++#define irqs_disabled_flags(flags) \ ++({ \ ++ BUILD_CHECK_IRQ_FLAGS(flags); \ ++ raw_irqs_disabled_flags(flags); \ ++}) + #endif /* CONFIG_X86 */ + + #endif --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0310-highmem-redo-mainline.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0310-highmem-redo-mainline.patch @@ -0,0 +1,23 @@ +--- + mm/highmem.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +Index: linux-2.6.24.7-rt21/mm/highmem.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/mm/highmem.c 2008-10-08 22:24:18.000000000 -0400 ++++ linux-2.6.24.7-rt21/mm/highmem.c 2008-10-08 22:24:18.000000000 -0400 +@@ -214,6 +214,14 @@ static unsigned long pkmap_insert(struct + return vaddr; + } + ++/* ++ * Flush all unused kmap mappings in order to remove stray mappings. ++ */ ++void kmap_flush_unused(void) ++{ ++ WARN_ON_ONCE(1); ++} ++ + fastcall void *kmap_high(struct page *page) + { + unsigned long vaddr; --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0418-mips-remove-duplicate-kconfig.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0418-mips-remove-duplicate-kconfig.patch @@ -0,0 +1,57 @@ +From frank.rowand@am.sony.com Wed Jan 16 20:24:36 2008 +Date: Wed, 16 Jan 2008 16:46:38 -0800 +From: Frank Rowand +To: Steven Rostedt +Cc: linux-kernel@vger.kernel.org, mingo@redhat.com, tglx@linutronix.de +Subject: Re: [PATCH 1/4] RT: remove duplicate time/Kconfig + + +On Tue, 2008-01-15 at 19:40 -0500, Steven Rostedt wrote: +> On Tue, Jan 15, 2008 at 02:18:45PM -0800, Frank Rowand wrote: +> > +> > Index: linux-2.6.24-rc7/arch/mips/Kconfig +> > =================================================================== +> > --- linux-2.6.24-rc7.orig/arch/mips/Kconfig +> > +++ linux-2.6.24-rc7/arch/mips/Kconfig +> > @@ -1775,8 +1775,6 @@ config NR_CPUS +> > performance should round up your number of processors to the next +> > power of two. +> > +> > -source "kernel/time/Kconfig" +> > - +> +> This doesn't apply with -rt2. Are you sure you have the right tree? +> +> -- Steve + +As you suspected, I pulled this one from the wrong tree. The correct +patch is below. + +-Frank + +> +> > # +> > # Timer Interrupt Frequency Configuration +> + +time/Kconfig added by preempt-realtime-mips.patch duplicates other entry, +resulting in kernel make error: + +Signed-off-by: Frank Rowand +--- + arch/mips/Kconfig | 2 -- + 1 file changed, 2 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/mips/Kconfig +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/mips/Kconfig 2008-10-08 22:23:51.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/mips/Kconfig 2008-10-08 22:24:44.000000000 -0400 +@@ -1777,8 +1777,6 @@ config NR_CPUS + performance should round up your number of processors to the next + power of two. + +-source "kernel/time/Kconfig" +- + # + # Timer Interrupt Frequency Configuration + # --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0449-rwlocks-multiple-readers.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0449-rwlocks-multiple-readers.patch @@ -0,0 +1,488 @@ +From: Steven Rostedt +Subject: implement rwlocks management + +This patch adds the managment for rwlocks to have multiple readers. +Like the rwsems, it does not do PI boosting on readers when a writer +is blocked. + +Signed-off-by: Steven Rostedt +--- + include/linux/rt_lock.h | 5 - + include/linux/spinlock.h | 2 + kernel/rt.c | 56 ++---------------- + kernel/rtmutex.c | 140 +++++++++++++++++++++++++++++++++++------------ + kernel/rtmutex_common.h | 4 + + 5 files changed, 119 insertions(+), 88 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/rt_lock.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/rt_lock.h 2008-10-08 22:24:51.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/rt_lock.h 2008-10-08 22:24:51.000000000 -0400 +@@ -87,8 +87,7 @@ struct rw_semaphore { + * rwlocks - an RW semaphore plus lock-break field: + */ + typedef struct { +- struct rt_mutex lock; +- int read_depth; ++ struct rw_mutex owners; + unsigned int break_lock; + #ifdef CONFIG_DEBUG_LOCK_ALLOC + struct lockdep_map dep_map; +@@ -96,7 +95,7 @@ typedef struct { + } rwlock_t; + + #define __RW_LOCK_UNLOCKED(name) (rwlock_t) \ +- { .lock = __RT_SPIN_INITIALIZER(name), \ ++ { .owners.mutex = __RT_SPIN_INITIALIZER(name.owners.mutex), \ + RW_DEP_MAP_INIT(name) } + #else /* !PREEMPT_RT */ + +Index: linux-2.6.24.7-rt21/include/linux/spinlock.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/spinlock.h 2008-10-08 22:24:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/spinlock.h 2008-10-08 22:24:51.000000000 -0400 +@@ -266,7 +266,7 @@ do { \ + + #ifdef CONFIG_PREEMPT_RT + # define rt_read_can_lock(rwl) (!rt_mutex_is_locked(&(rwl)->lock)) +-# define rt_write_can_lock(rwl) (!rt_mutex_is_locked(&(rwl)->lock)) ++# define rt_write_can_lock(rwl) ((rwl)->owners.owner == NULL) + #else + extern int rt_rwlock_can_lock_never_call_on_non_rt(rwlock_t *rwlock); + # define rt_read_can_lock(rwl) rt_rwlock_can_lock_never_call_on_non_rt(rwl) +Index: linux-2.6.24.7-rt21/kernel/rt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rt.c 2008-10-08 22:24:51.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rt.c 2008-10-08 22:24:51.000000000 -0400 +@@ -165,7 +165,7 @@ EXPORT_SYMBOL(_mutex_unlock); + */ + int __lockfunc rt_write_trylock(rwlock_t *rwlock) + { +- int ret = rt_mutex_trylock(&rwlock->lock); ++ int ret = rt_mutex_down_write_trylock(&rwlock->owners); + + if (ret) + rwlock_acquire(&rwlock->dep_map, 0, 1, _RET_IP_); +@@ -183,23 +183,9 @@ EXPORT_SYMBOL(rt_write_trylock_irqsave); + + int __lockfunc rt_read_trylock(rwlock_t *rwlock) + { +- struct rt_mutex *lock = &rwlock->lock; +- unsigned long flags; + int ret; + +- /* +- * Read locks within the self-held write lock succeed. +- */ +- spin_lock_irqsave(&lock->wait_lock, flags); +- if (rt_mutex_real_owner(lock) == current) { +- spin_unlock_irqrestore(&lock->wait_lock, flags); +- rwlock->read_depth++; +- rwlock_acquire_read(&rwlock->dep_map, 0, 1, _RET_IP_); +- return 1; +- } +- spin_unlock_irqrestore(&lock->wait_lock, flags); +- +- ret = rt_mutex_trylock(lock); ++ ret = rt_mutex_down_read_trylock(&rwlock->owners); + if (ret) + rwlock_acquire_read(&rwlock->dep_map, 0, 1, _RET_IP_); + +@@ -210,27 +196,14 @@ EXPORT_SYMBOL(rt_read_trylock); + void __lockfunc rt_write_lock(rwlock_t *rwlock) + { + rwlock_acquire(&rwlock->dep_map, 0, 0, _RET_IP_); +- LOCK_CONTENDED_RT(rwlock, rt_mutex_trylock, __rt_spin_lock); ++ LOCK_CONTENDED_RT_RW(rwlock, rt_mutex_down_write_trylock, rt_rwlock_write_lock); + } + EXPORT_SYMBOL(rt_write_lock); + + void __lockfunc rt_read_lock(rwlock_t *rwlock) + { +- unsigned long flags; +- struct rt_mutex *lock = &rwlock->lock; +- + rwlock_acquire_read(&rwlock->dep_map, 0, 0, _RET_IP_); +- /* +- * Read locks within the write lock succeed. +- */ +- spin_lock_irqsave(&lock->wait_lock, flags); +- if (rt_mutex_real_owner(lock) == current) { +- spin_unlock_irqrestore(&lock->wait_lock, flags); +- rwlock->read_depth++; +- return; +- } +- spin_unlock_irqrestore(&lock->wait_lock, flags); +- LOCK_CONTENDED_RT(rwlock, rt_mutex_trylock, __rt_spin_lock); ++ LOCK_CONTENDED_RT_RW(rwlock, rt_mutex_down_read_trylock, rt_rwlock_read_lock); + } + + EXPORT_SYMBOL(rt_read_lock); +@@ -239,28 +212,14 @@ void __lockfunc rt_write_unlock(rwlock_t + { + /* NOTE: we always pass in '1' for nested, for simplicity */ + rwlock_release(&rwlock->dep_map, 1, _RET_IP_); +- __rt_spin_unlock(&rwlock->lock); ++ rt_rwlock_write_unlock(&rwlock->owners); + } + EXPORT_SYMBOL(rt_write_unlock); + + void __lockfunc rt_read_unlock(rwlock_t *rwlock) + { +- struct rt_mutex *lock = &rwlock->lock; +- unsigned long flags; +- + rwlock_release(&rwlock->dep_map, 1, _RET_IP_); +- // TRACE_WARN_ON(lock->save_state != 1); +- /* +- * Read locks within the self-held write lock succeed. +- */ +- spin_lock_irqsave(&lock->wait_lock, flags); +- if (rt_mutex_real_owner(lock) == current && rwlock->read_depth) { +- spin_unlock_irqrestore(&lock->wait_lock, flags); +- rwlock->read_depth--; +- return; +- } +- spin_unlock_irqrestore(&lock->wait_lock, flags); +- __rt_spin_unlock(&rwlock->lock); ++ rt_rwlock_read_unlock(&rwlock->owners); + } + EXPORT_SYMBOL(rt_read_unlock); + +@@ -289,8 +248,7 @@ void __rt_rwlock_init(rwlock_t *rwlock, + debug_check_no_locks_freed((void *)rwlock, sizeof(*rwlock)); + lockdep_init_map(&rwlock->dep_map, name, key, 0); + #endif +- __rt_mutex_init(&rwlock->lock, name); +- rwlock->read_depth = 0; ++ rt_mutex_rwsem_init(&rwlock->owners, name); + } + EXPORT_SYMBOL(__rt_rwlock_init); + +Index: linux-2.6.24.7-rt21/kernel/rtmutex.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rtmutex.c 2008-10-08 22:24:51.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rtmutex.c 2008-10-08 22:24:51.000000000 -0400 +@@ -1149,7 +1149,7 @@ rt_read_slowlock(struct rw_mutex *rwm, i + struct rt_mutex_waiter waiter; + struct rt_mutex *mutex = &rwm->mutex; + int saved_lock_depth = -1; +- unsigned long flags; ++ unsigned long saved_state = -1, state, flags; + + spin_lock_irqsave(&mutex->wait_lock, flags); + init_lists(mutex); +@@ -1168,13 +1168,19 @@ rt_read_slowlock(struct rw_mutex *rwm, i + + init_lists(mutex); + +- /* +- * We drop the BKL here before we go into the wait loop to avoid a +- * possible deadlock in the scheduler. +- */ +- if (unlikely(current->lock_depth >= 0)) +- saved_lock_depth = rt_release_bkl(mutex, flags); +- set_current_state(TASK_UNINTERRUPTIBLE); ++ if (mtx) { ++ /* ++ * We drop the BKL here before we go into the wait loop to avoid a ++ * possible deadlock in the scheduler. ++ */ ++ if (unlikely(current->lock_depth >= 0)) ++ saved_lock_depth = rt_release_bkl(mutex, flags); ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ } else { ++ /* Spin lock must preserve BKL */ ++ saved_state = xchg(¤t->state, TASK_UNINTERRUPTIBLE); ++ saved_lock_depth = current->lock_depth; ++ } + + for (;;) { + unsigned long saved_flags; +@@ -1197,21 +1203,36 @@ rt_read_slowlock(struct rw_mutex *rwm, i + } + saved_flags = current->flags & PF_NOSCHED; + current->flags &= ~PF_NOSCHED; ++ if (!mtx) ++ current->lock_depth = -1; + + spin_unlock_irqrestore(&mutex->wait_lock, flags); + + debug_rt_mutex_print_deadlock(&waiter); + +- if (waiter.task) ++ if (!mtx || waiter.task) + schedule_rt_mutex(mutex); + + spin_lock_irqsave(&mutex->wait_lock, flags); + + current->flags |= saved_flags; +- set_current_state(TASK_UNINTERRUPTIBLE); ++ if (mtx) ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ else { ++ current->lock_depth = saved_lock_depth; ++ state = xchg(¤t->state, TASK_UNINTERRUPTIBLE); ++ if (unlikely(state == TASK_RUNNING)) ++ saved_state = TASK_RUNNING; ++ } + } + +- set_current_state(TASK_RUNNING); ++ if (mtx) ++ set_current_state(TASK_RUNNING); ++ else { ++ state = xchg(¤t->state, saved_state); ++ if (unlikely(state == TASK_RUNNING)) ++ current->state = TASK_RUNNING; ++ } + + if (unlikely(waiter.task)) + remove_waiter(mutex, &waiter, flags); +@@ -1224,7 +1245,7 @@ rt_read_slowlock(struct rw_mutex *rwm, i + spin_unlock_irqrestore(&mutex->wait_lock, flags); + + /* Must we reaquire the BKL? */ +- if (unlikely(saved_lock_depth >= 0)) ++ if (mtx && unlikely(saved_lock_depth >= 0)) + rt_reacquire_bkl(saved_lock_depth); + + debug_rt_mutex_free_waiter(&waiter); +@@ -1257,6 +1278,11 @@ void fastcall rt_mutex_down_read(struct + rt_read_fastlock(rwm, rt_read_slowlock, 1); + } + ++void fastcall rt_rwlock_read_lock(struct rw_mutex *rwm) ++{ ++ rt_read_fastlock(rwm, rt_read_slowlock, 0); ++} ++ + + static inline int + rt_read_slowtrylock(struct rw_mutex *rwm, int mtx) +@@ -1309,7 +1335,7 @@ rt_write_slowlock(struct rw_mutex *rwm, + struct rt_mutex *mutex = &rwm->mutex; + struct rt_mutex_waiter waiter; + int saved_lock_depth = -1; +- unsigned long flags; ++ unsigned long flags, saved_state = -1, state; + + debug_rt_mutex_init_waiter(&waiter); + waiter.task = NULL; +@@ -1326,13 +1352,19 @@ rt_write_slowlock(struct rw_mutex *rwm, + } + update_rw_mutex_owner(rwm); + +- /* +- * We drop the BKL here before we go into the wait loop to avoid a +- * possible deadlock in the scheduler. +- */ +- if (unlikely(current->lock_depth >= 0)) +- saved_lock_depth = rt_release_bkl(mutex, flags); +- set_current_state(TASK_UNINTERRUPTIBLE); ++ if (mtx) { ++ /* ++ * We drop the BKL here before we go into the wait loop to avoid a ++ * possible deadlock in the scheduler. ++ */ ++ if (unlikely(current->lock_depth >= 0)) ++ saved_lock_depth = rt_release_bkl(mutex, flags); ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ } else { ++ /* Spin locks must preserve the BKL */ ++ saved_lock_depth = current->lock_depth; ++ saved_state = xchg(¤t->state, TASK_UNINTERRUPTIBLE); ++ } + + for (;;) { + unsigned long saved_flags; +@@ -1355,21 +1387,36 @@ rt_write_slowlock(struct rw_mutex *rwm, + } + saved_flags = current->flags & PF_NOSCHED; + current->flags &= ~PF_NOSCHED; ++ if (!mtx) ++ current->lock_depth = -1; + + spin_unlock_irqrestore(&mutex->wait_lock, flags); + + debug_rt_mutex_print_deadlock(&waiter); + +- if (waiter.task) ++ if (!mtx || waiter.task) + schedule_rt_mutex(mutex); + + spin_lock_irqsave(&mutex->wait_lock, flags); + + current->flags |= saved_flags; +- set_current_state(TASK_UNINTERRUPTIBLE); ++ if (mtx) ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ else { ++ current->lock_depth = saved_lock_depth; ++ state = xchg(¤t->state, TASK_UNINTERRUPTIBLE); ++ if (unlikely(state == TASK_RUNNING)) ++ saved_state = TASK_RUNNING; ++ } + } + +- set_current_state(TASK_RUNNING); ++ if (mtx) ++ set_current_state(TASK_RUNNING); ++ else { ++ state = xchg(¤t->state, saved_state); ++ if (unlikely(state == TASK_RUNNING)) ++ current->state = TASK_RUNNING; ++ } + + if (unlikely(waiter.task)) + remove_waiter(mutex, &waiter, flags); +@@ -1381,7 +1428,7 @@ rt_write_slowlock(struct rw_mutex *rwm, + spin_unlock_irqrestore(&mutex->wait_lock, flags); + + /* Must we reaquire the BKL? */ +- if (unlikely(saved_lock_depth >= 0)) ++ if (mtx && unlikely(saved_lock_depth >= 0)) + rt_reacquire_bkl(saved_lock_depth); + + WARN_ON(atomic_read(&rwm->count)); +@@ -1409,6 +1456,11 @@ void fastcall rt_mutex_down_write(struct + rt_write_fastlock(rwm, rt_write_slowlock, 1); + } + ++void fastcall rt_rwlock_write_lock(struct rw_mutex *rwm) ++{ ++ rt_write_fastlock(rwm, rt_write_slowlock, 0); ++} ++ + static int + rt_write_slowtrylock(struct rw_mutex *rwm, int mtx) + { +@@ -1447,10 +1499,11 @@ int fastcall rt_mutex_down_write_trylock + } + + static void fastcall noinline __sched +-rt_read_slowunlock(struct rw_mutex *rwm) ++rt_read_slowunlock(struct rw_mutex *rwm, int mtx) + { + struct rt_mutex *mutex = &rwm->mutex; + unsigned long flags; ++ int savestate = !mtx; + struct rt_mutex_waiter *waiter; + + spin_lock_irqsave(&mutex->wait_lock, flags); +@@ -1510,7 +1563,7 @@ rt_read_slowunlock(struct rw_mutex *rwm) + * will steal the lock from the reader. This is the + * only time we can have a reader pending on a lock. + */ +- wakeup_next_waiter(mutex, 0); ++ wakeup_next_waiter(mutex, savestate); + + out: + spin_unlock_irqrestore(&mutex->wait_lock, flags); +@@ -1521,7 +1574,8 @@ rt_read_slowunlock(struct rw_mutex *rwm) + + static inline void + rt_read_fastunlock(struct rw_mutex *rwm, +- void fastcall (*slowfn)(struct rw_mutex *rwm)) ++ void fastcall (*slowfn)(struct rw_mutex *rwm, int mtx), ++ int mtx) + { + WARN_ON(!atomic_read(&rwm->count)); + WARN_ON(!rwm->owner); +@@ -1529,20 +1583,26 @@ rt_read_fastunlock(struct rw_mutex *rwm, + if (likely(rt_rwlock_cmpxchg(rwm, current, NULL))) + rt_mutex_deadlock_account_unlock(current); + else +- slowfn(rwm); ++ slowfn(rwm, mtx); + } + + void fastcall rt_mutex_up_read(struct rw_mutex *rwm) + { +- rt_read_fastunlock(rwm, rt_read_slowunlock); ++ rt_read_fastunlock(rwm, rt_read_slowunlock, 1); ++} ++ ++void fastcall rt_rwlock_read_unlock(struct rw_mutex *rwm) ++{ ++ rt_read_fastunlock(rwm, rt_read_slowunlock, 0); + } + + static void fastcall noinline __sched +-rt_write_slowunlock(struct rw_mutex *rwm) ++rt_write_slowunlock(struct rw_mutex *rwm, int mtx) + { + struct rt_mutex *mutex = &rwm->mutex; + struct rt_mutex_waiter *waiter; + struct task_struct *pendowner; ++ int savestate = !mtx; + unsigned long flags; + + spin_lock_irqsave(&mutex->wait_lock, flags); +@@ -1573,7 +1633,7 @@ rt_write_slowunlock(struct rw_mutex *rwm + + waiter = rt_mutex_top_waiter(mutex); + pendowner = waiter->task; +- wakeup_next_waiter(mutex, 0); ++ wakeup_next_waiter(mutex, savestate); + + /* another writer is next? */ + if (waiter->write_lock) { +@@ -1609,7 +1669,10 @@ rt_write_slowunlock(struct rw_mutex *rwm + waiter->task = NULL; + reader->pi_blocked_on = NULL; + +- wake_up_process(reader); ++ if (savestate) ++ wake_up_process_mutex(reader); ++ else ++ wake_up_process(reader); + + if (rt_mutex_has_waiters(mutex)) + waiter = rt_mutex_top_waiter(mutex); +@@ -1639,7 +1702,9 @@ rt_write_slowunlock(struct rw_mutex *rwm + + static inline void + rt_write_fastunlock(struct rw_mutex *rwm, +- void fastcall (*slowfn)(struct rw_mutex *rwm)) ++ void fastcall (*slowfn)(struct rw_mutex *rwm, ++ int mtx), ++ int mtx) + { + unsigned long val = (unsigned long)current | RT_RWLOCK_WRITER; + +@@ -1647,12 +1712,17 @@ rt_write_fastunlock(struct rw_mutex *rwm + if (likely(rt_rwlock_cmpxchg(rwm, (struct task_struct *)val, NULL))) + rt_mutex_deadlock_account_unlock(current); + else +- slowfn(rwm); ++ slowfn(rwm, mtx); + } + + void fastcall rt_mutex_up_write(struct rw_mutex *rwm) + { +- rt_write_fastunlock(rwm, rt_write_slowunlock); ++ rt_write_fastunlock(rwm, rt_write_slowunlock, 1); ++} ++ ++void fastcall rt_rwlock_write_unlock(struct rw_mutex *rwm) ++{ ++ rt_write_fastunlock(rwm, rt_write_slowunlock, 0); + } + + void rt_mutex_rwsem_init(struct rw_mutex *rwm, const char *name) +Index: linux-2.6.24.7-rt21/kernel/rtmutex_common.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rtmutex_common.h 2008-10-08 22:24:51.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rtmutex_common.h 2008-10-08 22:24:51.000000000 -0400 +@@ -166,6 +166,10 @@ extern void rt_mutex_down_write(struct r + extern int rt_mutex_down_read_trylock(struct rw_mutex *rwm); + extern void rt_mutex_down_read(struct rw_mutex *rwm); + extern void rt_mutex_rwsem_init(struct rw_mutex *rwm, const char *name); ++extern void rt_rwlock_write_lock(struct rw_mutex *rwm); ++extern void rt_rwlock_read_lock(struct rw_mutex *rwm); ++extern void rt_rwlock_write_unlock(struct rw_mutex *rwm); ++extern void rt_rwlock_read_unlock(struct rw_mutex *rwm); + + #endif /* CONFIG_PREEMPT_RT */ + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0171-rt-mutex-spinlock-might-sleep.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0171-rt-mutex-spinlock-might-sleep.patch @@ -0,0 +1,63 @@ +From rostedt@goodmis.org Sat Jun 2 00:35:54 2007 +Return-Path: +X-Spam-Checker-Version: SpamAssassin 3.1.7-deb (2006-10-05) on debian +X-Spam-Level: +X-Spam-Status: No, score=0.0 required=5.0 tests=AWL autolearn=ham + version=3.1.7-deb +Received: from ms-smtp-01.nyroc.rr.com (ms-smtp-01.nyroc.rr.com + [24.24.2.55]) by mail.tglx.de (Postfix) with ESMTP id C420E65C065 for + ; Sat, 2 Jun 2007 00:35:54 +0200 (CEST) +Received: from [192.168.23.10] (cpe-24-94-51-176.stny.res.rr.com + [24.94.51.176]) by ms-smtp-01.nyroc.rr.com (8.13.6/8.13.6) with ESMTP id + l51MZLun018065; Fri, 1 Jun 2007 18:35:24 -0400 (EDT) +Subject: [PATCH RT] add might_sleep in rt_spin_lock_fastlock +From: Steven Rostedt +To: Ingo Molnar +Cc: Thomas Gleixner , Arnaldo Carvalho de Melo , LKML +Content-Type: multipart/mixed; boundary="=-jgTmng/RcFNHiVaU9w/Z" +Date: Fri, 01 Jun 2007 18:35:21 -0400 +Message-Id: <1180737321.21781.46.camel@localhost.localdomain> +Mime-Version: 1.0 +X-Mailer: Evolution 2.6.3 +X-Virus-Scanned: Symantec AntiVirus Scan Engine +X-Evolution-Source: imap://tglx%40linutronix.de@localhost:8993/ + + +--=-jgTmng/RcFNHiVaU9w/Z +Content-Type: text/plain +Content-Transfer-Encoding: 8bit + +Ingo, + +Every so often we get bit by a bug "scheduling in atomic", and it comes +from a rtmutex spin_lock. The bug only happens when that lock has +contention, so we miss it a lot. + +This patch adds a might_sleep() to the rt_spin_lock_fastlock to find +bugs where we can schedule in atomic. + +The one place that exists now is from do_page_fault and sending a +signal. I wrote a simple crash program that segfaults (attached) and +with this patch, I get the warning. + +-- Steve + +Signed-off-by: Steven Rostedt + +--- + kernel/rtmutex.c | 2 ++ + 1 file changed, 2 insertions(+) + +Index: linux-2.6.24.7-rt21/kernel/rtmutex.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rtmutex.c 2008-10-08 22:23:37.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rtmutex.c 2008-10-08 22:23:38.000000000 -0400 +@@ -631,6 +631,8 @@ static inline void + rt_spin_lock_fastlock(struct rt_mutex *lock, + void fastcall (*slowfn)(struct rt_mutex *lock)) + { ++ might_sleep(); ++ + if (likely(rt_mutex_cmpxchg(lock, NULL, current))) + rt_mutex_deadlock_account_lock(lock, current); + else --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0217-preempt-realtime-ia64.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0217-preempt-realtime-ia64.patch @@ -0,0 +1,1484 @@ + +Hi, + +This is a first version of my port of Ingo's -rt kernel to the IA64 arch. + +So far the kernel boots with PREEMPT_RT enabled (on a 4-cpu tiger), and +that's about it. I've not done extensive tests (only scripts/rt-tester), +nor any measurements of any kind. + +There's very probably many bugs I'm not aware of. + +But there is already one thing I know should be fixed : I've changed the +declaration of (struct zone).lock (in include/linux/mmzone.h) from +spinlock_t to raw_spinlock_t. + +I did this because on IA64, cpu_idle(), which is not allowed to call +schedule(), calls check_pgt_cache(). I guess this could be fixed by moving +this call to another kernel thread... ideas are welcome. + + + Simon. + + + + +Signed-off-by: Simon.Derr@bull.net + + arch/ia64/Kconfig | 64 +++++++++++++++++++++++++ + arch/ia64/kernel/asm-offsets.c | 2 + arch/ia64/kernel/entry.S | 25 +++++----- + arch/ia64/kernel/fsys.S | 21 ++++++++ + arch/ia64/kernel/iosapic.c | 33 ++++++++++++- + arch/ia64/kernel/mca.c | 2 + arch/ia64/kernel/perfmon.c | 6 +- + arch/ia64/kernel/process.c | 14 +++-- + arch/ia64/kernel/sal.c | 2 + arch/ia64/kernel/salinfo.c | 6 +- + arch/ia64/kernel/semaphore.c | 8 +-- + arch/ia64/kernel/signal.c | 8 +++ + arch/ia64/kernel/smp.c | 16 ++++++ + arch/ia64/kernel/smpboot.c | 3 + + arch/ia64/kernel/time.c | 74 +++++++++++++++++++---------- + arch/ia64/kernel/traps.c | 10 ++-- + arch/ia64/kernel/unwind.c | 4 - + arch/ia64/kernel/unwind_i.h | 2 + arch/ia64/mm/init.c | 2 + arch/ia64/mm/tlb.c | 2 + include/asm-ia64/irqflags.h | 95 ++++++++++++++++++++++++++++++++++++++ + include/asm-ia64/mmu_context.h | 2 + include/asm-ia64/percpu.h | 21 +++++++- + include/asm-ia64/processor.h | 6 +- + include/asm-ia64/rtc.h | 7 ++ + include/asm-ia64/rwsem.h | 32 ++++++------ + include/asm-ia64/sal.h | 2 + include/asm-ia64/semaphore.h | 51 ++++++++++++-------- + include/asm-ia64/spinlock.h | 26 ++++------ + include/asm-ia64/spinlock_types.h | 4 - + include/asm-ia64/system.h | 67 -------------------------- + include/asm-ia64/thread_info.h | 1 + include/asm-ia64/tlb.h | 10 ++-- + 33 files changed, 436 insertions(+), 192 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/ia64/Kconfig +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ia64/Kconfig 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ia64/Kconfig 2008-10-08 22:23:52.000000000 -0400 +@@ -44,6 +44,7 @@ config SWIOTLB + + config RWSEM_XCHGADD_ALGORITHM + bool ++ depends on !PREEMPT_RT + default y + + config ARCH_HAS_ILOG2_U32 +@@ -280,6 +281,69 @@ config SMP + + If you don't know what to do here, say N. + ++ ++config GENERIC_TIME ++ bool ++ default y ++ ++config HIGH_RES_TIMERS ++ bool "High-Resolution Timers" ++ help ++ ++ POSIX timers are available by default. This option enables ++ high-resolution POSIX timers. With this option the resolution ++ is at least 1 microsecond. High resolution is not free. If ++ enabled this option will add a small overhead each time a ++ timer expires that is not on a 1/HZ tick boundary. If no such ++ timers are used the overhead is nil. ++ ++ This option enables two additional POSIX CLOCKS, ++ CLOCK_REALTIME_HR and CLOCK_MONOTONIC_HR. Note that this ++ option does not change the resolution of CLOCK_REALTIME or ++ CLOCK_MONOTONIC which remain at 1/HZ resolution. ++ ++config HIGH_RES_RESOLUTION ++ int "High-Resolution-Timer resolution (nanoseconds)" ++ depends on HIGH_RES_TIMERS ++ default 1000 ++ help ++ ++ This sets the resolution of timers accessed with ++ CLOCK_REALTIME_HR and CLOCK_MONOTONIC_HR. Too ++ fine a resolution (small a number) will usually not ++ be observable due to normal system latencies. For an ++ 800 MHZ processor about 10,000 is the recommended maximum ++ (smallest number). If you don't need that sort of resolution, ++ higher numbers may generate less overhead. ++ ++choice ++ prompt "Clock source" ++ depends on HIGH_RES_TIMERS ++ default HIGH_RES_TIMER_ITC ++ help ++ This option allows you to choose the hardware source in charge ++ of generating high precision interruptions on your system. ++ On IA-64 these are: ++ ++ ++ ITC Interval Time Counter 1/CPU clock ++ HPET High Precision Event Timer ~ (XXX:have to check the spec) ++ ++ The ITC timer is available on all the ia64 computers because ++ it is integrated directly into the processor. However it may not ++ give correct results on MP machines with processors running ++ at different clock rates. In this case you may want to use ++ the HPET if available on your machine. ++ ++ ++config HIGH_RES_TIMER_ITC ++ bool "Interval Time Counter/ITC" ++ ++config HIGH_RES_TIMER_HPET ++ bool "High Precision Event Timer/HPET" ++ ++endchoice ++ + config NR_CPUS + int "Maximum number of CPUs (2-1024)" + range 2 1024 +Index: linux-2.6.24.7-rt21/arch/ia64/kernel/asm-offsets.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ia64/kernel/asm-offsets.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ia64/kernel/asm-offsets.c 2008-10-08 22:23:52.000000000 -0400 +@@ -257,6 +257,7 @@ void foo(void) + offsetof (struct pal_min_state_area_s, pmsa_xip)); + BLANK(); + ++#ifdef CONFIG_TIME_INTERPOLATION + /* used by fsys_gettimeofday in arch/ia64/kernel/fsys.S */ + DEFINE(IA64_GTOD_LOCK_OFFSET, + offsetof (struct fsyscall_gtod_data_t, lock)); +@@ -278,4 +279,5 @@ void foo(void) + offsetof (struct itc_jitter_data_t, itc_jitter)); + DEFINE(IA64_ITC_LASTCYCLE_OFFSET, + offsetof (struct itc_jitter_data_t, itc_lastcycle)); ++#endif + } +Index: linux-2.6.24.7-rt21/arch/ia64/kernel/entry.S +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ia64/kernel/entry.S 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ia64/kernel/entry.S 2008-10-08 22:23:52.000000000 -0400 +@@ -1098,23 +1098,24 @@ skip_rbs_switch: + st8 [r2]=r8 + st8 [r3]=r10 + .work_pending: +- tbit.z p6,p0=r31,TIF_NEED_RESCHED // current_thread_info()->need_resched==0? ++ tbit.nz p6,p0=r31,TIF_NEED_RESCHED // current_thread_info()->need_resched==0? ++(p6) br.cond.sptk.few .needresched ++ tbit.z p6,p0=r31,TIF_NEED_RESCHED_DELAYED // current_thread_info()->need_resched_delayed==0? + (p6) br.cond.sptk.few .notify +-#ifdef CONFIG_PREEMPT +-(pKStk) dep r21=-1,r0,PREEMPT_ACTIVE_BIT,1 ++ ++.needresched: ++ ++(pKStk) br.cond.sptk.many .fromkernel + ;; +-(pKStk) st4 [r20]=r21 + ssm psr.i // enable interrupts +-#endif + br.call.spnt.many rp=schedule +-.ret9: cmp.eq p6,p0=r0,r0 // p6 <- 1 +- rsm psr.i // disable interrupts +- ;; +-#ifdef CONFIG_PREEMPT +-(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13 ++.ret9a: rsm psr.i // disable interrupts + ;; +-(pKStk) st4 [r20]=r0 // preempt_count() <- 0 +-#endif ++ br.cond.sptk.many .endpreemptdep ++.fromkernel: ++ br.call.spnt.many rp=preempt_schedule_irq ++.ret9b: rsm psr.i // disable interrupts ++.endpreemptdep: + (pLvSys)br.cond.sptk.few .work_pending_syscall_end + br.cond.sptk.many .work_processed_kernel // re-check + +Index: linux-2.6.24.7-rt21/arch/ia64/kernel/fsys.S +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ia64/kernel/fsys.S 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ia64/kernel/fsys.S 2008-10-08 22:23:52.000000000 -0400 +@@ -26,6 +26,7 @@ + + #include "entry.h" + ++#ifdef CONFIG_TIME_INTERPOLATION + /* + * See Documentation/ia64/fsys.txt for details on fsyscalls. + * +@@ -349,6 +350,26 @@ ENTRY(fsys_clock_gettime) + br.many .gettime + END(fsys_clock_gettime) + ++ ++#else // !CONFIG_TIME_INTERPOLATION ++ ++# define fsys_gettimeofday 0 ++# define fsys_clock_gettime 0 ++ ++.fail_einval: ++ mov r8 = EINVAL ++ mov r10 = -1 ++ FSYS_RETURN ++ ++.fail_efault: ++ mov r8 = EFAULT ++ mov r10 = -1 ++ FSYS_RETURN ++ ++#endif ++ ++ ++ + /* + * long fsys_rt_sigprocmask (int how, sigset_t *set, sigset_t *oset, size_t sigsetsize). + */ +Index: linux-2.6.24.7-rt21/arch/ia64/kernel/iosapic.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ia64/kernel/iosapic.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ia64/kernel/iosapic.c 2008-10-08 22:23:52.000000000 -0400 +@@ -111,7 +111,7 @@ + (PAGE_SIZE / sizeof(struct iosapic_rte_info)) + #define RTE_PREALLOCATED (1) + +-static DEFINE_SPINLOCK(iosapic_lock); ++static DEFINE_RAW_SPINLOCK(iosapic_lock); + + /* + * These tables map IA-64 vectors to the IOSAPIC pin that generates this +@@ -390,6 +390,34 @@ iosapic_startup_level_irq (unsigned int + return 0; + } + ++/* ++ * In the preemptible case mask the IRQ first then handle it and ack it. ++ */ ++#ifdef CONFIG_PREEMPT_HARDIRQS ++ ++static void ++iosapic_ack_level_irq (unsigned int irq) ++{ ++ ia64_vector vec = irq_to_vector(irq); ++ struct iosapic_rte_info *rte; ++ ++ move_irq(irq); ++ mask_irq(irq); ++ list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) ++ iosapic_eoi(rte->addr, vec); ++} ++ ++static void ++iosapic_end_level_irq (unsigned int irq) ++{ ++ if (!(irq_desc[irq].status & IRQ_INPROGRESS)) ++ unmask_irq(irq); ++} ++ ++#else /* !CONFIG_PREEMPT_HARDIRQS */ ++ ++#define iosapic_ack_level_irq nop ++ + static void + iosapic_end_level_irq (unsigned int irq) + { +@@ -411,10 +439,11 @@ iosapic_end_level_irq (unsigned int irq) + } + } + ++#endif ++ + #define iosapic_shutdown_level_irq mask_irq + #define iosapic_enable_level_irq unmask_irq + #define iosapic_disable_level_irq mask_irq +-#define iosapic_ack_level_irq nop + + static struct irq_chip irq_type_iosapic_level = { + .name = "IO-SAPIC-level", +Index: linux-2.6.24.7-rt21/arch/ia64/kernel/mca.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ia64/kernel/mca.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ia64/kernel/mca.c 2008-10-08 22:23:52.000000000 -0400 +@@ -323,7 +323,7 @@ ia64_mca_spin(const char *func) + + typedef struct ia64_state_log_s + { +- spinlock_t isl_lock; ++ raw_spinlock_t isl_lock; + int isl_index; + unsigned long isl_count; + ia64_err_rec_t *isl_log[IA64_MAX_LOGS]; /* need space to store header + error log */ +Index: linux-2.6.24.7-rt21/arch/ia64/kernel/perfmon.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ia64/kernel/perfmon.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ia64/kernel/perfmon.c 2008-10-08 22:23:52.000000000 -0400 +@@ -280,7 +280,7 @@ typedef struct { + */ + + typedef struct pfm_context { +- spinlock_t ctx_lock; /* context protection */ ++ raw_spinlock_t ctx_lock; /* context protection */ + + pfm_context_flags_t ctx_flags; /* bitmask of flags (block reason incl.) */ + unsigned int ctx_state; /* state: active/inactive (no bitfield) */ +@@ -369,7 +369,7 @@ typedef struct pfm_context { + * mostly used to synchronize between system wide and per-process + */ + typedef struct { +- spinlock_t pfs_lock; /* lock the structure */ ++ raw_spinlock_t pfs_lock; /* lock the structure */ + + unsigned int pfs_task_sessions; /* number of per task sessions */ + unsigned int pfs_sys_sessions; /* number of per system wide sessions */ +@@ -510,7 +510,7 @@ static pfm_intr_handler_desc_t *pfm_alt + static struct proc_dir_entry *perfmon_dir; + static pfm_uuid_t pfm_null_uuid = {0,}; + +-static spinlock_t pfm_buffer_fmt_lock; ++static raw_spinlock_t pfm_buffer_fmt_lock; + static LIST_HEAD(pfm_buffer_fmt_list); + + static pmu_config_t *pmu_conf; +Index: linux-2.6.24.7-rt21/arch/ia64/kernel/process.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ia64/kernel/process.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ia64/kernel/process.c 2008-10-08 22:23:52.000000000 -0400 +@@ -95,6 +95,9 @@ show_stack (struct task_struct *task, un + void + dump_stack (void) + { ++ if (irqs_disabled()) { ++ printk("Uh oh.. entering dump_stack() with irqs disabled.\n"); ++ } + show_stack(NULL, NULL); + } + +@@ -200,7 +203,7 @@ void + default_idle (void) + { + local_irq_enable(); +- while (!need_resched()) { ++ while (!need_resched() && !need_resched_delayed()) { + if (can_do_pal_halt) { + local_irq_disable(); + if (!need_resched()) { +@@ -288,7 +291,7 @@ cpu_idle (void) + current_thread_info()->status |= TS_POLLING; + } + +- if (!need_resched()) { ++ if (!need_resched() && !need_resched_delayed()) { + void (*idle)(void); + #ifdef CONFIG_SMP + min_xtp(); +@@ -310,10 +313,11 @@ cpu_idle (void) + normal_xtp(); + #endif + } +- preempt_enable_no_resched(); +- schedule(); ++ __preempt_enable_no_resched(); ++ __schedule(); ++ + preempt_disable(); +- check_pgt_cache(); ++ + if (cpu_is_offline(cpu)) + play_dead(); + } +Index: linux-2.6.24.7-rt21/arch/ia64/kernel/sal.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ia64/kernel/sal.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ia64/kernel/sal.c 2008-10-08 22:23:52.000000000 -0400 +@@ -18,7 +18,7 @@ + #include + #include + +- __cacheline_aligned DEFINE_SPINLOCK(sal_lock); ++ __cacheline_aligned DEFINE_RAW_SPINLOCK(sal_lock); + unsigned long sal_platform_features; + + unsigned short sal_revision; +Index: linux-2.6.24.7-rt21/arch/ia64/kernel/salinfo.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ia64/kernel/salinfo.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ia64/kernel/salinfo.c 2008-10-08 22:23:52.000000000 -0400 +@@ -140,7 +140,7 @@ enum salinfo_state { + + struct salinfo_data { + cpumask_t cpu_event; /* which cpus have outstanding events */ +- struct semaphore mutex; ++ struct compat_semaphore mutex; + u8 *log_buffer; + u64 log_size; + u8 *oemdata; /* decoded oem data */ +@@ -156,8 +156,8 @@ struct salinfo_data { + + static struct salinfo_data salinfo_data[ARRAY_SIZE(salinfo_log_name)]; + +-static DEFINE_SPINLOCK(data_lock); +-static DEFINE_SPINLOCK(data_saved_lock); ++static DEFINE_RAW_SPINLOCK(data_lock); ++static DEFINE_RAW_SPINLOCK(data_saved_lock); + + /** salinfo_platform_oemdata - optional callback to decode oemdata from an error + * record. +Index: linux-2.6.24.7-rt21/arch/ia64/kernel/semaphore.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ia64/kernel/semaphore.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ia64/kernel/semaphore.c 2008-10-08 22:23:52.000000000 -0400 +@@ -40,12 +40,12 @@ + */ + + void +-__up (struct semaphore *sem) ++__up (struct compat_semaphore *sem) + { + wake_up(&sem->wait); + } + +-void __sched __down (struct semaphore *sem) ++void __sched __down (struct compat_semaphore *sem) + { + struct task_struct *tsk = current; + DECLARE_WAITQUEUE(wait, tsk); +@@ -82,7 +82,7 @@ void __sched __down (struct semaphore *s + tsk->state = TASK_RUNNING; + } + +-int __sched __down_interruptible (struct semaphore * sem) ++int __sched __down_interruptible (struct compat_semaphore * sem) + { + int retval = 0; + struct task_struct *tsk = current; +@@ -142,7 +142,7 @@ int __sched __down_interruptible (struct + * count. + */ + int +-__down_trylock (struct semaphore *sem) ++__down_trylock (struct compat_semaphore *sem) + { + unsigned long flags; + int sleepers; +Index: linux-2.6.24.7-rt21/arch/ia64/kernel/signal.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ia64/kernel/signal.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ia64/kernel/signal.c 2008-10-08 22:23:52.000000000 -0400 +@@ -438,6 +438,14 @@ ia64_do_signal (struct sigscratch *scr, + long errno = scr->pt.r8; + # define ERR_CODE(c) (IS_IA32_PROCESS(&scr->pt) ? -(c) : (c)) + ++#ifdef CONFIG_PREEMPT_RT ++ /* ++ * Fully-preemptible kernel does not need interrupts disabled: ++ */ ++ local_irq_enable(); ++ preempt_check_resched(); ++#endif ++ + /* + * In the ia64_leave_kernel code path, we want the common case to go fast, which + * is why we may in certain cases get here from kernel mode. Just return without +Index: linux-2.6.24.7-rt21/arch/ia64/kernel/smp.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ia64/kernel/smp.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ia64/kernel/smp.c 2008-10-08 22:23:52.000000000 -0400 +@@ -261,6 +261,22 @@ smp_send_reschedule (int cpu) + } + + /* ++ * this function sends a 'reschedule' IPI to all other CPUs. ++ * This is used when RT tasks are starving and other CPUs ++ * might be able to run them: ++ */ ++void smp_send_reschedule_allbutself(void) ++{ ++ unsigned int cpu; ++ ++ for_each_online_cpu(cpu) { ++ if (cpu != smp_processor_id()) ++ platform_send_ipi(cpu, IA64_IPI_RESCHEDULE, ++ IA64_IPI_DM_INT, 0); ++ } ++} ++ ++/* + * Called with preemption disabled. + */ + static void +Index: linux-2.6.24.7-rt21/arch/ia64/kernel/smpboot.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ia64/kernel/smpboot.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ia64/kernel/smpboot.c 2008-10-08 22:23:52.000000000 -0400 +@@ -372,6 +372,8 @@ smp_setup_percpu_timer (void) + { + } + ++extern void register_itc_clockevent(void); ++ + static void __cpuinit + smp_callin (void) + { +@@ -450,6 +452,7 @@ smp_callin (void) + #ifdef CONFIG_IA32_SUPPORT + ia32_gdt_init(); + #endif ++ register_itc_clockevent(); + + /* + * Allow the master to continue. +Index: linux-2.6.24.7-rt21/arch/ia64/kernel/time.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ia64/kernel/time.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ia64/kernel/time.c 2008-10-08 22:23:52.000000000 -0400 +@@ -70,6 +70,7 @@ timer_interrupt (int irq, void *dev_id) + + platform_timer_interrupt(irq, dev_id); + ++#if 0 + new_itm = local_cpu_data->itm_next; + + if (!time_after(ia64_get_itc(), new_itm)) +@@ -77,29 +78,48 @@ timer_interrupt (int irq, void *dev_id) + ia64_get_itc(), new_itm); + + profile_tick(CPU_PROFILING); ++#endif ++ ++ if (time_after(ia64_get_itc(), local_cpu_data->itm_tick_next)) { + +- while (1) { +- update_process_times(user_mode(get_irq_regs())); ++ unsigned long new_tick_itm; ++ new_tick_itm = local_cpu_data->itm_tick_next; + +- new_itm += local_cpu_data->itm_delta; ++ profile_tick(CPU_PROFILING, get_irq_regs()); + +- if (smp_processor_id() == time_keeper_id) { +- /* +- * Here we are in the timer irq handler. We have irqs locally +- * disabled, but we don't know if the timer_bh is running on +- * another CPU. We need to avoid to SMP race by acquiring the +- * xtime_lock. +- */ +- write_seqlock(&xtime_lock); +- do_timer(1); +- local_cpu_data->itm_next = new_itm; +- write_sequnlock(&xtime_lock); +- } else +- local_cpu_data->itm_next = new_itm; ++ while (1) { ++ update_process_times(user_mode(get_irq_regs())); ++ ++ new_tick_itm += local_cpu_data->itm_tick_delta; ++ ++ if (smp_processor_id() == time_keeper_id) { ++ /* ++ * Here we are in the timer irq handler. We have irqs locally ++ * disabled, but we don't know if the timer_bh is running on ++ * another CPU. We need to avoid to SMP race by acquiring the ++ * xtime_lock. ++ */ ++ write_seqlock(&xtime_lock); ++ do_timer(get_irq_regs()); ++ local_cpu_data->itm_tick_next = new_tick_itm; ++ write_sequnlock(&xtime_lock); ++ } else ++ local_cpu_data->itm_tick_next = new_tick_itm; ++ ++ if (time_after(new_tick_itm, ia64_get_itc())) ++ break; ++ } ++ } + +- if (time_after(new_itm, ia64_get_itc())) +- break; ++ if (time_after(ia64_get_itc(), local_cpu_data->itm_timer_next)) { ++ if (itc_clockevent.event_handler) ++ itc_clockevent.event_handler(get_irq_regs()); + ++ // FIXME, really, please ++ new_itm = local_cpu_data->itm_tick_next; ++ ++ if (time_after(new_itm, local_cpu_data->itm_timer_next)) ++ new_itm = local_cpu_data->itm_timer_next; + /* + * Allow IPIs to interrupt the timer loop. + */ +@@ -117,8 +137,8 @@ timer_interrupt (int irq, void *dev_id) + * too fast (with the potentially devastating effect + * of losing monotony of time). + */ +- while (!time_after(new_itm, ia64_get_itc() + local_cpu_data->itm_delta/2)) +- new_itm += local_cpu_data->itm_delta; ++ while (!time_after(new_itm, ia64_get_itc() + local_cpu_data->itm_tick_delta/2)) ++ new_itm += local_cpu_data->itm_tick_delta; + ia64_set_itm(new_itm); + /* double check, in case we got hit by a (slow) PMI: */ + } while (time_after_eq(ia64_get_itc(), new_itm)); +@@ -137,7 +157,7 @@ ia64_cpu_local_tick (void) + /* arrange for the cycle counter to generate a timer interrupt: */ + ia64_set_itv(IA64_TIMER_VECTOR); + +- delta = local_cpu_data->itm_delta; ++ delta = local_cpu_data->itm_tick_delta; + /* + * Stagger the timer tick for each CPU so they don't occur all at (almost) the + * same time: +@@ -146,8 +166,8 @@ ia64_cpu_local_tick (void) + unsigned long hi = 1UL << ia64_fls(cpu); + shift = (2*(cpu - hi) + 1) * delta/hi/2; + } +- local_cpu_data->itm_next = ia64_get_itc() + delta + shift; +- ia64_set_itm(local_cpu_data->itm_next); ++ local_cpu_data->itm_tick_next = ia64_get_itc() + delta + shift; ++ ia64_set_itm(local_cpu_data->itm_tick_next); + } + + static int nojitter; +@@ -205,7 +225,7 @@ ia64_init_itm (void) + + itc_freq = (platform_base_freq*itc_ratio.num)/itc_ratio.den; + +- local_cpu_data->itm_delta = (itc_freq + HZ/2) / HZ; ++ local_cpu_data->itm_tick_delta = (itc_freq + HZ/2) / HZ; + printk(KERN_DEBUG "CPU %d: base freq=%lu.%03luMHz, ITC ratio=%u/%u, " + "ITC freq=%lu.%03luMHz", smp_processor_id(), + platform_base_freq / 1000000, (platform_base_freq / 1000) % 1000, +@@ -225,6 +245,7 @@ ia64_init_itm (void) + local_cpu_data->nsec_per_cyc = ((NSEC_PER_SEC<mfh = 1; + } +- preempt_enable_no_resched(); ++ __preempt_enable_no_resched(); + } + + static inline int +Index: linux-2.6.24.7-rt21/arch/ia64/kernel/unwind.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ia64/kernel/unwind.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ia64/kernel/unwind.c 2008-10-08 22:23:52.000000000 -0400 +@@ -82,7 +82,7 @@ typedef unsigned long unw_word; + typedef unsigned char unw_hash_index_t; + + static struct { +- spinlock_t lock; /* spinlock for unwind data */ ++ raw_spinlock_t lock; /* spinlock for unwind data */ + + /* list of unwind tables (one per load-module) */ + struct unw_table *tables; +@@ -146,7 +146,7 @@ static struct { + # endif + } unw = { + .tables = &unw.kernel_table, +- .lock = __SPIN_LOCK_UNLOCKED(unw.lock), ++ .lock = RAW_SPIN_LOCK_UNLOCKED(unw.lock), + .save_order = { + UNW_REG_RP, UNW_REG_PFS, UNW_REG_PSP, UNW_REG_PR, + UNW_REG_UNAT, UNW_REG_LC, UNW_REG_FPSR, UNW_REG_PRI_UNAT_GR +Index: linux-2.6.24.7-rt21/arch/ia64/kernel/unwind_i.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ia64/kernel/unwind_i.h 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ia64/kernel/unwind_i.h 2008-10-08 22:23:52.000000000 -0400 +@@ -154,7 +154,7 @@ struct unw_script { + unsigned long ip; /* ip this script is for */ + unsigned long pr_mask; /* mask of predicates script depends on */ + unsigned long pr_val; /* predicate values this script is for */ +- rwlock_t lock; ++ raw_rwlock_t lock; + unsigned int flags; /* see UNW_FLAG_* in unwind.h */ + unsigned short lru_chain; /* used for least-recently-used chain */ + unsigned short coll_chain; /* used for hash collisions */ +Index: linux-2.6.24.7-rt21/arch/ia64/mm/init.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ia64/mm/init.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ia64/mm/init.c 2008-10-08 22:23:52.000000000 -0400 +@@ -37,7 +37,7 @@ + #include + #include + +-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); ++DEFINE_PER_CPU_LOCKED(struct mmu_gather, mmu_gathers); + + extern void ia64_tlb_init (void); + +Index: linux-2.6.24.7-rt21/arch/ia64/mm/tlb.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/ia64/mm/tlb.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/ia64/mm/tlb.c 2008-10-08 22:23:52.000000000 -0400 +@@ -33,7 +33,7 @@ static struct { + } purge; + + struct ia64_ctx ia64_ctx = { +- .lock = __SPIN_LOCK_UNLOCKED(ia64_ctx.lock), ++ .lock = RAW_SPIN_LOCK_UNLOCKED(ia64_ctx.lock), + .next = 1, + .max_ctx = ~0U + }; +Index: linux-2.6.24.7-rt21/include/asm-ia64/irqflags.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/include/asm-ia64/irqflags.h 2008-10-08 22:23:52.000000000 -0400 +@@ -0,0 +1,95 @@ ++ ++/* ++ * include/asm-i64/irqflags.h ++ * ++ * IRQ flags handling ++ * ++ * This file gets included from lowlevel asm headers too, to provide ++ * wrapped versions of the local_irq_*() APIs, based on the ++ * raw_local_irq_*() macros from the lowlevel headers. ++ */ ++#ifndef _ASM_IRQFLAGS_H ++#define _ASM_IRQFLAGS_H ++ ++/* For spinlocks etc */ ++ ++/* ++ * - clearing psr.i is implicitly serialized (visible by next insn) ++ * - setting psr.i requires data serialization ++ * - we need a stop-bit before reading PSR because we sometimes ++ * write a floating-point register right before reading the PSR ++ * and that writes to PSR.mfl ++ */ ++#define __local_irq_save(x) \ ++do { \ ++ ia64_stop(); \ ++ (x) = ia64_getreg(_IA64_REG_PSR); \ ++ ia64_stop(); \ ++ ia64_rsm(IA64_PSR_I); \ ++} while (0) ++ ++#define __local_irq_disable() \ ++do { \ ++ ia64_stop(); \ ++ ia64_rsm(IA64_PSR_I); \ ++} while (0) ++ ++#define __local_irq_restore(x) ia64_intrin_local_irq_restore((x) & IA64_PSR_I) ++ ++#ifdef CONFIG_IA64_DEBUG_IRQ ++ ++ extern unsigned long last_cli_ip; ++ ++# define __save_ip() last_cli_ip = ia64_getreg(_IA64_REG_IP) ++ ++# define raw_local_irq_save(x) \ ++do { \ ++ unsigned long psr; \ ++ \ ++ __local_irq_save(psr); \ ++ if (psr & IA64_PSR_I) \ ++ __save_ip(); \ ++ (x) = psr; \ ++} while (0) ++ ++# define raw_local_irq_disable() do { unsigned long x; local_irq_save(x); } while (0) ++ ++# define raw_local_irq_restore(x) \ ++do { \ ++ unsigned long old_psr, psr = (x); \ ++ \ ++ local_save_flags(old_psr); \ ++ __local_irq_restore(psr); \ ++ if ((old_psr & IA64_PSR_I) && !(psr & IA64_PSR_I)) \ ++ __save_ip(); \ ++} while (0) ++ ++#else /* !CONFIG_IA64_DEBUG_IRQ */ ++# define raw_local_irq_save(x) __local_irq_save(x) ++# define raw_local_irq_disable() __local_irq_disable() ++# define raw_local_irq_restore(x) __local_irq_restore(x) ++#endif /* !CONFIG_IA64_DEBUG_IRQ */ ++ ++#define raw_local_irq_enable() ({ ia64_stop(); ia64_ssm(IA64_PSR_I); ia64_srlz_d(); }) ++#define raw_local_save_flags(flags) ({ ia64_stop(); (flags) = ia64_getreg(_IA64_REG_PSR); }) ++ ++#define raw_irqs_disabled() \ ++({ \ ++ unsigned long __ia64_id_flags; \ ++ local_save_flags(__ia64_id_flags); \ ++ (__ia64_id_flags & IA64_PSR_I) == 0; \ ++}) ++ ++#define raw_irqs_disabled_flags(flags) ((flags & IA64_PSR_I) == 0) ++ ++ ++#define raw_safe_halt() ia64_pal_halt_light() /* PAL_HALT_LIGHT */ ++ ++/* TBD... */ ++# define TRACE_IRQS_ON ++# define TRACE_IRQS_OFF ++# define TRACE_IRQS_ON_STR ++# define TRACE_IRQS_OFF_STR ++ ++#endif ++ +Index: linux-2.6.24.7-rt21/include/asm-ia64/mmu_context.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-ia64/mmu_context.h 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-ia64/mmu_context.h 2008-10-08 22:23:52.000000000 -0400 +@@ -32,7 +32,7 @@ + #include + + struct ia64_ctx { +- spinlock_t lock; ++ raw_spinlock_t lock; + unsigned int next; /* next context number to use */ + unsigned int limit; /* available free range */ + unsigned int max_ctx; /* max. context value supported by all CPUs */ +Index: linux-2.6.24.7-rt21/include/asm-ia64/percpu.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-ia64/percpu.h 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-ia64/percpu.h 2008-10-08 22:23:52.000000000 -0400 +@@ -24,10 +24,17 @@ + #define DECLARE_PER_CPU(type, name) \ + extern __SMALL_ADDR_AREA __typeof__(type) per_cpu__##name + ++#define DECLARE_PER_CPU_LOCKED(type, name) \ ++ extern spinlock_t per_cpu_lock__##name##_locked; \ ++ extern __SMALL_ADDR_AREA __typeof__(type) per_cpu__##name##_locked ++ + /* Separate out the type, so (int[3], foo) works. */ + #define DEFINE_PER_CPU(type, name) \ +- __attribute__((__section__(".data.percpu"))) \ +- __SMALL_ADDR_AREA __typeof__(type) per_cpu__##name ++ __attribute__((__section__(".data.percpu"))) __SMALL_ADDR_AREA __typeof__(type) per_cpu__##name ++ ++#define DEFINE_PER_CPU_LOCKED(type, name) \ ++ __attribute__((__section__(".data.percpu"))) __SMALL_ADDR_AREA __DEFINE_SPINLOCK(per_cpu_lock__##name##_locked); \ ++ __attribute__((__section__(".data.percpu"))) __SMALL_ADDR_AREA __typeof__(type) per_cpu__##name##_locked + + #ifdef CONFIG_SMP + #define DEFINE_PER_CPU_SHARED_ALIGNED(type, name) \ +@@ -55,6 +62,16 @@ DECLARE_PER_CPU(unsigned long, local_per + #define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __ia64_per_cpu_var(local_per_cpu_offset))) + #define __raw_get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __ia64_per_cpu_var(local_per_cpu_offset))) + ++#define per_cpu_lock(var, cpu) \ ++ (*RELOC_HIDE(&per_cpu_lock__##var##_locked, __per_cpu_offset[cpu])) ++#define per_cpu_var_locked(var, cpu) \ ++ (*RELOC_HIDE(&per_cpu__##var##_locked, __per_cpu_offset[cpu])) ++#define __get_cpu_lock(var, cpu) \ ++ per_cpu_lock(var, cpu) ++#define __get_cpu_var_locked(var, cpu) \ ++ per_cpu_var_locked(var, cpu) ++ ++ + extern void percpu_modcopy(void *pcpudst, const void *src, unsigned long size); + extern void setup_per_cpu_areas (void); + extern void *per_cpu_init(void); +Index: linux-2.6.24.7-rt21/include/asm-ia64/processor.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-ia64/processor.h 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-ia64/processor.h 2008-10-08 22:23:52.000000000 -0400 +@@ -124,8 +124,10 @@ struct ia64_psr { + */ + struct cpuinfo_ia64 { + __u32 softirq_pending; +- __u64 itm_delta; /* # of clock cycles between clock ticks */ +- __u64 itm_next; /* interval timer mask value to use for next clock tick */ ++ __u64 itm_tick_delta; /* # of clock cycles between clock ticks */ ++ __u64 itm_tick_next; /* interval timer mask value to use for next clock tick */ ++ __u64 itm_timer_next; ++ __u64 __itm_next; + __u64 nsec_per_cyc; /* (1000000000<count = RWSEM_UNLOCKED_VALUE; + spin_lock_init(&sem->wait_lock); +@@ -70,7 +70,7 @@ init_rwsem (struct rw_semaphore *sem) + * lock for reading + */ + static inline void +-__down_read (struct rw_semaphore *sem) ++__down_read (struct compat_rw_semaphore *sem) + { + long result = ia64_fetchadd8_acq((unsigned long *)&sem->count, 1); + +@@ -82,7 +82,7 @@ __down_read (struct rw_semaphore *sem) + * lock for writing + */ + static inline void +-__down_write (struct rw_semaphore *sem) ++__down_write (struct compat_rw_semaphore *sem) + { + long old, new; + +@@ -99,7 +99,7 @@ __down_write (struct rw_semaphore *sem) + * unlock after reading + */ + static inline void +-__up_read (struct rw_semaphore *sem) ++__up_read (struct compat_rw_semaphore *sem) + { + long result = ia64_fetchadd8_rel((unsigned long *)&sem->count, -1); + +@@ -111,7 +111,7 @@ __up_read (struct rw_semaphore *sem) + * unlock after writing + */ + static inline void +-__up_write (struct rw_semaphore *sem) ++__up_write (struct compat_rw_semaphore *sem) + { + long old, new; + +@@ -128,7 +128,7 @@ __up_write (struct rw_semaphore *sem) + * trylock for reading -- returns 1 if successful, 0 if contention + */ + static inline int +-__down_read_trylock (struct rw_semaphore *sem) ++__down_read_trylock (struct compat_rw_semaphore *sem) + { + long tmp; + while ((tmp = sem->count) >= 0) { +@@ -143,7 +143,7 @@ __down_read_trylock (struct rw_semaphore + * trylock for writing -- returns 1 if successful, 0 if contention + */ + static inline int +-__down_write_trylock (struct rw_semaphore *sem) ++__down_write_trylock (struct compat_rw_semaphore *sem) + { + long tmp = cmpxchg_acq(&sem->count, RWSEM_UNLOCKED_VALUE, + RWSEM_ACTIVE_WRITE_BIAS); +@@ -154,7 +154,7 @@ __down_write_trylock (struct rw_semaphor + * downgrade write lock to read lock + */ + static inline void +-__downgrade_write (struct rw_semaphore *sem) ++__downgrade_write (struct compat_rw_semaphore *sem) + { + long old, new; + +@@ -174,7 +174,7 @@ __downgrade_write (struct rw_semaphore * + #define rwsem_atomic_add(delta, sem) atomic64_add(delta, (atomic64_t *)(&(sem)->count)) + #define rwsem_atomic_update(delta, sem) atomic64_add_return(delta, (atomic64_t *)(&(sem)->count)) + +-static inline int rwsem_is_locked(struct rw_semaphore *sem) ++static inline int compat_rwsem_is_locked(struct compat_rw_semaphore *sem) + { + return (sem->count != 0); + } +Index: linux-2.6.24.7-rt21/include/asm-ia64/sal.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-ia64/sal.h 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-ia64/sal.h 2008-10-08 22:23:52.000000000 -0400 +@@ -43,7 +43,7 @@ + #include + #include + +-extern spinlock_t sal_lock; ++extern raw_spinlock_t sal_lock; + + /* SAL spec _requires_ eight args for each call. */ + #define __IA64_FW_CALL(entry,result,a0,a1,a2,a3,a4,a5,a6,a7) \ +Index: linux-2.6.24.7-rt21/include/asm-ia64/semaphore.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-ia64/semaphore.h 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-ia64/semaphore.h 2008-10-08 22:23:52.000000000 -0400 +@@ -11,53 +11,64 @@ + + #include + +-struct semaphore { ++/* ++ * On !PREEMPT_RT all semaphores are compat: ++ */ ++#ifndef CONFIG_PREEMPT_RT ++# define compat_semaphore semaphore ++#endif ++ ++struct compat_semaphore { + atomic_t count; + int sleepers; + wait_queue_head_t wait; + }; + +-#define __SEMAPHORE_INITIALIZER(name, n) \ ++#define __COMPAT_SEMAPHORE_INITIALIZER(name, n) \ + { \ + .count = ATOMIC_INIT(n), \ + .sleepers = 0, \ + .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ + } + +-#define __DECLARE_SEMAPHORE_GENERIC(name,count) \ +- struct semaphore name = __SEMAPHORE_INITIALIZER(name, count) ++#define __COMPAT_DECLARE_SEMAPHORE_GENERIC(name,count) \ ++ struct compat_semaphore name = __COMPAT_SEMAPHORE_INITIALIZER(name, count) + +-#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1) ++#define COMPAT_DECLARE_MUTEX(name) __COMPAT_DECLARE_SEMAPHORE_GENERIC(name, 1) ++ ++#define compat_sema_count(sem) atomic_read(&(sem)->count) ++ ++asmlinkage int compat_sem_is_locked(struct compat_semaphore *sem); + + static inline void +-sema_init (struct semaphore *sem, int val) ++compat_sema_init (struct compat_semaphore *sem, int val) + { +- *sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val); ++ *sem = (struct compat_semaphore) __COMPAT_SEMAPHORE_INITIALIZER(*sem, val); + } + + static inline void +-init_MUTEX (struct semaphore *sem) ++compat_init_MUTEX (struct compat_semaphore *sem) + { +- sema_init(sem, 1); ++ compat_sema_init(sem, 1); + } + + static inline void +-init_MUTEX_LOCKED (struct semaphore *sem) ++compat_init_MUTEX_LOCKED (struct compat_semaphore *sem) + { +- sema_init(sem, 0); ++ compat_sema_init(sem, 0); + } + +-extern void __down (struct semaphore * sem); +-extern int __down_interruptible (struct semaphore * sem); +-extern int __down_trylock (struct semaphore * sem); +-extern void __up (struct semaphore * sem); ++extern void __down (struct compat_semaphore * sem); ++extern int __down_interruptible (struct compat_semaphore * sem); ++extern int __down_trylock (struct compat_semaphore * sem); ++extern void __up (struct compat_semaphore * sem); + + /* + * Atomically decrement the semaphore's count. If it goes negative, + * block the calling thread in the TASK_UNINTERRUPTIBLE state. + */ + static inline void +-down (struct semaphore *sem) ++compat_down (struct compat_semaphore *sem) + { + might_sleep(); + if (ia64_fetchadd(-1, &sem->count.counter, acq) < 1) +@@ -69,7 +80,7 @@ down (struct semaphore *sem) + * block the calling thread in the TASK_INTERRUPTIBLE state. + */ + static inline int +-down_interruptible (struct semaphore * sem) ++compat_down_interruptible (struct compat_semaphore * sem) + { + int ret = 0; + +@@ -80,7 +91,7 @@ down_interruptible (struct semaphore * s + } + + static inline int +-down_trylock (struct semaphore *sem) ++compat_down_trylock (struct compat_semaphore *sem) + { + int ret = 0; + +@@ -90,10 +101,12 @@ down_trylock (struct semaphore *sem) + } + + static inline void +-up (struct semaphore * sem) ++compat_up (struct compat_semaphore * sem) + { + if (ia64_fetchadd(1, &sem->count.counter, rel) <= -1) + __up(sem); + } + ++#include ++ + #endif /* _ASM_IA64_SEMAPHORE_H */ +Index: linux-2.6.24.7-rt21/include/asm-ia64/spinlock.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-ia64/spinlock.h 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-ia64/spinlock.h 2008-10-08 22:23:52.000000000 -0400 +@@ -17,8 +17,6 @@ + #include + #include + +-#define __raw_spin_lock_init(x) ((x)->lock = 0) +- + #ifdef ASM_SUPPORTED + /* + * Try to get the lock. If we fail to get the lock, make a non-standard call to +@@ -30,7 +28,7 @@ + #define IA64_SPINLOCK_CLOBBERS "ar.ccv", "ar.pfs", "p14", "p15", "r27", "r28", "r29", "r30", "b6", "memory" + + static inline void +-__raw_spin_lock_flags (raw_spinlock_t *lock, unsigned long flags) ++__raw_spin_lock_flags (__raw_spinlock_t *lock, unsigned long flags) + { + register volatile unsigned int *ptr asm ("r31") = &lock->lock; + +@@ -89,7 +87,7 @@ __raw_spin_lock_flags (raw_spinlock_t *l + #define __raw_spin_lock(lock) __raw_spin_lock_flags(lock, 0) + + /* Unlock by doing an ordered store and releasing the cacheline with nta */ +-static inline void __raw_spin_unlock(raw_spinlock_t *x) { ++static inline void __raw_spin_unlock(__raw_spinlock_t *x) { + barrier(); + asm volatile ("st4.rel.nta [%0] = r0\n\t" :: "r"(x)); + } +@@ -109,7 +107,7 @@ do { \ + } while (ia64_spinlock_val); \ + } \ + } while (0) +-#define __raw_spin_unlock(x) do { barrier(); ((raw_spinlock_t *) x)->lock = 0; } while (0) ++#define __raw_spin_unlock(x) do { barrier(); ((__raw_spinlock_t *) x)->lock = 0; } while (0) + #endif /* !ASM_SUPPORTED */ + + #define __raw_spin_is_locked(x) ((x)->lock != 0) +@@ -122,7 +120,7 @@ do { \ + + #define __raw_read_lock(rw) \ + do { \ +- raw_rwlock_t *__read_lock_ptr = (rw); \ ++ __raw_rwlock_t *__read_lock_ptr = (rw); \ + \ + while (unlikely(ia64_fetchadd(1, (int *) __read_lock_ptr, acq) < 0)) { \ + ia64_fetchadd(-1, (int *) __read_lock_ptr, rel); \ +@@ -133,7 +131,7 @@ do { \ + + #define __raw_read_unlock(rw) \ + do { \ +- raw_rwlock_t *__read_lock_ptr = (rw); \ ++ __raw_rwlock_t *__read_lock_ptr = (rw); \ + ia64_fetchadd(-1, (int *) __read_lock_ptr, rel); \ + } while (0) + +@@ -165,7 +163,7 @@ do { \ + (result == 0); \ + }) + +-static inline void __raw_write_unlock(raw_rwlock_t *x) ++static inline void __raw_write_unlock(__raw_rwlock_t *x) + { + u8 *y = (u8 *)x; + barrier(); +@@ -193,7 +191,7 @@ static inline void __raw_write_unlock(ra + (ia64_val == 0); \ + }) + +-static inline void __raw_write_unlock(raw_rwlock_t *x) ++static inline void __raw_write_unlock(__raw_rwlock_t *x) + { + barrier(); + x->write_lock = 0; +@@ -201,10 +199,10 @@ static inline void __raw_write_unlock(ra + + #endif /* !ASM_SUPPORTED */ + +-static inline int __raw_read_trylock(raw_rwlock_t *x) ++static inline int __raw_read_trylock(__raw_rwlock_t *x) + { + union { +- raw_rwlock_t lock; ++ __raw_rwlock_t lock; + __u32 word; + } old, new; + old.lock = new.lock = *x; +@@ -213,8 +211,8 @@ static inline int __raw_read_trylock(raw + return (u32)ia64_cmpxchg4_acq((__u32 *)(x), new.word, old.word) == old.word; + } + +-#define _raw_spin_relax(lock) cpu_relax() +-#define _raw_read_relax(lock) cpu_relax() +-#define _raw_write_relax(lock) cpu_relax() ++#define __raw_spin_relax(lock) cpu_relax() ++#define __raw_read_relax(lock) cpu_relax() ++#define __raw_write_relax(lock) cpu_relax() + + #endif /* _ASM_IA64_SPINLOCK_H */ +Index: linux-2.6.24.7-rt21/include/asm-ia64/spinlock_types.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-ia64/spinlock_types.h 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-ia64/spinlock_types.h 2008-10-08 22:23:52.000000000 -0400 +@@ -7,14 +7,14 @@ + + typedef struct { + volatile unsigned int lock; +-} raw_spinlock_t; ++} __raw_spinlock_t; + + #define __RAW_SPIN_LOCK_UNLOCKED { 0 } + + typedef struct { + volatile unsigned int read_counter : 31; + volatile unsigned int write_lock : 1; +-} raw_rwlock_t; ++} __raw_rwlock_t; + + #define __RAW_RW_LOCK_UNLOCKED { 0, 0 } + +Index: linux-2.6.24.7-rt21/include/asm-ia64/system.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-ia64/system.h 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-ia64/system.h 2008-10-08 22:23:52.000000000 -0400 +@@ -106,81 +106,16 @@ extern struct ia64_boot_param { + */ + #define set_mb(var, value) do { (var) = (value); mb(); } while (0) + +-#define safe_halt() ia64_pal_halt_light() /* PAL_HALT_LIGHT */ + + /* + * The group barrier in front of the rsm & ssm are necessary to ensure + * that none of the previous instructions in the same group are + * affected by the rsm/ssm. + */ +-/* For spinlocks etc */ + +-/* +- * - clearing psr.i is implicitly serialized (visible by next insn) +- * - setting psr.i requires data serialization +- * - we need a stop-bit before reading PSR because we sometimes +- * write a floating-point register right before reading the PSR +- * and that writes to PSR.mfl +- */ +-#define __local_irq_save(x) \ +-do { \ +- ia64_stop(); \ +- (x) = ia64_getreg(_IA64_REG_PSR); \ +- ia64_stop(); \ +- ia64_rsm(IA64_PSR_I); \ +-} while (0) +- +-#define __local_irq_disable() \ +-do { \ +- ia64_stop(); \ +- ia64_rsm(IA64_PSR_I); \ +-} while (0) +- +-#define __local_irq_restore(x) ia64_intrin_local_irq_restore((x) & IA64_PSR_I) +- +-#ifdef CONFIG_IA64_DEBUG_IRQ + +- extern unsigned long last_cli_ip; +- +-# define __save_ip() last_cli_ip = ia64_getreg(_IA64_REG_IP) +- +-# define local_irq_save(x) \ +-do { \ +- unsigned long psr; \ +- \ +- __local_irq_save(psr); \ +- if (psr & IA64_PSR_I) \ +- __save_ip(); \ +- (x) = psr; \ +-} while (0) +- +-# define local_irq_disable() do { unsigned long x; local_irq_save(x); } while (0) +- +-# define local_irq_restore(x) \ +-do { \ +- unsigned long old_psr, psr = (x); \ +- \ +- local_save_flags(old_psr); \ +- __local_irq_restore(psr); \ +- if ((old_psr & IA64_PSR_I) && !(psr & IA64_PSR_I)) \ +- __save_ip(); \ +-} while (0) ++#include + +-#else /* !CONFIG_IA64_DEBUG_IRQ */ +-# define local_irq_save(x) __local_irq_save(x) +-# define local_irq_disable() __local_irq_disable() +-# define local_irq_restore(x) __local_irq_restore(x) +-#endif /* !CONFIG_IA64_DEBUG_IRQ */ +- +-#define local_irq_enable() ({ ia64_stop(); ia64_ssm(IA64_PSR_I); ia64_srlz_d(); }) +-#define local_save_flags(flags) ({ ia64_stop(); (flags) = ia64_getreg(_IA64_REG_PSR); }) +- +-#define irqs_disabled() \ +-({ \ +- unsigned long __ia64_id_flags; \ +- local_save_flags(__ia64_id_flags); \ +- (__ia64_id_flags & IA64_PSR_I) == 0; \ +-}) + + #ifdef __KERNEL__ + +Index: linux-2.6.24.7-rt21/include/asm-ia64/thread_info.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-ia64/thread_info.h 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-ia64/thread_info.h 2008-10-08 22:23:52.000000000 -0400 +@@ -91,6 +91,7 @@ struct thread_info { + #define TIF_MCA_INIT 18 /* this task is processing MCA or INIT */ + #define TIF_DB_DISABLED 19 /* debug trap disabled for fsyscall */ + #define TIF_FREEZE 20 /* is freezing for suspend */ ++#define TIF_NEED_RESCHED_DELAYED 20 /* reschedule on return to userspace */ + + #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) + #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) +Index: linux-2.6.24.7-rt21/include/asm-ia64/tlb.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-ia64/tlb.h 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-ia64/tlb.h 2008-10-08 22:23:52.000000000 -0400 +@@ -40,6 +40,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -61,11 +62,12 @@ struct mmu_gather { + unsigned char need_flush; /* really unmapped some PTEs? */ + unsigned long start_addr; + unsigned long end_addr; ++ int cpu; + struct page *pages[FREE_PTE_NR]; + }; + + /* Users of the generic TLB shootdown code must declare this storage space. */ +-DECLARE_PER_CPU(struct mmu_gather, mmu_gathers); ++DECLARE_PER_CPU_LOCKED(struct mmu_gather, mmu_gathers); + + /* + * Flush the TLB for address range START to END and, if not in fast mode, release the +@@ -127,8 +129,10 @@ ia64_tlb_flush_mmu (struct mmu_gather *t + static inline struct mmu_gather * + tlb_gather_mmu (struct mm_struct *mm, unsigned int full_mm_flush) + { +- struct mmu_gather *tlb = &get_cpu_var(mmu_gathers); ++ int cpu; ++ struct mmu_gather *tlb = &get_cpu_var_locked(mmu_gathers, &cpu); + ++ tlb->cpu = cpu; + tlb->mm = mm; + /* + * Use fast mode if only 1 CPU is online. +@@ -165,7 +169,7 @@ tlb_finish_mmu (struct mmu_gather *tlb, + /* keep the page table cache within bounds */ + check_pgt_cache(); + +- put_cpu_var(mmu_gathers); ++ put_cpu_var_locked(mmu_gathers, tlb->cpu); + } + + /* --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0094-i386-mark-atomic-irq-ops-raw.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0094-i386-mark-atomic-irq-ops-raw.patch @@ -0,0 +1,21 @@ +--- + include/asm-x86/atomic_32.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/include/asm-x86/atomic_32.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-x86/atomic_32.h 2008-10-08 22:22:41.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-x86/atomic_32.h 2008-10-08 22:23:19.000000000 -0400 +@@ -195,10 +195,10 @@ static __inline__ int atomic_add_return( + + #ifdef CONFIG_M386 + no_xadd: /* Legacy 386 processor */ +- local_irq_save(flags); ++ raw_local_irq_save(flags); + __i = atomic_read(v); + atomic_set(v, i + __i); +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + return i + __i; + #endif + } --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0415-mips-remove-finish-arch-switch.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0415-mips-remove-finish-arch-switch.patch @@ -0,0 +1,59 @@ +From: Frank Rowand +Subject: [PATCH 3/4] RT: remove finish_arch_switch +To: linux-kernel@vger.kernel.org +Cc: mingo@redhat.com, tglx@linutronix.de +Date: Tue, 15 Jan 2008 14:20:46 -0800 + +From: Frank Rowand + +This is probably just a temporary workaround for one procssor - the MIPS +community will most likely want to architect a solution to this issue. + +Make of preempt kernel barfs in kernel/sched.c ifdef finish_arch_switch. +Remove the finish_arch_switch() for boards with TX49xx MIPS processor. + +Signed-off-by: Frank Rowand +--- + include/asm-mips/mach-tx49xx/cpu-feature-overrides.h | 7 +++++++ + include/asm-mips/system.h | 3 +++ + 2 files changed, 10 insertions(+) + +Index: linux-2.6.24.7-rt21/include/asm-mips/mach-tx49xx/cpu-feature-overrides.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-mips/mach-tx49xx/cpu-feature-overrides.h 2008-10-08 22:22:16.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-mips/mach-tx49xx/cpu-feature-overrides.h 2008-10-08 22:24:43.000000000 -0400 +@@ -1,6 +1,13 @@ + #ifndef __ASM_MACH_TX49XX_CPU_FEATURE_OVERRIDES_H + #define __ASM_MACH_TX49XX_CPU_FEATURE_OVERRIDES_H + ++/* finish_arch_switch_empty is defined if we know finish_arch_switch() will ++ * be empty, based on the lack of features defined in this file. This is ++ * needed because config preempt will barf in kernel/sched.c ifdef ++ * finish_arch_switch ++ */ ++#define finish_arch_switch_empty ++ + #define cpu_has_llsc 1 + #define cpu_has_64bits 1 + #define cpu_has_inclusive_pcaches 0 +Index: linux-2.6.24.7-rt21/include/asm-mips/system.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-mips/system.h 2008-10-08 22:22:16.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-mips/system.h 2008-10-08 22:24:43.000000000 -0400 +@@ -70,6 +70,8 @@ do { \ + (last) = resume(prev, next, task_thread_info(next)); \ + } while (0) + ++/* preempt kernel barfs in kernel/sched.c ifdef finish_arch_switch */ ++#ifndef finish_arch_switch_empty + #define finish_arch_switch(prev) \ + do { \ + if (cpu_has_dsp) \ +@@ -77,6 +79,7 @@ do { \ + if (cpu_has_userlocal) \ + write_c0_userlocal(current_thread_info()->tp_value); \ + } while (0) ++#endif + + static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) + { --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0211-preempt-realtime-arm-integrator.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0211-preempt-realtime-arm-integrator.patch @@ -0,0 +1,31 @@ +--- + arch/arm/mach-integrator/core.c | 2 +- + arch/arm/mach-integrator/pci_v3.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/arm/mach-integrator/core.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/arm/mach-integrator/core.c 2008-10-08 22:22:32.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/arm/mach-integrator/core.c 2008-10-08 22:23:50.000000000 -0400 +@@ -164,7 +164,7 @@ static struct amba_pl010_data integrator + + #define CM_CTRL IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_CTRL_OFFSET + +-static DEFINE_SPINLOCK(cm_lock); ++static DEFINE_RAW_SPINLOCK(cm_lock); + + /** + * cm_control - update the CM_CTRL register. +Index: linux-2.6.24.7-rt21/arch/arm/mach-integrator/pci_v3.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/arm/mach-integrator/pci_v3.c 2008-10-08 22:22:32.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/arm/mach-integrator/pci_v3.c 2008-10-08 22:23:50.000000000 -0400 +@@ -162,7 +162,7 @@ + * 7:2 register number + * + */ +-static DEFINE_SPINLOCK(v3_lock); ++static DEFINE_RAW_SPINLOCK(v3_lock); + + #define PCI_BUS_NONMEM_START 0x00000000 + #define PCI_BUS_NONMEM_SIZE SZ_256M --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0119-ppc-gtod-notrace-fix.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0119-ppc-gtod-notrace-fix.patch @@ -0,0 +1,17 @@ +--- + arch/powerpc/kernel/time.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/arch/powerpc/kernel/time.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/kernel/time.c 2008-10-08 22:22:40.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/kernel/time.c 2008-10-08 22:23:25.000000000 -0400 +@@ -751,7 +751,7 @@ static cycle_t rtc_read(void) + return (cycle_t)get_rtc(); + } + +-static cycle_t timebase_read(void) ++static cycle_t notrace timebase_read(void) + { + return (cycle_t)get_tb(); + } --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0481-realtime-preempt-warn-about-tracing.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0481-realtime-preempt-warn-about-tracing.patch @@ -0,0 +1,41 @@ +--- + init/main.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +Index: linux-2.6.24.7-rt21/init/main.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/init/main.c 2008-10-08 22:24:20.000000000 -0400 ++++ linux-2.6.24.7-rt21/init/main.c 2008-10-08 22:24:59.000000000 -0400 +@@ -878,7 +878,7 @@ static int __init kernel_init(void * unu + WARN_ON(irqs_disabled()); + #endif + +-#define DEBUG_COUNT (defined(CONFIG_DEBUG_RT_MUTEXES) + defined(CONFIG_CRITICAL_PREEMPT_TIMING) + defined(CONFIG_CRITICAL_IRQSOFF_TIMING) + defined(CONFIG_FUNCTION_TRACE) + defined(CONFIG_DEBUG_SLAB) + defined(CONFIG_DEBUG_PAGEALLOC) + defined(CONFIG_LOCKDEP)) ++#define DEBUG_COUNT (defined(CONFIG_DEBUG_RT_MUTEXES) + defined(CONFIG_IRQSOFF_TRACER) + defined(CONFIG_PREEMPT_TRACER) + defined(CONFIG_FTRACE) + defined(CONFIG_WAKEUP_LATENCY_HIST) + defined(CONFIG_DEBUG_SLAB) + defined(CONFIG_DEBUG_PAGEALLOC) + defined(CONFIG_LOCKDEP)) + + #if DEBUG_COUNT > 0 + printk(KERN_ERR "*****************************************************************************\n"); +@@ -892,14 +892,17 @@ static int __init kernel_init(void * unu + #ifdef CONFIG_DEBUG_RT_MUTEXES + printk(KERN_ERR "* CONFIG_DEBUG_RT_MUTEXES *\n"); + #endif +-#ifdef CONFIG_CRITICAL_PREEMPT_TIMING +- printk(KERN_ERR "* CONFIG_CRITICAL_PREEMPT_TIMING *\n"); ++#ifdef CONFIG_IRQSOFF_TRACER ++ printk(KERN_ERR "* CONFIG_IRQSOFF_TRACER *\n"); + #endif +-#ifdef CONFIG_CRITICAL_IRQSOFF_TIMING +- printk(KERN_ERR "* CONFIG_CRITICAL_IRQSOFF_TIMING *\n"); ++#ifdef CONFIG_PREEMPT_TRACER ++ printk(KERN_ERR "* CONFIG_PREEMPT_TRACER *\n"); + #endif +-#ifdef CONFIG_FUNCTION_TRACE +- printk(KERN_ERR "* CONFIG_FUNCTION_TRACE *\n"); ++#ifdef CONFIG_FTRACE ++ printk(KERN_ERR "* CONFIG_FTRACE *\n"); ++#endif ++#ifdef CONFIG_WAKEUP_LATENCY_HIST ++ printk(KERN_ERR "* CONFIG_WAKEUP_LATENCY_HIST *\n"); + #endif + #ifdef CONFIG_DEBUG_SLAB + printk(KERN_ERR "* CONFIG_DEBUG_SLAB *\n"); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0201-posix-cpu-timers-fix.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0201-posix-cpu-timers-fix.patch @@ -0,0 +1,29 @@ + kernel/posix-cpu-timers.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/kernel/posix-cpu-timers.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/posix-cpu-timers.c 2008-10-08 22:23:47.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/posix-cpu-timers.c 2008-10-08 22:23:47.000000000 -0400 +@@ -1296,6 +1296,12 @@ void __run_posix_cpu_timers(struct task_ + * Double-check with locks held. + */ + read_lock(&tasklist_lock); ++ /* Make sure the task doesn't exit under us. */ ++ if (unlikely(tsk->exit_state)) { ++ read_unlock(&tasklist_lock); ++ return; ++ } ++ + if (likely(tsk->signal != NULL)) { + spin_lock(&tsk->sighand->siglock); + +@@ -1424,7 +1430,7 @@ void run_posix_cpu_timers(struct task_st + + if (UNEXPIRED(prof) && UNEXPIRED(virt) && + (tsk->it_sched_expires == 0 || +- tsk->sum_exec_runtime < tsk->it_sched_expires)) ++ tsk->se.sum_exec_runtime < tsk->it_sched_expires)) + return; + + #undef UNEXPIRED --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0524-fix_SCHED_FIFO_spec_violation.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0524-fix_SCHED_FIFO_spec_violation.patch @@ -0,0 +1,242 @@ +Enqueue deprioritized RT tasks to head of prio array + +From: Clark Williams + +This patch backports Peter Z's enqueue to head of prio array on +de-prioritization to 2.6.24.7-rt14 which doesn't have the +enqueue_rt_entity and associated changes. + +I've run several long running real-time java benchmarks and it's +holding so far. Steven, please consider this patch for inclusion +in the next 2.6.24.7-rtX release. + +Peter, I didn't include your Signed-off-by as only about half your +original patch applied to 2.6.24.7-r14. If you're happy with this +version, would you also sign off? + +Signed-off-by: Darren Hart +--- + + include/linux/sched.h | 9 +++++++-- + kernel/sched.c | 27 ++++++++++++++------------- + kernel/sched_fair.c | 6 ++++-- + kernel/sched_idletask.c | 2 +- + kernel/sched_rt.c | 13 +++++++++---- + 5 files changed, 35 insertions(+), 22 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/sched.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/sched.h 2008-10-08 22:25:08.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/sched.h 2008-10-08 22:25:10.000000000 -0400 +@@ -897,11 +897,16 @@ struct uts_namespace; + struct rq; + struct sched_domain; + ++#define ENQUEUE_WAKEUP 0x01 ++#define ENQUEUE_HEAD 0x02 ++ ++#define DEQUEUE_SLEEP 0x01 ++ + struct sched_class { + const struct sched_class *next; + +- void (*enqueue_task) (struct rq *rq, struct task_struct *p, int wakeup); +- void (*dequeue_task) (struct rq *rq, struct task_struct *p, int sleep); ++ void (*enqueue_task) (struct rq *rq, struct task_struct *p, int flags); ++ void (*dequeue_task) (struct rq *rq, struct task_struct *p, int flags); + void (*yield_task) (struct rq *rq); + int (*select_task_rq)(struct task_struct *p, int sync); + +Index: linux-2.6.24.7-rt21/kernel/sched.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched.c 2008-10-08 22:25:09.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched.c 2008-10-08 22:25:10.000000000 -0400 +@@ -1046,7 +1046,7 @@ static const u32 prio_to_wmult[40] = { + /* 15 */ 119304647, 148102320, 186737708, 238609294, 286331153, + }; + +-static void activate_task(struct rq *rq, struct task_struct *p, int wakeup); ++static void activate_task(struct rq *rq, struct task_struct *p, int flags); + + /* + * runqueue iterator, to support SMP load-balancing between different +@@ -1155,16 +1155,16 @@ static void set_load_weight(struct task_ + p->se.load.inv_weight = prio_to_wmult[p->static_prio - MAX_RT_PRIO]; + } + +-static void enqueue_task(struct rq *rq, struct task_struct *p, int wakeup) ++static void enqueue_task(struct rq *rq, struct task_struct *p, int flags) + { + sched_info_queued(p); +- p->sched_class->enqueue_task(rq, p, wakeup); ++ p->sched_class->enqueue_task(rq, p, flags); + p->se.on_rq = 1; + } + +-static void dequeue_task(struct rq *rq, struct task_struct *p, int sleep) ++static void dequeue_task(struct rq *rq, struct task_struct *p, int flags) + { +- p->sched_class->dequeue_task(rq, p, sleep); ++ p->sched_class->dequeue_task(rq, p, flags); + p->se.on_rq = 0; + } + +@@ -1219,26 +1219,26 @@ static int effective_prio(struct task_st + /* + * activate_task - move a task to the runqueue. + */ +-static void activate_task(struct rq *rq, struct task_struct *p, int wakeup) ++static void activate_task(struct rq *rq, struct task_struct *p, int flags) + { + if (p->state == TASK_UNINTERRUPTIBLE) + rq->nr_uninterruptible--; + + ftrace_event_task_activate(p, cpu_of(rq)); +- enqueue_task(rq, p, wakeup); ++ enqueue_task(rq, p, flags); + inc_nr_running(p, rq); + } + + /* + * deactivate_task - remove a task from the runqueue. + */ +-static void deactivate_task(struct rq *rq, struct task_struct *p, int sleep) ++static void deactivate_task(struct rq *rq, struct task_struct *p, int flags) + { + if (p->state == TASK_UNINTERRUPTIBLE) + rq->nr_uninterruptible++; + + ftrace_event_task_deactivate(p, cpu_of(rq)); +- dequeue_task(rq, p, sleep); ++ dequeue_task(rq, p, flags); + dec_nr_running(p, rq); + } + +@@ -1759,7 +1759,7 @@ out_activate: + else + schedstat_inc(p, se.nr_wakeups_remote); + update_rq_clock(rq); +- activate_task(rq, p, 1); ++ activate_task(rq, p, ENQUEUE_WAKEUP); + check_preempt_curr(rq, p); + success = 1; + +@@ -3968,7 +3968,7 @@ asmlinkage void __sched __schedule(void) + prev->state = TASK_RUNNING; + } else { + touch_softlockup_watchdog(); +- deactivate_task(rq, prev, 1); ++ deactivate_task(rq, prev, DEQUEUE_SLEEP); + } + switch_count = &prev->nvcsw; + } +@@ -4431,7 +4431,7 @@ EXPORT_SYMBOL(sleep_on_timeout); + void task_setprio(struct task_struct *p, int prio) + { + unsigned long flags; +- int oldprio, prev_resched, on_rq, running; ++ int oldprio, prev_resched, on_rq, running, down; + struct rq *rq; + const struct sched_class *prev_class = p->sched_class; + +@@ -4472,6 +4472,7 @@ void task_setprio(struct task_struct *p, + else + p->sched_class = &fair_sched_class; + ++ down = (prio > p->prio) ? ENQUEUE_HEAD : 0; + p->prio = prio; + + // trace_special_pid(p->pid, __PRIO(oldprio), PRIO(p)); +@@ -4480,7 +4481,7 @@ void task_setprio(struct task_struct *p, + if (running) + p->sched_class->set_curr_task(rq); + if (on_rq) { +- enqueue_task(rq, p, 0); ++ enqueue_task(rq, p, down); + check_class_changed(rq, p, prev_class, oldprio, running); + } + // trace_special(prev_resched, _need_resched(), 0); +Index: linux-2.6.24.7-rt21/kernel/sched_fair.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched_fair.c 2008-10-08 22:25:01.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched_fair.c 2008-10-08 22:25:10.000000000 -0400 +@@ -756,10 +756,11 @@ static inline struct sched_entity *paren + * increased. Here we update the fair scheduling stats and + * then put the task into the rbtree: + */ +-static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup) ++static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags) + { + struct cfs_rq *cfs_rq; + struct sched_entity *se = &p->se; ++ int wakeup = flags & ENQUEUE_WAKEUP; + + for_each_sched_entity(se) { + if (se->on_rq) +@@ -775,10 +776,11 @@ static void enqueue_task_fair(struct rq + * decreased. We remove the task from the rbtree and + * update the fair scheduling stats: + */ +-static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int sleep) ++static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int flags) + { + struct cfs_rq *cfs_rq; + struct sched_entity *se = &p->se; ++ int sleep = flags & DEQUEUE_SLEEP; + + for_each_sched_entity(se) { + cfs_rq = cfs_rq_of(se); +Index: linux-2.6.24.7-rt21/kernel/sched_idletask.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched_idletask.c 2008-10-08 22:24:55.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched_idletask.c 2008-10-08 22:25:10.000000000 -0400 +@@ -31,7 +31,7 @@ static struct task_struct *pick_next_tas + * message if some code attempts to do it: + */ + static void +-dequeue_task_idle(struct rq *rq, struct task_struct *p, int sleep) ++dequeue_task_idle(struct rq *rq, struct task_struct *p, int flags) + { + spin_unlock_irq(&rq->lock); + printk(KERN_ERR "bad: scheduling from the idle thread!\n"); +Index: linux-2.6.24.7-rt21/kernel/sched_rt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched_rt.c 2008-10-08 22:25:03.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched_rt.c 2008-10-08 22:25:10.000000000 -0400 +@@ -181,11 +181,16 @@ unsigned long rt_nr_uninterruptible_cpu( + return cpu_rq(cpu)->rt.rt_nr_uninterruptible; + } + +-static void enqueue_task_rt(struct rq *rq, struct task_struct *p, int wakeup) ++static void enqueue_task_rt(struct rq *rq, struct task_struct *p, int flags) + { + struct rt_prio_array *array = &rq->rt.active; + +- list_add_tail(&p->run_list, array->queue + p->prio); ++ ++ if (unlikely(flags & ENQUEUE_HEAD)) ++ list_add(&p->run_list, array->queue + p->prio); ++ else ++ list_add_tail(&p->run_list, array->queue + p->prio); ++ + __set_bit(p->prio, array->bitmap); + inc_rt_tasks(p, rq); + +@@ -196,7 +201,7 @@ static void enqueue_task_rt(struct rq *r + /* + * Adding/removing a task to/from a priority array: + */ +-static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int sleep) ++static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int flags) + { + struct rt_prio_array *array = &rq->rt.active; + +@@ -306,7 +311,7 @@ static void put_prev_task_rt(struct rq * + #define RT_MAX_TRIES 3 + + static int double_lock_balance(struct rq *this_rq, struct rq *busiest); +-static void deactivate_task(struct rq *rq, struct task_struct *p, int sleep); ++static void deactivate_task(struct rq *rq, struct task_struct *p, int flags); + + static int pick_rt_task(struct rq *rq, struct task_struct *p, int cpu) + { --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0162-rt-slab-new.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0162-rt-slab-new.patch @@ -0,0 +1,1271 @@ + +new slab port. + +Signed-off-by: Ingo Molnar + +--- + mm/slab.c | 494 +++++++++++++++++++++++++++++++++++++++----------------------- + 1 file changed, 317 insertions(+), 177 deletions(-) + +Index: linux-2.6.24.7-rt21/mm/slab.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/mm/slab.c 2008-10-08 22:22:36.000000000 -0400 ++++ linux-2.6.24.7-rt21/mm/slab.c 2008-10-08 22:23:35.000000000 -0400 +@@ -116,6 +116,63 @@ + #include + + /* ++ * On !PREEMPT_RT, raw irq flags are used as a per-CPU locking ++ * mechanism. ++ * ++ * On PREEMPT_RT, we use per-CPU locks for this. That's why the ++ * calling convention is changed slightly: a new 'flags' argument ++ * is passed to 'irq disable/enable' - the PREEMPT_RT code stores ++ * the CPU number of the lock there. ++ */ ++#ifndef CONFIG_PREEMPT_RT ++# define slab_irq_disable(cpu) \ ++ do { local_irq_disable(); (cpu) = smp_processor_id(); } while (0) ++# define slab_irq_enable(cpu) local_irq_enable() ++# define slab_irq_save(flags, cpu) \ ++ do { local_irq_save(flags); (cpu) = smp_processor_id(); } while (0) ++# define slab_irq_restore(flags, cpu) local_irq_restore(flags) ++/* ++ * In the __GFP_WAIT case we enable/disable interrupts on !PREEMPT_RT, ++ * which has no per-CPU locking effect since we are holding the cache ++ * lock in that case already. ++ * ++ * (On PREEMPT_RT, these are NOPs, but we have to drop/get the irq locks.) ++ */ ++# define slab_irq_disable_nort() local_irq_disable() ++# define slab_irq_enable_nort() local_irq_enable() ++# define slab_irq_disable_rt(flags) do { (void)(flags); } while (0) ++# define slab_irq_enable_rt(flags) do { (void)(flags); } while (0) ++# define slab_spin_lock_irq(lock, cpu) \ ++ do { spin_lock_irq(lock); (cpu) = smp_processor_id(); } while (0) ++# define slab_spin_unlock_irq(lock, cpu) \ ++ spin_unlock_irq(lock) ++# define slab_spin_lock_irqsave(lock, flags, cpu) \ ++ do { spin_lock_irqsave(lock, flags); (cpu) = smp_processor_id(); } while (0) ++# define slab_spin_unlock_irqrestore(lock, flags, cpu) \ ++ do { spin_unlock_irqrestore(lock, flags); } while (0) ++#else ++DEFINE_PER_CPU_LOCKED(int, slab_irq_locks) = { 0, }; ++# define slab_irq_disable(cpu) (void)get_cpu_var_locked(slab_irq_locks, &(cpu)) ++# define slab_irq_enable(cpu) put_cpu_var_locked(slab_irq_locks, cpu) ++# define slab_irq_save(flags, cpu) \ ++ do { slab_irq_disable(cpu); (void) (flags); } while (0) ++# define slab_irq_restore(flags, cpu) \ ++ do { slab_irq_enable(cpu); (void) (flags); } while (0) ++# define slab_irq_disable_rt(cpu) slab_irq_disable(cpu) ++# define slab_irq_enable_rt(cpu) slab_irq_enable(cpu) ++# define slab_irq_disable_nort() do { } while (0) ++# define slab_irq_enable_nort() do { } while (0) ++# define slab_spin_lock_irq(lock, cpu) \ ++ do { slab_irq_disable(cpu); spin_lock(lock); } while (0) ++# define slab_spin_unlock_irq(lock, cpu) \ ++ do { spin_unlock(lock); slab_irq_enable(cpu); } while (0) ++# define slab_spin_lock_irqsave(lock, flags, cpu) \ ++ do { slab_irq_disable(cpu); spin_lock_irqsave(lock, flags); } while (0) ++# define slab_spin_unlock_irqrestore(lock, flags, cpu) \ ++ do { spin_unlock_irqrestore(lock, flags); slab_irq_enable(cpu); } while (0) ++#endif ++ ++/* + * DEBUG - 1 for kmem_cache_create() to honour; SLAB_RED_ZONE & SLAB_POISON. + * 0 for faster, smaller code (especially in the critical paths). + * +@@ -313,7 +370,7 @@ struct kmem_list3 __initdata initkmem_li + static int drain_freelist(struct kmem_cache *cache, + struct kmem_list3 *l3, int tofree); + static void free_block(struct kmem_cache *cachep, void **objpp, int len, +- int node); ++ int node, int *this_cpu); + static int enable_cpucache(struct kmem_cache *cachep); + static void cache_reap(struct work_struct *unused); + +@@ -757,9 +814,10 @@ int slab_is_available(void) + + static DEFINE_PER_CPU(struct delayed_work, reap_work); + +-static inline struct array_cache *cpu_cache_get(struct kmem_cache *cachep) ++static inline struct array_cache * ++cpu_cache_get(struct kmem_cache *cachep, int this_cpu) + { +- return cachep->array[smp_processor_id()]; ++ return cachep->array[this_cpu]; + } + + static inline struct kmem_cache *__find_general_cachep(size_t size, +@@ -993,7 +1051,7 @@ static int transfer_objects(struct array + #ifndef CONFIG_NUMA + + #define drain_alien_cache(cachep, alien) do { } while (0) +-#define reap_alien(cachep, l3) do { } while (0) ++#define reap_alien(cachep, l3, this_cpu) do { } while (0) + + static inline struct array_cache **alloc_alien_cache(int node, int limit) + { +@@ -1004,7 +1062,8 @@ static inline void free_alien_cache(stru + { + } + +-static inline int cache_free_alien(struct kmem_cache *cachep, void *objp) ++static inline int ++cache_free_alien(struct kmem_cache *cachep, void *objp, int *this_cpu) + { + return 0; + } +@@ -1016,14 +1075,15 @@ static inline void *alternate_node_alloc + } + + static inline void *____cache_alloc_node(struct kmem_cache *cachep, +- gfp_t flags, int nodeid) ++ gfp_t flags, int nodeid, int *this_cpu) + { + return NULL; + } + + #else /* CONFIG_NUMA */ + +-static void *____cache_alloc_node(struct kmem_cache *, gfp_t, int); ++static void *____cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, ++ int nodeid, int *this_cpu); + static void *alternate_node_alloc(struct kmem_cache *, gfp_t); + + static struct array_cache **alloc_alien_cache(int node, int limit) +@@ -1065,7 +1125,8 @@ static void free_alien_cache(struct arra + } + + static void __drain_alien_cache(struct kmem_cache *cachep, +- struct array_cache *ac, int node) ++ struct array_cache *ac, int node, ++ int *this_cpu) + { + struct kmem_list3 *rl3 = cachep->nodelists[node]; + +@@ -1079,7 +1140,7 @@ static void __drain_alien_cache(struct k + if (rl3->shared) + transfer_objects(rl3->shared, ac, ac->limit); + +- free_block(cachep, ac->entry, ac->avail, node); ++ free_block(cachep, ac->entry, ac->avail, node, this_cpu); + ac->avail = 0; + spin_unlock(&rl3->list_lock); + } +@@ -1088,15 +1149,16 @@ static void __drain_alien_cache(struct k + /* + * Called from cache_reap() to regularly drain alien caches round robin. + */ +-static void reap_alien(struct kmem_cache *cachep, struct kmem_list3 *l3) ++static void ++reap_alien(struct kmem_cache *cachep, struct kmem_list3 *l3, int *this_cpu) + { +- int node = __get_cpu_var(reap_node); ++ int node = per_cpu(reap_node, *this_cpu); + + if (l3->alien) { + struct array_cache *ac = l3->alien[node]; + + if (ac && ac->avail && spin_trylock_irq(&ac->lock)) { +- __drain_alien_cache(cachep, ac, node); ++ __drain_alien_cache(cachep, ac, node, this_cpu); + spin_unlock_irq(&ac->lock); + } + } +@@ -1105,21 +1167,22 @@ static void reap_alien(struct kmem_cache + static void drain_alien_cache(struct kmem_cache *cachep, + struct array_cache **alien) + { +- int i = 0; ++ int i = 0, this_cpu; + struct array_cache *ac; + unsigned long flags; + + for_each_online_node(i) { + ac = alien[i]; + if (ac) { +- spin_lock_irqsave(&ac->lock, flags); +- __drain_alien_cache(cachep, ac, i); +- spin_unlock_irqrestore(&ac->lock, flags); ++ slab_spin_lock_irqsave(&ac->lock, flags, this_cpu); ++ __drain_alien_cache(cachep, ac, i, &this_cpu); ++ slab_spin_unlock_irqrestore(&ac->lock, flags, this_cpu); + } + } + } + +-static inline int cache_free_alien(struct kmem_cache *cachep, void *objp) ++static inline int ++cache_free_alien(struct kmem_cache *cachep, void *objp, int *this_cpu) + { + struct slab *slabp = virt_to_slab(objp); + int nodeid = slabp->nodeid; +@@ -1143,13 +1206,13 @@ static inline int cache_free_alien(struc + spin_lock(&alien->lock); + if (unlikely(alien->avail == alien->limit)) { + STATS_INC_ACOVERFLOW(cachep); +- __drain_alien_cache(cachep, alien, nodeid); ++ __drain_alien_cache(cachep, alien, nodeid, this_cpu); + } + alien->entry[alien->avail++] = objp; + spin_unlock(&alien->lock); + } else { + spin_lock(&(cachep->nodelists[nodeid])->list_lock); +- free_block(cachep, &objp, 1, nodeid); ++ free_block(cachep, &objp, 1, nodeid, this_cpu); + spin_unlock(&(cachep->nodelists[nodeid])->list_lock); + } + return 1; +@@ -1166,6 +1229,7 @@ static void __cpuinit cpuup_canceled(lon + struct array_cache *nc; + struct array_cache *shared; + struct array_cache **alien; ++ int this_cpu; + cpumask_t mask; + + mask = node_to_cpumask(node); +@@ -1177,29 +1241,31 @@ static void __cpuinit cpuup_canceled(lon + if (!l3) + goto free_array_cache; + +- spin_lock_irq(&l3->list_lock); ++ slab_spin_lock_irq(&l3->list_lock, this_cpu); + + /* Free limit for this kmem_list3 */ + l3->free_limit -= cachep->batchcount; + if (nc) +- free_block(cachep, nc->entry, nc->avail, node); ++ free_block(cachep, nc->entry, nc->avail, node, ++ &this_cpu); + + if (!cpus_empty(mask)) { +- spin_unlock_irq(&l3->list_lock); ++ slab_spin_unlock_irq(&l3->list_lock, ++ this_cpu); + goto free_array_cache; + } + + shared = l3->shared; + if (shared) { + free_block(cachep, shared->entry, +- shared->avail, node); ++ shared->avail, node, &this_cpu); + l3->shared = NULL; + } + + alien = l3->alien; + l3->alien = NULL; + +- spin_unlock_irq(&l3->list_lock); ++ slab_spin_unlock_irq(&l3->list_lock, this_cpu); + + kfree(shared); + if (alien) { +@@ -1228,6 +1294,7 @@ static int __cpuinit cpuup_prepare(long + struct kmem_list3 *l3 = NULL; + int node = cpu_to_node(cpu); + const int memsize = sizeof(struct kmem_list3); ++ int this_cpu; + + /* + * We need to do this right in the beginning since +@@ -1258,11 +1325,11 @@ static int __cpuinit cpuup_prepare(long + cachep->nodelists[node] = l3; + } + +- spin_lock_irq(&cachep->nodelists[node]->list_lock); ++ slab_spin_lock_irq(&cachep->nodelists[node]->list_lock, this_cpu); + cachep->nodelists[node]->free_limit = + (1 + nr_cpus_node(node)) * + cachep->batchcount + cachep->num; +- spin_unlock_irq(&cachep->nodelists[node]->list_lock); ++ slab_spin_unlock_irq(&cachep->nodelists[node]->list_lock, this_cpu); + } + + /* +@@ -1299,7 +1366,7 @@ static int __cpuinit cpuup_prepare(long + l3 = cachep->nodelists[node]; + BUG_ON(!l3); + +- spin_lock_irq(&l3->list_lock); ++ slab_spin_lock_irq(&l3->list_lock, this_cpu); + if (!l3->shared) { + /* + * We are serialised from CPU_DEAD or +@@ -1314,7 +1381,7 @@ static int __cpuinit cpuup_prepare(long + alien = NULL; + } + #endif +- spin_unlock_irq(&l3->list_lock); ++ slab_spin_unlock_irq(&l3->list_lock, this_cpu); + kfree(shared); + free_alien_cache(alien); + } +@@ -1393,11 +1460,13 @@ static void init_list(struct kmem_cache + int nodeid) + { + struct kmem_list3 *ptr; ++ int this_cpu; + + ptr = kmalloc_node(sizeof(struct kmem_list3), GFP_KERNEL, nodeid); + BUG_ON(!ptr); + +- local_irq_disable(); ++ WARN_ON(spin_is_locked(&list->list_lock)); ++ slab_irq_disable(this_cpu); + memcpy(ptr, list, sizeof(struct kmem_list3)); + /* + * Do not assume that spinlocks can be initialized via memcpy: +@@ -1406,7 +1475,7 @@ static void init_list(struct kmem_cache + + MAKE_ALL_LISTS(cachep, ptr, nodeid); + cachep->nodelists[nodeid] = ptr; +- local_irq_enable(); ++ slab_irq_enable(this_cpu); + } + + /* +@@ -1569,36 +1638,34 @@ void __init kmem_cache_init(void) + /* 4) Replace the bootstrap head arrays */ + { + struct array_cache *ptr; ++ int this_cpu; + + ptr = kmalloc(sizeof(struct arraycache_init), GFP_KERNEL); + +- local_irq_disable(); +- BUG_ON(cpu_cache_get(&cache_cache) != &initarray_cache.cache); +- memcpy(ptr, cpu_cache_get(&cache_cache), +- sizeof(struct arraycache_init)); ++ slab_irq_disable(this_cpu); ++ BUG_ON(cpu_cache_get(&cache_cache, this_cpu) != &initarray_cache.cache); ++ memcpy(ptr, cpu_cache_get(&cache_cache, this_cpu), ++ sizeof(struct arraycache_init)); + /* + * Do not assume that spinlocks can be initialized via memcpy: + */ + spin_lock_init(&ptr->lock); +- +- cache_cache.array[smp_processor_id()] = ptr; +- local_irq_enable(); ++ cache_cache.array[this_cpu] = ptr; ++ slab_irq_enable(this_cpu); + + ptr = kmalloc(sizeof(struct arraycache_init), GFP_KERNEL); + +- local_irq_disable(); +- BUG_ON(cpu_cache_get(malloc_sizes[INDEX_AC].cs_cachep) +- != &initarray_generic.cache); +- memcpy(ptr, cpu_cache_get(malloc_sizes[INDEX_AC].cs_cachep), +- sizeof(struct arraycache_init)); ++ slab_irq_disable(this_cpu); ++ BUG_ON(cpu_cache_get(malloc_sizes[INDEX_AC].cs_cachep, this_cpu) ++ != &initarray_generic.cache); ++ memcpy(ptr, cpu_cache_get(malloc_sizes[INDEX_AC].cs_cachep, this_cpu), ++ sizeof(struct arraycache_init)); + /* + * Do not assume that spinlocks can be initialized via memcpy: + */ + spin_lock_init(&ptr->lock); +- +- malloc_sizes[INDEX_AC].cs_cachep->array[smp_processor_id()] = +- ptr; +- local_irq_enable(); ++ malloc_sizes[INDEX_AC].cs_cachep->array[this_cpu] = ptr; ++ slab_irq_enable(this_cpu); + } + /* 5) Replace the bootstrap kmem_list3's */ + { +@@ -1750,7 +1817,7 @@ static void store_stackinfo(struct kmem_ + + *addr++ = 0x12345678; + *addr++ = caller; +- *addr++ = smp_processor_id(); ++ *addr++ = raw_smp_processor_id(); + size -= 3 * sizeof(unsigned long); + { + unsigned long *sptr = &caller; +@@ -1905,7 +1972,11 @@ static void check_poison_obj(struct kmem + } + #endif + ++static void ++__cache_free(struct kmem_cache *cachep, void *objp, int *this_cpu); ++ + #if DEBUG ++ + /** + * slab_destroy_objs - destroy a slab and its objects + * @cachep: cache pointer being destroyed +@@ -1914,7 +1985,8 @@ static void check_poison_obj(struct kmem + * Call the registered destructor for each object in a slab that is being + * destroyed. + */ +-static void slab_destroy_objs(struct kmem_cache *cachep, struct slab *slabp) ++static void ++slab_destroy_objs(struct kmem_cache *cachep, struct slab *slabp) + { + int i; + for (i = 0; i < cachep->num; i++) { +@@ -1957,7 +2029,8 @@ static void slab_destroy_objs(struct kme + * Before calling the slab must have been unlinked from the cache. The + * cache-lock is not held/needed. + */ +-static void slab_destroy(struct kmem_cache *cachep, struct slab *slabp) ++static void ++slab_destroy(struct kmem_cache *cachep, struct slab *slabp, int *this_cpu) + { + void *addr = slabp->s_mem - slabp->colouroff; + +@@ -1971,8 +2044,12 @@ static void slab_destroy(struct kmem_cac + call_rcu(&slab_rcu->head, kmem_rcu_free); + } else { + kmem_freepages(cachep, addr); +- if (OFF_SLAB(cachep)) +- kmem_cache_free(cachep->slabp_cache, slabp); ++ if (OFF_SLAB(cachep)) { ++ if (this_cpu) ++ __cache_free(cachep->slabp_cache, slabp, this_cpu); ++ else ++ kmem_cache_free(cachep->slabp_cache, slabp); ++ } + } + } + +@@ -2069,6 +2146,8 @@ static size_t calculate_slab_order(struc + + static int __init_refok setup_cpu_cache(struct kmem_cache *cachep) + { ++ int this_cpu; ++ + if (g_cpucache_up == FULL) + return enable_cpucache(cachep); + +@@ -2112,10 +2191,12 @@ static int __init_refok setup_cpu_cache( + jiffies + REAPTIMEOUT_LIST3 + + ((unsigned long)cachep) % REAPTIMEOUT_LIST3; + +- cpu_cache_get(cachep)->avail = 0; +- cpu_cache_get(cachep)->limit = BOOT_CPUCACHE_ENTRIES; +- cpu_cache_get(cachep)->batchcount = 1; +- cpu_cache_get(cachep)->touched = 0; ++ this_cpu = raw_smp_processor_id(); ++ ++ cpu_cache_get(cachep, this_cpu)->avail = 0; ++ cpu_cache_get(cachep, this_cpu)->limit = BOOT_CPUCACHE_ENTRIES; ++ cpu_cache_get(cachep, this_cpu)->batchcount = 1; ++ cpu_cache_get(cachep, this_cpu)->touched = 0; + cachep->batchcount = 1; + cachep->limit = BOOT_CPUCACHE_ENTRIES; + return 0; +@@ -2403,19 +2484,19 @@ EXPORT_SYMBOL(kmem_cache_create); + #if DEBUG + static void check_irq_off(void) + { ++/* ++ * On PREEMPT_RT we use locks to protect the per-CPU lists, ++ * and keep interrupts enabled. ++ */ ++#ifndef CONFIG_PREEMPT_RT + BUG_ON(!irqs_disabled()); ++#endif + } + + static void check_irq_on(void) + { ++#ifndef CONFIG_PREEMPT_RT + BUG_ON(irqs_disabled()); +-} +- +-static void check_spinlock_acquired(struct kmem_cache *cachep) +-{ +-#ifdef CONFIG_SMP +- check_irq_off(); +- assert_spin_locked(&cachep->nodelists[numa_node_id()]->list_lock); + #endif + } + +@@ -2430,7 +2511,6 @@ static void check_spinlock_acquired_node + #else + #define check_irq_off() do { } while(0) + #define check_irq_on() do { } while(0) +-#define check_spinlock_acquired(x) do { } while(0) + #define check_spinlock_acquired_node(x, y) do { } while(0) + #endif + +@@ -2438,26 +2518,60 @@ static void drain_array(struct kmem_cach + struct array_cache *ac, + int force, int node); + +-static void do_drain(void *arg) ++static void __do_drain(void *arg, int this_cpu) + { + struct kmem_cache *cachep = arg; ++ int node = cpu_to_node(this_cpu); + struct array_cache *ac; +- int node = numa_node_id(); + + check_irq_off(); +- ac = cpu_cache_get(cachep); ++ ac = cpu_cache_get(cachep, this_cpu); + spin_lock(&cachep->nodelists[node]->list_lock); +- free_block(cachep, ac->entry, ac->avail, node); ++ free_block(cachep, ac->entry, ac->avail, node, &this_cpu); + spin_unlock(&cachep->nodelists[node]->list_lock); + ac->avail = 0; + } + ++#ifdef CONFIG_PREEMPT_RT ++static void do_drain(void *arg, int this_cpu) ++{ ++ __do_drain(arg, this_cpu); ++} ++#else ++static void do_drain(void *arg) ++{ ++ __do_drain(arg, smp_processor_id()); ++} ++#endif ++ ++#ifdef CONFIG_PREEMPT_RT ++/* ++ * execute func() for all CPUs. On PREEMPT_RT we dont actually have ++ * to run on the remote CPUs - we only have to take their CPU-locks. ++ * (This is a rare operation, so cacheline bouncing is not an issue.) ++ */ ++static void ++slab_on_each_cpu(void (*func)(void *arg, int this_cpu), void *arg) ++{ ++ unsigned int i; ++ ++ check_irq_on(); ++ for_each_online_cpu(i) { ++ spin_lock(&__get_cpu_lock(slab_irq_locks, i)); ++ func(arg, i); ++ spin_unlock(&__get_cpu_lock(slab_irq_locks, i)); ++ } ++} ++#else ++# define slab_on_each_cpu(func, cachep) on_each_cpu(func, cachep, 1, 1) ++#endif ++ + static void drain_cpu_caches(struct kmem_cache *cachep) + { + struct kmem_list3 *l3; + int node; + +- on_each_cpu(do_drain, cachep, 1, 1); ++ slab_on_each_cpu(do_drain, cachep); + check_irq_on(); + for_each_online_node(node) { + l3 = cachep->nodelists[node]; +@@ -2482,16 +2596,16 @@ static int drain_freelist(struct kmem_ca + struct kmem_list3 *l3, int tofree) + { + struct list_head *p; +- int nr_freed; ++ int nr_freed, this_cpu; + struct slab *slabp; + + nr_freed = 0; + while (nr_freed < tofree && !list_empty(&l3->slabs_free)) { + +- spin_lock_irq(&l3->list_lock); ++ slab_spin_lock_irq(&l3->list_lock, this_cpu); + p = l3->slabs_free.prev; + if (p == &l3->slabs_free) { +- spin_unlock_irq(&l3->list_lock); ++ slab_spin_unlock_irq(&l3->list_lock, this_cpu); + goto out; + } + +@@ -2500,13 +2614,9 @@ static int drain_freelist(struct kmem_ca + BUG_ON(slabp->inuse); + #endif + list_del(&slabp->list); +- /* +- * Safe to drop the lock. The slab is no longer linked +- * to the cache. +- */ + l3->free_objects -= cache->num; +- spin_unlock_irq(&l3->list_lock); +- slab_destroy(cache, slabp); ++ slab_destroy(cache, slabp, &this_cpu); ++ slab_spin_unlock_irq(&l3->list_lock, this_cpu); + nr_freed++; + } + out: +@@ -2757,8 +2867,8 @@ static void slab_map_pages(struct kmem_c + * Grow (by 1) the number of slabs within a cache. This is called by + * kmem_cache_alloc() when there are no active objs left in a cache. + */ +-static int cache_grow(struct kmem_cache *cachep, +- gfp_t flags, int nodeid, void *objp) ++static int cache_grow(struct kmem_cache *cachep, gfp_t flags, int nodeid, ++ void *objp, int *this_cpu) + { + struct slab *slabp; + size_t offset; +@@ -2787,7 +2897,8 @@ static int cache_grow(struct kmem_cache + offset *= cachep->colour_off; + + if (local_flags & __GFP_WAIT) +- local_irq_enable(); ++ slab_irq_enable_nort(); ++ slab_irq_enable_rt(*this_cpu); + + /* + * The test for missing atomic flag is performed here, rather than +@@ -2817,8 +2928,10 @@ static int cache_grow(struct kmem_cache + + cache_init_objs(cachep, slabp); + ++ slab_irq_disable_rt(*this_cpu); + if (local_flags & __GFP_WAIT) +- local_irq_disable(); ++ slab_irq_disable_nort(); ++ + check_irq_off(); + spin_lock(&l3->list_lock); + +@@ -2831,8 +2944,9 @@ static int cache_grow(struct kmem_cache + opps1: + kmem_freepages(cachep, objp); + failed: ++ slab_irq_disable_rt(*this_cpu); + if (local_flags & __GFP_WAIT) +- local_irq_disable(); ++ slab_irq_disable_nort(); + return 0; + } + +@@ -2954,7 +3068,8 @@ bad: + #define check_slabp(x,y) do { } while(0) + #endif + +-static void *cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags) ++static void * ++cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags, int *this_cpu) + { + int batchcount; + struct kmem_list3 *l3; +@@ -2964,7 +3079,7 @@ static void *cache_alloc_refill(struct k + retry: + check_irq_off(); + node = numa_node_id(); +- ac = cpu_cache_get(cachep); ++ ac = cpu_cache_get(cachep, *this_cpu); + batchcount = ac->batchcount; + if (!ac->touched && batchcount > BATCHREFILL_LIMIT) { + /* +@@ -2974,7 +3089,7 @@ retry: + */ + batchcount = BATCHREFILL_LIMIT; + } +- l3 = cachep->nodelists[node]; ++ l3 = cachep->nodelists[cpu_to_node(*this_cpu)]; + + BUG_ON(ac->avail > 0 || !l3); + spin_lock(&l3->list_lock); +@@ -2997,7 +3112,7 @@ retry: + + slabp = list_entry(entry, struct slab, list); + check_slabp(cachep, slabp); +- check_spinlock_acquired(cachep); ++ check_spinlock_acquired_node(cachep, cpu_to_node(*this_cpu)); + + /* + * The slab was either on partial or free list so +@@ -3011,8 +3126,9 @@ retry: + STATS_INC_ACTIVE(cachep); + STATS_SET_HIGH(cachep); + +- ac->entry[ac->avail++] = slab_get_obj(cachep, slabp, +- node); ++ ac->entry[ac->avail++] = ++ slab_get_obj(cachep, slabp, ++ cpu_to_node(*this_cpu)); + } + check_slabp(cachep, slabp); + +@@ -3031,10 +3147,10 @@ alloc_done: + + if (unlikely(!ac->avail)) { + int x; +- x = cache_grow(cachep, flags | GFP_THISNODE, node, NULL); ++ x = cache_grow(cachep, flags | GFP_THISNODE, cpu_to_node(*this_cpu), NULL, this_cpu); + + /* cache_grow can reenable interrupts, then ac could change. */ +- ac = cpu_cache_get(cachep); ++ ac = cpu_cache_get(cachep, *this_cpu); + if (!x && ac->avail == 0) /* no objects in sight? abort */ + return NULL; + +@@ -3186,21 +3302,22 @@ static inline int should_failslab(struct + + #endif /* CONFIG_FAILSLAB */ + +-static inline void *____cache_alloc(struct kmem_cache *cachep, gfp_t flags) ++static inline void * ++____cache_alloc(struct kmem_cache *cachep, gfp_t flags, int *this_cpu) + { + void *objp; + struct array_cache *ac; + + check_irq_off(); + +- ac = cpu_cache_get(cachep); ++ ac = cpu_cache_get(cachep, *this_cpu); + if (likely(ac->avail)) { + STATS_INC_ALLOCHIT(cachep); + ac->touched = 1; + objp = ac->entry[--ac->avail]; + } else { + STATS_INC_ALLOCMISS(cachep); +- objp = cache_alloc_refill(cachep, flags); ++ objp = cache_alloc_refill(cachep, flags, this_cpu); + } + return objp; + } +@@ -3214,7 +3331,7 @@ static inline void *____cache_alloc(stru + */ + static void *alternate_node_alloc(struct kmem_cache *cachep, gfp_t flags) + { +- int nid_alloc, nid_here; ++ int nid_alloc, nid_here, this_cpu = raw_smp_processor_id(); + + if (in_interrupt() || (flags & __GFP_THISNODE)) + return NULL; +@@ -3224,7 +3341,7 @@ static void *alternate_node_alloc(struct + else if (current->mempolicy) + nid_alloc = slab_node(current->mempolicy); + if (nid_alloc != nid_here) +- return ____cache_alloc_node(cachep, flags, nid_alloc); ++ return ____cache_alloc_node(cachep, flags, nid_alloc, &this_cpu); + return NULL; + } + +@@ -3236,7 +3353,7 @@ static void *alternate_node_alloc(struct + * allocator to do its reclaim / fallback magic. We then insert the + * slab into the proper nodelist and then allocate from it. + */ +-static void *fallback_alloc(struct kmem_cache *cache, gfp_t flags) ++static void *fallback_alloc(struct kmem_cache *cache, gfp_t flags, int *this_cpu) + { + struct zonelist *zonelist; + gfp_t local_flags; +@@ -3262,8 +3379,10 @@ retry: + if (cpuset_zone_allowed_hardwall(*z, flags) && + cache->nodelists[nid] && + cache->nodelists[nid]->free_objects) +- obj = ____cache_alloc_node(cache, +- flags | GFP_THISNODE, nid); ++ ++ obj = ____cache_alloc_node(cache, ++ flags | GFP_THISNODE, nid, ++ this_cpu); + } + + if (!obj) { +@@ -3274,19 +3393,24 @@ retry: + * set and go into memory reserves if necessary. + */ + if (local_flags & __GFP_WAIT) +- local_irq_enable(); ++ slab_irq_enable_nort(); ++ slab_irq_enable_rt(*this_cpu); ++ + kmem_flagcheck(cache, flags); + obj = kmem_getpages(cache, flags, -1); ++ ++ slab_irq_disable_rt(*this_cpu); + if (local_flags & __GFP_WAIT) +- local_irq_disable(); ++ slab_irq_disable_nort(); ++ + if (obj) { + /* + * Insert into the appropriate per node queues + */ + nid = page_to_nid(virt_to_page(obj)); +- if (cache_grow(cache, flags, nid, obj)) { ++ if (cache_grow(cache, flags, nid, obj, this_cpu)) { + obj = ____cache_alloc_node(cache, +- flags | GFP_THISNODE, nid); ++ flags | GFP_THISNODE, nid, this_cpu); + if (!obj) + /* + * Another processor may allocate the +@@ -3307,7 +3431,7 @@ retry: + * A interface to enable slab creation on nodeid + */ + static void *____cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, +- int nodeid) ++ int nodeid, int *this_cpu) + { + struct list_head *entry; + struct slab *slabp; +@@ -3355,11 +3479,11 @@ retry: + + must_grow: + spin_unlock(&l3->list_lock); +- x = cache_grow(cachep, flags | GFP_THISNODE, nodeid, NULL); ++ x = cache_grow(cachep, flags | GFP_THISNODE, nodeid, NULL, this_cpu); + if (x) + goto retry; + +- return fallback_alloc(cachep, flags); ++ return fallback_alloc(cachep, flags, this_cpu); + + done: + return obj; +@@ -3381,39 +3505,41 @@ static __always_inline void * + __cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid, + void *caller) + { +- unsigned long save_flags; ++ unsigned long irqflags; ++ int this_cpu; + void *ptr; + + if (should_failslab(cachep, flags)) + return NULL; + + cache_alloc_debugcheck_before(cachep, flags); +- local_irq_save(save_flags); ++ ++ slab_irq_save(irqflags, this_cpu); + + if (unlikely(nodeid == -1)) +- nodeid = numa_node_id(); ++ nodeid = cpu_to_node(this_cpu); + + if (unlikely(!cachep->nodelists[nodeid])) { + /* Node not bootstrapped yet */ +- ptr = fallback_alloc(cachep, flags); ++ ptr = fallback_alloc(cachep, flags, &this_cpu); + goto out; + } + +- if (nodeid == numa_node_id()) { ++ if (nodeid == cpu_to_node(this_cpu)) { + /* + * Use the locally cached objects if possible. + * However ____cache_alloc does not allow fallback + * to other nodes. It may fail while we still have + * objects on other nodes available. + */ +- ptr = ____cache_alloc(cachep, flags); ++ ptr = ____cache_alloc(cachep, flags, &this_cpu); + if (ptr) + goto out; + } + /* ___cache_alloc_node can fall back to other nodes */ +- ptr = ____cache_alloc_node(cachep, flags, nodeid); ++ ptr = ____cache_alloc_node(cachep, flags, nodeid, &this_cpu); + out: +- local_irq_restore(save_flags); ++ slab_irq_restore(irqflags, this_cpu); + ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, caller); + + if (unlikely((flags & __GFP_ZERO) && ptr)) +@@ -3423,7 +3549,7 @@ __cache_alloc_node(struct kmem_cache *ca + } + + static __always_inline void * +-__do_cache_alloc(struct kmem_cache *cache, gfp_t flags) ++__do_cache_alloc(struct kmem_cache *cache, gfp_t flags, int *this_cpu) + { + void *objp; + +@@ -3432,24 +3558,24 @@ __do_cache_alloc(struct kmem_cache *cach + if (objp) + goto out; + } +- objp = ____cache_alloc(cache, flags); + ++ objp = ____cache_alloc(cache, flags, this_cpu); + /* + * We may just have run out of memory on the local node. + * ____cache_alloc_node() knows how to locate memory on other nodes + */ +- if (!objp) +- objp = ____cache_alloc_node(cache, flags, numa_node_id()); +- ++ if (!objp) ++ objp = ____cache_alloc_node(cache, flags, ++ cpu_to_node(*this_cpu), this_cpu); + out: + return objp; + } + #else + + static __always_inline void * +-__do_cache_alloc(struct kmem_cache *cachep, gfp_t flags) ++__do_cache_alloc(struct kmem_cache *cachep, gfp_t flags, int *this_cpu) + { +- return ____cache_alloc(cachep, flags); ++ return ____cache_alloc(cachep, flags, this_cpu); + } + + #endif /* CONFIG_NUMA */ +@@ -3458,15 +3584,16 @@ static __always_inline void * + __cache_alloc(struct kmem_cache *cachep, gfp_t flags, void *caller) + { + unsigned long save_flags; ++ int this_cpu; + void *objp; + + if (should_failslab(cachep, flags)) + return NULL; + + cache_alloc_debugcheck_before(cachep, flags); +- local_irq_save(save_flags); +- objp = __do_cache_alloc(cachep, flags); +- local_irq_restore(save_flags); ++ slab_irq_save(save_flags, this_cpu); ++ objp = __do_cache_alloc(cachep, flags, &this_cpu); ++ slab_irq_restore(save_flags, this_cpu); + objp = cache_alloc_debugcheck_after(cachep, flags, objp, caller); + prefetchw(objp); + +@@ -3480,7 +3607,7 @@ __cache_alloc(struct kmem_cache *cachep, + * Caller needs to acquire correct kmem_list's list_lock + */ + static void free_block(struct kmem_cache *cachep, void **objpp, int nr_objects, +- int node) ++ int node, int *this_cpu) + { + int i; + struct kmem_list3 *l3; +@@ -3509,7 +3636,7 @@ static void free_block(struct kmem_cache + * a different cache, refer to comments before + * alloc_slabmgmt. + */ +- slab_destroy(cachep, slabp); ++ slab_destroy(cachep, slabp, this_cpu); + } else { + list_add(&slabp->list, &l3->slabs_free); + } +@@ -3523,11 +3650,12 @@ static void free_block(struct kmem_cache + } + } + +-static void cache_flusharray(struct kmem_cache *cachep, struct array_cache *ac) ++static void ++cache_flusharray(struct kmem_cache *cachep, struct array_cache *ac, int *this_cpu) + { + int batchcount; + struct kmem_list3 *l3; +- int node = numa_node_id(); ++ int node = cpu_to_node(*this_cpu); + + batchcount = ac->batchcount; + #if DEBUG +@@ -3549,7 +3677,7 @@ static void cache_flusharray(struct kmem + } + } + +- free_block(cachep, ac->entry, batchcount, node); ++ free_block(cachep, ac->entry, batchcount, node, this_cpu); + free_done: + #if STATS + { +@@ -3578,9 +3706,9 @@ free_done: + * Release an obj back to its cache. If the obj has a constructed state, it must + * be in this state _before_ it is released. Called with disabled ints. + */ +-static inline void __cache_free(struct kmem_cache *cachep, void *objp) ++static void __cache_free(struct kmem_cache *cachep, void *objp, int *this_cpu) + { +- struct array_cache *ac = cpu_cache_get(cachep); ++ struct array_cache *ac = cpu_cache_get(cachep, *this_cpu); + + check_irq_off(); + objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0)); +@@ -3592,7 +3720,7 @@ static inline void __cache_free(struct k + * variable to skip the call, which is mostly likely to be present in + * the cache. + */ +- if (numa_platform && cache_free_alien(cachep, objp)) ++ if (numa_platform && cache_free_alien(cachep, objp, this_cpu)) + return; + + if (likely(ac->avail < ac->limit)) { +@@ -3601,7 +3729,7 @@ static inline void __cache_free(struct k + return; + } else { + STATS_INC_FREEMISS(cachep); +- cache_flusharray(cachep, ac); ++ cache_flusharray(cachep, ac, this_cpu); + ac->entry[ac->avail++] = objp; + } + } +@@ -3759,11 +3887,12 @@ EXPORT_SYMBOL(__kmalloc); + void kmem_cache_free(struct kmem_cache *cachep, void *objp) + { + unsigned long flags; ++ int this_cpu; + +- local_irq_save(flags); ++ slab_irq_save(flags, this_cpu); + debug_check_no_locks_freed(objp, obj_size(cachep)); +- __cache_free(cachep, objp); +- local_irq_restore(flags); ++ __cache_free(cachep, objp, &this_cpu); ++ slab_irq_restore(flags, this_cpu); + } + EXPORT_SYMBOL(kmem_cache_free); + +@@ -3780,15 +3909,16 @@ void kfree(const void *objp) + { + struct kmem_cache *c; + unsigned long flags; ++ int this_cpu; + + if (unlikely(ZERO_OR_NULL_PTR(objp))) + return; +- local_irq_save(flags); ++ slab_irq_save(flags, this_cpu); + kfree_debugcheck(objp); + c = virt_to_cache(objp); + debug_check_no_locks_freed(objp, obj_size(c)); +- __cache_free(c, (void *)objp); +- local_irq_restore(flags); ++ __cache_free(c, (void *)objp, &this_cpu); ++ slab_irq_restore(flags, this_cpu); + } + EXPORT_SYMBOL(kfree); + +@@ -3809,7 +3939,7 @@ EXPORT_SYMBOL_GPL(kmem_cache_name); + */ + static int alloc_kmemlist(struct kmem_cache *cachep) + { +- int node; ++ int node, this_cpu; + struct kmem_list3 *l3; + struct array_cache *new_shared; + struct array_cache **new_alien = NULL; +@@ -3837,11 +3967,11 @@ static int alloc_kmemlist(struct kmem_ca + if (l3) { + struct array_cache *shared = l3->shared; + +- spin_lock_irq(&l3->list_lock); ++ slab_spin_lock_irq(&l3->list_lock, this_cpu); + + if (shared) + free_block(cachep, shared->entry, +- shared->avail, node); ++ shared->avail, node, &this_cpu); + + l3->shared = new_shared; + if (!l3->alien) { +@@ -3850,7 +3980,7 @@ static int alloc_kmemlist(struct kmem_ca + } + l3->free_limit = (1 + nr_cpus_node(node)) * + cachep->batchcount + cachep->num; +- spin_unlock_irq(&l3->list_lock); ++ slab_spin_unlock_irq(&l3->list_lock, this_cpu); + kfree(shared); + free_alien_cache(new_alien); + continue; +@@ -3897,42 +4027,50 @@ struct ccupdate_struct { + struct array_cache *new[NR_CPUS]; + }; + +-static void do_ccupdate_local(void *info) ++static void __do_ccupdate_local(void *info, int this_cpu) + { + struct ccupdate_struct *new = info; + struct array_cache *old; + + check_irq_off(); +- old = cpu_cache_get(new->cachep); ++ old = cpu_cache_get(new->cachep, this_cpu); + +- new->cachep->array[smp_processor_id()] = new->new[smp_processor_id()]; +- new->new[smp_processor_id()] = old; ++ new->cachep->array[this_cpu] = new->new[this_cpu]; ++ new->new[this_cpu] = old; + } + ++#ifdef CONFIG_PREEMPT_RT ++static void do_ccupdate_local(void *arg, int this_cpu) ++{ ++ __do_ccupdate_local(arg, this_cpu); ++} ++#else ++static void do_ccupdate_local(void *arg) ++{ ++ __do_ccupdate_local(arg, smp_processor_id()); ++} ++#endif ++ + /* Always called with the cache_chain_mutex held */ + static int do_tune_cpucache(struct kmem_cache *cachep, int limit, + int batchcount, int shared) + { +- struct ccupdate_struct *new; +- int i; +- +- new = kzalloc(sizeof(*new), GFP_KERNEL); +- if (!new) +- return -ENOMEM; ++ struct ccupdate_struct new; ++ int i, this_cpu; + ++ memset(&new.new, 0, sizeof(new.new)); + for_each_online_cpu(i) { +- new->new[i] = alloc_arraycache(cpu_to_node(i), limit, ++ new.new[i] = alloc_arraycache(cpu_to_node(i), limit, + batchcount); +- if (!new->new[i]) { ++ if (!new.new[i]) { + for (i--; i >= 0; i--) +- kfree(new->new[i]); +- kfree(new); ++ kfree(new.new[i]); + return -ENOMEM; + } + } +- new->cachep = cachep; ++ new.cachep = cachep; + +- on_each_cpu(do_ccupdate_local, (void *)new, 1, 1); ++ slab_on_each_cpu(do_ccupdate_local, (void *)&new); + + check_irq_on(); + cachep->batchcount = batchcount; +@@ -3940,15 +4078,15 @@ static int do_tune_cpucache(struct kmem_ + cachep->shared = shared; + + for_each_online_cpu(i) { +- struct array_cache *ccold = new->new[i]; ++ struct array_cache *ccold = new.new[i]; + if (!ccold) + continue; +- spin_lock_irq(&cachep->nodelists[cpu_to_node(i)]->list_lock); +- free_block(cachep, ccold->entry, ccold->avail, cpu_to_node(i)); +- spin_unlock_irq(&cachep->nodelists[cpu_to_node(i)]->list_lock); ++ slab_spin_lock_irq(&cachep->nodelists[cpu_to_node(i)]->list_lock, this_cpu); ++ free_block(cachep, ccold->entry, ccold->avail, cpu_to_node(i), &this_cpu); ++ slab_spin_unlock_irq(&cachep->nodelists[cpu_to_node(i)]->list_lock, this_cpu); + kfree(ccold); + } +- kfree(new); ++ + return alloc_kmemlist(cachep); + } + +@@ -4012,26 +4150,26 @@ static int enable_cpucache(struct kmem_c + * if drain_array() is used on the shared array. + */ + void drain_array(struct kmem_cache *cachep, struct kmem_list3 *l3, +- struct array_cache *ac, int force, int node) ++ struct array_cache *ac, int force, int node) + { +- int tofree; ++ int tofree, this_cpu; + + if (!ac || !ac->avail) + return; + if (ac->touched && !force) { + ac->touched = 0; + } else { +- spin_lock_irq(&l3->list_lock); ++ slab_spin_lock_irq(&l3->list_lock, this_cpu); + if (ac->avail) { + tofree = force ? ac->avail : (ac->limit + 4) / 5; + if (tofree > ac->avail) + tofree = (ac->avail + 1) / 2; +- free_block(cachep, ac->entry, tofree, node); ++ free_block(cachep, ac->entry, tofree, node, &this_cpu); + ac->avail -= tofree; + memmove(ac->entry, &(ac->entry[tofree]), + sizeof(void *) * ac->avail); + } +- spin_unlock_irq(&l3->list_lock); ++ slab_spin_unlock_irq(&l3->list_lock, this_cpu); + } + } + +@@ -4049,11 +4187,12 @@ void drain_array(struct kmem_cache *cach + */ + static void cache_reap(struct work_struct *w) + { ++ int this_cpu = raw_smp_processor_id(), node = cpu_to_node(this_cpu); + struct kmem_cache *searchp; + struct kmem_list3 *l3; +- int node = numa_node_id(); + struct delayed_work *work = + container_of(w, struct delayed_work, work); ++ int work_done = 0; + + if (!mutex_trylock(&cache_chain_mutex)) + /* Give up. Setup the next iteration. */ +@@ -4069,9 +4208,10 @@ static void cache_reap(struct work_struc + */ + l3 = searchp->nodelists[node]; + +- reap_alien(searchp, l3); ++ reap_alien(searchp, l3, &this_cpu); + +- drain_array(searchp, l3, cpu_cache_get(searchp), 0, node); ++ drain_array(searchp, l3, cpu_cache_get(searchp, this_cpu), ++ 0, node); + + /* + * These are racy checks but it does not matter +@@ -4160,7 +4300,7 @@ static int s_show(struct seq_file *m, vo + unsigned long num_slabs, free_objects = 0, shared_avail = 0; + const char *name; + char *error = NULL; +- int node; ++ int this_cpu, node; + struct kmem_list3 *l3; + + active_objs = 0; +@@ -4171,7 +4311,7 @@ static int s_show(struct seq_file *m, vo + continue; + + check_irq_on(); +- spin_lock_irq(&l3->list_lock); ++ slab_spin_lock_irq(&l3->list_lock, this_cpu); + + list_for_each_entry(slabp, &l3->slabs_full, list) { + if (slabp->inuse != cachep->num && !error) +@@ -4196,7 +4336,7 @@ static int s_show(struct seq_file *m, vo + if (l3->shared) + shared_avail += l3->shared->avail; + +- spin_unlock_irq(&l3->list_lock); ++ slab_spin_unlock_irq(&l3->list_lock, this_cpu); + } + num_slabs += active_slabs; + num_objs = num_slabs * cachep->num; +@@ -4392,7 +4532,7 @@ static int leaks_show(struct seq_file *m + struct kmem_list3 *l3; + const char *name; + unsigned long *n = m->private; +- int node; ++ int node, this_cpu; + int i; + + if (!(cachep->flags & SLAB_STORE_USER)) +@@ -4410,13 +4550,13 @@ static int leaks_show(struct seq_file *m + continue; + + check_irq_on(); +- spin_lock_irq(&l3->list_lock); ++ slab_spin_lock_irq(&l3->list_lock, this_cpu); + + list_for_each_entry(slabp, &l3->slabs_full, list) + handle_slab(n, cachep, slabp); + list_for_each_entry(slabp, &l3->slabs_partial, list) + handle_slab(n, cachep, slabp); +- spin_unlock_irq(&l3->list_lock); ++ slab_spin_unlock_irq(&l3->list_lock, this_cpu); + } + name = cachep->name; + if (n[0] == n[1]) { --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0476-adaptive-adjust-pi-wakeup.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0476-adaptive-adjust-pi-wakeup.patch @@ -0,0 +1,67 @@ +From ghaskins@novell.com Fri May 23 23:34:24 2008 +Date: Tue, 20 May 2008 10:49:31 -0400 +From: Gregory Haskins +To: mingo@elte.hu, tglx@linutronix.de, rostedt@goodmis.org, + linux-rt-users@vger.kernel.org +Cc: linux-kernel@vger.kernel.org, sdietrich@novell.com, pmorreale@novell.com, + mkohari@novell.com, ghaskins@novell.com +Subject: [PATCH 4/5] adjust pi_lock usage in wakeup + + [ The following text is in the "utf-8" character set. ] + [ Your display is set for the "iso-8859-1" character set. ] + [ Some characters may be displayed incorrectly. ] + +From: Peter W.Morreale + +In wakeup_next_waiter(), we take the pi_lock, and then find out whether +we have another waiter to add to the pending owner. We can reduce +contention on the pi_lock for the pending owner if we first obtain the +pointer to the next waiter outside of the pi_lock. + +Signed-off-by: Peter W. Morreale +Signed-off-by: Gregory Haskins +--- + + kernel/rtmutex.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/rtmutex.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rtmutex.c 2008-10-08 22:24:58.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rtmutex.c 2008-10-08 22:24:58.000000000 -0400 +@@ -562,6 +562,7 @@ static void wakeup_next_waiter(struct rt + { + struct rt_mutex_waiter *waiter; + struct task_struct *pendowner; ++ struct rt_mutex_waiter *next; + + spin_lock(¤t->pi_lock); + +@@ -624,6 +625,12 @@ static void wakeup_next_waiter(struct rt + * waiter with higher priority than pending-owner->normal_prio + * is blocked on the unboosted (pending) owner. + */ ++ ++ if (rt_mutex_has_waiters(lock)) ++ next = rt_mutex_top_waiter(lock); ++ else ++ next = NULL; ++ + spin_lock(&pendowner->pi_lock); + + WARN_ON(!pendowner->pi_blocked_on); +@@ -632,12 +639,9 @@ static void wakeup_next_waiter(struct rt + + pendowner->pi_blocked_on = NULL; + +- if (rt_mutex_has_waiters(lock)) { +- struct rt_mutex_waiter *next; +- +- next = rt_mutex_top_waiter(lock); ++ if (next) + plist_add(&next->pi_list_entry, &pendowner->pi_waiters); +- } ++ + spin_unlock(&pendowner->pi_lock); + } + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0504-rt-mutex-use-inline.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0504-rt-mutex-use-inline.patch @@ -0,0 +1,28 @@ +Subject: rt-mutex-cleanup.patch +From: Thomas Gleixner +Date: Fri, 20 Jun 2008 12:20:09 +0200 + +Signed-off-by: Thomas Gleixner +--- + kernel/rtmutex.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/rtmutex.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rtmutex.c 2008-10-08 22:25:05.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rtmutex.c 2008-10-08 22:25:05.000000000 -0400 +@@ -124,9 +124,12 @@ static inline void mark_rt_rwlock_check( + #endif + + #ifdef CONFIG_PREEMPT_RT +-#define task_is_reader(task) ((task) == RT_RW_READER) ++static inline int task_is_reader(struct task_struct *task) ++{ ++ return task == RT_RW_READER; ++} + #else +-#define task_is_reader(task) (0) ++static inline int task_is_reader(struct task_struct *task) { return 0; } + #endif + + int pi_initialized; --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0031-0015-sched-wake-balance-fixes.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0031-0015-sched-wake-balance-fixes.patch @@ -0,0 +1,87 @@ +From ec30f584b4d095d00067850f07f3dc65d587939b Mon Sep 17 00:00:00 2001 +From: Gregory Haskins +Date: Tue, 11 Dec 2007 10:02:38 +0100 +Subject: [PATCH] sched: wake-balance fixes + +We have logic to detect whether the system has migratable tasks, but we are +not using it when deciding whether to push tasks away. So we add support +for considering this new information. + +Signed-off-by: Gregory Haskins +Signed-off-by: Steven Rostedt +Signed-off-by: Ingo Molnar + +--- + kernel/sched.c | 2 ++ + kernel/sched_rt.c | 10 ++++++++-- + 2 files changed, 10 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/sched.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched.c 2008-10-08 22:22:58.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched.c 2008-10-08 22:22:59.000000000 -0400 +@@ -270,6 +270,7 @@ struct rt_rq { + unsigned long rt_nr_migratory; + /* highest queued rt task prio */ + int highest_prio; ++ int overloaded; + }; + + /* +@@ -6744,6 +6745,7 @@ void __init sched_init(void) + rq->migration_thread = NULL; + INIT_LIST_HEAD(&rq->migration_queue); + rq->rt.highest_prio = MAX_RT_PRIO; ++ rq->rt.overloaded = 0; + #endif + atomic_set(&rq->nr_iowait, 0); + +Index: linux-2.6.24.7-rt21/kernel/sched_rt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched_rt.c 2008-10-08 22:22:59.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched_rt.c 2008-10-08 22:22:59.000000000 -0400 +@@ -16,6 +16,7 @@ static inline cpumask_t *rt_overload(voi + } + static inline void rt_set_overload(struct rq *rq) + { ++ rq->rt.overloaded = 1; + cpu_set(rq->cpu, rt_overload_mask); + /* + * Make sure the mask is visible before we set +@@ -32,6 +33,7 @@ static inline void rt_clear_overload(str + /* the order here really doesn't matter */ + atomic_dec(&rto_count); + cpu_clear(rq->cpu, rt_overload_mask); ++ rq->rt.overloaded = 0; + } + + static void update_rt_migration(struct rq *rq) +@@ -444,6 +446,9 @@ static int push_rt_task(struct rq *rq) + + assert_spin_locked(&rq->lock); + ++ if (!rq->rt.overloaded) ++ return 0; ++ + next_task = pick_next_highest_task_rt(rq, -1); + if (!next_task) + return 0; +@@ -671,7 +676,7 @@ static void schedule_tail_balance_rt(str + * the lock was owned by prev, we need to release it + * first via finish_lock_switch and then reaquire it here. + */ +- if (unlikely(rq->rt.rt_nr_running > 1)) { ++ if (unlikely(rq->rt.overloaded)) { + spin_lock_irq(&rq->lock); + push_rt_tasks(rq); + spin_unlock_irq(&rq->lock); +@@ -683,7 +688,8 @@ static void wakeup_balance_rt(struct rq + { + if (unlikely(rt_task(p)) && + !task_running(rq, p) && +- (p->prio >= rq->curr->prio)) ++ (p->prio >= rq->rt.highest_prio) && ++ rq->rt.overloaded) + push_rt_tasks(rq); + } + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0115-lockdep-lock_set_subclass.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0115-lockdep-lock_set_subclass.patch @@ -0,0 +1,123 @@ +Subject: [patch] lockdep: lock_set_subclass - reset a held lock's subclass +From: Peter Zijlstra + +this can be used to reset a held lock's subclass, for arbitrary-depth +iterated data structures such as trees or lists which have per-node +locks. + +Signed-off-by: Peter Zijlstra +Signed-off-by: Ingo Molnar +--- + include/linux/lockdep.h | 4 ++ + kernel/lockdep.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 73 insertions(+) + +Index: linux-2.6.24.7-rt21/include/linux/lockdep.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/lockdep.h 2008-10-08 22:22:40.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/lockdep.h 2008-10-08 22:23:24.000000000 -0400 +@@ -304,6 +304,9 @@ extern void lock_acquire(struct lockdep_ + extern void lock_release(struct lockdep_map *lock, int nested, + unsigned long ip); + ++extern void lock_set_subclass(struct lockdep_map *lock, unsigned int subclass, ++ unsigned long ip); ++ + # define INIT_LOCKDEP .lockdep_recursion = 0, + + #define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0) +@@ -320,6 +323,7 @@ static inline void lockdep_on(void) + + # define lock_acquire(l, s, t, r, c, i) do { } while (0) + # define lock_release(l, n, i) do { } while (0) ++# define lock_set_subclass(l, s, i) do { } while (0) + # define lockdep_init() do { } while (0) + # define lockdep_info() do { } while (0) + # define lockdep_init_map(lock, name, key, sub) do { (void)(key); } while (0) +Index: linux-2.6.24.7-rt21/kernel/lockdep.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/lockdep.c 2008-10-08 22:23:24.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/lockdep.c 2008-10-08 22:23:24.000000000 -0400 +@@ -2539,6 +2539,55 @@ static int check_unlock(struct task_stru + return 1; + } + ++static int ++__lock_set_subclass(struct lockdep_map *lock, ++ unsigned int subclass, unsigned long ip) ++{ ++ struct task_struct *curr = current; ++ struct held_lock *hlock, *prev_hlock; ++ struct lock_class *class; ++ unsigned int depth; ++ int i; ++ ++ depth = curr->lockdep_depth; ++ if (DEBUG_LOCKS_WARN_ON(!depth)) ++ return 0; ++ ++ prev_hlock = NULL; ++ for (i = depth-1; i >= 0; i--) { ++ hlock = curr->held_locks + i; ++ /* ++ * We must not cross into another context: ++ */ ++ if (prev_hlock && prev_hlock->irq_context != hlock->irq_context) ++ break; ++ if (hlock->instance == lock) ++ goto found_it; ++ prev_hlock = hlock; ++ } ++ return print_unlock_inbalance_bug(curr, lock, ip); ++ ++found_it: ++ class = register_lock_class(lock, subclass, 0); ++ hlock->class = class; ++ ++ curr->lockdep_depth = i; ++ curr->curr_chain_key = hlock->prev_chain_key; ++ ++ for (; i < depth; i++) { ++ hlock = curr->held_locks + i; ++ if (!__lock_acquire(hlock->instance, ++ hlock->class->subclass, hlock->trylock, ++ hlock->read, hlock->check, hlock->hardirqs_off, ++ hlock->acquire_ip)) ++ return 0; ++ } ++ ++ if (DEBUG_LOCKS_WARN_ON(curr->lockdep_depth != depth)) ++ return 0; ++ return 1; ++} ++ + /* + * Remove the lock to the list of currently held locks in a + * potentially non-nested (out of order) manner. This is a +@@ -2702,6 +2751,26 @@ static void check_flags(unsigned long fl + #endif + } + ++void ++lock_set_subclass(struct lockdep_map *lock, ++ unsigned int subclass, unsigned long ip) ++{ ++ unsigned long flags; ++ ++ if (unlikely(current->lockdep_recursion)) ++ return; ++ ++ raw_local_irq_save(flags); ++ current->lockdep_recursion = 1; ++ check_flags(flags); ++ if (__lock_set_subclass(lock, subclass, ip)) ++ check_chain_key(current); ++ current->lockdep_recursion = 0; ++ raw_local_irq_restore(flags); ++} ++ ++EXPORT_SYMBOL_GPL(lock_set_subclass); ++ + /* + * We are not always called with irqs disabled - do that here, + * and also avoid lockdep recursion: --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0112-latency-measurement-drivers.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0112-latency-measurement-drivers.patch @@ -0,0 +1,798 @@ + +this patch adds: + + - histogram support to /dev/rtc + + - the /dev/blocker lock-latency test-device + + - the /dev/lpptest parallel-port irq latency test-device + + drivers/char/Kconfig | 40 ++++++++++ + drivers/char/Makefile | 2 + drivers/char/blocker.c | 109 +++++++++++++++++++++++++++++ + drivers/char/lpptest.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++++ + drivers/char/rtc.c | 179 ++++++++++++++++++++++++++++++++++++++++++++++++- + scripts/Makefile | 3 + scripts/testlpp.c | 159 +++++++++++++++++++++++++++++++++++++++++++ + 7 files changed, 668 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/drivers/char/Kconfig +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/char/Kconfig 2008-10-08 22:22:40.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/char/Kconfig 2008-10-08 22:23:23.000000000 -0400 +@@ -753,6 +753,46 @@ config JS_RTC + To compile this driver as a module, choose M here: the + module will be called js-rtc. + ++config RTC_HISTOGRAM ++ bool "Real Time Clock Histogram Support" ++ default n ++ depends on RTC ++ ---help--- ++ If you say Y here then the kernel will track the delivery and ++ wakeup latency of /dev/rtc using tasks and will report a ++ histogram to the kernel log when the application closes /dev/rtc. ++ ++config BLOCKER ++ tristate "Priority Inheritance Debugging (Blocker) Device Support" ++ depends on X86 ++ default y ++ ---help--- ++ If you say Y here then a device will be created that the userspace ++ pi_test suite uses to test and measure kernel locking primitives. ++ ++config LPPTEST ++ tristate "Parallel Port Based Latency Measurement Device" ++ depends on !PARPORT && X86 ++ default y ++ ---help--- ++ If you say Y here then a device will be created that the userspace ++ testlpp utility uses to measure IRQ latencies of a target system ++ from an independent measurement system. ++ ++ NOTE: this code assumes x86 PCs and that the parallel port is ++ bidirectional and is on IRQ 7. ++ ++ to use the device, both the target and the source system needs to ++ run a kernel with CONFIG_LPPTEST enabled. To measure latencies, ++ use the scripts/testlpp utility in your kernel source directory, ++ and run it (as root) on the source system - it will start printing ++ out the latencies it took to get a response from the target system: ++ ++ Latency of response: 12.2 usecs (121265 cycles) ++ ++ then generate various workloads on the target system to see how ++ (worst-case-) latencies are impacted. ++ + config SGI_DS1286 + tristate "SGI DS1286 RTC support" + depends on SGI_IP22 +Index: linux-2.6.24.7-rt21/drivers/char/Makefile +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/char/Makefile 2008-10-08 22:22:40.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/char/Makefile 2008-10-08 22:23:23.000000000 -0400 +@@ -85,6 +85,8 @@ obj-$(CONFIG_TOSHIBA) += toshiba.o + obj-$(CONFIG_I8K) += i8k.o + obj-$(CONFIG_DS1620) += ds1620.o + obj-$(CONFIG_HW_RANDOM) += hw_random/ ++obj-$(CONFIG_BLOCKER) += blocker.o ++obj-$(CONFIG_LPPTEST) += lpptest.o + obj-$(CONFIG_COBALT_LCD) += lcd.o + obj-$(CONFIG_PPDEV) += ppdev.o + obj-$(CONFIG_NWBUTTON) += nwbutton.o +Index: linux-2.6.24.7-rt21/drivers/char/blocker.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/drivers/char/blocker.c 2008-10-08 22:23:23.000000000 -0400 +@@ -0,0 +1,109 @@ ++/* ++ * priority inheritance testing device ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#define BLOCKER_MINOR 221 ++ ++#define BLOCK_IOCTL 4245 ++#define BLOCK_SET_DEPTH 4246 ++ ++#define BLOCKER_MAX_LOCK_DEPTH 10 ++ ++void loop(int loops) ++{ ++ int i; ++ ++ for (i = 0; i < loops; i++) ++ get_cycles(); ++} ++ ++static spinlock_t blocker_lock[BLOCKER_MAX_LOCK_DEPTH]; ++ ++static unsigned int lock_depth = 1; ++ ++void do_the_lock_and_loop(unsigned int args) ++{ ++ int i, max; ++ ++ if (rt_task(current)) ++ max = lock_depth; ++ else if (lock_depth > 1) ++ max = (current->pid % lock_depth) + 1; ++ else ++ max = 1; ++ ++ /* Always lock from the top down */ ++ for (i = max-1; i >= 0; i--) ++ spin_lock(&blocker_lock[i]); ++ loop(args); ++ for (i = 0; i < max; i++) ++ spin_unlock(&blocker_lock[i]); ++} ++ ++static int blocker_open(struct inode *in, struct file *file) ++{ ++ printk(KERN_INFO "blocker_open called\n"); ++ ++ return 0; ++} ++ ++static long blocker_ioctl(struct file *file, ++ unsigned int cmd, unsigned long args) ++{ ++ switch(cmd) { ++ case BLOCK_IOCTL: ++ do_the_lock_and_loop(args); ++ return 0; ++ case BLOCK_SET_DEPTH: ++ if (args >= BLOCKER_MAX_LOCK_DEPTH) ++ return -EINVAL; ++ lock_depth = args; ++ return 0; ++ default: ++ return -EINVAL; ++ } ++} ++ ++static struct file_operations blocker_fops = { ++ .owner = THIS_MODULE, ++ .llseek = no_llseek, ++ .unlocked_ioctl = blocker_ioctl, ++ .open = blocker_open, ++}; ++ ++static struct miscdevice blocker_dev = ++{ ++ BLOCKER_MINOR, ++ "blocker", ++ &blocker_fops ++}; ++ ++static int __init blocker_init(void) ++{ ++ int i; ++ ++ if (misc_register(&blocker_dev)) ++ return -ENODEV; ++ ++ for (i = 0; i < BLOCKER_MAX_LOCK_DEPTH; i++) ++ spin_lock_init(blocker_lock + i); ++ ++ return 0; ++} ++ ++void __exit blocker_exit(void) ++{ ++ printk(KERN_INFO "blocker device uninstalled\n"); ++ misc_deregister(&blocker_dev); ++} ++ ++module_init(blocker_init); ++module_exit(blocker_exit); ++ ++MODULE_LICENSE("GPL"); ++ +Index: linux-2.6.24.7-rt21/drivers/char/lpptest.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/drivers/char/lpptest.c 2008-10-08 22:23:23.000000000 -0400 +@@ -0,0 +1,178 @@ ++/* ++ * /dev/lpptest device: test IRQ handling latencies over parallel port ++ * ++ * Copyright (C) 2005 Thomas Gleixner, Ingo Molnar ++ * ++ * licensed under the GPL ++ * ++ * You need to have CONFIG_PARPORT disabled for this device, it is a ++ * completely self-contained device that assumes sole ownership of the ++ * parallel port. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * API wrappers so that the code can be shared with the -rt tree: ++ */ ++#ifndef local_irq_disable ++# define local_irq_disable local_irq_disable ++# define local_irq_enable local_irq_enable ++#endif ++ ++#ifndef IRQ_NODELAY ++# define IRQ_NODELAY 0 ++# define IRQF_NODELAY 0 ++#endif ++ ++/* ++ * Driver: ++ */ ++#define LPPTEST_CHAR_MAJOR 245 ++#define LPPTEST_DEVICE_NAME "lpptest" ++ ++#define LPPTEST_IRQ 7 ++ ++#define LPPTEST_TEST _IOR (LPPTEST_CHAR_MAJOR, 1, unsigned long long) ++#define LPPTEST_DISABLE _IOR (LPPTEST_CHAR_MAJOR, 2, unsigned long long) ++#define LPPTEST_ENABLE _IOR (LPPTEST_CHAR_MAJOR, 3, unsigned long long) ++ ++static char dev_id[] = "lpptest"; ++ ++#define INIT_PORT() outb(0x04, 0x37a) ++#define ENABLE_IRQ() outb(0x10, 0x37a) ++#define DISABLE_IRQ() outb(0, 0x37a) ++ ++static unsigned char out = 0x5a; ++ ++/** ++ * Interrupt handler. Flip a bit in the reply. ++ */ ++static int lpptest_irq (int irq, void *dev_id) ++{ ++ out ^= 0xff; ++ outb(out, 0x378); ++ ++ return IRQ_HANDLED; ++} ++ ++static cycles_t test_response(void) ++{ ++ cycles_t now, end; ++ unsigned char in; ++ int timeout = 0; ++ ++ local_irq_disable(); ++ in = inb(0x379); ++ inb(0x378); ++ outb(0x08, 0x378); ++ now = get_cycles(); ++ while(1) { ++ if (inb(0x379) != in) ++ break; ++ if (timeout++ > 1000000) { ++ outb(0x00, 0x378); ++ local_irq_enable(); ++ ++ return 0; ++ } ++ } ++ end = get_cycles(); ++ outb(0x00, 0x378); ++ local_irq_enable(); ++ ++ return end - now; ++} ++ ++static int lpptest_open(struct inode *inode, struct file *file) ++{ ++ return 0; ++} ++ ++static int lpptest_close(struct inode *inode, struct file *file) ++{ ++ return 0; ++} ++ ++int lpptest_ioctl(struct inode *inode, struct file *file, unsigned int ioctl_num, unsigned long ioctl_param) ++{ ++ int retval = 0; ++ ++ switch (ioctl_num) { ++ ++ case LPPTEST_DISABLE: ++ DISABLE_IRQ(); ++ break; ++ ++ case LPPTEST_ENABLE: ++ ENABLE_IRQ(); ++ break; ++ ++ case LPPTEST_TEST: { ++ ++ cycles_t diff = test_response(); ++ if (copy_to_user((void *)ioctl_param, (void*) &diff, sizeof(diff))) ++ goto errcpy; ++ break; ++ } ++ default: retval = -EINVAL; ++ } ++ ++ return retval; ++ ++ errcpy: ++ return -EFAULT; ++} ++ ++static struct file_operations lpptest_dev_fops = { ++ .ioctl = lpptest_ioctl, ++ .open = lpptest_open, ++ .release = lpptest_close, ++}; ++ ++static int __init lpptest_init (void) ++{ ++ if (register_chrdev(LPPTEST_CHAR_MAJOR, LPPTEST_DEVICE_NAME, &lpptest_dev_fops)) ++ { ++ printk(KERN_NOTICE "Can't allocate major number %d for lpptest.\n", ++ LPPTEST_CHAR_MAJOR); ++ return -EAGAIN; ++ } ++ ++ if (request_irq (LPPTEST_IRQ, lpptest_irq, 0, "lpptest", dev_id)) { ++ printk (KERN_WARNING "lpptest: irq %d in use. Unload parport module!\n", LPPTEST_IRQ); ++ unregister_chrdev(LPPTEST_CHAR_MAJOR, LPPTEST_DEVICE_NAME); ++ return -EAGAIN; ++ } ++ irq_desc[LPPTEST_IRQ].status |= IRQ_NODELAY; ++ irq_desc[LPPTEST_IRQ].action->flags |= IRQF_NODELAY | IRQF_DISABLED; ++ ++ INIT_PORT(); ++ ENABLE_IRQ(); ++ ++ return 0; ++} ++module_init (lpptest_init); ++ ++static void __exit lpptest_exit (void) ++{ ++ DISABLE_IRQ(); ++ ++ free_irq(LPPTEST_IRQ, dev_id); ++ unregister_chrdev(LPPTEST_CHAR_MAJOR, LPPTEST_DEVICE_NAME); ++} ++module_exit (lpptest_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("lpp test module"); ++ +Index: linux-2.6.24.7-rt21/drivers/char/rtc.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/char/rtc.c 2008-10-08 22:22:40.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/char/rtc.c 2008-10-08 22:23:23.000000000 -0400 +@@ -90,6 +90,32 @@ + #include + #include + ++#ifdef CONFIG_MIPS ++# include ++#endif ++ ++#ifdef CONFIG_RTC_HISTOGRAM ++ ++static cycles_t last_interrupt_time; ++ ++#include ++ ++#define CPU_MHZ (cpu_khz / 1000) ++ ++#define HISTSIZE 10000 ++static int histogram[HISTSIZE]; ++ ++static int rtc_state; ++ ++enum rtc_states { ++ S_STARTUP, /* First round - let the application start */ ++ S_IDLE, /* Waiting for an interrupt */ ++ S_WAITING_FOR_READ, /* Signal delivered. waiting for rtc_read() */ ++ S_READ_MISSED, /* Signal delivered, read() deadline missed */ ++}; ++ ++#endif ++ + static unsigned long rtc_port; + static int rtc_irq = PCI_IRQ_NONE; + #endif +@@ -222,7 +248,146 @@ static inline unsigned char rtc_is_updat + return uip; + } + ++#ifndef RTC_IRQ ++# undef CONFIG_RTC_HISTOGRAM ++#endif ++ ++static inline void rtc_open_event(void) ++{ ++#ifdef CONFIG_RTC_HISTOGRAM ++ int i; ++ ++ last_interrupt_time = 0; ++ rtc_state = S_STARTUP; ++ rtc_irq_data = 0; ++ ++ for (i = 0; i < HISTSIZE; i++) ++ histogram[i] = 0; ++#endif ++} ++ ++static inline void rtc_wake_event(void) ++{ ++#ifndef CONFIG_RTC_HISTOGRAM ++ kill_fasync (&rtc_async_queue, SIGIO, POLL_IN); ++#else ++ if (!(rtc_status & RTC_IS_OPEN)) ++ return; ++ ++ switch (rtc_state) { ++ /* Startup */ ++ case S_STARTUP: ++ kill_fasync (&rtc_async_queue, SIGIO, POLL_IN); ++ break; ++ /* Waiting for an interrupt */ ++ case S_IDLE: ++ kill_fasync (&rtc_async_queue, SIGIO, POLL_IN); ++ last_interrupt_time = get_cycles(); ++ rtc_state = S_WAITING_FOR_READ; ++ break; ++ ++ /* Signal has been delivered. waiting for rtc_read() */ ++ case S_WAITING_FOR_READ: ++ /* ++ * Well foo. The usermode application didn't ++ * schedule and read in time. ++ */ ++ last_interrupt_time = get_cycles(); ++ rtc_state = S_READ_MISSED; ++ printk("Read missed before next interrupt\n"); ++ break; ++ /* Signal has been delivered, read() deadline was missed */ ++ case S_READ_MISSED: ++ /* ++ * Not much we can do here. We're waiting for the usermode ++ * application to read the rtc ++ */ ++ last_interrupt_time = get_cycles(); ++ break; ++ } ++#endif ++} ++ ++static inline void rtc_read_event(void) ++{ ++#ifdef CONFIG_RTC_HISTOGRAM ++ cycles_t now = get_cycles(); ++ ++ switch (rtc_state) { ++ /* Startup */ ++ case S_STARTUP: ++ rtc_state = S_IDLE; ++ break; ++ ++ /* Waiting for an interrupt */ ++ case S_IDLE: ++ printk("bug in rtc_read(): called in state S_IDLE!\n"); ++ break; ++ case S_WAITING_FOR_READ: /* ++ * Signal has been delivered. ++ * waiting for rtc_read() ++ */ ++ /* ++ * Well done ++ */ ++ case S_READ_MISSED: /* ++ * Signal has been delivered, read() ++ * deadline was missed ++ */ ++ /* ++ * So, you finally got here. ++ */ ++ if (!last_interrupt_time) ++ printk("bug in rtc_read(): last_interrupt_time = 0\n"); ++ rtc_state = S_IDLE; ++ { ++ cycles_t latency = now - last_interrupt_time; ++ unsigned long delta; /* Microseconds */ ++ ++ delta = latency; ++ delta /= CPU_MHZ; ++ ++ if (delta > 1000 * 1000) { ++ printk("rtc: eek\n"); ++ } else { ++ unsigned long slot = delta; ++ if (slot >= HISTSIZE) ++ slot = HISTSIZE - 1; ++ histogram[slot]++; ++ if (delta > 2000) ++ printk("wow! That was a " ++ "%ld millisec bump\n", ++ delta / 1000); ++ } ++ } ++ rtc_state = S_IDLE; ++ break; ++ } ++#endif ++} ++ ++static inline void rtc_close_event(void) ++{ ++#ifdef CONFIG_RTC_HISTOGRAM ++ int i = 0; ++ unsigned long total = 0; ++ ++ for (i = 0; i < HISTSIZE; i++) ++ total += histogram[i]; ++ if (!total) ++ return; ++ ++ printk("\nrtc latency histogram of {%s/%d, %lu samples}:\n", ++ current->comm, current->pid, total); ++ for (i = 0; i < HISTSIZE; i++) { ++ if (histogram[i]) ++ printk("%d %d\n", i, histogram[i]); ++ } ++#endif ++} ++ + #ifdef RTC_IRQ ++ + /* + * A very tiny interrupt handler. It runs with IRQF_DISABLED set, + * but there is possibility of conflicting with the set_rtc_mmss() +@@ -266,9 +431,9 @@ irqreturn_t rtc_interrupt(int irq, void + if (rtc_callback) + rtc_callback->func(rtc_callback->private_data); + spin_unlock(&rtc_task_lock); +- wake_up_interruptible(&rtc_wait); + +- kill_fasync (&rtc_async_queue, SIGIO, POLL_IN); ++ rtc_wake_event(); ++ wake_up_interruptible(&rtc_wait); + + return IRQ_HANDLED; + } +@@ -378,6 +543,8 @@ static ssize_t rtc_read(struct file *fil + schedule(); + } while (1); + ++ rtc_read_event(); ++ + if (count == sizeof(unsigned int)) + retval = put_user(data, (unsigned int __user *)buf) ?: sizeof(int); + else +@@ -610,6 +777,11 @@ static int rtc_do_ioctl(unsigned int cmd + save_freq_select = CMOS_READ(RTC_FREQ_SELECT); + CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); + ++ /* ++ * Make CMOS date writes nonpreemptible even on PREEMPT_RT. ++ * There's a limit to everything! =B-) ++ */ ++ preempt_disable(); + #ifdef CONFIG_MACH_DECSTATION + CMOS_WRITE(real_yrs, RTC_DEC_YEAR); + #endif +@@ -619,6 +791,7 @@ static int rtc_do_ioctl(unsigned int cmd + CMOS_WRITE(hrs, RTC_HOURS); + CMOS_WRITE(min, RTC_MINUTES); + CMOS_WRITE(sec, RTC_SECONDS); ++ preempt_enable(); + + CMOS_WRITE(save_control, RTC_CONTROL); + CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); +@@ -717,6 +890,7 @@ static int rtc_open(struct inode *inode, + if(rtc_status & RTC_IS_OPEN) + goto out_busy; + ++ rtc_open_event(); + rtc_status |= RTC_IS_OPEN; + + rtc_irq_data = 0; +@@ -772,6 +946,7 @@ no_irq: + rtc_irq_data = 0; + rtc_status &= ~RTC_IS_OPEN; + spin_unlock_irq (&rtc_lock); ++ rtc_close_event(); + return 0; + } + +Index: linux-2.6.24.7-rt21/scripts/Makefile +=================================================================== +--- linux-2.6.24.7-rt21.orig/scripts/Makefile 2008-10-08 22:22:40.000000000 -0400 ++++ linux-2.6.24.7-rt21/scripts/Makefile 2008-10-08 22:23:23.000000000 -0400 +@@ -12,6 +12,9 @@ hostprogs-$(CONFIG_LOGO) += pnmt + hostprogs-$(CONFIG_VT) += conmakehash + hostprogs-$(CONFIG_PROM_CONSOLE) += conmakehash + hostprogs-$(CONFIG_IKCONFIG) += bin2c ++ifdef CONFIG_LPPTEST ++hostprogs-y += testlpp ++endif + + always := $(hostprogs-y) $(hostprogs-m) + +Index: linux-2.6.24.7-rt21/scripts/testlpp.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/scripts/testlpp.c 2008-10-08 22:23:23.000000000 -0400 +@@ -0,0 +1,159 @@ ++/* ++ * testlpp.c: use the /dev/lpptest device to test IRQ handling ++ * latencies over parallel port ++ * ++ * Copyright (C) 2005 Thomas Gleixner ++ * ++ * licensed under the GPL ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define LPPTEST_CHAR_MAJOR 245 ++#define LPPTEST_DEVICE_NAME "lpptest" ++ ++#define LPPTEST_TEST _IOR (LPPTEST_CHAR_MAJOR, 1, unsigned long long) ++#define LPPTEST_DISABLE _IOR (LPPTEST_CHAR_MAJOR, 2, unsigned long long) ++#define LPPTEST_ENABLE _IOR (LPPTEST_CHAR_MAJOR, 3, unsigned long long) ++ ++#define HIST_SIZE 10000 ++ ++static int hist_total; ++static unsigned long hist[HIST_SIZE]; ++ ++static void hist_hit(unsigned long usecs) ++{ ++ hist_total++; ++ if (usecs >= HIST_SIZE-1) ++ hist[HIST_SIZE-1]++; ++ else ++ hist[usecs]++; ++} ++ ++static void print_hist(void) ++{ ++ int i; ++ ++ printf("LPP latency histogram:\n"); ++ ++ for (i = 0; i < HIST_SIZE; i++) { ++ if (hist[i]) ++ printf("%3d usecs: %9ld\n", i, hist[i]); ++ } ++} ++ ++static inline unsigned long long int rdtsc(void) ++{ ++ unsigned long long int x, y; ++ for (;;) { ++ __asm__ volatile ("rdtsc" : "=A" (x)); ++ __asm__ volatile ("rdtsc" : "=A" (y)); ++ if (y - x < 1000) ++ return y; ++ } ++} ++ ++static unsigned long long calibrate_loop(void) ++{ ++ unsigned long long mytime1, mytime2; ++ ++ mytime1 = rdtsc(); ++ usleep(500000); ++ mytime2 = rdtsc(); ++ ++ return (mytime2 - mytime1) * 2; ++} ++ ++#define time_to_usecs(time) ((double)time*1000000.0/(double)cycles_per_sec) ++ ++#define time_to_usecs_l(time) (long)(time*1000000/cycles_per_sec) ++ ++int fd, total; ++unsigned long long tim, sum_tim, min_tim = -1ULL, max_tim, cycles_per_sec; ++ ++void cleanup(int sig) ++{ ++ ioctl (fd, LPPTEST_ENABLE, &tim); ++ if (sig) ++ printf("[ interrupted - exiting ]\n"); ++ printf("\ntotal number of responses: %d\n", total); ++ printf("average reponse latency: %.2lf usecs\n", ++ time_to_usecs(sum_tim/total)); ++ printf("minimum latency: %.2lf usecs\n", ++ time_to_usecs(min_tim)); ++ printf("maximum latency: %.2lf usecs\n", ++ time_to_usecs(max_tim)); ++ print_hist(); ++ exit(0); ++} ++ ++#define HZ 3000 ++ ++int main (int argc, char **argv) ++{ ++ unsigned int nr_requests = 0; ++ ++ if (argc > 2) { ++ fprintf(stderr, "usage: testlpp []\n"); ++ exit(-1); ++ } ++ if (argc == 2) ++ nr_requests = atol(argv[1]); ++ ++ if (getuid() != 0) { ++ fprintf(stderr, "need to run as root!\n"); ++ exit(-1); ++ } ++ mknod("/dev/lpptest", S_IFCHR|0666, makedev(245, 1)); ++ ++ fd = open("/dev/lpptest", O_RDWR); ++ if (fd == -1) { ++ fprintf(stderr, "could not open /dev/lpptest, your kernel doesnt have CONFIG_LPPTEST enabled?\n"); ++ exit(-1); ++ } ++ ++ signal(SIGINT,&cleanup); ++ ++ ioctl (fd, LPPTEST_DISABLE, &tim); ++ ++ fprintf(stderr, "calibrating cycles to usecs: "); ++ cycles_per_sec = calibrate_loop(); ++ fprintf(stderr, "%lld cycles per usec\n", cycles_per_sec/1000000); ++ if (nr_requests) ++ fprintf(stderr, "[max # of requests: %u]\n", nr_requests); ++ fprintf(stderr, "starting %dHz test, hit Ctrl-C to stop:\n\n", HZ); ++ ++ while(1) { ++ ioctl (fd, LPPTEST_TEST, &tim); ++ if (tim == 0) ++ printf ("No response from target.\n"); ++ else { ++ hist_hit(time_to_usecs_l(tim)); ++ if (tim > max_tim) { ++ printf ("new max latency: %.2lf usecs (%Ld cycles)\n", time_to_usecs(tim), tim); ++ max_tim = tim; ++ } ++ if (tim < min_tim) ++ min_tim = tim; ++ total++; ++ if (total == nr_requests) ++ break; ++ sum_tim += tim; ++ } ++ usleep(1000000/HZ); ++ } ++ cleanup(0); ++ ++ return 0; ++} ++ ++ --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0182-rt-mutex-compat-semaphores.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0182-rt-mutex-compat-semaphores.patch @@ -0,0 +1,296 @@ + drivers/acpi/osl.c | 12 ++++++------ + drivers/media/dvb/dvb-core/dvb_frontend.c | 2 +- + drivers/net/3c527.c | 2 +- + drivers/net/hamradio/6pack.c | 2 +- + drivers/net/hamradio/mkiss.c | 2 +- + drivers/net/plip.c | 5 ++++- + drivers/net/ppp_async.c | 2 +- + drivers/net/ppp_synctty.c | 2 +- + drivers/pci/hotplug/ibmphp_hpc.c | 2 +- + drivers/scsi/aacraid/aacraid.h | 4 ++-- + drivers/scsi/qla2xxx/qla_def.h | 2 +- + drivers/usb/storage/usb.h | 2 +- + fs/jffs2/jffs2_fs_i.h | 2 +- + fs/xfs/linux-2.6/sema.h | 9 +++++++-- + fs/xfs/linux-2.6/xfs_buf.h | 4 ++-- + include/linux/parport.h | 2 +- + 16 files changed, 32 insertions(+), 24 deletions(-) + +Index: linux-2.6.24.7-rt21/drivers/acpi/osl.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/acpi/osl.c 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/acpi/osl.c 2008-10-08 22:23:41.000000000 -0400 +@@ -775,13 +775,13 @@ void acpi_os_delete_lock(acpi_spinlock h + acpi_status + acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle) + { +- struct semaphore *sem = NULL; ++ struct compat_semaphore *sem = NULL; + + +- sem = acpi_os_allocate(sizeof(struct semaphore)); ++ sem = acpi_os_allocate(sizeof(struct compat_semaphore)); + if (!sem) + return AE_NO_MEMORY; +- memset(sem, 0, sizeof(struct semaphore)); ++ memset(sem, 0, sizeof(struct compat_semaphore)); + + sema_init(sem, initial_units); + +@@ -804,7 +804,7 @@ EXPORT_SYMBOL(acpi_os_create_semaphore); + + acpi_status acpi_os_delete_semaphore(acpi_handle handle) + { +- struct semaphore *sem = (struct semaphore *)handle; ++ struct compat_semaphore *sem = (struct compat_semaphore *)handle; + + + if (!sem) +@@ -832,7 +832,7 @@ EXPORT_SYMBOL(acpi_os_delete_semaphore); + acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout) + { + acpi_status status = AE_OK; +- struct semaphore *sem = (struct semaphore *)handle; ++ struct compat_semaphore *sem = (struct compat_semaphore *)handle; + int ret = 0; + + +@@ -919,7 +919,7 @@ EXPORT_SYMBOL(acpi_os_wait_semaphore); + */ + acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units) + { +- struct semaphore *sem = (struct semaphore *)handle; ++ struct compat_semaphore *sem = (struct compat_semaphore *)handle; + + + if (!sem || (units < 1)) +Index: linux-2.6.24.7-rt21/drivers/media/dvb/dvb-core/dvb_frontend.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/media/dvb/dvb-core/dvb_frontend.c 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/media/dvb/dvb-core/dvb_frontend.c 2008-10-08 22:23:41.000000000 -0400 +@@ -97,7 +97,7 @@ struct dvb_frontend_private { + struct dvb_device *dvbdev; + struct dvb_frontend_parameters parameters; + struct dvb_fe_events events; +- struct semaphore sem; ++ struct compat_semaphore sem; + struct list_head list_head; + wait_queue_head_t wait_queue; + struct task_struct *thread; +Index: linux-2.6.24.7-rt21/drivers/net/3c527.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/net/3c527.c 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/net/3c527.c 2008-10-08 22:23:41.000000000 -0400 +@@ -182,7 +182,7 @@ struct mc32_local + + u16 rx_ring_tail; /* index to rx de-queue end */ + +- struct semaphore cmd_mutex; /* Serialises issuing of execute commands */ ++ struct compat_semaphore cmd_mutex; /* Serialises issuing of execute commands */ + struct completion execution_cmd; /* Card has completed an execute command */ + struct completion xceiver_cmd; /* Card has completed a tx or rx command */ + }; +Index: linux-2.6.24.7-rt21/drivers/net/hamradio/6pack.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/net/hamradio/6pack.c 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/net/hamradio/6pack.c 2008-10-08 22:23:41.000000000 -0400 +@@ -123,7 +123,7 @@ struct sixpack { + struct timer_list tx_t; + struct timer_list resync_t; + atomic_t refcnt; +- struct semaphore dead_sem; ++ struct compat_semaphore dead_sem; + spinlock_t lock; + }; + +Index: linux-2.6.24.7-rt21/drivers/net/hamradio/mkiss.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/net/hamradio/mkiss.c 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/net/hamradio/mkiss.c 2008-10-08 22:23:41.000000000 -0400 +@@ -84,7 +84,7 @@ struct mkiss { + #define CRC_MODE_SMACK_TEST 4 + + atomic_t refcnt; +- struct semaphore dead_sem; ++ struct compat_semaphore dead_sem; + }; + + /*---------------------------------------------------------------------------*/ +Index: linux-2.6.24.7-rt21/drivers/net/plip.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/net/plip.c 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/net/plip.c 2008-10-08 22:23:41.000000000 -0400 +@@ -221,7 +221,10 @@ struct net_local { + int should_relinquish; + spinlock_t lock; + atomic_t kill_timer; +- struct semaphore killed_timer_sem; ++ /* ++ * PREEMPT_RT: this isnt a mutex, it should be struct completion. ++ */ ++ struct compat_semaphore killed_timer_sem; + }; + + static inline void enable_parport_interrupts (struct net_device *dev) +Index: linux-2.6.24.7-rt21/drivers/net/ppp_async.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/net/ppp_async.c 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/net/ppp_async.c 2008-10-08 22:23:41.000000000 -0400 +@@ -67,7 +67,7 @@ struct asyncppp { + struct tasklet_struct tsk; + + atomic_t refcnt; +- struct semaphore dead_sem; ++ struct compat_semaphore dead_sem; + struct ppp_channel chan; /* interface to generic ppp layer */ + unsigned char obuf[OBUFSIZE]; + }; +Index: linux-2.6.24.7-rt21/drivers/net/ppp_synctty.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/net/ppp_synctty.c 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/net/ppp_synctty.c 2008-10-08 22:23:41.000000000 -0400 +@@ -70,7 +70,7 @@ struct syncppp { + struct tasklet_struct tsk; + + atomic_t refcnt; +- struct semaphore dead_sem; ++ struct compat_semaphore dead_sem; + struct ppp_channel chan; /* interface to generic ppp layer */ + }; + +Index: linux-2.6.24.7-rt21/drivers/pci/hotplug/ibmphp_hpc.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/pci/hotplug/ibmphp_hpc.c 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/pci/hotplug/ibmphp_hpc.c 2008-10-08 22:23:41.000000000 -0400 +@@ -104,7 +104,7 @@ static int to_debug = 0; + static struct mutex sem_hpcaccess; // lock access to HPC + static struct semaphore semOperations; // lock all operations and + // access to data structures +-static struct semaphore sem_exit; // make sure polling thread goes away ++static struct compat_semaphore sem_exit; // make sure polling thread goes away + static struct task_struct *ibmphp_poll_thread; + //---------------------------------------------------------------------------- + // local function prototypes +Index: linux-2.6.24.7-rt21/drivers/scsi/aacraid/aacraid.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/scsi/aacraid/aacraid.h 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/scsi/aacraid/aacraid.h 2008-10-08 22:23:41.000000000 -0400 +@@ -715,7 +715,7 @@ struct aac_fib_context { + u32 unique; // unique value representing this context + ulong jiffies; // used for cleanup - dmb changed to ulong + struct list_head next; // used to link context's into a linked list +- struct semaphore wait_sem; // this is used to wait for the next fib to arrive. ++ struct compat_semaphore wait_sem; // this is used to wait for the next fib to arrive. + int wait; // Set to true when thread is in WaitForSingleObject + unsigned long count; // total number of FIBs on FibList + struct list_head fib_list; // this holds fibs and their attachd hw_fibs +@@ -785,7 +785,7 @@ struct fib { + * This is the event the sendfib routine will wait on if the + * caller did not pass one and this is synch io. + */ +- struct semaphore event_wait; ++ struct compat_semaphore event_wait; + spinlock_t event_lock; + + u32 done; /* gets set to 1 when fib is complete */ +Index: linux-2.6.24.7-rt21/drivers/scsi/qla2xxx/qla_def.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/scsi/qla2xxx/qla_def.h 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/scsi/qla2xxx/qla_def.h 2008-10-08 22:23:41.000000000 -0400 +@@ -2418,7 +2418,7 @@ typedef struct scsi_qla_host { + + struct semaphore mbx_cmd_sem; /* Serialialize mbx access */ + struct semaphore vport_sem; /* Virtual port synchronization */ +- struct semaphore mbx_intr_sem; /* Used for completion notification */ ++ struct compat_semaphore mbx_intr_sem; /* Used for completion notification */ + + uint32_t mbx_flags; + #define MBX_IN_PROGRESS BIT_0 +Index: linux-2.6.24.7-rt21/drivers/usb/storage/usb.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/usb/storage/usb.h 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/usb/storage/usb.h 2008-10-08 22:23:41.000000000 -0400 +@@ -147,7 +147,7 @@ struct us_data { + struct task_struct *ctl_thread; /* the control thread */ + + /* mutual exclusion and synchronization structures */ +- struct semaphore sema; /* to sleep thread on */ ++ struct compat_semaphore sema; /* to sleep thread on */ + struct completion notify; /* thread begin/end */ + wait_queue_head_t delay_wait; /* wait during scan, reset */ + struct completion scanning_done; /* wait for scan thread */ +Index: linux-2.6.24.7-rt21/fs/jffs2/jffs2_fs_i.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/jffs2/jffs2_fs_i.h 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/jffs2/jffs2_fs_i.h 2008-10-08 22:23:41.000000000 -0400 +@@ -24,7 +24,7 @@ struct jffs2_inode_info { + before letting GC proceed. Or we'd have to put ugliness + into the GC code so it didn't attempt to obtain the i_mutex + for the inode(s) which are already locked */ +- struct semaphore sem; ++ struct compat_semaphore sem; + + /* The highest (datanode) version number used for this ino */ + uint32_t highest_version; +Index: linux-2.6.24.7-rt21/fs/xfs/linux-2.6/sema.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/xfs/linux-2.6/sema.h 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/xfs/linux-2.6/sema.h 2008-10-08 22:23:41.000000000 -0400 +@@ -27,7 +27,7 @@ + * sema_t structure just maps to struct semaphore in Linux kernel. + */ + +-typedef struct semaphore sema_t; ++typedef struct compat_semaphore sema_t; + + #define initnsema(sp, val, name) sema_init(sp, val) + #define psema(sp, b) down(sp) +@@ -36,7 +36,12 @@ typedef struct semaphore sema_t; + + static inline int issemalocked(sema_t *sp) + { +- return down_trylock(sp) || (up(sp), 0); ++ int rv; ++ ++ if ((rv = down_trylock(sp))) ++ return (rv); ++ up(sp); ++ return (0); + } + + /* +Index: linux-2.6.24.7-rt21/fs/xfs/linux-2.6/xfs_buf.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/xfs/linux-2.6/xfs_buf.h 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/xfs/linux-2.6/xfs_buf.h 2008-10-08 22:23:41.000000000 -0400 +@@ -118,7 +118,7 @@ typedef int (*xfs_buf_bdstrat_t)(struct + #define XB_PAGES 2 + + typedef struct xfs_buf { +- struct semaphore b_sema; /* semaphore for lockables */ ++ struct compat_semaphore b_sema; /* semaphore for lockables */ + unsigned long b_queuetime; /* time buffer was queued */ + atomic_t b_pin_count; /* pin count */ + wait_queue_head_t b_waiters; /* unpin waiters */ +@@ -138,7 +138,7 @@ typedef struct xfs_buf { + xfs_buf_iodone_t b_iodone; /* I/O completion function */ + xfs_buf_relse_t b_relse; /* releasing function */ + xfs_buf_bdstrat_t b_strat; /* pre-write function */ +- struct semaphore b_iodonesema; /* Semaphore for I/O waiters */ ++ struct compat_semaphore b_iodonesema; /* Semaphore for I/O waiters */ + void *b_fspriv; + void *b_fspriv2; + void *b_fspriv3; +Index: linux-2.6.24.7-rt21/include/linux/parport.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/parport.h 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/parport.h 2008-10-08 22:23:41.000000000 -0400 +@@ -266,7 +266,7 @@ enum ieee1284_phase { + struct ieee1284_info { + int mode; + volatile enum ieee1284_phase phase; +- struct semaphore irq; ++ struct compat_semaphore irq; + }; + + /* A parallel port */ --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0189-bh-uptodate-lock.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0189-bh-uptodate-lock.patch @@ -0,0 +1,139 @@ + fs/buffer.c | 20 ++++++++------------ + fs/ntfs/aops.c | 9 +++------ + include/linux/buffer_head.h | 5 +---- + 3 files changed, 12 insertions(+), 22 deletions(-) + +Index: linux-2.6.24.7-rt21/fs/buffer.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/buffer.c 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/buffer.c 2008-10-08 22:23:44.000000000 -0400 +@@ -403,8 +403,7 @@ static void end_buffer_async_read(struct + * decide that the page is now completely done. + */ + first = page_buffers(page); +- local_irq_save(flags); +- bit_spin_lock(BH_Uptodate_Lock, &first->b_state); ++ spin_lock_irqsave(&first->b_uptodate_lock, flags); + clear_buffer_async_read(bh); + unlock_buffer(bh); + tmp = bh; +@@ -417,8 +416,7 @@ static void end_buffer_async_read(struct + } + tmp = tmp->b_this_page; + } while (tmp != bh); +- bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(&first->b_uptodate_lock, flags); + + /* + * If none of the buffers had errors and they are all +@@ -430,8 +428,7 @@ static void end_buffer_async_read(struct + return; + + still_busy: +- bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(&first->b_uptodate_lock, flags); + return; + } + +@@ -466,8 +463,7 @@ static void end_buffer_async_write(struc + } + + first = page_buffers(page); +- local_irq_save(flags); +- bit_spin_lock(BH_Uptodate_Lock, &first->b_state); ++ spin_lock_irqsave(&first->b_uptodate_lock, flags); + + clear_buffer_async_write(bh); + unlock_buffer(bh); +@@ -479,14 +475,12 @@ static void end_buffer_async_write(struc + } + tmp = tmp->b_this_page; + } +- bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(&first->b_uptodate_lock, flags); + end_page_writeback(page); + return; + + still_busy: +- bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(&first->b_uptodate_lock, flags); + return; + } + +@@ -3172,6 +3166,7 @@ struct buffer_head *alloc_buffer_head(gf + set_migrateflags(gfp_flags, __GFP_RECLAIMABLE)); + if (ret) { + INIT_LIST_HEAD(&ret->b_assoc_buffers); ++ spin_lock_init(&ret->b_uptodate_lock); + get_cpu_var(bh_accounting).nr++; + recalc_bh_state(); + put_cpu_var(bh_accounting); +@@ -3183,6 +3178,7 @@ EXPORT_SYMBOL(alloc_buffer_head); + void free_buffer_head(struct buffer_head *bh) + { + BUG_ON(!list_empty(&bh->b_assoc_buffers)); ++ BUG_ON(spin_is_locked(&bh->b_uptodate_lock)); + kmem_cache_free(bh_cachep, bh); + get_cpu_var(bh_accounting).nr--; + recalc_bh_state(); +Index: linux-2.6.24.7-rt21/fs/ntfs/aops.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/ntfs/aops.c 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/ntfs/aops.c 2008-10-08 22:23:44.000000000 -0400 +@@ -103,8 +103,7 @@ static void ntfs_end_buffer_async_read(s + "0x%llx.", (unsigned long long)bh->b_blocknr); + } + first = page_buffers(page); +- local_irq_save(flags); +- bit_spin_lock(BH_Uptodate_Lock, &first->b_state); ++ spin_lock_irqsave(&first->b_uptodate_lock, flags); + clear_buffer_async_read(bh); + unlock_buffer(bh); + tmp = bh; +@@ -119,8 +118,7 @@ static void ntfs_end_buffer_async_read(s + } + tmp = tmp->b_this_page; + } while (tmp != bh); +- bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(&first->b_uptodate_lock, flags); + /* + * If none of the buffers had errors then we can set the page uptodate, + * but we first have to perform the post read mst fixups, if the +@@ -155,8 +153,7 @@ static void ntfs_end_buffer_async_read(s + unlock_page(page); + return; + still_busy: +- bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(&first->b_uptodate_lock, flags); + return; + } + +Index: linux-2.6.24.7-rt21/include/linux/buffer_head.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/buffer_head.h 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/buffer_head.h 2008-10-08 22:23:44.000000000 -0400 +@@ -21,10 +21,6 @@ enum bh_state_bits { + BH_Dirty, /* Is dirty */ + BH_Lock, /* Is locked */ + BH_Req, /* Has been submitted for I/O */ +- BH_Uptodate_Lock,/* Used by the first bh in a page, to serialise +- * IO completion of other buffers in the page +- */ +- + BH_Mapped, /* Has a disk mapping */ + BH_New, /* Disk mapping was newly created by get_block */ + BH_Async_Read, /* Is under end_buffer_async_read I/O */ +@@ -73,6 +69,7 @@ struct buffer_head { + struct address_space *b_assoc_map; /* mapping this buffer is + associated with */ + atomic_t b_count; /* users using this buffer_head */ ++ spinlock_t b_uptodate_lock; + }; + + /* --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0221-preempt-realtime-powerpc-update.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0221-preempt-realtime-powerpc-update.patch @@ -0,0 +1,61 @@ +--- + arch/powerpc/Kconfig.debug | 4 ++++ + arch/powerpc/kernel/idle.c | 2 +- + include/asm-powerpc/hw_irq.h | 2 +- + include/asm-powerpc/pmac_feature.h | 2 +- + 4 files changed, 7 insertions(+), 3 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/powerpc/Kconfig.debug +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/Kconfig.debug 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/Kconfig.debug 2008-10-08 22:23:53.000000000 -0400 +@@ -2,6 +2,10 @@ menu "Kernel hacking" + + source "lib/Kconfig.debug" + ++config TRACE_IRQFLAGS_SUPPORT ++ bool ++ default y ++ + config DEBUG_STACKOVERFLOW + bool "Check for stack overflows" + depends on DEBUG_KERNEL +Index: linux-2.6.24.7-rt21/arch/powerpc/kernel/idle.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/kernel/idle.c 2008-10-08 22:23:53.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/kernel/idle.c 2008-10-08 22:23:53.000000000 -0400 +@@ -98,7 +98,7 @@ void cpu_idle(void) + tick_nohz_restart_sched_tick(); + if (cpu_should_die()) + cpu_die(); +- preempt_enable_no_resched(); ++ __preempt_enable_no_resched(); + schedule(); + preempt_disable(); + } +Index: linux-2.6.24.7-rt21/include/asm-powerpc/hw_irq.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-powerpc/hw_irq.h 2008-10-08 22:23:53.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-powerpc/hw_irq.h 2008-10-08 22:23:53.000000000 -0400 +@@ -120,7 +120,7 @@ static inline void raw_local_irq_save_pt + #define hard_irq_enable() local_irq_enable() + #define hard_irq_disable() local_irq_disable() + +-#include ++#include + + #endif /* CONFIG_PPC64 */ + +Index: linux-2.6.24.7-rt21/include/asm-powerpc/pmac_feature.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-powerpc/pmac_feature.h 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-powerpc/pmac_feature.h 2008-10-08 22:23:53.000000000 -0400 +@@ -378,7 +378,7 @@ extern struct macio_chip* macio_find(str + * Those are exported by pmac feature for internal use by arch code + * only like the platform function callbacks, do not use directly in drivers + */ +-extern spinlock_t feature_lock; ++extern raw_spinlock_t feature_lock; + extern struct device_node *uninorth_node; + extern u32 __iomem *uninorth_base; + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0403-dev-queue-xmit-preempt-fix.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0403-dev-queue-xmit-preempt-fix.patch @@ -0,0 +1,155 @@ +From mingo@elte.hu Fri Jan 11 14:56:57 2008 +Date: Thu, 3 Jan 2008 09:22:03 +0100 +From: Ingo Molnar +To: Steven Rostedt +Subject: [mbeauch@cox.net: FW: [PATCH -rt] Preemption problem in kernel RT + Patch] + + +----- Forwarded message from mbeauch ----- + +Date: Wed, 02 Jan 2008 20:27:09 -0500 +From: mbeauch +To: mingo@elte.hu +Subject: FW: [PATCH -rt] Preemption problem in kernel RT Patch + +Here's the updated patch: + +Changed the real-time patch code to detect recursive calls +to dev_queue_xmit and drop the packet when detected. + + +Signed-off-by: Mark Beauchemin + + +--- + include/linux/netdevice.h | 20 ++++++++++---------- + net/core/dev.c | 14 +++----------- + net/sched/sch_generic.c | 4 ++-- + 3 files changed, 15 insertions(+), 23 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/netdevice.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/netdevice.h 2008-10-08 22:24:07.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/netdevice.h 2008-10-08 22:24:40.000000000 -0400 +@@ -629,7 +629,7 @@ struct net_device + /* cpu id of processor entered to hard_start_xmit or -1, + if nobody entered there. + */ +- int xmit_lock_owner; ++ void *xmit_lock_owner; + void *priv; /* pointer to private data */ + int (*hard_start_xmit) (struct sk_buff *skb, + struct net_device *dev); +@@ -1341,46 +1341,46 @@ static inline void netif_rx_complete(str + * + * Get network device transmit lock + */ +-static inline void __netif_tx_lock(struct net_device *dev, int cpu) ++static inline void __netif_tx_lock(struct net_device *dev) + { + spin_lock(&dev->_xmit_lock); +- dev->xmit_lock_owner = cpu; ++ dev->xmit_lock_owner = (void *)current; + } + + static inline void netif_tx_lock(struct net_device *dev) + { +- __netif_tx_lock(dev, raw_smp_processor_id()); ++ __netif_tx_lock(dev); + } + + static inline void netif_tx_lock_bh(struct net_device *dev) + { + spin_lock_bh(&dev->_xmit_lock); +- dev->xmit_lock_owner = raw_smp_processor_id(); ++ dev->xmit_lock_owner = (void *)current; + } + + static inline int netif_tx_trylock(struct net_device *dev) + { + int ok = spin_trylock(&dev->_xmit_lock); + if (likely(ok)) +- dev->xmit_lock_owner = raw_smp_processor_id(); ++ dev->xmit_lock_owner = (void *)current; + return ok; + } + + static inline void netif_tx_unlock(struct net_device *dev) + { +- dev->xmit_lock_owner = -1; ++ dev->xmit_lock_owner = (void *)-1; + spin_unlock(&dev->_xmit_lock); + } + + static inline void netif_tx_unlock_bh(struct net_device *dev) + { +- dev->xmit_lock_owner = -1; ++ dev->xmit_lock_owner = (void *)-1; + spin_unlock_bh(&dev->_xmit_lock); + } + +-#define HARD_TX_LOCK(dev, cpu) { \ ++#define HARD_TX_LOCK(dev) { \ + if ((dev->features & NETIF_F_LLTX) == 0) { \ +- __netif_tx_lock(dev, cpu); \ ++ __netif_tx_lock(dev); \ + } \ + } + +Index: linux-2.6.24.7-rt21/net/core/dev.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/net/core/dev.c 2008-10-08 22:24:07.000000000 -0400 ++++ linux-2.6.24.7-rt21/net/core/dev.c 2008-10-08 22:24:40.000000000 -0400 +@@ -1692,18 +1692,10 @@ gso: + Either shot noqueue qdisc, it is even simpler 8) + */ + if (dev->flags & IFF_UP) { +- int cpu = raw_smp_processor_id(); /* ok because BHs are off */ + +- /* +- * No need to check for recursion with threaded interrupts: +- */ +-#ifdef CONFIG_PREEMPT_RT +- if (1) { +-#else +- if (dev->xmit_lock_owner != cpu) { +-#endif ++ if (dev->xmit_lock_owner != (void *)current) { + +- HARD_TX_LOCK(dev, cpu); ++ HARD_TX_LOCK(dev); + + if (!netif_queue_stopped(dev) && + !netif_subqueue_stopped(dev, skb)) { +@@ -3634,7 +3626,7 @@ int register_netdevice(struct net_device + spin_lock_init(&dev->queue_lock); + spin_lock_init(&dev->_xmit_lock); + netdev_set_lockdep_class(&dev->_xmit_lock, dev->type); +- dev->xmit_lock_owner = -1; ++ dev->xmit_lock_owner = (void *)-1; + spin_lock_init(&dev->ingress_lock); + + dev->iflink = -1; +Index: linux-2.6.24.7-rt21/net/sched/sch_generic.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/net/sched/sch_generic.c 2008-10-08 22:24:07.000000000 -0400 ++++ linux-2.6.24.7-rt21/net/sched/sch_generic.c 2008-10-08 22:24:40.000000000 -0400 +@@ -89,7 +89,7 @@ static inline int handle_dev_cpu_collisi + { + int ret; + +- if (unlikely(dev->xmit_lock_owner == raw_smp_processor_id())) { ++ if (unlikely(dev->xmit_lock_owner == (void *)current)) { + /* + * Same CPU holding the lock. It may be a transient + * configuration error, when hard_start_xmit() recurses. We +@@ -146,7 +146,7 @@ static inline int qdisc_restart(struct n + /* And release queue */ + spin_unlock(&dev->queue_lock); + +- HARD_TX_LOCK(dev, raw_smp_processor_id()); ++ HARD_TX_LOCK(dev); + if (!netif_subqueue_stopped(dev, skb)) + ret = dev_hard_start_xmit(skb, dev); + HARD_TX_UNLOCK(dev); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0185-percpu-locked-netfilter2.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0185-percpu-locked-netfilter2.patch @@ -0,0 +1,118 @@ +--- + include/net/netfilter/nf_conntrack.h | 2 +- + include/net/netfilter/nf_conntrack_ecache.h | 13 +++++++------ + net/netfilter/nf_conntrack_ecache.c | 16 ++++++++-------- + 3 files changed, 16 insertions(+), 15 deletions(-) + +Index: linux-2.6.24.7-rt21/include/net/netfilter/nf_conntrack.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/net/netfilter/nf_conntrack.h 2008-10-08 22:23:21.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/net/netfilter/nf_conntrack.h 2008-10-08 22:23:42.000000000 -0400 +@@ -259,13 +259,13 @@ extern atomic_t nf_conntrack_count; + extern int nf_conntrack_max; + + DECLARE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat); +-#define NF_CT_STAT_INC(count) (__get_cpu_var(nf_conntrack_stat).count++) + #define NF_CT_STAT_INC_ATOMIC(count) \ + do { \ + local_bh_disable(); \ + __get_cpu_var(nf_conntrack_stat).count++; \ + local_bh_enable(); \ + } while (0) ++#define NF_CT_STAT_INC(count) (__raw_get_cpu_var(nf_conntrack_stat).count++) + + extern int + nf_conntrack_register_cache(u_int32_t features, const char *name, size_t size); +Index: linux-2.6.24.7-rt21/include/net/netfilter/nf_conntrack_ecache.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/net/netfilter/nf_conntrack_ecache.h 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/net/netfilter/nf_conntrack_ecache.h 2008-10-08 22:23:42.000000000 -0400 +@@ -15,16 +15,15 @@ struct nf_conntrack_ecache { + struct nf_conn *ct; + unsigned int events; + }; +-DECLARE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache); +- +-#define CONNTRACK_ECACHE(x) (__get_cpu_var(nf_conntrack_ecache).x) ++DECLARE_PER_CPU_LOCKED(struct nf_conntrack_ecache, nf_conntrack_ecache); + + extern struct atomic_notifier_head nf_conntrack_chain; + extern int nf_conntrack_register_notifier(struct notifier_block *nb); + extern int nf_conntrack_unregister_notifier(struct notifier_block *nb); + + extern void nf_ct_deliver_cached_events(const struct nf_conn *ct); +-extern void __nf_ct_event_cache_init(struct nf_conn *ct); ++extern void __nf_ct_event_cache_init(struct nf_conntrack_ecache *ecache, ++ struct nf_conn *ct); + extern void nf_ct_event_cache_flush(void); + + static inline void +@@ -33,12 +32,14 @@ nf_conntrack_event_cache(enum ip_conntra + { + struct nf_conn *ct = (struct nf_conn *)skb->nfct; + struct nf_conntrack_ecache *ecache; ++ int cpu; + + local_bh_disable(); +- ecache = &__get_cpu_var(nf_conntrack_ecache); ++ ecache = &get_cpu_var_locked(nf_conntrack_ecache, &cpu); + if (ct != ecache->ct) +- __nf_ct_event_cache_init(ct); ++ __nf_ct_event_cache_init(ecache, ct); + ecache->events |= event; ++ put_cpu_var_locked(nf_conntrack_ecache, cpu); + local_bh_enable(); + } + +Index: linux-2.6.24.7-rt21/net/netfilter/nf_conntrack_ecache.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/net/netfilter/nf_conntrack_ecache.c 2008-10-08 22:22:34.000000000 -0400 ++++ linux-2.6.24.7-rt21/net/netfilter/nf_conntrack_ecache.c 2008-10-08 22:23:42.000000000 -0400 +@@ -29,8 +29,8 @@ EXPORT_SYMBOL_GPL(nf_conntrack_chain); + ATOMIC_NOTIFIER_HEAD(nf_ct_expect_chain); + EXPORT_SYMBOL_GPL(nf_ct_expect_chain); + +-DEFINE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache); +-EXPORT_PER_CPU_SYMBOL_GPL(nf_conntrack_ecache); ++DEFINE_PER_CPU_LOCKED(struct nf_conntrack_ecache, nf_conntrack_ecache); ++EXPORT_PER_CPU_LOCKED_SYMBOL_GPL(nf_conntrack_ecache); + + /* deliver cached events and clear cache entry - must be called with locally + * disabled softirqs */ +@@ -52,22 +52,22 @@ __nf_ct_deliver_cached_events(struct nf_ + void nf_ct_deliver_cached_events(const struct nf_conn *ct) + { + struct nf_conntrack_ecache *ecache; ++ int cpu; + + local_bh_disable(); +- ecache = &__get_cpu_var(nf_conntrack_ecache); ++ ecache = &get_cpu_var_locked(nf_conntrack_ecache, &cpu); + if (ecache->ct == ct) + __nf_ct_deliver_cached_events(ecache); ++ put_cpu_var_locked(nf_conntrack_ecache, cpu); + local_bh_enable(); + } + EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events); + + /* Deliver cached events for old pending events, if current conntrack != old */ +-void __nf_ct_event_cache_init(struct nf_conn *ct) ++void ++__nf_ct_event_cache_init(struct nf_conntrack_ecache *ecache, struct nf_conn *ct) + { +- struct nf_conntrack_ecache *ecache; +- + /* take care of delivering potentially old events */ +- ecache = &__get_cpu_var(nf_conntrack_ecache); + BUG_ON(ecache->ct == ct); + if (ecache->ct) + __nf_ct_deliver_cached_events(ecache); +@@ -85,7 +85,7 @@ void nf_ct_event_cache_flush(void) + int cpu; + + for_each_possible_cpu(cpu) { +- ecache = &per_cpu(nf_conntrack_ecache, cpu); ++ ecache = &__get_cpu_var_locked(nf_conntrack_ecache, cpu); + if (ecache->ct) + nf_ct_put(ecache->ct); + } --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0470-lockstat-fix-contention-points.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0470-lockstat-fix-contention-points.patch @@ -0,0 +1,23 @@ +Subject: lockstat: fix contention points +From: Peter Zijlstra + +blatantly stupid bug.. + +Signed-off-by: Peter Zijlstra +--- + kernel/lockdep.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/kernel/lockdep.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/lockdep.c 2008-10-08 22:24:26.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/lockdep.c 2008-10-08 22:24:56.000000000 -0400 +@@ -2889,7 +2889,7 @@ found_it: + + stats = get_lock_stats(hlock->class); + if (point < ARRAY_SIZE(stats->contention_point)) +- stats->contention_point[i]++; ++ stats->contention_point[point]++; + if (lock->cpu != smp_processor_id()) + stats->bounces[bounce_contended + !!hlock->read]++; + put_lock_stats(stats); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0226-preempt-realtime-powerpc-add-raw-relax-macros.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0226-preempt-realtime-powerpc-add-raw-relax-macros.patch @@ -0,0 +1,31 @@ +From tsutomu.owa@toshiba.co.jp Mon May 14 15:26:25 2007 +Date: Mon, 14 May 2007 15:26:25 +0900 +From: Tsutomu OWA +To: linuxppc-dev@ozlabs.org, linux-kernel@vger.kernel.org +Cc: mingo@elte.hu, tglx@linutronix.de +Subject: Re: [patch 1/4] powerpc 2.6.21-rt1: fix a build breakage by adding __raw_*_relax() macros + + +Add missing macros to fix a build breakage for PREEMPT_DESKTOP. + +Signed-off-by: Tsutomu OWA +-- owa + +--- + include/asm-powerpc/spinlock.h | 4 ++++ + 1 file changed, 4 insertions(+) + +Index: linux-2.6.24.7-rt21/include/asm-powerpc/spinlock.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-powerpc/spinlock.h 2008-10-08 22:23:39.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-powerpc/spinlock.h 2008-10-08 22:23:55.000000000 -0400 +@@ -289,5 +289,9 @@ static __inline__ void __raw_write_unloc + #define _raw_read_relax(lock) __rw_yield(lock) + #define _raw_write_relax(lock) __rw_yield(lock) + ++#define __raw_spin_relax(lock) cpu_relax() ++#define __raw_read_relax(lock) cpu_relax() ++#define __raw_write_relax(lock) cpu_relax() ++ + #endif /* __KERNEL__ */ + #endif /* __ASM_SPINLOCK_H */ --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0485-rcupreempt-trace-marker-update.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0485-rcupreempt-trace-marker-update.patch @@ -0,0 +1,87 @@ +From: Steven Rostedt +Subject: rcupreempt trace update to new markers + +Update the rcupreempt tracing with the new markers. + +Signed-off-by: Steven Rostedt +--- + include/linux/rcupreempt_trace.h | 8 ++++---- + kernel/rcupreempt_trace.c | 21 +++++++++------------ + 2 files changed, 13 insertions(+), 16 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/rcupreempt_trace.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/rcupreempt_trace.h 2008-10-08 22:24:41.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/rcupreempt_trace.h 2008-10-08 22:25:00.000000000 -0400 +@@ -76,8 +76,8 @@ struct rcupreempt_probe_data { + }; + + #define DEFINE_RCUPREEMPT_MARKER_HANDLER(rcupreempt_trace_worker) \ +-void rcupreempt_trace_worker##_callback(const struct marker *mdata, \ +- void *private_data, const char *format, ...) \ ++void rcupreempt_trace_worker##_callback(void *private_data, void *call_data, \ ++ const char *format, va_list *args) \ + { \ + struct rcupreempt_trace *trace; \ + trace = (&per_cpu(trace_data, smp_processor_id())); \ +@@ -113,8 +113,8 @@ struct preempt_rcu_boost_trace { + }; + + #define DEFINE_PREEMPT_RCU_BOOST_MARKER_HANDLER(preempt_rcu_boost_var) \ +-void preempt_rcu_boost_var##_callback(const struct marker *mdata, \ +- void *private_data, const char *format, ...) \ ++void preempt_rcu_boost_var##_callback(void *private_data, void *call_data, \ ++ const char *format, va_list *args) \ + { \ + struct preempt_rcu_boost_trace *boost_trace; \ + boost_trace = (&per_cpu(boost_trace_data, smp_processor_id())); \ +Index: linux-2.6.24.7-rt21/kernel/rcupreempt_trace.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rcupreempt_trace.c 2008-10-08 22:24:41.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rcupreempt_trace.c 2008-10-08 22:25:00.000000000 -0400 +@@ -536,10 +536,6 @@ static int __init rcupreempt_trace_init( + if (ret) + printk(KERN_INFO "Unable to register rcupreempt \ + probe %s\n", rcupreempt_probe_array[i].name); +- ret = marker_arm(p->name); +- if (ret) +- printk(KERN_INFO "Unable to arm rcupreempt probe %s\n", +- p->name); + } + printk(KERN_INFO "RCU Preempt markers registered\n"); + +@@ -552,10 +548,6 @@ static int __init rcupreempt_trace_init( + if (ret) + printk(KERN_INFO "Unable to register Preempt RCU Boost \ + probe %s\n", preempt_rcu_boost_probe_array[i].name); +- ret = marker_arm(p->name); +- if (ret) +- printk(KERN_INFO "Unable to arm Preempt RCU Boost \ +- markers %s\n", p->name); + } + #endif /* CONFIG_PREEMPT_RCU_BOOST */ + +@@ -573,14 +565,19 @@ static void __exit rcupreempt_trace_clea + { + int i; + +- for (i = 0; i < ARRAY_SIZE(rcupreempt_probe_array); i++) +- marker_probe_unregister(rcupreempt_probe_array[i].name); ++ for (i = 0; i < ARRAY_SIZE(rcupreempt_probe_array); i++) { ++ struct rcupreempt_probe_data *p = &rcupreempt_probe_array[i]; ++ marker_probe_unregister(p->name, p->probe_func, p); ++ } + printk(KERN_INFO "RCU Preempt markers unregistered\n"); + + #ifdef CONFIG_PREEMPT_RCU_BOOST + rcu_trace_boost_destroy(); +- for (i = 0; i < ARRAY_SIZE(preempt_rcu_boost_probe_array); i++) +- marker_probe_unregister(preempt_rcu_boost_probe_array[i].name); ++ for (i = 0; i < ARRAY_SIZE(preempt_rcu_boost_probe_array); i++) { ++ struct preempt_rcu_boost_probe *p = \ ++ &preempt_rcu_boost_probe_array[i]; ++ marker_probe_unregister(p->name, p->probe_func, p); ++ } + printk(KERN_INFO "Preempt RCU Boost markers unregistered\n"); + #endif /* CONFIG_PREEMPT_RCU_BOOST */ + debugfs_remove(statdir); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0214-preempt-realtime-arm-shark.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0214-preempt-realtime-arm-shark.patch @@ -0,0 +1,17 @@ +--- + arch/arm/mach-shark/leds.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/arch/arm/mach-shark/leds.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/arm/mach-shark/leds.c 2008-10-08 22:22:32.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/arm/mach-shark/leds.c 2008-10-08 22:23:51.000000000 -0400 +@@ -32,7 +32,7 @@ static char led_state; + static short hw_led_state; + static short saved_state; + +-static DEFINE_SPINLOCK(leds_lock); ++static DEFINE_RAW_SPINLOCK(leds_lock); + + short sequoia_read(int addr) { + outw(addr,0x24); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0328-lockdep-rt-mutex.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0328-lockdep-rt-mutex.patch @@ -0,0 +1,159 @@ +Subject: lockdep-rt: annotate PREEMPT_RT DEFINE_MUTEX + + +Signed-off-by: Peter Zijlstra +--- + include/linux/mutex.h | 16 ++++++---- + include/linux/rt_lock.h | 70 ++++++++++++++++++++---------------------------- + 2 files changed, 39 insertions(+), 47 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/mutex.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/mutex.h 2008-10-08 22:23:37.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/mutex.h 2008-10-08 22:24:23.000000000 -0400 +@@ -18,6 +18,13 @@ + + #include + ++#ifdef CONFIG_DEBUG_LOCK_ALLOC ++# define __DEP_MAP_MUTEX_INITIALIZER(lockname) \ ++ , .dep_map = { .name = #lockname } ++#else ++# define __DEP_MAP_MUTEX_INITIALIZER(lockname) ++#endif ++ + #ifdef CONFIG_PREEMPT_RT + + #include +@@ -29,9 +36,11 @@ struct mutex { + #endif + }; + ++ + #define __MUTEX_INITIALIZER(mutexname) \ + { \ + .lock = __RT_MUTEX_INITIALIZER(mutexname.lock) \ ++ __DEP_MAP_MUTEX_INITIALIZER(mutexname) \ + } + + #define DEFINE_MUTEX(mutexname) \ +@@ -141,13 +150,6 @@ do { \ + # define mutex_destroy(mutex) do { } while (0) + #endif + +-#ifdef CONFIG_DEBUG_LOCK_ALLOC +-# define __DEP_MAP_MUTEX_INITIALIZER(lockname) \ +- , .dep_map = { .name = #lockname } +-#else +-# define __DEP_MAP_MUTEX_INITIALIZER(lockname) +-#endif +- + #define __MUTEX_INITIALIZER(lockname) \ + { .count = ATOMIC_INIT(1) \ + , .wait_lock = __SPIN_LOCK_UNLOCKED(lockname.wait_lock) \ +Index: linux-2.6.24.7-rt21/include/linux/rt_lock.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/rt_lock.h 2008-10-08 22:23:37.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/rt_lock.h 2008-10-08 22:24:23.000000000 -0400 +@@ -27,30 +27,31 @@ typedef struct { + } spinlock_t; + + #ifdef CONFIG_DEBUG_RT_MUTEXES +-# define __SPIN_LOCK_UNLOCKED(name) \ +- (spinlock_t) { { .wait_lock = _RAW_SPIN_LOCK_UNLOCKED(name) \ +- , .save_state = 1, .file = __FILE__, .line = __LINE__ }, SPIN_DEP_MAP_INIT(name) } ++# define __RT_SPIN_INITIALIZER(name) \ ++ { .wait_lock = _RAW_SPIN_LOCK_UNLOCKED(name.wait_lock), \ ++ .save_state = 1, \ ++ .file = __FILE__, \ ++ .line = __LINE__, } + #else +-# define __SPIN_LOCK_UNLOCKED(name) \ +- (spinlock_t) { { .wait_lock = _RAW_SPIN_LOCK_UNLOCKED(name) }, SPIN_DEP_MAP_INIT(name) } ++# define __RT_SPIN_INITIALIZER(name) \ ++ { .wait_lock = _RAW_SPIN_LOCK_UNLOCKED(name.wait_lock) } + #endif +-# define SPIN_LOCK_UNLOCKED __SPIN_LOCK_UNLOCKED(spin_old_style) ++ ++#define __SPIN_LOCK_UNLOCKED(name) (spinlock_t) \ ++ { .lock = __RT_SPIN_INITIALIZER(name), \ ++ SPIN_DEP_MAP_INIT(name) } ++ + #else /* !PREEMPT_RT */ +- typedef raw_spinlock_t spinlock_t; +-# ifdef CONFIG_DEBUG_SPINLOCK +-# define _SPIN_LOCK_UNLOCKED \ +- { .raw_lock = __RAW_SPIN_LOCK_UNLOCKED, \ +- .magic = SPINLOCK_MAGIC, \ +- .owner = SPINLOCK_OWNER_INIT, \ +- .owner_cpu = -1 } +-# else +-# define _SPIN_LOCK_UNLOCKED \ +- { .raw_lock = __RAW_SPIN_LOCK_UNLOCKED } +-# endif +-# define SPIN_LOCK_UNLOCKED _SPIN_LOCK_UNLOCKED +-# define __SPIN_LOCK_UNLOCKED(name) _SPIN_LOCK_UNLOCKED ++ ++typedef raw_spinlock_t spinlock_t; ++ ++#define __SPIN_LOCK_UNLOCKED _RAW_SPIN_LOCK_UNLOCKED ++ + #endif + ++#define SPIN_LOCK_UNLOCKED __SPIN_LOCK_UNLOCKED(spin_old_style) ++ ++ + #define __DEFINE_SPINLOCK(name) \ + spinlock_t name = __SPIN_LOCK_UNLOCKED(name) + +@@ -89,32 +90,20 @@ typedef struct { + #endif + } rwlock_t; + +-# ifdef CONFIG_DEBUG_RT_MUTEXES +-# define __RW_LOCK_UNLOCKED(name) (rwlock_t) \ +- { .lock = { .wait_lock = _RAW_SPIN_LOCK_UNLOCKED(name), \ +- .save_state = 1, .file = __FILE__, .line = __LINE__ } } +-# else +-# define __RW_LOCK_UNLOCKED(name) (rwlock_t) \ +- { .lock = { .wait_lock = _RAW_SPIN_LOCK_UNLOCKED(name) } } +-# endif ++#define __RW_LOCK_UNLOCKED(name) (rwlock_t) \ ++ { .lock = __RT_SPIN_INITIALIZER(name), \ ++ RW_DEP_MAP_INIT(name) } + #else /* !PREEMPT_RT */ + +- typedef raw_rwlock_t rwlock_t; +-# ifdef CONFIG_DEBUG_SPINLOCK +-# define _RW_LOCK_UNLOCKED \ +- (rwlock_t) { .raw_lock = __RAW_RW_LOCK_UNLOCKED, \ +- .magic = RWLOCK_MAGIC, \ +- .owner = SPINLOCK_OWNER_INIT, \ +- .owner_cpu = -1 } +-# else +-# define _RW_LOCK_UNLOCKED \ +- (rwlock_t) { .raw_lock = __RAW_RW_LOCK_UNLOCKED } +-# endif +-# define __RW_LOCK_UNLOCKED(name) _RW_LOCK_UNLOCKED ++typedef raw_rwlock_t rwlock_t; ++ ++#define __RW_LOCK_UNLOCKED _RAW_RW_LOCK_UNLOCKED ++ + #endif + + #define RW_LOCK_UNLOCKED __RW_LOCK_UNLOCKED(rw_old_style) + ++ + #define DEFINE_RWLOCK(name) \ + rwlock_t name __cacheline_aligned_in_smp = __RW_LOCK_UNLOCKED(name) + +@@ -236,7 +225,8 @@ do { \ + */ + + #define __RWSEM_INITIALIZER(name) \ +- { .lock = __RT_MUTEX_INITIALIZER(name.lock) } ++ { .lock = __RT_MUTEX_INITIALIZER(name.lock), \ ++ RW_DEP_MAP_INIT(name) } + + #define DECLARE_RWSEM(lockname) \ + struct rw_semaphore lockname = __RWSEM_INITIALIZER(lockname) --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0446-adaptive-spinlock-lite-v2.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0446-adaptive-spinlock-lite-v2.patch @@ -0,0 +1,178 @@ +From: Steven Rostedt +Subject: adaptive spinlocks lite + +After talking with Gregory Haskins about how they implemented his +version of adaptive spinlocks and before I actually looked at their +code, I was thinking about it while lying in bed. + +I always thought that adaptive spinlocks were to spin for a short +period of time based off of some heuristic and then sleep. This idea +is totally bogus. No heuristic can account for a bunch of different +activities. But Gregory mentioned something to me that made a hell of a lot +of sense. And that is to only spin while the owner is running. + +If the owner is running, then it would seem that it would be quicker to +spin then to take the scheduling hit. While lying awake in bed, it dawned +on me that we could simply spin in the fast lock and never touch the +"has waiters" flag, which would keep the owner from going into the +slow path. Also, the task itself is preemptible while spinning so this +would not affect latencies. + +The only trick was to not have the owner get freed between the time +you saw the owner and the time you check its run queue. This was +easily solved by simply grabing the RCU read lock because freeing +of a task must happen after a grace period. + +I first tried to stay only in the fast path. This works fine until you want +to guarantee that the highest prio task gets the lock next. I tried all +sorts of hackeries and found that there was too many cases where we can +miss. I finally concurred with Gregory, and decided that going into the +slow path was the way to go. + +I then started looking into what the guys over at Novell did. The had the +basic idea correct, but went way overboard in the implementation, making +it far more complex than it needed to be. I rewrote their work using the +ideas from my original patch, and simplified it quite a bit. + +This is the patch that they wanted to do ;-) + +Special thanks goes out to Gregory Haskins, Sven Dietrich and +Peter Morreale, for proving that adaptive spin locks certainly *can* +make a difference. + +Signed-off-by: Steven Rostedt +--- + include/linux/sched.h | 2 + + kernel/rtmutex.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++--- + kernel/sched.c | 5 +++ + 3 files changed, 68 insertions(+), 3 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/sched.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/sched.h 2008-10-08 22:24:47.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/sched.h 2008-10-08 22:24:50.000000000 -0400 +@@ -2217,6 +2217,8 @@ static inline void migration_init(void) + } + #endif + ++extern int task_is_current(struct task_struct *task); ++ + #define TASK_STATE_TO_CHAR_STR "RMSDTtZX" + + #endif /* __KERNEL__ */ +Index: linux-2.6.24.7-rt21/kernel/rtmutex.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rtmutex.c 2008-10-08 22:24:50.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rtmutex.c 2008-10-08 22:24:50.000000000 -0400 +@@ -8,6 +8,12 @@ + * Copyright (C) 2005 Kihon Technologies Inc., Steven Rostedt + * Copyright (C) 2006 Esben Nielsen + * ++ * Adaptive Spinlocks: ++ * Copyright (C) 2008 Novell, Inc., Gregory Haskins, Sven Dietrich, ++ * and Peter Morreale, ++ * Adaptive Spinlocks simplification: ++ * Copyright (C) 2008 Red Hat, Inc., Steven Rostedt ++ * + * See Documentation/rt-mutex-design.txt for details. + */ + #include +@@ -674,6 +680,54 @@ update_current(unsigned long new_state, + *saved_state = TASK_RUNNING; + } + ++#ifdef CONFIG_SMP ++static int adaptive_wait(struct rt_mutex_waiter *waiter, ++ struct task_struct *orig_owner) ++{ ++ int sleep = 0; ++ ++ for (;;) { ++ ++ /* we are the owner? */ ++ if (!waiter->task) ++ break; ++ ++ /* ++ * We need to read the owner of the lock and then check ++ * its state. But we can't let the owner task be freed ++ * while we read the state. We grab the rcu_lock and ++ * this makes sure that the owner task wont disappear ++ * between testing that it still has the lock, and checking ++ * its state. ++ */ ++ rcu_read_lock(); ++ /* Owner changed? Then lets update the original */ ++ if (orig_owner != rt_mutex_owner(waiter->lock)) { ++ rcu_read_unlock(); ++ break; ++ } ++ ++ /* Owner went to bed, so should we */ ++ if (!task_is_current(orig_owner)) { ++ sleep = 1; ++ rcu_read_unlock(); ++ break; ++ } ++ rcu_read_unlock(); ++ ++ cpu_relax(); ++ } ++ ++ return sleep; ++} ++#else ++static int adaptive_wait(struct rt_mutex_waiter *waiter, ++ struct task_struct *orig_owner) ++{ ++ return 1; ++} ++#endif ++ + /* + * Slow path lock function spin_lock style: this variant is very + * careful not to miss any non-lock wakeups. +@@ -689,6 +743,7 @@ rt_spin_lock_slowlock(struct rt_mutex *l + { + struct rt_mutex_waiter waiter; + unsigned long saved_state, state, flags; ++ struct task_struct *orig_owner; + + debug_rt_mutex_init_waiter(&waiter); + waiter.task = NULL; +@@ -741,13 +796,16 @@ rt_spin_lock_slowlock(struct rt_mutex *l + saved_flags = current->flags & PF_NOSCHED; + current->lock_depth = -1; + current->flags &= ~PF_NOSCHED; ++ orig_owner = rt_mutex_owner(lock); + spin_unlock_irqrestore(&lock->wait_lock, flags); + + debug_rt_mutex_print_deadlock(&waiter); + +- update_current(TASK_UNINTERRUPTIBLE, &saved_state); +- if (waiter.task) +- schedule_rt_mutex(lock); ++ if (adaptive_wait(&waiter, orig_owner)) { ++ update_current(TASK_UNINTERRUPTIBLE, &saved_state); ++ if (waiter.task) ++ schedule_rt_mutex(lock); ++ } + + spin_lock_irqsave(&lock->wait_lock, flags); + current->flags |= saved_flags; +Index: linux-2.6.24.7-rt21/kernel/sched.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched.c 2008-10-08 22:24:47.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched.c 2008-10-08 22:24:50.000000000 -0400 +@@ -573,6 +573,11 @@ int runqueue_is_locked(void) + return ret; + } + ++int task_is_current(struct task_struct *task) ++{ ++ return task_rq(task)->curr == task; ++} ++ + /* + * Debugging: various feature bits + */ --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0538-nfs-stats-miss-preemption.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0538-nfs-stats-miss-preemption.patch @@ -0,0 +1,36 @@ +Subject: nfs: fix missing preemption check +From: Thomas Gleixner +Date: Sun, 27 Jul 2008 00:54:19 +0200 + +NFS iostats use get_cpu()/put_cpu_no_preempt(). That misses a +preemption check for no good reason and introduces long latencies when +a wakeup of a higher priority task happens in the preempt disabled +region. + +Signed-off-by: Thomas Gleixner +--- + fs/nfs/iostat.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/fs/nfs/iostat.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/nfs/iostat.h 2008-10-08 22:22:09.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/nfs/iostat.h 2008-10-08 22:25:13.000000000 -0400 +@@ -125,7 +125,7 @@ static inline void nfs_inc_server_stats( + cpu = get_cpu(); + iostats = per_cpu_ptr(server->io_stats, cpu); + iostats->events[stat] ++; +- put_cpu_no_resched(); ++ put_cpu(); + } + + static inline void nfs_inc_stats(struct inode *inode, enum nfs_stat_eventcounters stat) +@@ -141,7 +141,7 @@ static inline void nfs_add_server_stats( + cpu = get_cpu(); + iostats = per_cpu_ptr(server->io_stats, cpu); + iostats->bytes[stat] += addend; +- put_cpu_no_resched(); ++ put_cpu(); + } + + static inline void nfs_add_stats(struct inode *inode, enum nfs_stat_bytecounters stat, unsigned long addend) --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0252-preempt-realtime-ide.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0252-preempt-realtime-ide.patch @@ -0,0 +1,334 @@ +--- + drivers/ide/ide-floppy.c | 4 ++-- + drivers/ide/ide-io.c | 4 ++-- + drivers/ide/ide-iops.c | 24 +++++++++++------------- + drivers/ide/ide-lib.c | 14 +++++--------- + drivers/ide/ide-probe.c | 8 ++++---- + drivers/ide/ide-taskfile.c | 6 +++--- + drivers/ide/pci/alim15x3.c | 12 ++++++------ + drivers/ide/pci/hpt366.c | 4 ++-- + 8 files changed, 35 insertions(+), 41 deletions(-) + +Index: linux-2.6.24.7-rt21/drivers/ide/ide-floppy.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/ide/ide-floppy.c 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/ide/ide-floppy.c 2008-10-08 22:24:02.000000000 -0400 +@@ -1668,9 +1668,9 @@ static int idefloppy_get_format_progress + atapi_status_t status; + unsigned long flags; + +- local_irq_save(flags); ++ local_irq_save_nort(flags); + status.all = HWIF(drive)->INB(IDE_STATUS_REG); +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + + progress_indication = !status.b.dsc ? 0 : 0x10000; + } +Index: linux-2.6.24.7-rt21/drivers/ide/ide-io.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/ide/ide-io.c 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/ide/ide-io.c 2008-10-08 22:24:02.000000000 -0400 +@@ -1194,7 +1194,7 @@ static void ide_do_request (ide_hwgroup_ + ide_get_lock(ide_intr, hwgroup); + + /* caller must own ide_lock */ +- BUG_ON(!irqs_disabled()); ++ BUG_ON_NONRT(!irqs_disabled()); + + while (!hwgroup->busy) { + hwgroup->busy = 1; +@@ -1462,7 +1462,7 @@ void ide_timer_expiry (unsigned long dat + #endif /* DISABLE_IRQ_NOSYNC */ + /* local CPU only, + * as if we were handling an interrupt */ +- local_irq_disable(); ++ local_irq_disable_nort(); + if (hwgroup->polling) { + startstop = handler(drive); + } else if (drive_is_ready(drive)) { +Index: linux-2.6.24.7-rt21/drivers/ide/ide-iops.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/ide/ide-iops.c 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/ide/ide-iops.c 2008-10-08 22:24:02.000000000 -0400 +@@ -220,10 +220,10 @@ static void ata_input_data(ide_drive_t * + if (io_32bit) { + if (io_32bit & 2) { + unsigned long flags; +- local_irq_save(flags); ++ local_irq_save_nort(flags); + ata_vlb_sync(drive, IDE_NSECTOR_REG); + hwif->INSL(IDE_DATA_REG, buffer, wcount); +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + } else + hwif->INSL(IDE_DATA_REG, buffer, wcount); + } else { +@@ -242,10 +242,10 @@ static void ata_output_data(ide_drive_t + if (io_32bit) { + if (io_32bit & 2) { + unsigned long flags; +- local_irq_save(flags); ++ local_irq_save_nort(flags); + ata_vlb_sync(drive, IDE_NSECTOR_REG); + hwif->OUTSL(IDE_DATA_REG, buffer, wcount); +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + } else + hwif->OUTSL(IDE_DATA_REG, buffer, wcount); + } else { +@@ -506,12 +506,12 @@ static int __ide_wait_stat(ide_drive_t * + if (!(stat & BUSY_STAT)) + break; + +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + *rstat = stat; + return -EBUSY; + } + } +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + } + /* + * Allow status to settle, then read it again. +@@ -730,17 +730,15 @@ int ide_driveid_update(ide_drive_t *driv + printk("%s: CHECK for good STATUS\n", drive->name); + return 0; + } +- local_irq_save(flags); +- SELECT_MASK(drive, 0); + id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC); +- if (!id) { +- local_irq_restore(flags); ++ if (!id) + return 0; +- } ++ local_irq_save_nort(flags); ++ SELECT_MASK(drive, 0); + ata_input_data(drive, id, SECTOR_WORDS); + (void) hwif->INB(IDE_STATUS_REG); /* clear drive IRQ */ +- local_irq_enable(); +- local_irq_restore(flags); ++ local_irq_enable_nort(); ++ local_irq_restore_nort(flags); + ide_fix_driveid(id); + if (id) { + drive->id->dma_ultra = id->dma_ultra; +Index: linux-2.6.24.7-rt21/drivers/ide/ide-lib.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/ide/ide-lib.c 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/ide/ide-lib.c 2008-10-08 22:24:02.000000000 -0400 +@@ -447,15 +447,16 @@ int ide_set_xfer_rate(ide_drive_t *drive + + static void ide_dump_opcode(ide_drive_t *drive) + { ++ unsigned long flags; + struct request *rq; + u8 opcode = 0; + int found = 0; + +- spin_lock(&ide_lock); ++ spin_lock_irqsave(&ide_lock, flags); + rq = NULL; + if (HWGROUP(drive)) + rq = HWGROUP(drive)->rq; +- spin_unlock(&ide_lock); ++ spin_unlock_irqrestore(&ide_lock, flags); + if (!rq) + return; + if (rq->cmd_type == REQ_TYPE_ATA_CMD || +@@ -484,10 +485,8 @@ static void ide_dump_opcode(ide_drive_t + static u8 ide_dump_ata_status(ide_drive_t *drive, const char *msg, u8 stat) + { + ide_hwif_t *hwif = HWIF(drive); +- unsigned long flags; + u8 err = 0; + +- local_irq_save(flags); + printk("%s: %s: status=0x%02x { ", drive->name, msg, stat); + if (stat & BUSY_STAT) + printk("Busy "); +@@ -548,7 +547,7 @@ static u8 ide_dump_ata_status(ide_drive_ + printk("\n"); + } + ide_dump_opcode(drive); +- local_irq_restore(flags); ++ + return err; + } + +@@ -563,14 +562,11 @@ static u8 ide_dump_ata_status(ide_drive_ + + static u8 ide_dump_atapi_status(ide_drive_t *drive, const char *msg, u8 stat) + { +- unsigned long flags; +- + atapi_status_t status; + atapi_error_t error; + + status.all = stat; + error.all = 0; +- local_irq_save(flags); + printk("%s: %s: status=0x%02x { ", drive->name, msg, stat); + if (status.b.bsy) + printk("Busy "); +@@ -596,7 +592,7 @@ static u8 ide_dump_atapi_status(ide_driv + printk("}\n"); + } + ide_dump_opcode(drive); +- local_irq_restore(flags); ++ + return error.all; + } + +Index: linux-2.6.24.7-rt21/drivers/ide/ide-probe.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/ide/ide-probe.c 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/ide/ide-probe.c 2008-10-08 22:24:02.000000000 -0400 +@@ -128,7 +128,7 @@ static inline void do_identify (ide_driv + hwif->ata_input_data(drive, id, SECTOR_WORDS); + + drive->id_read = 1; +- local_irq_enable(); ++ local_irq_enable_nort(); + ide_fix_driveid(id); + + #if defined (CONFIG_SCSI_EATA_PIO) || defined (CONFIG_SCSI_EATA) +@@ -311,14 +311,14 @@ static int actual_try_to_identify (ide_d + unsigned long flags; + + /* local CPU only; some systems need this */ +- local_irq_save(flags); ++ local_irq_save_nort(flags); + /* drive returned ID */ + do_identify(drive, cmd); + /* drive responded with ID */ + rc = 0; + /* clear drive IRQ */ + (void) hwif->INB(IDE_STATUS_REG); +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + } else { + /* drive refused ID */ + rc = 2; +@@ -801,7 +801,7 @@ static void probe_hwif(ide_hwif_t *hwif) + } while ((stat & BUSY_STAT) && time_after(timeout, jiffies)); + + } +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + /* + * Use cached IRQ number. It might be (and is...) changed by probe + * code above +Index: linux-2.6.24.7-rt21/drivers/ide/ide-taskfile.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/ide/ide-taskfile.c 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/ide/ide-taskfile.c 2008-10-08 22:24:02.000000000 -0400 +@@ -269,7 +269,7 @@ static void ide_pio_sector(ide_drive_t * + offset %= PAGE_SIZE; + + #ifdef CONFIG_HIGHMEM +- local_irq_save(flags); ++ local_irq_save_nort(flags); + #endif + buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset; + +@@ -289,7 +289,7 @@ static void ide_pio_sector(ide_drive_t * + + kunmap_atomic(buf, KM_BIO_SRC_IRQ); + #ifdef CONFIG_HIGHMEM +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + #endif + } + +@@ -457,7 +457,7 @@ ide_startstop_t pre_task_out_intr (ide_d + } + + if (!drive->unmask) +- local_irq_disable(); ++ local_irq_disable_nort(); + + ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); + ide_pio_datablock(drive, rq, 1); +Index: linux-2.6.24.7-rt21/drivers/ide/pci/alim15x3.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/ide/pci/alim15x3.c 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/ide/pci/alim15x3.c 2008-10-08 22:24:02.000000000 -0400 +@@ -322,7 +322,7 @@ static void ali_set_pio_mode(ide_drive_t + if (r_clc >= 16) + r_clc = 0; + } +- local_irq_save(flags); ++ local_irq_save_nort(flags); + + /* + * PIO mode => ATA FIFO on, ATAPI FIFO off +@@ -344,7 +344,7 @@ static void ali_set_pio_mode(ide_drive_t + + pci_write_config_byte(dev, port, s_clc); + pci_write_config_byte(dev, port+drive->select.b.unit+2, (a_clc << 4) | r_clc); +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + + /* + * setup active rec +@@ -479,7 +479,7 @@ static unsigned int __devinit init_chips + } + #endif /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_IDE_PROC_FS) */ + +- local_irq_save(flags); ++ local_irq_save_nort(flags); + + if (m5229_revision < 0xC2) { + /* +@@ -570,7 +570,7 @@ out: + } + pci_dev_put(north); + pci_dev_put(isa_dev); +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + return 0; + } + +@@ -632,7 +632,7 @@ static u8 __devinit ata66_ali15x3(ide_hw + unsigned long flags; + u8 cbl = ATA_CBL_PATA40, tmpbyte; + +- local_irq_save(flags); ++ local_irq_save_nort(flags); + + if (m5229_revision >= 0xC2) { + /* +@@ -653,7 +653,7 @@ static u8 __devinit ata66_ali15x3(ide_hw + } + } + +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + + return cbl; + } +Index: linux-2.6.24.7-rt21/drivers/ide/pci/hpt366.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/ide/pci/hpt366.c 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/ide/pci/hpt366.c 2008-10-08 22:24:02.000000000 -0400 +@@ -1430,7 +1430,7 @@ static void __devinit init_dma_hpt366(id + + dma_old = inb(dmabase + 2); + +- local_irq_save(flags); ++ local_irq_save_nort(flags); + + dma_new = dma_old; + pci_read_config_byte(dev, hwif->channel ? 0x4b : 0x43, &masterdma); +@@ -1441,7 +1441,7 @@ static void __devinit init_dma_hpt366(id + if (dma_new != dma_old) + outb(dma_new, dmabase + 2); + +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + + ide_setup_dma(hwif, dmabase, 8); + } --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0402-use-edge-triggered-irq-handler-instead-of-simple-irq.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0402-use-edge-triggered-irq-handler-instead-of-simple-irq.patch @@ -0,0 +1,67 @@ +From: Remy Bohmer +Subject: [AT91: PATCH]: Use edge triggered interrupt handling for AT91-GPIO instead of simple_irq-handler + +On ARM there is a problem where the interrupt handler stalls when they are +coming faster than the kernel can handle. +The problem seems to occur on RT primarily, but the problem is also valid for +non-RT kernels. + +The problem is twofold: +* the handle_simple_irq() mechanism is used for GPIO, but because the GPIO +interrupt source is actually an edge triggered interrupt source, the +handle_edge_irq() mechanism must be used. While using the simple_irq() +mechanisms edges can be missed for either mainline as RT kernels. +The simple_irq mechanism is *never* meant to be used for these types +of interrupts. See the thread at: http://lkml.org/lkml/2007/11/26/73 +* The RT kernels has a problem that the interrupt get masked forever while +the interrupt thread is running and a new interrupt arrives. +In the interrupt threads there is masking done in the handle_simple_irq() +path, while a simple_irq typically cannot be masked. + +This patch only solves the first bullet, which is enough for AT91, by +moving the GPIO interrupt handler towards the handle_edge_irq(). +To solve the problem in the simple_irq() path a seperate fix has to be done, +but as it is no longer used by AT91, that fix will not affect AT91. + +Tested on: +* AT91rm9200-ek, and proprietary board +* AT91SAM9261-ek. (This patches also solves the problem that the DM9000 does + not work on this board while using PREEMPT-RT) + +Signed-off-by: Remy Bohmer +--- + arch/arm/mach-at91/gpio.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/arch/arm/mach-at91/gpio.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/arm/mach-at91/gpio.c 2008-10-08 22:22:17.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/arm/mach-at91/gpio.c 2008-10-08 22:24:40.000000000 -0400 +@@ -362,12 +362,18 @@ static int gpio_irq_type(unsigned pin, u + return (type == IRQT_BOTHEDGE) ? 0 : -EINVAL; + } + ++static void gpio_irq_ack_noop(unsigned int irq) ++{ ++ /* Dummy function. */ ++} ++ + static struct irq_chip gpio_irqchip = { + .name = "GPIO", + .mask = gpio_irq_mask, + .unmask = gpio_irq_unmask, + .set_type = gpio_irq_type, + .set_wake = gpio_irq_set_wake, ++ .ack = gpio_irq_ack_noop, + }; + + static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) +@@ -442,7 +448,7 @@ void __init at91_gpio_irq_setup(void) + * shorter, and the AIC handles interrupts sanely. + */ + set_irq_chip(pin, &gpio_irqchip); +- set_irq_handler(pin, handle_simple_irq); ++ set_irq_handler(pin, handle_edge_irq); + set_irq_flags(pin, IRQF_VALID); + } + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0311-rt-kmap-scale-fix.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0311-rt-kmap-scale-fix.patch @@ -0,0 +1,233 @@ +Hi Ingo, + +Apply on top of what is still in -rt. + +This seems to survive a kbuild -j64 & -j512 (although with that latter the +machine goes off for a while, but does return with a kernel). + +If you can spare a cycle between hacking syslets and -rt, could you have a +look at the logic this patch adds? + +--- +Solve 2 deadlocks in the current kmap code. + +1) akpm spotted a race in the waitqueue usage that could deadlock the machine. + the very unlikely scenario was what we would not find a usable map in + LAST_PKMAP tries but right before we hit schedule the very last returns. + + Solve this by keeping a free count. + +2) akpm told about the kmap deadlock where multiple processes each require 2 + maps (src, dst). When they deplete the maps for the src maps they will be + stuck waiting for their dst maps. + + Solve this by by tracking (and limiting) kmap users and account two maps + for each. + +This all adds more atomic globals, this will bounce like mad on real large smp. +(perhaps add some __cacheline_aligned_on_smp) + +Signed-off-by: Peter Zijlstra +--- + include/linux/sched.h | 1 + mm/highmem.c | 96 ++++++++++++++++++++++++++++++++++++++++++++------ + 2 files changed, 87 insertions(+), 10 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/sched.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/sched.h 2008-10-08 22:24:16.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/sched.h 2008-10-08 22:24:18.000000000 -0400 +@@ -1493,6 +1493,7 @@ static inline void put_task_struct(struc + #define PF_MEMALLOC 0x00000800 /* Allocating memory */ + #define PF_FLUSHER 0x00001000 /* responsible for disk writeback */ + #define PF_USED_MATH 0x00002000 /* if unset the fpu must be initialized before use */ ++#define PF_KMAP 0x00004000 /* this context has a kmap */ + #define PF_NOFREEZE 0x00008000 /* this thread should not be frozen */ + #define PF_FROZEN 0x00010000 /* frozen for system suspend */ + #define PF_FSTRANS 0x00020000 /* inside a filesystem transaction */ +Index: linux-2.6.24.7-rt21/mm/highmem.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/mm/highmem.c 2008-10-08 22:24:18.000000000 -0400 ++++ linux-2.6.24.7-rt21/mm/highmem.c 2008-10-08 22:24:18.000000000 -0400 +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -67,10 +68,12 @@ unsigned int nr_free_highpages (void) + */ + static atomic_t pkmap_count[LAST_PKMAP]; + static atomic_t pkmap_hand; ++static atomic_t pkmap_free; ++static atomic_t pkmap_users; + + pte_t * pkmap_page_table; + +-static DECLARE_WAIT_QUEUE_HEAD(pkmap_map_wait); ++static DECLARE_WAIT_QUEUE_HEAD(pkmap_wait); + + /* + * Try to free a given kmap slot. +@@ -85,6 +88,7 @@ static int pkmap_try_free(int pos) + if (atomic_cmpxchg(&pkmap_count[pos], 1, 0) != 1) + return -1; + ++ atomic_dec(&pkmap_free); + /* + * TODO: add a young bit to make it CLOCK + */ +@@ -113,7 +117,8 @@ static inline void pkmap_put(atomic_t *c + BUG(); + + case 1: +- wake_up(&pkmap_map_wait); ++ atomic_inc(&pkmap_free); ++ wake_up(&pkmap_wait); + } + } + +@@ -122,11 +127,10 @@ static inline void pkmap_put(atomic_t *c + static int pkmap_get_free(void) + { + int i, pos, flush; +- DECLARE_WAITQUEUE(wait, current); + + restart: + for (i = 0; i < LAST_PKMAP; i++) { +- pos = atomic_inc_return(&pkmap_hand) % LAST_PKMAP; ++ pos = atomic_inc_return(&pkmap_hand) & LAST_PKMAP_MASK; + flush = pkmap_try_free(pos); + if (flush >= 0) + goto got_one; +@@ -135,10 +139,8 @@ restart: + /* + * wait for somebody else to unmap their entries + */ +- __set_current_state(TASK_UNINTERRUPTIBLE); +- add_wait_queue(&pkmap_map_wait, &wait); +- schedule(); +- remove_wait_queue(&pkmap_map_wait, &wait); ++ if (likely(!in_interrupt())) ++ wait_event(pkmap_wait, atomic_read(&pkmap_free) != 0); + + goto restart; + +@@ -147,7 +149,7 @@ got_one: + #if 0 + flush_tlb_kernel_range(PKMAP_ADDR(pos), PKMAP_ADDR(pos+1)); + #else +- int pos2 = (pos + 1) % LAST_PKMAP; ++ int pos2 = (pos + 1) & LAST_PKMAP_MASK; + int nr; + int entries[TLB_BATCH]; + +@@ -157,7 +159,7 @@ got_one: + * Scan ahead of the hand to minimise search distances. + */ + for (i = 0, nr = 0; i < LAST_PKMAP && nr < TLB_BATCH; +- i++, pos2 = (pos2 + 1) % LAST_PKMAP) { ++ i++, pos2 = (pos2 + 1) & LAST_PKMAP_MASK) { + + flush = pkmap_try_free(pos2); + if (flush < 0) +@@ -222,9 +224,79 @@ void kmap_flush_unused(void) + WARN_ON_ONCE(1); + } + ++/* ++ * Avoid starvation deadlock by limiting the number of tasks that can obtain a ++ * kmap to (LAST_PKMAP - KM_TYPE_NR*NR_CPUS)/2. ++ */ ++static void kmap_account(void) ++{ ++ int weight; ++ ++#ifndef CONFIG_PREEMPT_RT ++ if (in_interrupt()) { ++ /* irqs can always get them */ ++ weight = -1; ++ } else ++#endif ++ if (current->flags & PF_KMAP) { ++ current->flags &= ~PF_KMAP; ++ /* we already accounted the second */ ++ weight = 0; ++ } else { ++ /* mark 1, account 2 */ ++ current->flags |= PF_KMAP; ++ weight = 2; ++ } ++ ++ if (weight > 0) { ++ /* ++ * reserve KM_TYPE_NR maps per CPU for interrupt context ++ */ ++ const int target = LAST_PKMAP ++#ifndef CONFIG_PREEMPT_RT ++ - KM_TYPE_NR*NR_CPUS ++#endif ++ ; ++ ++again: ++ wait_event(pkmap_wait, ++ atomic_read(&pkmap_users) + weight <= target); ++ ++ if (atomic_add_return(weight, &pkmap_users) > target) { ++ atomic_sub(weight, &pkmap_users); ++ goto again; ++ } ++ } ++} ++ ++static void kunmap_account(void) ++{ ++ int weight; ++ ++#ifndef CONFIG_PREEMPT_RT ++ if (in_irq()) { ++ weight = -1; ++ } else ++#endif ++ if (current->flags & PF_KMAP) { ++ /* there was only 1 kmap, un-account both */ ++ current->flags &= ~PF_KMAP; ++ weight = 2; ++ } else { ++ /* there were two kmaps, un-account per kunmap */ ++ weight = 1; ++ } ++ ++ if (weight > 0) ++ atomic_sub(weight, &pkmap_users); ++ wake_up(&pkmap_wait); ++} ++ + fastcall void *kmap_high(struct page *page) + { + unsigned long vaddr; ++ ++ kmap_account(); + again: + vaddr = (unsigned long)page_address(page); + if (vaddr) { +@@ -265,6 +337,7 @@ fastcall void kunmap_high(struct page *p + unsigned long vaddr = (unsigned long)page_address(page); + BUG_ON(!vaddr); + pkmap_put(&pkmap_count[PKMAP_NR(vaddr)]); ++ kunmap_account(); + } + + EXPORT_SYMBOL(kunmap_high); +@@ -409,6 +482,9 @@ void __init page_address_init(void) + + for (i = 0; i < ARRAY_SIZE(pkmap_count); i++) + atomic_set(&pkmap_count[i], 1); ++ atomic_set(&pkmap_hand, 0); ++ atomic_set(&pkmap_free, LAST_PKMAP); ++ atomic_set(&pkmap_users, 0); + #endif + + #ifdef HASHED_PAGE_VIRTUAL --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0024-0008-sched-add-RT-balance-cpu-weight.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0024-0008-sched-add-RT-balance-cpu-weight.patch @@ -0,0 +1,219 @@ +From 70e614272ba7e0dbc23621e800972099f729447f Mon Sep 17 00:00:00 2001 +From: Gregory Haskins +Date: Tue, 11 Dec 2007 10:02:37 +0100 +Subject: [PATCH] sched: add RT-balance cpu-weight + +Some RT tasks (particularly kthreads) are bound to one specific CPU. +It is fairly common for two or more bound tasks to get queued up at the +same time. Consider, for instance, softirq_timer and softirq_sched. A +timer goes off in an ISR which schedules softirq_thread to run at RT50. +Then the timer handler determines that it's time to smp-rebalance the +system so it schedules softirq_sched to run. So we are in a situation +where we have two RT50 tasks queued, and the system will go into +rt-overload condition to request other CPUs for help. + +This causes two problems in the current code: + +1) If a high-priority bound task and a low-priority unbounded task queue + up behind the running task, we will fail to ever relocate the unbounded + task because we terminate the search on the first unmovable task. + +2) We spend precious futile cycles in the fast-path trying to pull + overloaded tasks over. It is therefore optimial to strive to avoid the + overhead all together if we can cheaply detect the condition before + overload even occurs. + +This patch tries to achieve this optimization by utilizing the hamming +weight of the task->cpus_allowed mask. A weight of 1 indicates that +the task cannot be migrated. We will then utilize this information to +skip non-migratable tasks and to eliminate uncessary rebalance attempts. + +We introduce a per-rq variable to count the number of migratable tasks +that are currently running. We only go into overload if we have more +than one rt task, AND at least one of them is migratable. + +In addition, we introduce a per-task variable to cache the cpus_allowed +weight, since the hamming calculation is probably relatively expensive. +We only update the cached value when the mask is updated which should be +relatively infrequent, especially compared to scheduling frequency +in the fast path. + +Signed-off-by: Gregory Haskins +Signed-off-by: Steven Rostedt +Signed-off-by: Ingo Molnar + +--- + include/linux/init_task.h | 1 + include/linux/sched.h | 2 + + kernel/fork.c | 1 + kernel/sched.c | 9 +++++++- + kernel/sched_rt.c | 50 +++++++++++++++++++++++++++++++++++++++++----- + 5 files changed, 57 insertions(+), 6 deletions(-) + +Index: hardy/include/linux/init_task.h +=================================================================== +--- hardy.orig/include/linux/init_task.h 2008-11-18 16:01:47.000000000 +0100 ++++ hardy/include/linux/init_task.h 2008-11-21 17:07:18.000000000 +0100 +@@ -130,6 +130,7 @@ + .normal_prio = MAX_PRIO-20, \ + .policy = SCHED_NORMAL, \ + .cpus_allowed = CPU_MASK_ALL, \ ++ .nr_cpus_allowed = NR_CPUS, \ + .mm = NULL, \ + .active_mm = &init_mm, \ + .run_list = LIST_HEAD_INIT(tsk.run_list), \ +Index: hardy/include/linux/sched.h +=================================================================== +--- hardy.orig/include/linux/sched.h 2008-11-18 16:01:47.000000000 +0100 ++++ hardy/include/linux/sched.h 2008-11-21 17:07:39.000000000 +0100 +@@ -848,6 +848,7 @@ + void (*set_curr_task) (struct rq *rq); + void (*task_tick) (struct rq *rq, struct task_struct *p); + void (*task_new) (struct rq *rq, struct task_struct *p); ++ void (*set_cpus_allowed)(struct task_struct *p, cpumask_t *newmask); + + #ifdef CONFIG_FAIR_GROUP_SCHED + void (*moved_group) (struct task_struct *p); +@@ -961,6 +962,7 @@ + + unsigned int policy; + cpumask_t cpus_allowed; ++ int nr_cpus_allowed; + unsigned int time_slice; + + #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) +Index: hardy/kernel/fork.c +=================================================================== +--- hardy.orig/kernel/fork.c 2008-11-18 16:01:47.000000000 +0100 ++++ hardy/kernel/fork.c 2008-11-21 17:07:18.000000000 +0100 +@@ -1239,6 +1239,7 @@ + * parent's CPU). This avoids alot of nasty races. + */ + p->cpus_allowed = current->cpus_allowed; ++ p->nr_cpus_allowed = current->nr_cpus_allowed; + if (unlikely(!cpu_isset(task_cpu(p), p->cpus_allowed) || + !cpu_online(task_cpu(p)))) + set_task_cpu(p, smp_processor_id()); +Index: hardy/kernel/sched.c +=================================================================== +--- hardy.orig/kernel/sched.c 2008-11-21 17:07:15.000000000 +0100 ++++ hardy/kernel/sched.c 2008-11-21 17:07:18.000000000 +0100 +@@ -267,6 +267,7 @@ + int rt_load_balance_idx; + struct list_head *rt_load_balance_head, *rt_load_balance_curr; + unsigned long rt_nr_running; ++ unsigned long rt_nr_migratory; + /* highest queued rt task prio */ + int highest_prio; + }; +@@ -5130,7 +5131,13 @@ + goto out; + } + +- p->cpus_allowed = new_mask; ++ if (p->sched_class->set_cpus_allowed) ++ p->sched_class->set_cpus_allowed(p, &new_mask); ++ else { ++ p->cpus_allowed = new_mask; ++ p->nr_cpus_allowed = cpus_weight(new_mask); ++ } ++ + /* Can the task run on the task's current CPU? If so, we're done */ + if (cpu_isset(task_cpu(p), new_mask)) + goto out; +Index: hardy/kernel/sched_rt.c +=================================================================== +--- hardy.orig/kernel/sched_rt.c 2008-11-21 17:07:15.000000000 +0100 ++++ hardy/kernel/sched_rt.c 2008-11-21 17:07:18.000000000 +0100 +@@ -33,6 +33,14 @@ + atomic_dec(&rto_count); + cpu_clear(rq->cpu, rt_overload_mask); + } ++ ++static void update_rt_migration(struct rq *rq) ++{ ++ if (rq->rt.rt_nr_migratory && (rq->rt.rt_nr_running > 1)) ++ rt_set_overload(rq); ++ else ++ rt_clear_overload(rq); ++} + #endif /* CONFIG_SMP */ + + /* +@@ -65,8 +73,10 @@ + #ifdef CONFIG_SMP + if (p->prio < rq->rt.highest_prio) + rq->rt.highest_prio = p->prio; +- if (rq->rt.rt_nr_running > 1) +- rt_set_overload(rq); ++ if (p->nr_cpus_allowed > 1) ++ rq->rt.rt_nr_migratory++; ++ ++ update_rt_migration(rq); + #endif /* CONFIG_SMP */ + } + +@@ -88,8 +98,10 @@ + } /* otherwise leave rq->highest prio alone */ + } else + rq->rt.highest_prio = MAX_RT_PRIO; +- if (rq->rt.rt_nr_running < 2) +- rt_clear_overload(rq); ++ if (p->nr_cpus_allowed > 1) ++ rq->rt.rt_nr_migratory--; ++ ++ update_rt_migration(rq); + #endif /* CONFIG_SMP */ + } + +@@ -178,7 +190,8 @@ + static int pick_rt_task(struct rq *rq, struct task_struct *p, int cpu) + { + if (!task_running(rq, p) && +- (cpu < 0 || cpu_isset(cpu, p->cpus_allowed))) ++ (cpu < 0 || cpu_isset(cpu, p->cpus_allowed)) && ++ (p->nr_cpus_allowed > 1)) + return 1; + return 0; + } +@@ -580,6 +593,32 @@ + /* don't touch RT tasks */ + return 0; + } ++static void set_cpus_allowed_rt(struct task_struct *p, cpumask_t *new_mask) ++{ ++ int weight = cpus_weight(*new_mask); ++ ++ BUG_ON(!rt_task(p)); ++ ++ /* ++ * Update the migration status of the RQ if we have an RT task ++ * which is running AND changing its weight value. ++ */ ++ if (p->se.on_rq && (weight != p->nr_cpus_allowed)) { ++ struct rq *rq = task_rq(p); ++ ++ if ((p->nr_cpus_allowed <= 1) && (weight > 1)) ++ rq->rt.rt_nr_migratory++; ++ else if((p->nr_cpus_allowed > 1) && (weight <= 1)) { ++ BUG_ON(!rq->rt.rt_nr_migratory); ++ rq->rt.rt_nr_migratory--; ++ } ++ ++ update_rt_migration(rq); ++ } ++ ++ p->cpus_allowed = *new_mask; ++ p->nr_cpus_allowed = weight; ++} + #else /* CONFIG_SMP */ + # define schedule_tail_balance_rt(rq) do { } while (0) + # define schedule_balance_rt(rq, prev) do { } while (0) +@@ -633,6 +672,7 @@ + #ifdef CONFIG_SMP + .load_balance = load_balance_rt, + .move_one_task = move_one_task_rt, ++ .set_cpus_allowed = set_cpus_allowed_rt, + #endif + + .set_curr_task = set_curr_task_rt, --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0518-ftrace-call-function-pointer.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0518-ftrace-call-function-pointer.patch @@ -0,0 +1,26 @@ +Date: Tue, 15 Jul 2008 08:09:29 -0700 +From: Josh Triplett +Subject: [PATCH] ftrace: Actually call function pointer in ftrace_stop + +ftrace_stop used a function pointed as a no-op expression, rather than +actually calling it. + +Signed-off-by: Josh Triplett +Signed-off-by: Thomas Gleixner +--- + kernel/trace/trace.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/kernel/trace/trace.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/trace.c 2008-10-08 22:25:06.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/trace.c 2008-10-08 22:25:08.000000000 -0400 +@@ -3268,7 +3268,7 @@ void ftrace_stop(void) + if (tr->ctrl) { + tr->ctrl = 0; + if (saved_tracer && saved_tracer->ctrl_update) +- saved_tracer->ctrl_update; ++ saved_tracer->ctrl_update(tr); + } + + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0259-preempt-realtime-rcu.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0259-preempt-realtime-rcu.patch @@ -0,0 +1,62 @@ +--- + kernel/rcuclassic.c | 6 +++--- + kernel/rcupreempt.c | 6 +++--- + 2 files changed, 6 insertions(+), 6 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/rcuclassic.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rcuclassic.c 2008-10-08 22:23:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rcuclassic.c 2008-10-08 22:24:04.000000000 -0400 +@@ -57,7 +57,7 @@ struct rcu_ctrlblk { + + int signaled; + +- spinlock_t lock ____cacheline_internodealigned_in_smp; ++ raw_spinlock_t lock ____cacheline_internodealigned_in_smp; + cpumask_t cpumask; /* CPUs that need to switch in order */ + /* for current batch to proceed. */ + } ____cacheline_internodealigned_in_smp; +@@ -96,13 +96,13 @@ struct rcu_data { + static struct rcu_ctrlblk rcu_ctrlblk = { + .cur = -300, + .completed = -300, +- .lock = __SPIN_LOCK_UNLOCKED(&rcu_ctrlblk.lock), ++ .lock = RAW_SPIN_LOCK_UNLOCKED(&rcu_ctrlblk.lock), + .cpumask = CPU_MASK_NONE, + }; + static struct rcu_ctrlblk rcu_bh_ctrlblk = { + .cur = -300, + .completed = -300, +- .lock = __SPIN_LOCK_UNLOCKED(&rcu_bh_ctrlblk.lock), ++ .lock = RAW_SPIN_LOCK_UNLOCKED(&rcu_bh_ctrlblk.lock), + .cpumask = CPU_MASK_NONE, + }; + +Index: linux-2.6.24.7-rt21/kernel/rcupreempt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rcupreempt.c 2008-10-08 22:23:27.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rcupreempt.c 2008-10-08 22:24:04.000000000 -0400 +@@ -62,7 +62,7 @@ + + #define GP_STAGES 2 + struct rcu_data { +- spinlock_t lock; /* Protect rcu_data fields. */ ++ raw_spinlock_t lock; /* Protect rcu_data fields. */ + long completed; /* Number of last completed batch. */ + int waitlistcount; + struct rcu_head *nextlist; +@@ -76,12 +76,12 @@ struct rcu_data { + #endif /* #ifdef CONFIG_RCU_TRACE */ + }; + struct rcu_ctrlblk { +- spinlock_t fliplock; /* Protect state-machine transitions. */ ++ raw_spinlock_t fliplock; /* Protect state-machine transitions. */ + long completed; /* Number of last completed batch. */ + }; + static DEFINE_PER_CPU(struct rcu_data, rcu_data); + static struct rcu_ctrlblk rcu_ctrlblk = { +- .fliplock = SPIN_LOCK_UNLOCKED, ++ .fliplock = RAW_SPIN_LOCK_UNLOCKED(rcu_ctrlblk.fliplock), + .completed = 0, + }; + static DEFINE_PER_CPU(int [2], rcu_flipctr) = { 0, 0 }; --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0308-highmem-revert-mainline.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0308-highmem-revert-mainline.patch @@ -0,0 +1,24 @@ +--- + mm/highmem.c | 9 --------- + 1 file changed, 9 deletions(-) + +Index: linux-2.6.24.7-rt21/mm/highmem.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/mm/highmem.c 2008-10-08 22:22:23.000000000 -0400 ++++ linux-2.6.24.7-rt21/mm/highmem.c 2008-10-08 22:24:18.000000000 -0400 +@@ -104,15 +104,6 @@ static void flush_all_zero_pkmaps(void) + flush_tlb_kernel_range(PKMAP_ADDR(0), PKMAP_ADDR(LAST_PKMAP)); + } + +-/* Flush all unused kmap mappings in order to remove stray +- mappings. */ +-void kmap_flush_unused(void) +-{ +- spin_lock(&kmap_lock); +- flush_all_zero_pkmaps(); +- spin_unlock(&kmap_lock); +-} +- + static inline unsigned long map_new_virtual(struct page *page) + { + unsigned long vaddr; --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0032-0016-sched-RT-balance-avoid-overloading.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0032-0016-sched-RT-balance-avoid-overloading.patch @@ -0,0 +1,71 @@ +From 363a36e818e14bec32470f0d9e196fdef49ca293 Mon Sep 17 00:00:00 2001 +From: Steven Rostedt +Date: Tue, 11 Dec 2007 10:02:38 +0100 +Subject: [PATCH] sched: RT-balance, avoid overloading + +This patch changes the searching for a run queue by a waking RT task +to try to pick another runqueue if the currently running task +is an RT task. + +The reason is that RT tasks behave different than normal +tasks. Preempting a normal task to run a RT task to keep +its cache hot is fine, because the preempted non-RT task +may wait on that same runqueue to run again unless the +migration thread comes along and pulls it off. + +RT tasks behave differently. If one is preempted, it makes +an active effort to continue to run. So by having a high +priority task preempt a lower priority RT task, that lower +RT task will then quickly try to run on another runqueue. +This will cause that lower RT task to replace its nice +hot cache (and TLB) with a completely cold one. This is +for the hope that the new high priority RT task will keep + its cache hot. + +Remeber that this high priority RT task was just woken up. +So it may likely have been sleeping for several milliseconds, +and will end up with a cold cache anyway. RT tasks run till +they voluntarily stop, or are preempted by a higher priority +task. This means that it is unlikely that the woken RT task +will have a hot cache to wake up to. So pushing off a lower +RT task is just killing its cache for no good reason. + +Signed-off-by: Steven Rostedt +Signed-off-by: Ingo Molnar + +--- + kernel/sched_rt.c | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/sched_rt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched_rt.c 2008-10-08 22:22:59.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched_rt.c 2008-10-08 22:22:59.000000000 -0400 +@@ -156,11 +156,23 @@ static int select_task_rq_rt(struct task + struct rq *rq = task_rq(p); + + /* +- * If the task will not preempt the RQ, try to find a better RQ +- * before we even activate the task ++ * If the current task is an RT task, then ++ * try to see if we can wake this RT task up on another ++ * runqueue. Otherwise simply start this RT task ++ * on its current runqueue. ++ * ++ * We want to avoid overloading runqueues. Even if ++ * the RT task is of higher priority than the current RT task. ++ * RT tasks behave differently than other tasks. If ++ * one gets preempted, we try to push it off to another queue. ++ * So trying to keep a preempting RT task on the same ++ * cache hot CPU will force the running RT task to ++ * a cold CPU. So we waste all the cache for the lower ++ * RT task in hopes of saving some of a RT task ++ * that is just being woken and probably will have ++ * cold cache anyway. + */ +- if ((p->prio >= rq->rt.highest_prio) +- && (p->nr_cpus_allowed > 1)) { ++ if (unlikely(rt_task(rq->curr))) { + int cpu = find_lowest_rq(p); + + return (cpu == -1) ? task_cpu(p) : cpu; --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0514-rcu-backport-rcu-cpu-hotplug-support.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0514-rcu-backport-rcu-cpu-hotplug-support.patch @@ -0,0 +1,119 @@ +Subject: rcu: backport RCU cpu hotplug support +From: Peter Zijlstra +Date: Tue, 10 Jun 2008 13:13:03 +0200 + +backport the RCU cpu-hotplug support from .26-rc to .24-rt + +Signed-off-by: Peter Zijlstra +Cc: Steven Rostedt +Cc: Clark Williams +Cc: Gregory Haskins +Cc: "Paul E. McKenney" +Cc: Gautham R Shenoy +Cc: Pekka Enberg +Cc: Arnaldo Carvalho de Melo +Cc: Peter Zijlstra +Signed-off-by: Thomas Gleixner +--- + kernel/rcupreempt.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 55 insertions(+), 3 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/rcupreempt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rcupreempt.c 2008-10-08 22:24:41.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rcupreempt.c 2008-10-08 22:25:07.000000000 -0400 +@@ -820,6 +820,13 @@ void rcu_offline_cpu_rt(int cpu) + smp_mb(); /* Subsequent RCU read-side critical sections */ + /* seen -after- acknowledgement. */ + } ++ ++ __get_cpu_var(rcu_flipctr)[0] += per_cpu(rcu_flipctr, cpu)[0]; ++ __get_cpu_var(rcu_flipctr)[1] += per_cpu(rcu_flipctr, cpu)[1]; ++ ++ per_cpu(rcu_flipctr, cpu)[0] = 0; ++ per_cpu(rcu_flipctr, cpu)[1] = 0; ++ + cpu_clear(cpu, rcu_cpu_online_map); + spin_unlock_irqrestore(&rcu_ctrlblk.fliplock, oldirq); + +@@ -833,8 +840,9 @@ void rcu_offline_cpu_rt(int cpu) + * fix. + */ + ++ local_irq_save(oldirq); + rdp = RCU_DATA_ME(); +- spin_lock_irqsave(&rdp->lock, oldirq); ++ spin_lock(&rdp->lock); + *rdp->nexttail = list; + if (list) + rdp->nexttail = tail; +@@ -866,9 +874,11 @@ void rcu_process_callbacks_rt(struct sof + { + unsigned long flags; + struct rcu_head *next, *list; +- struct rcu_data *rdp = RCU_DATA_ME(); ++ struct rcu_data *rdp; + +- spin_lock_irqsave(&rdp->lock, flags); ++ local_irq_save(flags); ++ rdp = RCU_DATA_ME(); ++ spin_lock(&rdp->lock); + list = rdp->donelist; + if (list == NULL) { + spin_unlock_irqrestore(&rdp->lock, flags); +@@ -951,6 +961,32 @@ int rcu_pending_rt(int cpu) + return 0; + } + ++static int __cpuinit rcu_cpu_notify(struct notifier_block *self, ++ unsigned long action, void *hcpu) ++{ ++ long cpu = (long)hcpu; ++ ++ switch (action) { ++ case CPU_UP_PREPARE: ++ case CPU_UP_PREPARE_FROZEN: ++ rcu_online_cpu_rt(cpu); ++ break; ++ case CPU_UP_CANCELED: ++ case CPU_UP_CANCELED_FROZEN: ++ case CPU_DEAD: ++ case CPU_DEAD_FROZEN: ++ rcu_offline_cpu_rt(cpu); ++ break; ++ default: ++ break; ++ } ++ return NOTIFY_OK; ++} ++ ++static struct notifier_block __cpuinitdata rcu_nb = { ++ .notifier_call = rcu_cpu_notify, ++}; ++ + void __init rcu_init_rt(void) + { + int cpu; +@@ -972,6 +1008,22 @@ void __init rcu_init_rt(void) + rdp->donetail = &rdp->donelist; + } + rcu_preempt_boost_init(); ++ register_cpu_notifier(&rcu_nb); ++ ++ /* ++ * We don't need protection against CPU-Hotplug here ++ * since ++ * a) If a CPU comes online while we are iterating over the ++ * cpu_online_map below, we would only end up making a ++ * duplicate call to rcu_online_cpu() which sets the corresponding ++ * CPU's mask in the rcu_cpu_online_map. ++ * ++ * b) A CPU cannot go offline at this point in time since the user ++ * does not have access to the sysfs interface, nor do we ++ * suspend the system. ++ */ ++ for_each_online_cpu(cpu) ++ rcu_cpu_notify(&rcu_nb, CPU_UP_PREPARE, (void *)(long) cpu); + } + + /* --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0040-0025-sched-remove-rt_overload.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0040-0025-sched-remove-rt_overload.patch @@ -0,0 +1,48 @@ +From 03c269c753ca432cc33c3039c743bfceba10a3e9 Mon Sep 17 00:00:00 2001 +From: Ingo Molnar +Date: Tue, 11 Dec 2007 10:02:39 +0100 +Subject: [PATCH] sched: remove rt_overload() + +remove rt_overload() - it's an unnecessary indirection. + +Signed-off-by: Ingo Molnar + +--- + kernel/sched_rt.c | 10 +--------- + 1 file changed, 1 insertion(+), 9 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/sched_rt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched_rt.c 2008-10-08 22:23:01.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched_rt.c 2008-10-08 22:23:01.000000000 -0400 +@@ -17,11 +17,6 @@ static inline int rt_overloaded(void) + return atomic_read(&rto_count); + } + +-static inline cpumask_t *rt_overload(void) +-{ +- return &rt_overload_mask; +-} +- + static inline void rt_set_overload(struct rq *rq) + { + rq->rt.overloaded = 1; +@@ -586,7 +581,6 @@ static int pull_rt_task(struct rq *this_ + struct task_struct *next; + struct task_struct *p; + struct rq *src_rq; +- cpumask_t *rto_cpumask; + int this_cpu = this_rq->cpu; + int cpu; + int ret = 0; +@@ -604,9 +598,7 @@ static int pull_rt_task(struct rq *this_ + + next = pick_next_task_rt(this_rq); + +- rto_cpumask = rt_overload(); +- +- for_each_cpu_mask(cpu, *rto_cpumask) { ++ for_each_cpu_mask(cpu, rt_overload_mask) { + if (this_cpu == cpu) + continue; + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0525-ppc64-fix-preempt-unsafe-paths-accessing-per_cpu-variables.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0525-ppc64-fix-preempt-unsafe-paths-accessing-per_cpu-variables.patch @@ -0,0 +1,192 @@ +From chirag@linux.vnet.ibm.com Wed Jul 9 18:33:02 2008 +Date: Wed, 9 Jul 2008 21:35:43 +0530 +From: Chirag Jog +To: linux.kernel@vger.kernel.org, linux-rt-users@vger.kernel.org, linuxppc-dev@ozlabs.org +Cc: Dinakar Guniguntala , Timothy R. Chavez , paulmck@linux.vnet.ibm.com, Nivedita Singhvi , Josh Triplett , Steven Rostedt +Subject: [PATCH][RT][PPC64] Fix preempt unsafe paths accessing per_cpu variables + + +Hi, +This patch fixes various paths in the -rt kernel on powerpc64 where per_cpu +variables are accessed in a preempt unsafe way. +When a power box with -rt kernel is booted, multiple BUG messages are +generated "BUG: init:1 task might have lost a preemption check!". +After booting a kernel with these patches applied, these messages +don't appear. + +Also I ran the realtime tests from ltp to ensure the stability. + + +Signed-Off-By: Chirag +arch/powerpc/mm/tlb_64.c | 31 ++++++++++++++++--------------- +arch/powerpc/platforms/pseries/iommu.c | 14 ++++++++++---- +include/asm-powerpc/tlb.h | 5 ++--- +3 files changed, 28 insertions(+), 22 deletions(-) + + +--- + arch/powerpc/mm/tlb_64.c | 31 ++++++++++++++++--------------- + arch/powerpc/platforms/pseries/iommu.c | 14 ++++++++++---- + include/asm-powerpc/tlb.h | 5 ++--- + 3 files changed, 28 insertions(+), 22 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/powerpc/mm/tlb_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/mm/tlb_64.c 2008-10-08 22:24:41.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/mm/tlb_64.c 2008-10-08 22:25:10.000000000 -0400 +@@ -38,7 +38,6 @@ DEFINE_PER_CPU(struct ppc64_tlb_batch, p + * include/asm-powerpc/tlb.h file -- tgall + */ + DEFINE_PER_CPU_LOCKED(struct mmu_gather, mmu_gathers); +-DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur); + unsigned long pte_freelist_forced_free; + + struct pte_freelist_batch +@@ -48,7 +47,7 @@ struct pte_freelist_batch + pgtable_free_t tables[0]; + }; + +-DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur); ++DEFINE_PER_CPU_LOCKED(struct pte_freelist_batch *, pte_freelist_cur); + unsigned long pte_freelist_forced_free; + + #define PTE_FREELIST_SIZE \ +@@ -92,24 +91,21 @@ static void pte_free_submit(struct pte_f + + void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf) + { +- /* +- * This is safe since tlb_gather_mmu has disabled preemption. +- * tlb->cpu is set by tlb_gather_mmu as well. +- */ ++ int cpu; + cpumask_t local_cpumask = cpumask_of_cpu(tlb->cpu); +- struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur); ++ struct pte_freelist_batch **batchp = &get_cpu_var_locked(pte_freelist_cur, &cpu); + + if (atomic_read(&tlb->mm->mm_users) < 2 || + cpus_equal(tlb->mm->cpu_vm_mask, local_cpumask)) { + pgtable_free(pgf); +- return; ++ goto cleanup; + } + + if (*batchp == NULL) { + *batchp = (struct pte_freelist_batch *)__get_free_page(GFP_ATOMIC); + if (*batchp == NULL) { + pgtable_free_now(pgf); +- return; ++ goto cleanup; + } + (*batchp)->index = 0; + } +@@ -118,6 +114,9 @@ void pgtable_free_tlb(struct mmu_gather + pte_free_submit(*batchp); + *batchp = NULL; + } ++ ++ cleanup: ++ put_cpu_var_locked(pte_freelist_cur, cpu); + } + + /* +@@ -253,13 +252,15 @@ void __flush_tlb_pending(struct ppc64_tl + + void pte_free_finish(void) + { +- /* This is safe since tlb_gather_mmu has disabled preemption */ +- struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur); ++ int cpu; ++ struct pte_freelist_batch **batchp = &get_cpu_var_locked(pte_freelist_cur, &cpu); + +- if (*batchp == NULL) +- return; +- pte_free_submit(*batchp); +- *batchp = NULL; ++ if (*batchp) { ++ pte_free_submit(*batchp); ++ *batchp = NULL; ++ } ++ ++ put_cpu_var_locked(pte_freelist_cur, cpu); + } + + /** +Index: linux-2.6.24.7-rt21/include/asm-powerpc/tlb.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-powerpc/tlb.h 2008-10-08 22:24:41.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-powerpc/tlb.h 2008-10-08 22:25:10.000000000 -0400 +@@ -40,18 +40,17 @@ extern void pte_free_finish(void); + + static inline void tlb_flush(struct mmu_gather *tlb) + { +- struct ppc64_tlb_batch *tlbbatch = &__get_cpu_var(ppc64_tlb_batch); ++ struct ppc64_tlb_batch *tlbbatch = &get_cpu_var(ppc64_tlb_batch); + + /* If there's a TLB batch pending, then we must flush it because the + * pages are going to be freed and we really don't want to have a CPU + * access a freed page because it has a stale TLB + */ + if (tlbbatch->index) { +- preempt_disable(); + __flush_tlb_pending(tlbbatch); +- preempt_enable(); + } + ++ put_cpu_var(ppc64_tlb_batch); + pte_free_finish(); + } + +Index: linux-2.6.24.7-rt21/arch/powerpc/platforms/pseries/iommu.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/platforms/pseries/iommu.c 2008-10-08 22:22:09.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/platforms/pseries/iommu.c 2008-10-08 22:25:10.000000000 -0400 +@@ -124,7 +124,7 @@ static void tce_build_pSeriesLP(struct i + } + } + +-static DEFINE_PER_CPU(u64 *, tce_page) = NULL; ++static DEFINE_PER_CPU_LOCKED(u64 *, tce_page) = NULL; + + static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, + long npages, unsigned long uaddr, +@@ -135,12 +135,13 @@ static void tce_buildmulti_pSeriesLP(str + u64 *tcep; + u64 rpn; + long l, limit; ++ int cpu; + + if (npages == 1) + return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, + direction); + +- tcep = __get_cpu_var(tce_page); ++ tcep = get_cpu_var_locked(tce_page, &cpu); + + /* This is safe to do since interrupts are off when we're called + * from iommu_alloc{,_sg}() +@@ -148,10 +149,13 @@ static void tce_buildmulti_pSeriesLP(str + if (!tcep) { + tcep = (u64 *)__get_free_page(GFP_ATOMIC); + /* If allocation fails, fall back to the loop implementation */ +- if (!tcep) ++ if (!tcep) { ++ put_cpu_var_locked(tce_page, cpu); + return tce_build_pSeriesLP(tbl, tcenum, npages, + uaddr, direction); +- __get_cpu_var(tce_page) = tcep; ++ } ++ ++ per_cpu_var_locked(tce_page, cpu) = tcep; + } + + rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; +@@ -188,6 +192,8 @@ static void tce_buildmulti_pSeriesLP(str + printk("\ttce[0] val = 0x%lx\n", tcep[0]); + show_stack(current, (unsigned long *)__get_SP()); + } ++ ++ put_cpu_var_locked(tce_page, cpu); + } + + static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages) --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0460-sched_load_balance_flags.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0460-sched_load_balance_flags.patch @@ -0,0 +1,223 @@ +Subject: sched: load_balance flags +From: Peter Zijlstra + +Change all_pinned into a flags field that is passed around the load balance +routines. This is done because we need more state in the following patches. + +Signed-off-by: Peter Zijlstra +--- + kernel/sched.c | 39 +++++++++++++++++++++------------------ + kernel/sched_fair.c | 4 ++-- + kernel/sched_idletask.c | 2 +- + kernel/sched_rt.c | 2 +- + 4 files changed, 25 insertions(+), 22 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/sched.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched.c 2008-10-08 22:24:54.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched.c 2008-10-08 22:24:54.000000000 -0400 +@@ -1043,7 +1043,7 @@ struct rq_iterator { + static unsigned long + balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, + unsigned long max_load_move, struct sched_domain *sd, +- enum cpu_idle_type idle, int *all_pinned, ++ enum cpu_idle_type idle, int *lb_flags, + int *this_best_prio, struct rq_iterator *iterator); + + static int +@@ -2269,6 +2269,8 @@ static void update_cpu_load(struct rq *t + + #ifdef CONFIG_SMP + ++#define LB_ALL_PINNED 0x01 ++ + /* + * double_rq_lock - safely lock two runqueues + * +@@ -2411,7 +2413,7 @@ static void pull_task(struct rq *src_rq, + static + int can_migrate_task(struct task_struct *p, struct rq *rq, int this_cpu, + struct sched_domain *sd, enum cpu_idle_type idle, +- int *all_pinned) ++ int *lb_flags) + { + /* + * We do not migrate tasks that are: +@@ -2423,7 +2425,7 @@ int can_migrate_task(struct task_struct + schedstat_inc(p, se.nr_failed_migrations_affine); + return 0; + } +- *all_pinned = 0; ++ *lb_flags &= ~LB_ALL_PINNED; + + if (task_running(rq, p)) { + schedstat_inc(p, se.nr_failed_migrations_running); +@@ -2457,7 +2459,7 @@ int can_migrate_task(struct task_struct + static unsigned long + balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, + unsigned long max_load_move, struct sched_domain *sd, +- enum cpu_idle_type idle, int *all_pinned, ++ enum cpu_idle_type idle, int *lb_flags, + int *this_best_prio, struct rq_iterator *iterator) + { + int loops = 0, pulled = 0, pinned = 0, skip_for_load; +@@ -2467,12 +2469,12 @@ balance_tasks(struct rq *this_rq, int th + if (max_load_move == 0) + goto out; + +- pinned = 1; +- + /* + * Start the load-balancing iterator: + */ + p = iterator->start(iterator->arg); ++ if (p) ++ pinned = 1; + next: + if (!p || loops++ > sysctl_sched_nr_migrate) + goto out; +@@ -2510,8 +2512,8 @@ out: + */ + schedstat_add(sd, lb_gained[idle], pulled); + +- if (all_pinned) +- *all_pinned = pinned; ++ if (pinned) ++ *lb_flags |= LB_ALL_PINNED; + + return max_load_move - rem_load_move; + } +@@ -2526,7 +2528,7 @@ out: + static int move_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, + unsigned long max_load_move, + struct sched_domain *sd, enum cpu_idle_type idle, +- int *all_pinned) ++ int *lb_flags) + { + const struct sched_class *class = sched_class_highest; + unsigned long total_load_moved = 0; +@@ -2536,7 +2538,7 @@ static int move_tasks(struct rq *this_rq + total_load_moved += + class->load_balance(this_rq, this_cpu, busiest, + max_load_move - total_load_moved, +- sd, idle, all_pinned, &this_best_prio); ++ sd, idle, lb_flags, &this_best_prio); + class = class->next; + } while (class && max_load_move > total_load_moved); + +@@ -2938,7 +2940,7 @@ static int load_balance(int this_cpu, st + struct sched_domain *sd, enum cpu_idle_type idle, + int *balance) + { +- int ld_moved, all_pinned = 0, active_balance = 0, sd_idle = 0; ++ int ld_moved, lb_flags = 0, active_balance = 0, sd_idle = 0; + struct sched_group *group; + unsigned long imbalance; + struct rq *busiest; +@@ -2990,7 +2992,7 @@ redo: + local_irq_save(flags); + double_rq_lock(this_rq, busiest); + ld_moved = move_tasks(this_rq, this_cpu, busiest, +- imbalance, sd, idle, &all_pinned); ++ imbalance, sd, idle, &lb_flags); + double_rq_unlock(this_rq, busiest); + local_irq_restore(flags); + +@@ -3001,7 +3003,7 @@ redo: + resched_cpu(this_cpu); + + /* All tasks on this runqueue were pinned by CPU affinity */ +- if (unlikely(all_pinned)) { ++ if (unlikely(lb_flags & LB_ALL_PINNED)) { + cpu_clear(cpu_of(busiest), cpus); + if (!cpus_empty(cpus)) + goto redo; +@@ -3022,7 +3024,7 @@ redo: + */ + if (!cpu_isset(this_cpu, busiest->curr->cpus_allowed)) { + spin_unlock_irqrestore(&busiest->lock, flags); +- all_pinned = 1; ++ lb_flags |= LB_ALL_PINNED; + goto out_one_pinned; + } + +@@ -3070,7 +3072,8 @@ out_balanced: + + out_one_pinned: + /* tune up the balancing interval */ +- if ((all_pinned && sd->balance_interval < MAX_PINNED_INTERVAL) || ++ if (((lb_flags & LB_ALL_PINNED) && ++ sd->balance_interval < MAX_PINNED_INTERVAL) || + (sd->balance_interval < sd->max_interval)) + sd->balance_interval *= 2; + +@@ -3095,7 +3098,7 @@ load_balance_newidle(int this_cpu, struc + unsigned long imbalance; + int ld_moved = 0; + int sd_idle = 0; +- int all_pinned = 0; ++ int lb_flags = 0; + cpumask_t cpus = CPU_MASK_ALL; + + /* +@@ -3136,10 +3139,10 @@ redo: + update_rq_clock(busiest); + ld_moved = move_tasks(this_rq, this_cpu, busiest, + imbalance, sd, CPU_NEWLY_IDLE, +- &all_pinned); ++ &lb_flags); + spin_unlock(&busiest->lock); + +- if (unlikely(all_pinned)) { ++ if (unlikely(lb_flags & LB_ALL_PINNED)) { + cpu_clear(cpu_of(busiest), cpus); + if (!cpus_empty(cpus)) + goto redo; +Index: linux-2.6.24.7-rt21/kernel/sched_fair.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched_fair.c 2008-10-08 22:23:04.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched_fair.c 2008-10-08 22:24:54.000000000 -0400 +@@ -1115,7 +1115,7 @@ static unsigned long + load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, + unsigned long max_load_move, + struct sched_domain *sd, enum cpu_idle_type idle, +- int *all_pinned, int *this_best_prio) ++ int *lb_flags, int *this_best_prio) + { + struct cfs_rq *busy_cfs_rq; + long rem_load_move = max_load_move; +@@ -1151,7 +1151,7 @@ load_balance_fair(struct rq *this_rq, in + */ + cfs_rq_iterator.arg = busy_cfs_rq; + rem_load_move -= balance_tasks(this_rq, this_cpu, busiest, +- maxload, sd, idle, all_pinned, ++ maxload, sd, idle, lb_flags, + this_best_prio, + &cfs_rq_iterator); + +Index: linux-2.6.24.7-rt21/kernel/sched_idletask.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched_idletask.c 2008-10-08 22:23:04.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched_idletask.c 2008-10-08 22:24:54.000000000 -0400 +@@ -48,7 +48,7 @@ static unsigned long + load_balance_idle(struct rq *this_rq, int this_cpu, struct rq *busiest, + unsigned long max_load_move, + struct sched_domain *sd, enum cpu_idle_type idle, +- int *all_pinned, int *this_best_prio) ++ int *lb_flags, int *this_best_prio) + { + return 0; + } +Index: linux-2.6.24.7-rt21/kernel/sched_rt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched_rt.c 2008-10-08 22:24:45.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched_rt.c 2008-10-08 22:24:54.000000000 -0400 +@@ -718,7 +718,7 @@ static unsigned long + load_balance_rt(struct rq *this_rq, int this_cpu, struct rq *busiest, + unsigned long max_load_move, + struct sched_domain *sd, enum cpu_idle_type idle, +- int *all_pinned, int *this_best_prio) ++ int *lb_flags, int *this_best_prio) + { + /* don't touch RT tasks */ + return 0; --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0256-preempt-realtime-printk.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0256-preempt-realtime-printk.patch @@ -0,0 +1,144 @@ +--- + kernel/printk.c | 54 +++++++++++++++++++++++++++++++++++++++++++++--------- + 1 file changed, 45 insertions(+), 9 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/printk.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/printk.c 2008-10-08 22:22:27.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/printk.c 2008-10-08 22:24:03.000000000 -0400 +@@ -84,7 +84,7 @@ static int console_locked, console_suspe + * It is also used in interesting ways to provide interlocking in + * release_console_sem(). + */ +-static DEFINE_SPINLOCK(logbuf_lock); ++static DEFINE_RAW_SPINLOCK(logbuf_lock); + + #define LOG_BUF_MASK (log_buf_len-1) + #define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK]) +@@ -435,7 +435,7 @@ static void __call_console_drivers(unsig + + for (con = console_drivers; con; con = con->next) { + if ((con->flags & CON_ENABLED) && con->write && +- (cpu_online(smp_processor_id()) || ++ (cpu_online(raw_smp_processor_id()) || + (con->flags & CON_ANYTIME))) + con->write(con, &LOG_BUF(start), end - start); + } +@@ -551,6 +551,7 @@ static void zap_locks(void) + spin_lock_init(&logbuf_lock); + /* And make sure that we print immediately */ + init_MUTEX(&console_sem); ++ zap_rt_locks(); + } + + #if defined(CONFIG_PRINTK_TIME) +@@ -649,6 +650,7 @@ asmlinkage int vprintk(const char *fmt, + lockdep_off(); + spin_lock(&logbuf_lock); + printk_cpu = smp_processor_id(); ++ preempt_enable(); + + /* Emit the output into the temporary buffer */ + printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args); +@@ -718,6 +720,8 @@ asmlinkage int vprintk(const char *fmt, + console_locked = 1; + printk_cpu = UINT_MAX; + spin_unlock(&logbuf_lock); ++ lockdep_on(); ++ local_irq_restore(flags); + + /* + * Console drivers may assume that per-cpu resources have +@@ -725,7 +729,7 @@ asmlinkage int vprintk(const char *fmt, + * being able to cope (CON_ANYTIME) don't call them until + * this CPU is officially up. + */ +- if (cpu_online(smp_processor_id()) || have_callable_console()) { ++ if (cpu_online(raw_smp_processor_id()) || have_callable_console()) { + console_may_schedule = 0; + release_console_sem(); + } else { +@@ -733,8 +737,6 @@ asmlinkage int vprintk(const char *fmt, + console_locked = 0; + up(&console_sem); + } +- lockdep_on(); +- raw_local_irq_restore(flags); + } else { + /* + * Someone else owns the drivers. We drop the spinlock, which +@@ -747,7 +749,6 @@ asmlinkage int vprintk(const char *fmt, + raw_local_irq_restore(flags); + } + +- preempt_enable(); + return printed_len; + } + EXPORT_SYMBOL(printk); +@@ -971,13 +972,31 @@ void release_console_sem(void) + _con_start = con_start; + _log_end = log_end; + con_start = log_end; /* Flush */ ++ /* ++ * on PREEMPT_RT, call console drivers with ++ * interrupts enabled (if printk was called ++ * with interrupts disabled): ++ */ ++#ifdef CONFIG_PREEMPT_RT ++ spin_unlock_irqrestore(&logbuf_lock, flags); ++#else + spin_unlock(&logbuf_lock); ++#endif + call_console_drivers(_con_start, _log_end); +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + } + console_locked = 0; +- up(&console_sem); + spin_unlock_irqrestore(&logbuf_lock, flags); ++ up(&console_sem); ++ /* ++ * On PREEMPT_RT kernels __wake_up may sleep, so wake syslogd ++ * up only if we are in a preemptible section. We normally dont ++ * printk from non-preemptible sections so this is for the emergency ++ * case only. ++ */ ++#ifdef CONFIG_PREEMPT_RT ++ if (!in_atomic() && !irqs_disabled()) ++#endif + if (wake_klogd) + wake_up_klogd(); + } +@@ -1244,7 +1263,7 @@ void tty_write_message(struct tty_struct + */ + int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst) + { +- static DEFINE_SPINLOCK(ratelimit_lock); ++ static DEFINE_RAW_SPINLOCK(ratelimit_lock); + static unsigned long toks = 10 * 5 * HZ; + static unsigned long last_msg; + static int missed; +@@ -1285,6 +1304,23 @@ int printk_ratelimit(void) + } + EXPORT_SYMBOL(printk_ratelimit); + ++static DEFINE_RAW_SPINLOCK(warn_lock); ++ ++void __WARN_ON(const char *func, const char *file, const int line) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&warn_lock, flags); ++ printk("%s/%d[CPU#%d]: BUG in %s at %s:%d\n", ++ current->comm, current->pid, raw_smp_processor_id(), ++ func, file, line); ++ dump_stack(); ++ spin_unlock_irqrestore(&warn_lock, flags); ++} ++ ++EXPORT_SYMBOL(__WARN_ON); ++ ++ + /** + * printk_timed_ratelimit - caller-controlled printk ratelimiting + * @caller_jiffies: pointer to caller's state --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0019-0003-sched-add-RT-task-pushing.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0019-0003-sched-add-RT-task-pushing.patch @@ -0,0 +1,321 @@ +From 6d3e7dfa47b1d3ae3abd608e5d89b56cad72cccb Mon Sep 17 00:00:00 2001 +From: Steven Rostedt +Date: Tue, 11 Dec 2007 10:02:37 +0100 +Subject: [PATCH] sched: add RT task pushing + +This patch adds an algorithm to push extra RT tasks off a run queue to +other CPU runqueues. + +When more than one RT task is added to a run queue, this algorithm takes +an assertive approach to push the RT tasks that are not running onto other +run queues that have lower priority. The way this works is that the highest +RT task that is not running is looked at and we examine the runqueues on +the CPUS for that tasks affinity mask. We find the runqueue with the lowest +prio in the CPU affinity of the picked task, and if it is lower in prio than +the picked task, we push the task onto that CPU runqueue. + +We continue pushing RT tasks off the current runqueue until we don't push any +more. The algorithm stops when the next highest RT task can't preempt any +other processes on other CPUS. + +TODO: The algorithm may stop when there are still RT tasks that can be + migrated. Specifically, if the highest non running RT task CPU affinity + is restricted to CPUs that are running higher priority tasks, there may + be a lower priority task queued that has an affinity with a CPU that is + running a lower priority task that it could be migrated to. This + patch set does not address this issue. + +Note: checkpatch reveals two over 80 character instances. I'm not sure + that breaking them up will help visually, so I left them as is. + +Signed-off-by: Steven Rostedt +Signed-off-by: Ingo Molnar + +--- + kernel/sched.c | 8 + + kernel/sched_rt.c | 225 +++++++++++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 231 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/sched.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched.c 2008-10-08 22:22:56.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched.c 2008-10-08 22:22:56.000000000 -0400 +@@ -1937,6 +1937,8 @@ static void finish_task_switch(struct rq + prev_state = prev->state; + finish_arch_switch(prev); + finish_lock_switch(rq, prev); ++ schedule_tail_balance_rt(rq); ++ + fire_sched_in_preempt_notifiers(current); + if (mm) + mmdrop(mm); +@@ -2170,11 +2172,13 @@ static void double_rq_unlock(struct rq * + /* + * double_lock_balance - lock the busiest runqueue, this_rq is locked already. + */ +-static void double_lock_balance(struct rq *this_rq, struct rq *busiest) ++static int double_lock_balance(struct rq *this_rq, struct rq *busiest) + __releases(this_rq->lock) + __acquires(busiest->lock) + __acquires(this_rq->lock) + { ++ int ret = 0; ++ + if (unlikely(!irqs_disabled())) { + /* printk() doesn't work good under rq->lock */ + spin_unlock(&this_rq->lock); +@@ -2185,9 +2189,11 @@ static void double_lock_balance(struct r + spin_unlock(&this_rq->lock); + spin_lock(&busiest->lock); + spin_lock(&this_rq->lock); ++ ret = 1; + } else + spin_lock(&busiest->lock); + } ++ return ret; + } + + /* +Index: linux-2.6.24.7-rt21/kernel/sched_rt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched_rt.c 2008-10-08 22:22:56.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched_rt.c 2008-10-08 22:22:56.000000000 -0400 +@@ -133,6 +133,227 @@ static void put_prev_task_rt(struct rq * + } + + #ifdef CONFIG_SMP ++/* Only try algorithms three times */ ++#define RT_MAX_TRIES 3 ++ ++static int double_lock_balance(struct rq *this_rq, struct rq *busiest); ++static void deactivate_task(struct rq *rq, struct task_struct *p, int sleep); ++ ++/* Return the second highest RT task, NULL otherwise */ ++static struct task_struct *pick_next_highest_task_rt(struct rq *rq) ++{ ++ struct rt_prio_array *array = &rq->rt.active; ++ struct task_struct *next; ++ struct list_head *queue; ++ int idx; ++ ++ assert_spin_locked(&rq->lock); ++ ++ if (likely(rq->rt.rt_nr_running < 2)) ++ return NULL; ++ ++ idx = sched_find_first_bit(array->bitmap); ++ if (unlikely(idx >= MAX_RT_PRIO)) { ++ WARN_ON(1); /* rt_nr_running is bad */ ++ return NULL; ++ } ++ ++ queue = array->queue + idx; ++ next = list_entry(queue->next, struct task_struct, run_list); ++ if (unlikely(next != rq->curr)) ++ return next; ++ ++ if (queue->next->next != queue) { ++ /* same prio task */ ++ next = list_entry(queue->next->next, struct task_struct, run_list); ++ return next; ++ } ++ ++ /* slower, but more flexible */ ++ idx = find_next_bit(array->bitmap, MAX_RT_PRIO, idx+1); ++ if (unlikely(idx >= MAX_RT_PRIO)) { ++ WARN_ON(1); /* rt_nr_running was 2 and above! */ ++ return NULL; ++ } ++ ++ queue = array->queue + idx; ++ next = list_entry(queue->next, struct task_struct, run_list); ++ ++ return next; ++} ++ ++static DEFINE_PER_CPU(cpumask_t, local_cpu_mask); ++ ++/* Will lock the rq it finds */ ++static struct rq *find_lock_lowest_rq(struct task_struct *task, ++ struct rq *this_rq) ++{ ++ struct rq *lowest_rq = NULL; ++ int cpu; ++ int tries; ++ cpumask_t *cpu_mask = &__get_cpu_var(local_cpu_mask); ++ ++ cpus_and(*cpu_mask, cpu_online_map, task->cpus_allowed); ++ ++ for (tries = 0; tries < RT_MAX_TRIES; tries++) { ++ /* ++ * Scan each rq for the lowest prio. ++ */ ++ for_each_cpu_mask(cpu, *cpu_mask) { ++ struct rq *rq = &per_cpu(runqueues, cpu); ++ ++ if (cpu == this_rq->cpu) ++ continue; ++ ++ /* We look for lowest RT prio or non-rt CPU */ ++ if (rq->rt.highest_prio >= MAX_RT_PRIO) { ++ lowest_rq = rq; ++ break; ++ } ++ ++ /* no locking for now */ ++ if (rq->rt.highest_prio > task->prio && ++ (!lowest_rq || rq->rt.highest_prio > lowest_rq->rt.highest_prio)) { ++ lowest_rq = rq; ++ } ++ } ++ ++ if (!lowest_rq) ++ break; ++ ++ /* if the prio of this runqueue changed, try again */ ++ if (double_lock_balance(this_rq, lowest_rq)) { ++ /* ++ * We had to unlock the run queue. In ++ * the mean time, task could have ++ * migrated already or had its affinity changed. ++ * Also make sure that it wasn't scheduled on its rq. ++ */ ++ if (unlikely(task_rq(task) != this_rq || ++ !cpu_isset(lowest_rq->cpu, task->cpus_allowed) || ++ task_running(this_rq, task) || ++ !task->se.on_rq)) { ++ spin_unlock(&lowest_rq->lock); ++ lowest_rq = NULL; ++ break; ++ } ++ } ++ ++ /* If this rq is still suitable use it. */ ++ if (lowest_rq->rt.highest_prio > task->prio) ++ break; ++ ++ /* try again */ ++ spin_unlock(&lowest_rq->lock); ++ lowest_rq = NULL; ++ } ++ ++ return lowest_rq; ++} ++ ++/* ++ * If the current CPU has more than one RT task, see if the non ++ * running task can migrate over to a CPU that is running a task ++ * of lesser priority. ++ */ ++static int push_rt_task(struct rq *this_rq) ++{ ++ struct task_struct *next_task; ++ struct rq *lowest_rq; ++ int ret = 0; ++ int paranoid = RT_MAX_TRIES; ++ ++ assert_spin_locked(&this_rq->lock); ++ ++ next_task = pick_next_highest_task_rt(this_rq); ++ if (!next_task) ++ return 0; ++ ++ retry: ++ if (unlikely(next_task == this_rq->curr)) ++ return 0; ++ ++ /* ++ * It's possible that the next_task slipped in of ++ * higher priority than current. If that's the case ++ * just reschedule current. ++ */ ++ if (unlikely(next_task->prio < this_rq->curr->prio)) { ++ resched_task(this_rq->curr); ++ return 0; ++ } ++ ++ /* We might release this_rq lock */ ++ get_task_struct(next_task); ++ ++ /* find_lock_lowest_rq locks the rq if found */ ++ lowest_rq = find_lock_lowest_rq(next_task, this_rq); ++ if (!lowest_rq) { ++ struct task_struct *task; ++ /* ++ * find lock_lowest_rq releases this_rq->lock ++ * so it is possible that next_task has changed. ++ * If it has, then try again. ++ */ ++ task = pick_next_highest_task_rt(this_rq); ++ if (unlikely(task != next_task) && task && paranoid--) { ++ put_task_struct(next_task); ++ next_task = task; ++ goto retry; ++ } ++ goto out; ++ } ++ ++ assert_spin_locked(&lowest_rq->lock); ++ ++ deactivate_task(this_rq, next_task, 0); ++ set_task_cpu(next_task, lowest_rq->cpu); ++ activate_task(lowest_rq, next_task, 0); ++ ++ resched_task(lowest_rq->curr); ++ ++ spin_unlock(&lowest_rq->lock); ++ ++ ret = 1; ++out: ++ put_task_struct(next_task); ++ ++ return ret; ++} ++ ++/* ++ * TODO: Currently we just use the second highest prio task on ++ * the queue, and stop when it can't migrate (or there's ++ * no more RT tasks). There may be a case where a lower ++ * priority RT task has a different affinity than the ++ * higher RT task. In this case the lower RT task could ++ * possibly be able to migrate where as the higher priority ++ * RT task could not. We currently ignore this issue. ++ * Enhancements are welcome! ++ */ ++static void push_rt_tasks(struct rq *rq) ++{ ++ /* push_rt_task will return true if it moved an RT */ ++ while (push_rt_task(rq)) ++ ; ++} ++ ++static void schedule_tail_balance_rt(struct rq *rq) ++{ ++ /* ++ * If we have more than one rt_task queued, then ++ * see if we can push the other rt_tasks off to other CPUS. ++ * Note we may release the rq lock, and since ++ * the lock was owned by prev, we need to release it ++ * first via finish_lock_switch and then reaquire it here. ++ */ ++ if (unlikely(rq->rt.rt_nr_running > 1)) { ++ spin_lock_irq(&rq->lock); ++ push_rt_tasks(rq); ++ spin_unlock_irq(&rq->lock); ++ } ++} ++ + /* + * Load-balancing iterator. Note: while the runqueue stays locked + * during the whole iteration, the current task might be +@@ -237,7 +458,9 @@ move_one_task_rt(struct rq *this_rq, int + return iter_move_one_task(this_rq, this_cpu, busiest, sd, idle, + &rt_rq_iterator); + } +-#endif ++#else /* CONFIG_SMP */ ++# define schedule_tail_balance_rt(rq) do { } while (0) ++#endif /* CONFIG_SMP */ + + static void task_tick_rt(struct rq *rq, struct task_struct *p) + { --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0089-neptune-no-at-keyboard.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0089-neptune-no-at-keyboard.patch @@ -0,0 +1,64 @@ +neptune needs this to boot ... +--- + drivers/input/keyboard/atkbd.c | 14 ++++++++++++++ + drivers/input/mouse/psmouse-base.c | 15 +++++++++++++++ + 2 files changed, 29 insertions(+) + +Index: linux-2.6.24.7-rt21/drivers/input/keyboard/atkbd.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/input/keyboard/atkbd.c 2008-10-08 22:22:42.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/input/keyboard/atkbd.c 2008-10-08 22:23:18.000000000 -0400 +@@ -1401,9 +1401,23 @@ static ssize_t atkbd_show_err_count(stru + return sprintf(buf, "%lu\n", atkbd->err_count); + } + ++static int __read_mostly noatkbd; ++ ++static int __init noatkbd_setup(char *str) ++{ ++ noatkbd = 1; ++ printk(KERN_INFO "debug: not setting up AT keyboard.\n"); ++ ++ return 1; ++} ++ ++__setup("noatkbd", noatkbd_setup); + + static int __init atkbd_init(void) + { ++ if (noatkbd) ++ return 0; ++ + return serio_register_driver(&atkbd_drv); + } + +Index: linux-2.6.24.7-rt21/drivers/input/mouse/psmouse-base.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/input/mouse/psmouse-base.c 2008-10-08 22:22:42.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/input/mouse/psmouse-base.c 2008-10-08 22:23:18.000000000 -0400 +@@ -1598,10 +1598,25 @@ static int psmouse_get_maxproto(char *bu + return sprintf(buffer, "%s\n", psmouse_protocol_by_type(type)->name); + } + ++static int __read_mostly nopsmouse; ++ ++static int __init nopsmouse_setup(char *str) ++{ ++ nopsmouse = 1; ++ printk(KERN_INFO "debug: not setting up psmouse.\n"); ++ ++ return 1; ++} ++ ++__setup("nopsmouse", nopsmouse_setup); ++ + static int __init psmouse_init(void) + { + int err; + ++ if (nopsmouse) ++ return 0; ++ + kpsmoused_wq = create_singlethread_workqueue("kpsmoused"); + if (!kpsmoused_wq) { + printk(KERN_ERR "psmouse: failed to create kpsmoused workqueue\n"); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0218-preempt-realtime-ppc-need-resched-delayed.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0218-preempt-realtime-ppc-need-resched-delayed.patch @@ -0,0 +1,34 @@ +From tsutomu.owa@toshiba.co.jp Mon May 14 15:29:17 2007 +Date: Mon, 14 May 2007 15:29:17 +0900 +From: Tsutomu OWA +To: linuxppc-dev@ozlabs.org, linux-kernel@vger.kernel.org +Cc: mingo@elte.hu, tglx@linutronix.de +Subject: Re: [patch 3/4] powerpc 2.6.21-rt1: add a need_resched_delayed() check + + +Add a need_resched_delayed() check. +This was pointed by Sergei Shtylyov; + http://ozlabs.org/pipermail/linuxppc-dev/2007-March/033148.html + +Signed-off-by: Tsutomu Owa +-- owa + +--- + arch/powerpc/kernel/idle.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/arch/powerpc/kernel/idle.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/kernel/idle.c 2008-10-08 22:22:31.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/kernel/idle.c 2008-10-08 22:23:52.000000000 -0400 +@@ -74,7 +74,9 @@ void cpu_idle(void) + local_irq_disable(); + + /* check again after disabling irqs */ +- if (!need_resched() && !cpu_should_die()) ++ if (!need_resched() && ++ !need_resched_delayed() && ++ !cpu_should_die()) + ppc_md.power_save(); + + local_irq_enable(); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0080-ftrace-m68knommu-add-FTRACE-support.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0080-ftrace-m68knommu-add-FTRACE-support.patch @@ -0,0 +1,128 @@ +From 674ceaadcb008adc57249a54c1b5b20c74c8c80b Mon Sep 17 00:00:00 2001 +From: Sebastian Siewior +Date: Wed, 9 Jul 2008 13:33:20 +0200 +Subject: [PATCH] m68knommu: add FTRACE support + +due to a gcc bug or feature or me too stupid, the following patch +has to be applied to gcc: + +|m68k: remove label generation on -pg +| +|haven't found a reason why this flag is needed. Maybe glibc needs this label. +|However this implementation puts the labels too far away. +| +|Signed-off-by: Sebastian Siewior +| +|--- a/gcc/config/m68k/linux.h +|+++ b/gcc/config/m68k/linux.h +|@@ -143,7 +143,6 @@ along with GCC; see the file COPYING3. +| #undef FUNCTION_PROFILER +| #define FUNCTION_PROFILER(FILE, LABELNO) \ +| { \ +|- asm_fprintf (FILE, "\tlea (%LLP%d,%Rpc),%Ra1\n", (LABELNO)); \ +| if (flag_pic) \ +| fprintf (FILE, "\tbsr.l _mcount@PLTPC\n"); \ +| else \ +|--- a/gcc/config/m68k/m68k.h +|+++ b/gcc/config/m68k/m68k.h +|@@ -576,7 +576,7 @@ extern enum reg_class regno_reg_class[]; +| #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) 0 +| +| #define FUNCTION_PROFILER(FILE, LABELNO) \ +|- asm_fprintf (FILE, "\tlea %LLP%d,%Ra0\n\tjsr mcount\n", (LABELNO)) +|+ asm_fprintf (FILE, "\tjsr mcount\n", (LABELNO)) +| +| #define EXIT_IGNORE_STACK 1 +| + +Signed-off-by: Sebastian Siewior +Signed-off-by: Thomas Gleixner +--- + arch/m68knommu/Kconfig | 1 + arch/m68knommu/kernel/process.c | 2 + + arch/m68knommu/platform/coldfire/entry.S | 33 +++++++++++++++++++++++++++++++ + kernel/trace/trace.c | 1 + 4 files changed, 36 insertions(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/arch/m68knommu/Kconfig +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/Kconfig 2008-10-08 22:22:55.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/Kconfig 2008-10-08 22:23:11.000000000 -0400 +@@ -175,6 +175,7 @@ config M527x + config COLDFIRE + bool + depends on (M5206 || M5206e || M520x || M523x || M5249 || M527x || M5272 || M528x || M5307 || M532x || M5407) ++ select HAVE_FTRACE + default y + + config CLOCK_SET +Index: linux-2.6.24.7-rt21/arch/m68knommu/kernel/process.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/kernel/process.c 2008-10-08 22:22:42.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/kernel/process.c 2008-10-08 22:23:11.000000000 -0400 +@@ -74,7 +74,9 @@ void cpu_idle(void) + { + /* endless idle loop with no priority at all */ + while (1) { ++ stop_critical_timings(); + idle(); ++ start_critical_timings(); + preempt_enable_no_resched(); + schedule(); + preempt_disable(); +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/coldfire/entry.S +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/platform/coldfire/entry.S 2008-10-08 22:22:55.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/coldfire/entry.S 2008-10-08 22:23:11.000000000 -0400 +@@ -55,6 +55,39 @@ sw_usp: + .globl inthandler + .globl fasthandler + ++#ifdef CONFIG_FTRACE ++ENTRY(_mcount) ++ linkw %fp, #0 ++ ++ moveal ftrace_trace_function, %a0 ++ movel #ftrace_stub, %d0 ++ cmpl %a0@, %d0 ++ ++ bnew do_mcount ++ ++ unlk %fp ++ rts ++ ++do_mcount: ++ ++ movel %fp, %d0 ++ moveal %d0, %a1 ++ ++ moveal %a1@, %a0 ++ movel %a0@(4), %sp@- /* push parent ip */ ++ movel %a1@(4), %sp@- /* push ip */ ++ ++ moveal ftrace_trace_function, %a0 ++ jsr %a0@ ++ ++ unlk %fp ++ ++.globl ftrace_stub ++ftrace_stub: ++ rts ++END(mcount) ++#endif ++ + enosys: + mov.l #sys_ni_syscall,%d3 + bra 1f +Index: linux-2.6.24.7-rt21/kernel/trace/trace.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/trace.c 2008-10-08 22:23:09.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/trace.c 2008-10-08 22:23:11.000000000 -0400 +@@ -31,7 +31,6 @@ + + #include + +-#include + #include + + #include "trace.h" --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0016-m68knommu-upstream-patches.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0016-m68knommu-upstream-patches.patch @@ -0,0 +1,9160 @@ +From: Sebastian Siewior +Date: Sun, 27 Apr 2008 14:28:21 +0200 +Subject: m68knommu: upstream pending patches + +That's a conglomerate of Greg Ungerers and Sebastian Siewiors +m68knommu patches which are not in .24 but on the way upstream +(partly included in .25/.26) + +Compressed-into-one-patch-by: tglx +--- + arch/m68knommu/Kconfig | 24 + arch/m68knommu/Makefile | 31 + arch/m68knommu/kernel/asm-offsets.c | 1 + arch/m68knommu/kernel/irq.c | 11 + arch/m68knommu/kernel/setup.c | 2 + arch/m68knommu/kernel/time.c | 109 - + arch/m68knommu/kernel/traps.c | 112 + + arch/m68knommu/kernel/vmlinux.lds.S | 90 - + arch/m68knommu/platform/5206/config.c | 76 - + arch/m68knommu/platform/5206e/config.c | 80 - + arch/m68knommu/platform/520x/config.c | 101 + + arch/m68knommu/platform/523x/config.c | 138 +- + arch/m68knommu/platform/5249/config.c | 77 - + arch/m68knommu/platform/5272/config.c | 89 - + arch/m68knommu/platform/527x/config.c | 87 + + arch/m68knommu/platform/528x/config.c | 355 +++++ + arch/m68knommu/platform/5307/Makefile | 14 + arch/m68knommu/platform/5307/config.c | 88 - + arch/m68knommu/platform/5307/entry.S | 235 --- + arch/m68knommu/platform/5307/head.S | 222 --- + arch/m68knommu/platform/5307/pit.c | 97 - + arch/m68knommu/platform/5307/timers.c | 155 -- + arch/m68knommu/platform/5307/vectors.c | 105 - + arch/m68knommu/platform/532x/config.c | 179 +- + arch/m68knommu/platform/532x/spi-mcf532x.c | 176 ++ + arch/m68knommu/platform/532x/usb-mcf532x.c | 171 ++ + arch/m68knommu/platform/5407/config.c | 83 - + arch/m68knommu/platform/68328/ints.c | 2 + arch/m68knommu/platform/68328/timers.c | 56 + arch/m68knommu/platform/68360/config.c | 5 + arch/m68knommu/platform/coldfire/Makefile | 32 + arch/m68knommu/platform/coldfire/dma.c | 39 + arch/m68knommu/platform/coldfire/dma_timer.c | 84 + + arch/m68knommu/platform/coldfire/entry.S | 241 +++ + arch/m68knommu/platform/coldfire/head.S | 222 +++ + arch/m68knommu/platform/coldfire/irq_chip.c | 110 + + arch/m68knommu/platform/coldfire/pit.c | 180 ++ + arch/m68knommu/platform/coldfire/timers.c | 182 ++ + arch/m68knommu/platform/coldfire/vectors.c | 105 + + drivers/net/fec.c | 1812 +++++++++++++-------------- + drivers/serial/68328serial.c | 2 + drivers/serial/mcf.c | 22 + drivers/serial/mcfserial.c | 121 - + fs/nfs/file.c | 4 + include/asm-generic/vmlinux.lds.h | 40 + include/asm-m68knommu/bitops.h | 30 + include/asm-m68knommu/byteorder.h | 16 + include/asm-m68knommu/cacheflush.h | 2 + include/asm-m68knommu/commproc.h | 19 + include/asm-m68knommu/dma.h | 3 + include/asm-m68knommu/m523xsim.h | 147 ++ + include/asm-m68knommu/m528xsim.h | 63 + include/asm-m68knommu/m532xsim.h | 86 - + include/asm-m68knommu/mcfcache.h | 2 + include/asm-m68knommu/mcfuart.h | 3 + mm/nommu.c | 10 + mm/page_alloc.c | 8 + 57 files changed, 4172 insertions(+), 2384 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/m68knommu/Kconfig +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/Kconfig 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/Kconfig 2008-10-08 22:22:55.000000000 -0400 +@@ -53,10 +53,22 @@ config GENERIC_CALIBRATE_DELAY + bool + default y + ++config GENERIC_TIME ++ bool ++ default y ++ ++config GENERIC_CMOS_UPDATE ++ bool ++ default y ++ + config TIME_LOW_RES + bool + default y + ++config GENERIC_CLOCKEVENTS ++ bool ++ default n ++ + config NO_IOPORT + def_bool y + +@@ -100,11 +112,14 @@ config M5206e + + config M520x + bool "MCF520x" ++ select GENERIC_CLOCKEVENTS + help + Freescale Coldfire 5207/5208 processor support. + + config M523x + bool "MCF523x" ++ select GENERIC_CLOCKEVENTS ++ select GENERIC_HARDIRQS_NO__DO_IRQ + help + Freescale Coldfire 5230/1/2/4/5 processor support + +@@ -130,6 +145,7 @@ config M5275 + + config M528x + bool "MCF528x" ++ select GENERIC_CLOCKEVENTS + help + Motorola ColdFire 5280/5282 processor support. + +@@ -153,6 +169,7 @@ endchoice + config M527x + bool + depends on (M5271 || M5275) ++ select GENERIC_CLOCKEVENTS + default y + + config COLDFIRE +@@ -658,6 +675,13 @@ config ROMKERNEL + + endchoice + ++config GENERIC_HARDIRQS_NO__DO_IRQ ++ bool "Force generic IRQ implementation" ++ ++source "kernel/time/Kconfig" ++if COLDFIRE ++source "kernel/Kconfig.preempt" ++endif + source "mm/Kconfig" + + endmenu +Index: linux-2.6.24.7-rt21/arch/m68knommu/Makefile +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/Makefile 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/Makefile 2008-10-08 22:22:55.000000000 -0400 +@@ -61,17 +61,17 @@ MODEL := $(model-y) + # for the selected cpu. ONLY need to define this for the non-base member + # of the family. + # +-cpuclass-$(CONFIG_M5206) := 5307 +-cpuclass-$(CONFIG_M5206e) := 5307 +-cpuclass-$(CONFIG_M520x) := 5307 +-cpuclass-$(CONFIG_M523x) := 5307 +-cpuclass-$(CONFIG_M5249) := 5307 +-cpuclass-$(CONFIG_M527x) := 5307 +-cpuclass-$(CONFIG_M5272) := 5307 +-cpuclass-$(CONFIG_M528x) := 5307 +-cpuclass-$(CONFIG_M5307) := 5307 +-cpuclass-$(CONFIG_M532x) := 5307 +-cpuclass-$(CONFIG_M5407) := 5307 ++cpuclass-$(CONFIG_M5206) := coldfire ++cpuclass-$(CONFIG_M5206e) := coldfire ++cpuclass-$(CONFIG_M520x) := coldfire ++cpuclass-$(CONFIG_M523x) := coldfire ++cpuclass-$(CONFIG_M5249) := coldfire ++cpuclass-$(CONFIG_M527x) := coldfire ++cpuclass-$(CONFIG_M5272) := coldfire ++cpuclass-$(CONFIG_M528x) := coldfire ++cpuclass-$(CONFIG_M5307) := coldfire ++cpuclass-$(CONFIG_M532x) := coldfire ++cpuclass-$(CONFIG_M5407) := coldfire + cpuclass-$(CONFIG_M68328) := 68328 + cpuclass-$(CONFIG_M68EZ328) := 68328 + cpuclass-$(CONFIG_M68VZ328) := 68328 +@@ -90,13 +90,14 @@ export PLATFORM BOARD MODEL CPUCLASS + cflags-$(CONFIG_M5206) := -m5200 + cflags-$(CONFIG_M5206e) := -m5200 + cflags-$(CONFIG_M520x) := -m5307 +-cflags-$(CONFIG_M523x) := -m5307 ++cflags-$(CONFIG_M523x) := $(call cc-option,-mcpu=523x,-m5307) + cflags-$(CONFIG_M5249) := -m5200 +-cflags-$(CONFIG_M527x) := -m5307 ++cflags-$(CONFIG_M5271) := $(call cc-option,-mcpu=5271,-m5307) + cflags-$(CONFIG_M5272) := -m5307 +-cflags-$(CONFIG_M528x) := -m5307 ++cflags-$(CONFIG_M5275) := $(call cc-option,-mcpu=5275,-m5307) ++cflags-$(CONFIG_M528x) := $(call cc-option,-m528x,-m5307) + cflags-$(CONFIG_M5307) := -m5307 +-cflags-$(CONFIG_M532x) := -m5307 ++cflags-$(CONFIG_M532x) := $(call cc-option,-mcpu=532x,-m5307) + cflags-$(CONFIG_M5407) := -m5200 + cflags-$(CONFIG_M68328) := -m68000 + cflags-$(CONFIG_M68EZ328) := -m68000 +Index: linux-2.6.24.7-rt21/arch/m68knommu/kernel/asm-offsets.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/kernel/asm-offsets.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/kernel/asm-offsets.c 2008-10-08 22:22:55.000000000 -0400 +@@ -91,6 +91,7 @@ int main(void) + DEFINE(TI_TASK, offsetof(struct thread_info, task)); + DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain)); + DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); ++ DEFINE(TI_PREEMPTCOUNT, offsetof(struct thread_info, preempt_count)); + DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); + + return 0; +Index: linux-2.6.24.7-rt21/arch/m68knommu/kernel/irq.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/kernel/irq.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/kernel/irq.c 2008-10-08 22:22:55.000000000 -0400 +@@ -23,7 +23,7 @@ asmlinkage void do_IRQ(int irq, struct p + struct pt_regs *oldregs = set_irq_regs(regs); + + irq_enter(); +- __do_IRQ(irq); ++ generic_handle_irq(irq); + irq_exit(); + + set_irq_regs(oldregs); +@@ -34,12 +34,16 @@ void ack_bad_irq(unsigned int irq) + printk(KERN_ERR "IRQ: unexpected irq=%d\n", irq); + } + ++#ifndef CONFIG_M523x + static struct irq_chip m_irq_chip = { + .name = "M68K-INTC", + .enable = enable_vector, + .disable = disable_vector, + .ack = ack_vector, + }; ++#else ++void coldfire_init_irq_chip(void); ++#endif + + void __init init_IRQ(void) + { +@@ -47,12 +51,16 @@ void __init init_IRQ(void) + + init_vectors(); + ++#ifndef CONFIG_M523x + for (irq = 0; (irq < NR_IRQS); irq++) { + irq_desc[irq].status = IRQ_DISABLED; + irq_desc[irq].action = NULL; + irq_desc[irq].depth = 1; + irq_desc[irq].chip = &m_irq_chip; + } ++#else ++ coldfire_init_irq_chip(); ++#endif + } + + int show_interrupts(struct seq_file *p, void *v) +@@ -79,4 +87,3 @@ int show_interrupts(struct seq_file *p, + + return 0; + } +- +Index: linux-2.6.24.7-rt21/arch/m68knommu/kernel/setup.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/kernel/setup.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/kernel/setup.c 2008-10-08 22:22:55.000000000 -0400 +@@ -165,7 +165,7 @@ void __init setup_arch(char **cmdline_p) + printk(KERN_INFO "DragonEngine II board support by Georges Menie\n"); + #endif + #ifdef CONFIG_M5235EVB +- printk(KERN_INFO "Motorola M5235EVB support (C)2005 Syn-tech Systems, Inc. (Jate Sujjavanich)"); ++ printk(KERN_INFO "Motorola M5235EVB support (C)2005 Syn-tech Systems, Inc. (Jate Sujjavanich)\n"); + #endif + + #ifdef DEBUG +Index: linux-2.6.24.7-rt21/arch/m68knommu/kernel/time.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/kernel/time.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/kernel/time.c 2008-10-08 22:22:55.000000000 -0400 +@@ -22,7 +22,6 @@ + #include + + #include +-#include + #include + + #define TICK_SIZE (tick_nsec / 1000) +@@ -34,14 +33,13 @@ static inline int set_rtc_mmss(unsigned + return -1; + } + ++#ifndef CONFIG_GENERIC_CLOCKEVENTS + /* + * timer_interrupt() needs to keep up the real-time clock, + * as well as call the "do_timer()" routine every clocktick + */ + irqreturn_t arch_timer_interrupt(int irq, void *dummy) + { +- /* last time the cmos clock got updated */ +- static long last_rtc_update=0; + + write_seqlock(&xtime_lock); + +@@ -52,49 +50,12 @@ irqreturn_t arch_timer_interrupt(int irq + if (current->pid) + profile_tick(CPU_PROFILING); + +- /* +- * If we have an externally synchronized Linux clock, then update +- * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be +- * called as close as possible to 500 ms before the new second starts. +- */ +- if (ntp_synced() && +- xtime.tv_sec > last_rtc_update + 660 && +- (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && +- (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { +- if (set_rtc_mmss(xtime.tv_sec) == 0) +- last_rtc_update = xtime.tv_sec; +- else +- last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ +- } +-#ifdef CONFIG_HEARTBEAT +- /* use power LED as a heartbeat instead -- much more useful +- for debugging -- based on the version for PReP by Cort */ +- /* acts like an actual heart beat -- ie thump-thump-pause... */ +- if (mach_heartbeat) { +- static unsigned cnt = 0, period = 0, dist = 0; +- +- if (cnt == 0 || cnt == dist) +- mach_heartbeat( 1 ); +- else if (cnt == 7 || cnt == dist+7) +- mach_heartbeat( 0 ); +- +- if (++cnt > period) { +- cnt = 0; +- /* The hyperbolic function below modifies the heartbeat period +- * length in dependency of the current (5min) load. It goes +- * through the points f(0)=126, f(1)=86, f(5)=51, +- * f(inf)->30. */ +- period = ((672<= 1000000) { +- usec -= 1000000; +- sec++; +- } +- +- tv->tv_sec = sec; +- tv->tv_usec = usec; ++ return read_rtc_mmss(); + } + +-EXPORT_SYMBOL(do_gettimeofday); +- +-int do_settimeofday(struct timespec *tv) ++int update_persistent_clock(struct timespec now) + { +- time_t wtm_sec, sec = tv->tv_sec; +- long wtm_nsec, nsec = tv->tv_nsec; +- +- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) +- return -EINVAL; +- +- write_seqlock_irq(&xtime_lock); +- /* +- * This is revolting. We need to set the xtime.tv_usec +- * correctly. However, the value in this location is +- * is value at the last tick. +- * Discover what correction gettimeofday +- * would have done, and then undo it! +- */ +- nsec -= (hw_timer_offset() * 1000); +- +- wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); +- wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); +- +- set_normalized_timespec(&xtime, sec, nsec); +- set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); ++ return set_rtc_mmss(now.tv_sec); ++} + +- ntp_clear(); +- write_sequnlock_irq(&xtime_lock); +- clock_was_set(); +- return 0; ++void time_init(void) ++{ ++ hw_timer_init(); + } +-EXPORT_SYMBOL(do_settimeofday); +Index: linux-2.6.24.7-rt21/arch/m68knommu/kernel/traps.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/kernel/traps.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/kernel/traps.c 2008-10-08 22:22:55.000000000 -0400 +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -102,56 +103,79 @@ asmlinkage void buserr_c(struct frame *f + force_sig(SIGSEGV, current); + } + ++static void print_this_address(unsigned long addr, int i) ++{ ++#ifdef CONFIG_KALLSYMS ++ printk(KERN_EMERG " [%08lx] ", addr); ++ print_symbol(KERN_CONT "%s\n", addr); ++#else ++ if (i % 5) ++ printk(KERN_CONT " [%08lx] ", addr); ++ else ++ printk(KERN_CONT "\n" KERN_EMERG " [%08lx] ", addr); ++ i++; ++#endif ++} + + int kstack_depth_to_print = 48; + +-void show_stack(struct task_struct *task, unsigned long *stack) ++static void __show_stack(struct task_struct *task, unsigned long *stack) + { + unsigned long *endstack, addr; +- extern char _start, _etext; ++#ifdef CONFIG_FRAME_POINTER ++ unsigned long *last_stack; ++#endif + int i; + +- if (!stack) { +- if (task) +- stack = (unsigned long *)task->thread.ksp; +- else +- stack = (unsigned long *)&stack; +- } ++ if (!stack) ++ stack = (unsigned long *)task->thread.ksp; + + addr = (unsigned long) stack; + endstack = (unsigned long *) PAGE_ALIGN(addr); + + printk(KERN_EMERG "Stack from %08lx:", (unsigned long)stack); + for (i = 0; i < kstack_depth_to_print; i++) { +- if (stack + 1 > endstack) ++ if (stack + 1 + i > endstack) + break; + if (i % 8 == 0) + printk("\n" KERN_EMERG " "); +- printk(" %08lx", *stack++); ++ printk(" %08lx", *(stack + i)); + } + printk("\n"); +- +- printk(KERN_EMERG "Call Trace:"); + i = 0; +- while (stack + 1 <= endstack) { ++ ++#ifdef CONFIG_FRAME_POINTER ++ printk(KERN_EMERG "Call Trace:\n"); ++ ++ last_stack = stack - 1; ++ while (stack <= endstack && stack > last_stack) { ++ ++ addr = *(stack + 1); ++ print_this_address(addr, i); ++ i++; ++ ++ last_stack = stack; ++ stack = (unsigned long *)*stack; ++ } ++ printk("\n"); ++#else ++ printk(KERN_EMERG "Call Trace with CONFIG_FRAME_POINTER disabled:\n"); ++ while (stack <= endstack) { + addr = *stack++; + /* +- * If the address is either in the text segment of the +- * kernel, or in the region which contains vmalloc'ed +- * memory, it *may* be the address of a calling +- * routine; if so, print it so that someone tracing +- * down the cause of the crash will be able to figure +- * out the call path that was taken. ++ * If the address is either in the text segment of the kernel, ++ * or in a region which is occupied by a module then it *may* ++ * be the address of a calling routine; if so, print it so that ++ * someone tracing down the cause of the crash will be able to ++ * figure out the call path that was taken. + */ +- if (((addr >= (unsigned long) &_start) && +- (addr <= (unsigned long) &_etext))) { +- if (i % 4 == 0) +- printk("\n" KERN_EMERG " "); +- printk(" [<%08lx>]", addr); ++ if (__kernel_text_address(addr)) { ++ print_this_address(addr, i); + i++; + } + } +- printk("\n"); ++ printk(KERN_CONT "\n"); ++#endif + } + + void bad_super_trap(struct frame *fp) +@@ -298,19 +322,47 @@ asmlinkage void set_esp0(unsigned long s + current->thread.esp0 = ssp; + } + +- + /* + * The architecture-independent backtrace generator + */ + void dump_stack(void) + { +- unsigned long stack; +- +- show_stack(current, &stack); ++ /* ++ * We need frame pointers for this little trick, which works as follows: ++ * ++ * +------------+ 0x00 ++ * | Next SP | -> 0x0c ++ * +------------+ 0x04 ++ * | Caller | ++ * +------------+ 0x08 ++ * | Local vars | -> our stack var ++ * +------------+ 0x0c ++ * | Next SP | -> 0x18, that is what we pass to show_stack() ++ * +------------+ 0x10 ++ * | Caller | ++ * +------------+ 0x14 ++ * | Local vars | ++ * +------------+ 0x18 ++ * | ... | ++ * +------------+ ++ */ ++ ++ unsigned long *stack; ++ ++ stack = (unsigned long *)&stack; ++ stack++; ++ __show_stack(current, stack); + } +- + EXPORT_SYMBOL(dump_stack); + ++void show_stack(struct task_struct *task, unsigned long *stack) ++{ ++ if (!stack && !task) ++ dump_stack(); ++ else ++ __show_stack(task, stack); ++} ++ + #ifdef CONFIG_M68KFPU_EMU + asmlinkage void fpemu_signal(int signal, int code, void *addr) + { +Index: linux-2.6.24.7-rt21/arch/m68knommu/kernel/vmlinux.lds.S +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/kernel/vmlinux.lds.S 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/kernel/vmlinux.lds.S 2008-10-08 22:22:55.000000000 -0400 +@@ -7,6 +7,8 @@ + * run kernels. + */ + ++#define OUTPUT_DATA_SECTION > DATA ++ + #include + + #if defined(CONFIG_RAMKERNEL) +@@ -34,7 +36,6 @@ + #define DATA_ADDR + #endif + +- + OUTPUT_ARCH(m68k) + ENTRY(_start) + +@@ -64,81 +65,32 @@ SECTIONS { + _stext = . ; + TEXT_TEXT + SCHED_TEXT ++ LOCK_TEXT + *(.text.lock) + +- . = ALIGN(16); /* Exception table */ +- __start___ex_table = .; +- *(__ex_table) +- __stop___ex_table = .; +- +- *(.rodata) *(.rodata.*) +- *(__vermagic) /* Kernel version magic */ +- *(.rodata1) +- *(.rodata.str1.1) +- +- /* Kernel symbol table: Normal symbols */ +- . = ALIGN(4); +- __start___ksymtab = .; +- *(__ksymtab) +- __stop___ksymtab = .; +- +- /* Kernel symbol table: GPL-only symbols */ +- __start___ksymtab_gpl = .; +- *(__ksymtab_gpl) +- __stop___ksymtab_gpl = .; +- +- /* Kernel symbol table: Normal unused symbols */ +- __start___ksymtab_unused = .; +- *(__ksymtab_unused) +- __stop___ksymtab_unused = .; +- +- /* Kernel symbol table: GPL-only unused symbols */ +- __start___ksymtab_unused_gpl = .; +- *(__ksymtab_unused_gpl) +- __stop___ksymtab_unused_gpl = .; +- +- /* Kernel symbol table: GPL-future symbols */ +- __start___ksymtab_gpl_future = .; +- *(__ksymtab_gpl_future) +- __stop___ksymtab_gpl_future = .; +- +- /* Kernel symbol table: Normal symbols */ +- __start___kcrctab = .; +- *(__kcrctab) +- __stop___kcrctab = .; +- +- /* Kernel symbol table: GPL-only symbols */ +- __start___kcrctab_gpl = .; +- *(__kcrctab_gpl) +- __stop___kcrctab_gpl = .; +- +- /* Kernel symbol table: GPL-future symbols */ +- __start___kcrctab_gpl_future = .; +- *(__kcrctab_gpl_future) +- __stop___kcrctab_gpl_future = .; +- +- /* Kernel symbol table: strings */ +- *(__ksymtab_strings) +- +- /* Built-in module parameters */ +- . = ALIGN(4) ; +- __start___param = .; +- *(__param) +- __stop___param = .; +- + . = ALIGN(4) ; +- _etext = . ; + } > TEXT + ++ _etext = . ; ++ ++ RODATA ++ + .data DATA_ADDR : { + . = ALIGN(4); + _sdata = . ; + DATA_DATA ++ . = ALIGN(16); /* Exception table */ ++ __start___ex_table = .; ++ *(__ex_table) ++ __stop___ex_table = .; + . = ALIGN(8192) ; + *(.data.init_task) + _edata = . ; + } > DATA + ++ BUG_TABLE ++ PERCPU(4096) ++ + .init : { + . = ALIGN(4096); + __init_begin = .; +@@ -169,12 +121,6 @@ SECTIONS { + __init_end = .; + } > INIT + +- /DISCARD/ : { +- *(.exit.text) +- *(.exit.data) +- *(.exitcall.exit) +- } +- + .bss : { + . = ALIGN(4); + _sbss = . ; +@@ -184,5 +130,11 @@ SECTIONS { + _ebss = . ; + } > BSS + +-} ++ _end = . ; + ++ /DISCARD/ : { ++ *(.exit.text) ++ *(.exit.data) ++ *(.exitcall.exit) ++ } ++} +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/5206/config.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/platform/5206/config.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/5206/config.c 2008-10-08 22:22:55.000000000 -0400 +@@ -13,12 +13,11 @@ + #include + #include + #include +-#include ++#include + #include + #include +-#include + #include +-#include ++#include + + /***************************************************************************/ + +@@ -26,15 +25,51 @@ void coldfire_reset(void); + + /***************************************************************************/ + +-/* +- * DMA channel base address table. +- */ +-unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = { +- MCF_MBAR + MCFDMA_BASE0, +- MCF_MBAR + MCFDMA_BASE1, ++static struct mcf_platform_uart m5206_uart_platform[] = { ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE1, ++ .irq = 73, ++ }, ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE2, ++ .irq = 74, ++ }, ++ { }, + }; + +-unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS]; ++static struct platform_device m5206_uart = { ++ .name = "mcfuart", ++ .id = 0, ++ .dev.platform_data = m5206_uart_platform, ++}; ++ ++static struct platform_device *m5206_devices[] __initdata = { ++ &m5206_uart, ++}; ++ ++/***************************************************************************/ ++ ++static void __init m5206_uart_init_line(int line, int irq) ++{ ++ if (line == 0) { ++ writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR); ++ writeb(irq, MCFUART_BASE1 + MCFUART_UIVR); ++ mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1); ++ } else if (line == 1) { ++ writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR); ++ writeb(irq, MCFUART_BASE2 + MCFUART_UIVR); ++ mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2); ++ } ++} ++ ++static void __init m5206_uarts_init(void) ++{ ++ const int nrlines = ARRAY_SIZE(m5206_uart_platform); ++ int line; ++ ++ for (line = 0; (line < nrlines); line++) ++ m5206_uart_init_line(line, m5206_uart_platform[line].irq); ++} + + /***************************************************************************/ + +@@ -74,24 +109,21 @@ void mcf_settimericr(unsigned int timer, + + /***************************************************************************/ + +-int mcf_timerirqpending(int timer) ++void __init config_BSP(char *commandp, int size) + { +- unsigned int imr = 0; +- +- switch (timer) { +- case 1: imr = MCFSIM_IMR_TIMER1; break; +- case 2: imr = MCFSIM_IMR_TIMER2; break; +- default: break; +- } +- return (mcf_getipr() & imr); ++ mcf_setimr(MCFSIM_IMR_MASKALL); ++ mach_reset = coldfire_reset; + } + + /***************************************************************************/ + +-void config_BSP(char *commandp, int size) ++static int __init init_BSP(void) + { +- mcf_setimr(MCFSIM_IMR_MASKALL); +- mach_reset = coldfire_reset; ++ m5206_uarts_init(); ++ platform_add_devices(m5206_devices, ARRAY_SIZE(m5206_devices)); ++ return 0; + } + ++arch_initcall(init_BSP); ++ + /***************************************************************************/ +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/5206e/config.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/platform/5206e/config.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/5206e/config.c 2008-10-08 22:22:55.000000000 -0400 +@@ -10,8 +10,9 @@ + + #include + #include ++#include + #include +-#include ++#include + #include + #include + #include +@@ -23,15 +24,51 @@ void coldfire_reset(void); + + /***************************************************************************/ + +-/* +- * DMA channel base address table. +- */ +-unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = { +- MCF_MBAR + MCFDMA_BASE0, +- MCF_MBAR + MCFDMA_BASE1, ++static struct mcf_platform_uart m5206_uart_platform[] = { ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE1, ++ .irq = 73, ++ }, ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE2, ++ .irq = 74, ++ }, ++ { }, + }; + +-unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS]; ++static struct platform_device m5206_uart = { ++ .name = "mcfuart", ++ .id = 0, ++ .dev.platform_data = m5206_uart_platform, ++}; ++ ++static struct platform_device *m5206_devices[] __initdata = { ++ &m5206_uart, ++}; ++ ++/***************************************************************************/ ++ ++static void __init m5206_uart_init_line(int line, int irq) ++{ ++ if (line == 0) { ++ writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR); ++ writeb(irq, MCFUART_BASE1 + MCFUART_UIVR); ++ mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1); ++ } else if (line == 1) { ++ writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR); ++ writeb(irq, MCFUART_BASE2 + MCFUART_UIVR); ++ mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2); ++ } ++} ++ ++static void __init m5206_uarts_init(void) ++{ ++ const int nrlines = ARRAY_SIZE(m5206_uart_platform); ++ int line; ++ ++ for (line = 0; (line < nrlines); line++) ++ m5206_uart_init_line(line, m5206_uart_platform[line].irq); ++} + + /***************************************************************************/ + +@@ -71,21 +108,7 @@ void mcf_settimericr(unsigned int timer, + + /***************************************************************************/ + +-int mcf_timerirqpending(int timer) +-{ +- unsigned int imr = 0; +- +- switch (timer) { +- case 1: imr = MCFSIM_IMR_TIMER1; break; +- case 2: imr = MCFSIM_IMR_TIMER2; break; +- default: break; +- } +- return (mcf_getipr() & imr); +-} +- +-/***************************************************************************/ +- +-void config_BSP(char *commandp, int size) ++void __init config_BSP(char *commandp, int size) + { + mcf_setimr(MCFSIM_IMR_MASKALL); + +@@ -99,3 +122,14 @@ void config_BSP(char *commandp, int size + } + + /***************************************************************************/ ++ ++static int __init init_BSP(void) ++{ ++ m5206_uarts_init(); ++ platform_add_devices(m5206_devices, ARRAY_SIZE(m5206_devices)); ++ return 0; ++} ++ ++arch_initcall(init_BSP); ++ ++/***************************************************************************/ +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/520x/config.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/platform/520x/config.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/520x/config.c 2008-10-08 22:22:55.000000000 -0400 +@@ -5,7 +5,7 @@ + * + * Copyright (C) 2005, Freescale (www.freescale.com) + * Copyright (C) 2005, Intec Automation (mike@steroidmicros.com) +- * Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com) ++ * Copyright (C) 1999-2007, Greg Ungerer (gerg@snapgear.com) + * Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com) + */ + +@@ -13,21 +13,93 @@ + + #include + #include ++#include + #include ++#include + #include +-#include ++#include ++#include ++#include + + /***************************************************************************/ + +-/* +- * DMA channel base address table. +- */ +-unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS]; +-unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS]; ++void coldfire_reset(void); + + /***************************************************************************/ + +-void coldfire_reset(void); ++static struct mcf_platform_uart m520x_uart_platform[] = { ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE1, ++ .irq = MCFINT_VECBASE + MCFINT_UART0, ++ }, ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE2, ++ .irq = MCFINT_VECBASE + MCFINT_UART1, ++ }, ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE3, ++ .irq = MCFINT_VECBASE + MCFINT_UART2, ++ }, ++ { }, ++}; ++ ++static struct platform_device m520x_uart = { ++ .name = "mcfuart", ++ .id = 0, ++ .dev.platform_data = m520x_uart_platform, ++}; ++ ++static struct platform_device *m520x_devices[] __initdata = { ++ &m520x_uart, ++}; ++ ++/***************************************************************************/ ++ ++#define INTC0 (MCF_MBAR + MCFICM_INTC0) ++ ++static void __init m520x_uart_init_line(int line, int irq) ++{ ++ u32 imr; ++ u16 par; ++ u8 par2; ++ ++ writeb(0x03, INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line); ++ ++ imr = readl(INTC0 + MCFINTC_IMRL); ++ imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1); ++ writel(imr, INTC0 + MCFINTC_IMRL); ++ ++ switch (line) { ++ case 0: ++ par = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART); ++ par |= MCF_GPIO_PAR_UART_PAR_UTXD0 | ++ MCF_GPIO_PAR_UART_PAR_URXD0; ++ writew(par, MCF_IPSBAR + MCF_GPIO_PAR_UART); ++ break; ++ case 1: ++ par = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART); ++ par |= MCF_GPIO_PAR_UART_PAR_UTXD1 | ++ MCF_GPIO_PAR_UART_PAR_URXD1; ++ writew(par, MCF_IPSBAR + MCF_GPIO_PAR_UART); ++ break; ++ case 2: ++ par2 = readb(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C); ++ par2 &= ~0x0F; ++ par2 |= MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2 | ++ MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2; ++ writeb(par2, MCF_IPSBAR + MCF_GPIO_PAR_FECI2C); ++ break; ++ } ++} ++ ++static void __init m520x_uarts_init(void) ++{ ++ const int nrlines = ARRAY_SIZE(m520x_uart_platform); ++ int line; ++ ++ for (line = 0; (line < nrlines); line++) ++ m520x_uart_init_line(line, m520x_uart_platform[line].irq); ++} + + /***************************************************************************/ + +@@ -42,9 +114,20 @@ void mcf_autovector(unsigned int vec) + + /***************************************************************************/ + +-void config_BSP(char *commandp, int size) ++void __init config_BSP(char *commandp, int size) + { + mach_reset = coldfire_reset; ++ m520x_uarts_init(); ++} ++ ++/***************************************************************************/ ++ ++static int __init init_BSP(void) ++{ ++ platform_add_devices(m520x_devices, ARRAY_SIZE(m520x_devices)); ++ return 0; + } + ++arch_initcall(init_BSP); ++ + /***************************************************************************/ +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/523x/config.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/platform/523x/config.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/523x/config.c 2008-10-08 22:22:55.000000000 -0400 +@@ -16,11 +16,15 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include +-#include ++#include ++ ++#ifdef CONFIG_MTD ++#include ++#endif + + /***************************************************************************/ + +@@ -28,14 +32,58 @@ void coldfire_reset(void); + + /***************************************************************************/ + +-/* +- * DMA channel base address table. +- */ +-unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = { +- MCF_MBAR + MCFDMA_BASE0, ++static struct mcf_platform_uart m523x_uart_platform[] = { ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE1, ++ .irq = MCFINT_VECBASE + MCFINT_UART0, ++ }, ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE2, ++ .irq = MCFINT_VECBASE + MCFINT_UART0 + 1, ++ }, ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE3, ++ .irq = MCFINT_VECBASE + MCFINT_UART0 + 2, ++ }, ++ { }, ++}; ++ ++static struct platform_device m523x_uart = { ++ .name = "mcfuart", ++ .id = 0, ++ .dev.platform_data = m523x_uart_platform, + }; + +-unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS]; ++static struct platform_device *m523x_devices[] __initdata = { ++ &m523x_uart, ++}; ++ ++/***************************************************************************/ ++ ++#define INTC0 (MCF_MBAR + MCFICM_INTC0) ++ ++static void __init m523x_uart_init_line(int line, int irq) ++{ ++ u32 imr; ++ ++ if ((line < 0) || (line > 2)) ++ return; ++ ++ writeb(0x30+line, (INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line)); ++ ++ imr = readl(INTC0 + MCFINTC_IMRL); ++ imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1); ++ writel(imr, INTC0 + MCFINTC_IMRL); ++} ++ ++static void __init m523x_uarts_init(void) ++{ ++ const int nrlines = ARRAY_SIZE(m523x_uart_platform); ++ int line; ++ ++ for (line = 0; (line < nrlines); line++) ++ m523x_uart_init_line(line, m523x_uart_platform[line].irq); ++} + + /***************************************************************************/ + +@@ -49,15 +97,85 @@ void mcf_disableall(void) + + void mcf_autovector(unsigned int vec) + { +- /* Everything is auto-vectored on the 5272 */ ++ /* Everything is auto-vectored on the 523x */ + } + + /***************************************************************************/ + +-void config_BSP(char *commandp, int size) ++#if defined(CONFIG_SAVANT) ++ ++/* ++ * Do special config for SAVANT BSP ++ */ ++static void __init config_savantBSP(char *commandP, int size) ++{ ++ /* setup BOOTPARAM_STRING */ ++ strncpy(commandP, "root=/dev/mtdblock1 ro rootfstype=romfs", size); ++ /* Look at Chatter DIP Switch, if CS3 is enabled */ ++ { ++ uint32_t *csmr3 = (uint32_t *) (MCF_IPSBAR + MCF523x_CSMR3); ++ uint32_t *csar3 = (uint32_t *) (MCF_IPSBAR + MCF523x_CSAR3); ++ uint16_t *dipsP = (uint16_t *) *csar3; ++ uint16_t dipSetOff = *dipsP & 0x0100; // switch #1 ++ uint16_t *btnPressP = (uint16_t *)(*csar3 + 0x10); ++ uint16_t shortButtonPress = *btnPressP & 0x8000; ++ if (*csmr3 & 1) { ++ /* CS3 enabled */ ++ if (!dipSetOff && shortButtonPress) { ++ /* switch on, so be quiet */ ++ strncat(commandP, " console=", size-strlen(commandP)-1); ++ } ++ } ++ } ++ commandP[size-1] = 0; ++ ++ /* Set on-chip peripheral space to user mode */ ++ { ++ uint8_t *gpacr = (uint8_t *) (MCF_IPSBAR + MCF523x_GPACR); ++ uint8_t *pacr1 = (uint8_t *) (MCF_IPSBAR + MCF523x_PACR1); ++ uint8_t *pacr4 = (uint8_t *) (MCF_IPSBAR + MCF523x_PACR4); ++ uint8_t *pacr7 = (uint8_t *) (MCF_IPSBAR + MCF523x_PACR7); ++ uint8_t *pacr8 = (uint8_t *) (MCF_IPSBAR + MCF523x_PACR8); ++ *gpacr = 0x04; ++ *pacr1 = 0x40; /* EIM required for Chip Select access */ ++ *pacr4 = 0x40; /* I2C */ ++ *pacr7 = 0x44; /* INTC0 & 1 handy for debug */ ++ *pacr8 = 0x40; /* FEC MAC */ ++ } ++ ++#ifdef CONFIG_MTD ++ /* all board spins cannot access flash from linux unless we change the map here */ ++ { ++ uint32_t *csar0 = (uint32_t *) (MCF_IPSBAR + MCF523x_CSAR0); ++ uint32_t start = *csar0; ++ uint32_t size = 0xffffFFFF - start + 1; ++ physmap_configure(start, size, CONFIG_MTD_PHYSMAP_BANKWIDTH, NULL); ++ } ++#endif ++} ++ ++#endif /* CONFIG_SAVANT */ ++ ++/***************************************************************************/ ++ ++void __init config_BSP(char *commandp, int size) + { + mcf_disableall(); ++#if defined(CONFIG_SAVANT) ++ config_savantBSP(commandp, size); ++#endif /* CONFIG_SAVANT */ + mach_reset = coldfire_reset; ++ m523x_uarts_init(); ++} ++ ++/***************************************************************************/ ++ ++static int __init init_BSP(void) ++{ ++ platform_add_devices(m523x_devices, ARRAY_SIZE(m523x_devices)); ++ return 0; + } + ++arch_initcall(init_BSP); ++ + /***************************************************************************/ +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/5249/config.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/platform/5249/config.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/5249/config.c 2008-10-08 22:22:55.000000000 -0400 +@@ -12,11 +12,11 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include +-#include ++#include + + /***************************************************************************/ + +@@ -24,17 +24,51 @@ void coldfire_reset(void); + + /***************************************************************************/ + +-/* +- * DMA channel base address table. +- */ +-unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = { +- MCF_MBAR + MCFDMA_BASE0, +- MCF_MBAR + MCFDMA_BASE1, +- MCF_MBAR + MCFDMA_BASE2, +- MCF_MBAR + MCFDMA_BASE3, ++static struct mcf_platform_uart m5249_uart_platform[] = { ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE1, ++ .irq = 73, ++ }, ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE2, ++ .irq = 74, ++ } ++}; ++ ++static struct platform_device m5249_uart = { ++ .name = "mcfuart", ++ .id = 0, ++ .dev.platform_data = m5249_uart_platform, + }; + +-unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS]; ++static struct platform_device *m5249_devices[] __initdata = { ++ &m5249_uart, ++}; ++ ++/***************************************************************************/ ++ ++static void __init m5249_uart_init_line(int line, int irq) ++{ ++ if (line == 0) { ++ writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR); ++ writeb(irq, MCFUART_BASE1 + MCFUART_UIVR); ++ mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1); ++ } else if (line == 1) { ++ writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR); ++ writeb(irq, MCFUART_BASE2 + MCFUART_UIVR); ++ mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2); ++ } ++} ++ ++static void __init m5249_uarts_init(void) ++{ ++ const int nrlines = ARRAY_SIZE(m5249_uart_platform); ++ int line; ++ ++ for (line = 0; (line < nrlines); line++) ++ m5249_uart_init_line(line, m5249_uart_platform[line].irq); ++} ++ + + /***************************************************************************/ + +@@ -71,24 +105,21 @@ void mcf_settimericr(unsigned int timer, + + /***************************************************************************/ + +-int mcf_timerirqpending(int timer) ++void __init config_BSP(char *commandp, int size) + { +- unsigned int imr = 0; +- +- switch (timer) { +- case 1: imr = MCFSIM_IMR_TIMER1; break; +- case 2: imr = MCFSIM_IMR_TIMER2; break; +- default: break; +- } +- return (mcf_getipr() & imr); ++ mcf_setimr(MCFSIM_IMR_MASKALL); ++ mach_reset = coldfire_reset; + } + + /***************************************************************************/ + +-void config_BSP(char *commandp, int size) ++static int __init init_BSP(void) + { +- mcf_setimr(MCFSIM_IMR_MASKALL); +- mach_reset = coldfire_reset; ++ m5249_uarts_init(); ++ platform_add_devices(m5249_devices, ARRAY_SIZE(m5249_devices)); ++ return 0; + } + ++arch_initcall(init_BSP); ++ + /***************************************************************************/ +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/5272/config.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/platform/5272/config.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/5272/config.c 2008-10-08 22:22:55.000000000 -0400 +@@ -13,11 +13,11 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include +-#include ++#include + + /***************************************************************************/ + +@@ -37,14 +37,57 @@ unsigned char ledbank = 0xff; + + /***************************************************************************/ + +-/* +- * DMA channel base address table. +- */ +-unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = { +- MCF_MBAR + MCFDMA_BASE0, ++static struct mcf_platform_uart m5272_uart_platform[] = { ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE1, ++ .irq = 73, ++ }, ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE2, ++ .irq = 74, ++ }, ++ { }, + }; + +-unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS]; ++static struct platform_device m5272_uart = { ++ .name = "mcfuart", ++ .id = 0, ++ .dev.platform_data = m5272_uart_platform, ++}; ++ ++static struct platform_device *m5272_devices[] __initdata = { ++ &m5272_uart, ++}; ++ ++/***************************************************************************/ ++ ++static void __init m5272_uart_init_line(int line, int irq) ++{ ++ u32 v; ++ ++ if ((line >= 0) && (line < 2)) { ++ v = (line) ? 0x0e000000 : 0xe0000000; ++ writel(v, MCF_MBAR + MCFSIM_ICR2); ++ ++ /* Enable the output lines for the serial ports */ ++ v = readl(MCF_MBAR + MCFSIM_PBCNT); ++ v = (v & ~0x000000ff) | 0x00000055; ++ writel(v, MCF_MBAR + MCFSIM_PBCNT); ++ ++ v = readl(MCF_MBAR + MCFSIM_PDCNT); ++ v = (v & ~0x000003fc) | 0x000002a8; ++ writel(v, MCF_MBAR + MCFSIM_PDCNT); ++ } ++} ++ ++static void __init m5272_uarts_init(void) ++{ ++ const int nrlines = ARRAY_SIZE(m5272_uart_platform); ++ int line; ++ ++ for (line = 0; (line < nrlines); line++) ++ m5272_uart_init_line(line, m5272_uart_platform[line].irq); ++} + + /***************************************************************************/ + +@@ -80,20 +123,7 @@ void mcf_settimericr(int timer, int leve + + /***************************************************************************/ + +-int mcf_timerirqpending(int timer) +-{ +- volatile unsigned long *icrp; +- +- if ((timer >= 1 ) && (timer <= 4)) { +- icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1); +- return (*icrp & (0x8 << ((4 - timer) * 4))); +- } +- return 0; +-} +- +-/***************************************************************************/ +- +-void config_BSP(char *commandp, int size) ++void __init config_BSP(char *commandp, int size) + { + #if defined (CONFIG_MOD5272) + volatile unsigned char *pivrp; +@@ -109,10 +139,6 @@ void config_BSP(char *commandp, int size + /* Copy command line from FLASH to local buffer... */ + memcpy(commandp, (char *) 0xf0004000, size); + commandp[size-1] = 0; +-#elif defined(CONFIG_MTD_KeyTechnology) +- /* Copy command line from FLASH to local buffer... */ +- memcpy(commandp, (char *) 0xffe06000, size); +- commandp[size-1] = 0; + #elif defined(CONFIG_CANCam) + /* Copy command line from FLASH to local buffer... */ + memcpy(commandp, (char *) 0xf0010000, size); +@@ -125,3 +151,14 @@ void config_BSP(char *commandp, int size + } + + /***************************************************************************/ ++ ++static int __init init_BSP(void) ++{ ++ m5272_uarts_init(); ++ platform_add_devices(m5272_devices, ARRAY_SIZE(m5272_devices)); ++ return 0; ++} ++ ++arch_initcall(init_BSP); ++ ++/***************************************************************************/ +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/527x/config.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/platform/527x/config.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/527x/config.c 2008-10-08 22:22:55.000000000 -0400 +@@ -16,11 +16,11 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include +-#include ++#include + + /***************************************************************************/ + +@@ -28,14 +28,72 @@ void coldfire_reset(void); + + /***************************************************************************/ + +-/* +- * DMA channel base address table. +- */ +-unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = { +- MCF_MBAR + MCFDMA_BASE0, ++static struct mcf_platform_uart m527x_uart_platform[] = { ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE1, ++ .irq = MCFINT_VECBASE + MCFINT_UART0, ++ }, ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE2, ++ .irq = MCFINT_VECBASE + MCFINT_UART1, ++ }, ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE3, ++ .irq = MCFINT_VECBASE + MCFINT_UART2, ++ }, ++ { }, + }; + +-unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS]; ++static struct platform_device m527x_uart = { ++ .name = "mcfuart", ++ .id = 0, ++ .dev.platform_data = m527x_uart_platform, ++}; ++ ++static struct platform_device *m527x_devices[] __initdata = { ++ &m527x_uart, ++}; ++ ++/***************************************************************************/ ++ ++#define INTC0 (MCF_MBAR + MCFICM_INTC0) ++ ++static void __init m527x_uart_init_line(int line, int irq) ++{ ++ u16 sepmask; ++ u32 imr; ++ ++ if ((line < 0) || (line > 2)) ++ return; ++ ++ /* level 6, line based priority */ ++ writeb(0x30+line, INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line); ++ ++ imr = readl(INTC0 + MCFINTC_IMRL); ++ imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1); ++ writel(imr, INTC0 + MCFINTC_IMRL); ++ ++ /* ++ * External Pin Mask Setting & Enable External Pin for Interface ++ */ ++ sepmask = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART); ++ if (line == 0) ++ sepmask |= UART0_ENABLE_MASK; ++ else if (line == 1) ++ sepmask |= UART1_ENABLE_MASK; ++ else if (line == 2) ++ sepmask |= UART2_ENABLE_MASK; ++ writew(sepmask, MCF_IPSBAR + MCF_GPIO_PAR_UART); ++} ++ ++static void __init m527x_uarts_init(void) ++{ ++ const int nrlines = ARRAY_SIZE(m527x_uart_platform); ++ int line; ++ ++ for (line = 0; (line < nrlines); line++) ++ m527x_uart_init_line(line, m527x_uart_platform[line].irq); ++} + + /***************************************************************************/ + +@@ -54,10 +112,21 @@ void mcf_autovector(unsigned int vec) + + /***************************************************************************/ + +-void config_BSP(char *commandp, int size) ++void __init config_BSP(char *commandp, int size) + { + mcf_disableall(); + mach_reset = coldfire_reset; + } + + /***************************************************************************/ ++ ++static int __init init_BSP(void) ++{ ++ m527x_uarts_init(); ++ platform_add_devices(m527x_devices, ARRAY_SIZE(m527x_devices)); ++ return 0; ++} ++ ++arch_initcall(init_BSP); ++ ++/***************************************************************************/ +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/528x/config.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/platform/528x/config.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/528x/config.c 2008-10-08 22:22:55.000000000 -0400 +@@ -16,26 +16,314 @@ + #include + #include + #include +-#include ++#include ++#include ++#include ++#include + #include + #include + #include +-#include ++#include ++#include ++ ++#ifdef CONFIG_MTD_PARTITIONS ++#include ++#endif + + /***************************************************************************/ + + void coldfire_reset(void); ++void coldfire_qspi_cs_control(u8 cs, u8 command); ++ ++/***************************************************************************/ ++ ++#if defined(CONFIG_SPI) ++ ++#if defined(CONFIG_WILDFIRE) ++#define SPI_NUM_CHIPSELECTS 0x02 ++#define SPI_PAR_VAL 0x07 // Enable DIN, DOUT, CLK ++#define SPI_CS_MASK 0x18 ++ ++#define FLASH_BLOCKSIZE (1024*64) ++#define FLASH_NUMBLOCKS 16 ++#define FLASH_TYPE "m25p80" ++ ++#define M25P80_CS 0 ++#define MMC_CS 1 ++ ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition stm25p_partitions[] = { ++ /* sflash */ ++ [0] = { ++ .name = "stm25p80", ++ .offset = 0x00000000, ++ .size = FLASH_BLOCKSIZE * FLASH_NUMBLOCKS, ++ .mask_flags = 0 ++ } ++}; ++ ++#endif ++ ++#elif defined(CONFIG_WILDFIREMOD) ++ ++#define SPI_NUM_CHIPSELECTS 0x08 ++#define SPI_PAR_VAL 0x07 // Enable DIN, DOUT, CLK ++#define SPI_CS_MASK 0x78 ++ ++#define FLASH_BLOCKSIZE (1024*64) ++#define FLASH_NUMBLOCKS 64 ++#define FLASH_TYPE "m25p32" ++/* Reserve 1M for the kernel parition */ ++#define FLASH_KERNEL_SIZE (1024 * 1024) ++ ++#define M25P80_CS 5 ++#define MMC_CS 6 ++ ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition stm25p_partitions[] = { ++ /* sflash */ ++ [0] = { ++ .name = "kernel", ++ .offset = FLASH_BLOCKSIZE * FLASH_NUMBLOCKS - FLASH_KERNEL_SIZE, ++ .size = FLASH_KERNEL_SIZE, ++ .mask_flags = 0 ++ }, ++ [1] = { ++ .name = "image", ++ .offset = 0x00000000, ++ .size = FLASH_BLOCKSIZE * FLASH_NUMBLOCKS - FLASH_KERNEL_SIZE, ++ .mask_flags = 0 ++ }, ++ [2] = { ++ .name = "all", ++ .offset = 0x00000000, ++ .size = FLASH_BLOCKSIZE * FLASH_NUMBLOCKS, ++ .mask_flags = 0 ++ } ++}; ++#endif ++ ++#else ++#define SPI_NUM_CHIPSELECTS 0x04 ++#define SPI_PAR_VAL 0x7F // Enable DIN, DOUT, CLK, CS0 - CS4 ++#endif ++ ++#ifdef MMC_CS ++static struct coldfire_spi_chip flash_chip_info = { ++ .mode = SPI_MODE_0, ++ .bits_per_word = 16, ++ .del_cs_to_clk = 17, ++ .del_after_trans = 1, ++ .void_write_data = 0 ++}; ++ ++static struct coldfire_spi_chip mmc_chip_info = { ++ .mode = SPI_MODE_0, ++ .bits_per_word = 16, ++ .del_cs_to_clk = 17, ++ .del_after_trans = 1, ++ .void_write_data = 0xFFFF ++}; ++#endif ++ ++#ifdef M25P80_CS ++static struct flash_platform_data stm25p80_platform_data = { ++ .name = "ST M25P80 SPI Flash chip", ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = stm25p_partitions, ++ .nr_parts = sizeof(stm25p_partitions) / sizeof(*stm25p_partitions), ++#endif ++ .type = FLASH_TYPE ++}; ++#endif ++ ++static struct spi_board_info spi_board_info[] __initdata = { ++#ifdef M25P80_CS ++ { ++ .modalias = "m25p80", ++ .max_speed_hz = 16000000, ++ .bus_num = 1, ++ .chip_select = M25P80_CS, ++ .platform_data = &stm25p80_platform_data, ++ .controller_data = &flash_chip_info ++ }, ++#endif ++#ifdef MMC_CS ++ { ++ .modalias = "mmc_spi", ++ .max_speed_hz = 16000000, ++ .bus_num = 1, ++ .chip_select = MMC_CS, ++ .controller_data = &mmc_chip_info ++ } ++#endif ++}; ++ ++static struct coldfire_spi_master coldfire_master_info = { ++ .bus_num = 1, ++ .num_chipselect = SPI_NUM_CHIPSELECTS, ++ .irq_source = MCF5282_QSPI_IRQ_SOURCE, ++ .irq_vector = MCF5282_QSPI_IRQ_VECTOR, ++ .irq_mask = ((0x01 << MCF5282_QSPI_IRQ_SOURCE) | 0x01), ++ .irq_lp = 0x2B, // Level 5 and Priority 3 ++ .par_val = SPI_PAR_VAL, ++ .cs_control = coldfire_qspi_cs_control, ++}; ++ ++static struct resource coldfire_spi_resources[] = { ++ [0] = { ++ .name = "qspi-par", ++ .start = MCF5282_QSPI_PAR, ++ .end = MCF5282_QSPI_PAR, ++ .flags = IORESOURCE_MEM ++ }, ++ ++ [1] = { ++ .name = "qspi-module", ++ .start = MCF5282_QSPI_QMR, ++ .end = MCF5282_QSPI_QMR + 0x18, ++ .flags = IORESOURCE_MEM ++ }, ++ ++ [2] = { ++ .name = "qspi-int-level", ++ .start = MCF5282_INTC0 + MCFINTC_ICR0 + MCF5282_QSPI_IRQ_SOURCE, ++ .end = MCF5282_INTC0 + MCFINTC_ICR0 + MCF5282_QSPI_IRQ_SOURCE, ++ .flags = IORESOURCE_MEM ++ }, ++ ++ [3] = { ++ .name = "qspi-int-mask", ++ .start = MCF5282_INTC0 + MCFINTC_IMRL, ++ .end = MCF5282_INTC0 + MCFINTC_IMRL, ++ .flags = IORESOURCE_MEM ++ } ++}; ++ ++static struct platform_device coldfire_spi = { ++ .name = "spi_coldfire", ++ .id = -1, ++ .resource = coldfire_spi_resources, ++ .num_resources = ARRAY_SIZE(coldfire_spi_resources), ++ .dev = { ++ .platform_data = &coldfire_master_info, ++ } ++}; ++ ++void coldfire_qspi_cs_control(u8 cs, u8 command) ++{ ++ u8 cs_bit = ((0x01 << cs) << 3) & SPI_CS_MASK; ++ ++#if defined(CONFIG_WILDFIRE) ++ u8 cs_mask = ~(((0x01 << cs) << 3) & SPI_CS_MASK); ++#endif ++#if defined(CONFIG_WILDFIREMOD) ++ u8 cs_mask = (cs << 3) & SPI_CS_MASK; ++#endif ++ ++ /* ++ * Don't do anything if the chip select is not ++ * one of the port qs pins. ++ */ ++ if (command & QSPI_CS_INIT) { ++#if defined(CONFIG_WILDFIRE) ++ MCF5282_GPIO_DDRQS |= cs_bit; ++ MCF5282_GPIO_PQSPAR &= ~cs_bit; ++#endif ++ ++#if defined(CONFIG_WILDFIREMOD) ++ MCF5282_GPIO_DDRQS |= SPI_CS_MASK; ++ MCF5282_GPIO_PQSPAR &= ~SPI_CS_MASK; ++#endif ++ } ++ ++ if (command & QSPI_CS_ASSERT) { ++ MCF5282_GPIO_PORTQS &= ~SPI_CS_MASK; ++ MCF5282_GPIO_PORTQS |= cs_mask; ++ } else if (command & QSPI_CS_DROP) { ++ MCF5282_GPIO_PORTQS |= SPI_CS_MASK; ++ } ++} ++ ++static int __init spi_dev_init(void) ++{ ++ int retval; ++ ++ retval = platform_device_register(&coldfire_spi); ++ if (retval < 0) ++ return retval; ++ ++ if (ARRAY_SIZE(spi_board_info)) ++ retval = spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); ++ ++ return retval; ++} ++ ++#endif /* CONFIG_SPI */ + + /***************************************************************************/ + +-/* +- * DMA channel base address table. +- */ +-unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = { +- MCF_MBAR + MCFDMA_BASE0, ++static struct mcf_platform_uart m528x_uart_platform[] = { ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE1, ++ .irq = MCFINT_VECBASE + MCFINT_UART0, ++ }, ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE2, ++ .irq = MCFINT_VECBASE + MCFINT_UART0 + 1, ++ }, ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE3, ++ .irq = MCFINT_VECBASE + MCFINT_UART0 + 2, ++ }, ++ { }, ++}; ++ ++static struct platform_device m528x_uart = { ++ .name = "mcfuart", ++ .id = 0, ++ .dev.platform_data = m528x_uart_platform, ++}; ++ ++static struct platform_device *m528x_devices[] __initdata = { ++ &m528x_uart, + }; + +-unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS]; ++/***************************************************************************/ ++ ++#define INTC0 (MCF_MBAR + MCFICM_INTC0) ++ ++static void __init m528x_uart_init_line(int line, int irq) ++{ ++ u8 port; ++ u32 imr; ++ ++ if ((line < 0) || (line > 2)) ++ return; ++ ++ /* level 6, line based priority */ ++ writeb(0x30+line, INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line); ++ ++ imr = readl(INTC0 + MCFINTC_IMRL); ++ imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1); ++ writel(imr, INTC0 + MCFINTC_IMRL); ++ ++ /* make sure PUAPAR is set for UART0 and UART1 */ ++ if (line < 2) { ++ port = readb(MCF_MBAR + MCF5282_GPIO_PUAPAR); ++ port |= (0x03 << (line * 2)); ++ writeb(port, MCF_MBAR + MCF5282_GPIO_PUAPAR); ++ } ++} ++ ++static void __init m528x_uarts_init(void) ++{ ++ const int nrlines = ARRAY_SIZE(m528x_uart_platform); ++ int line; ++ ++ for (line = 0; (line < nrlines); line++) ++ m528x_uart_init_line(line, m528x_uart_platform[line].irq); ++} + + /***************************************************************************/ + +@@ -54,10 +342,57 @@ void mcf_autovector(unsigned int vec) + + /***************************************************************************/ + +-void config_BSP(char *commandp, int size) ++#ifdef CONFIG_WILDFIRE ++void wildfire_halt (void) ++{ ++ writeb(0, 0x30000007); ++ writeb(0x2, 0x30000007); ++} ++#endif ++ ++#ifdef CONFIG_WILDFIREMOD ++void wildfiremod_halt (void) ++{ ++ printk("WildFireMod hibernating...\n"); ++ ++ /* Set portE.5 to Digital IO */ ++ MCF5282_GPIO_PEPAR &= ~(1 << (5 * 2)); ++ ++ /* Make portE.5 an output */ ++ MCF5282_GPIO_DDRE |= (1 << 5); ++ ++ /* Now toggle portE.5 from low to high */ ++ MCF5282_GPIO_PORTE &= ~(1 << 5); ++ MCF5282_GPIO_PORTE |= (1 << 5); ++ ++ printk("Failed to hibernate. Halting!\n"); ++} ++#endif ++ ++void __init config_BSP(char *commandp, int size) + { + mcf_disableall(); +- mach_reset = coldfire_reset; ++ ++#ifdef CONFIG_WILDFIRE ++ mach_halt = wildfire_halt; ++#endif ++#ifdef CONFIG_WILDFIREMOD ++ mach_halt = wildfiremod_halt; ++#endif ++} ++ ++/***************************************************************************/ ++ ++static int __init init_BSP(void) ++{ ++ m528x_uarts_init(); ++#ifdef CONFIG_SPI ++ spi_dev_init(); ++#endif ++ platform_add_devices(m528x_devices, ARRAY_SIZE(m528x_devices)); ++ return 0; + } + ++arch_initcall(init_BSP); ++ + /***************************************************************************/ +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/5307/Makefile +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/platform/5307/Makefile 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/5307/Makefile 2008-10-08 22:22:55.000000000 -0400 +@@ -16,17 +16,5 @@ ifdef CONFIG_FULLDEBUG + EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 + endif + +-obj-$(CONFIG_COLDFIRE) += entry.o vectors.o +-obj-$(CONFIG_M5206) += timers.o +-obj-$(CONFIG_M5206e) += timers.o +-obj-$(CONFIG_M520x) += pit.o +-obj-$(CONFIG_M523x) += pit.o +-obj-$(CONFIG_M5249) += timers.o +-obj-$(CONFIG_M527x) += pit.o +-obj-$(CONFIG_M5272) += timers.o +-obj-$(CONFIG_M5307) += config.o timers.o +-obj-$(CONFIG_M532x) += timers.o +-obj-$(CONFIG_M528x) += pit.o +-obj-$(CONFIG_M5407) += timers.o ++obj-y += config.o + +-extra-y := head.o +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/5307/config.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/platform/5307/config.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/5307/config.c 2008-10-08 22:22:55.000000000 -0400 +@@ -13,11 +13,11 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include +-#include ++#include + #include + + /***************************************************************************/ +@@ -38,17 +38,51 @@ unsigned char ledbank = 0xff; + + /***************************************************************************/ + +-/* +- * DMA channel base address table. +- */ +-unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = { +- MCF_MBAR + MCFDMA_BASE0, +- MCF_MBAR + MCFDMA_BASE1, +- MCF_MBAR + MCFDMA_BASE2, +- MCF_MBAR + MCFDMA_BASE3, ++static struct mcf_platform_uart m5307_uart_platform[] = { ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE1, ++ .irq = 73, ++ }, ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE2, ++ .irq = 74, ++ }, ++ { }, ++}; ++ ++static struct platform_device m5307_uart = { ++ .name = "mcfuart", ++ .id = 0, ++ .dev.platform_data = m5307_uart_platform, + }; + +-unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS]; ++static struct platform_device *m5307_devices[] __initdata = { ++ &m5307_uart, ++}; ++ ++/***************************************************************************/ ++ ++static void __init m5307_uart_init_line(int line, int irq) ++{ ++ if (line == 0) { ++ writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR); ++ writeb(irq, MCFUART_BASE1 + MCFUART_UIVR); ++ mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1); ++ } else if (line == 1) { ++ writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR); ++ writeb(irq, MCFUART_BASE2 + MCFUART_UIVR); ++ mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2); ++ } ++} ++ ++static void __init m5307_uarts_init(void) ++{ ++ const int nrlines = ARRAY_SIZE(m5307_uart_platform); ++ int line; ++ ++ for (line = 0; (line < nrlines); line++) ++ m5307_uart_init_line(line, m5307_uart_platform[line].irq); ++} + + /***************************************************************************/ + +@@ -85,27 +119,12 @@ void mcf_settimericr(unsigned int timer, + + /***************************************************************************/ + +-int mcf_timerirqpending(int timer) +-{ +- unsigned int imr = 0; +- +- switch (timer) { +- case 1: imr = MCFSIM_IMR_TIMER1; break; +- case 2: imr = MCFSIM_IMR_TIMER2; break; +- default: break; +- } +- return (mcf_getipr() & imr); +-} +- +-/***************************************************************************/ +- +-void config_BSP(char *commandp, int size) ++void __init config_BSP(char *commandp, int size) + { + mcf_setimr(MCFSIM_IMR_MASKALL); + + #if defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \ +- defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3) || \ +- defined(CONFIG_CLEOPATRA) ++ defined(CONFIG_SECUREEDGEMP3) || defined(CONFIG_CLEOPATRA) + /* Copy command line from FLASH to local buffer... */ + memcpy(commandp, (char *) 0xf0004000, size); + commandp[size-1] = 0; +@@ -117,7 +136,7 @@ void config_BSP(char *commandp, int size + + mach_reset = coldfire_reset; + +-#ifdef MCF_BDM_DISABLE ++#ifdef CONFIG_BDM_DISABLE + /* + * Disable the BDM clocking. This also turns off most of the rest of + * the BDM device. This is good for EMC reasons. This option is not +@@ -128,3 +147,14 @@ void config_BSP(char *commandp, int size + } + + /***************************************************************************/ ++ ++static int __init init_BSP(void) ++{ ++ m5307_uarts_init(); ++ platform_add_devices(m5307_devices, ARRAY_SIZE(m5307_devices)); ++ return 0; ++} ++ ++arch_initcall(init_BSP); ++ ++/***************************************************************************/ +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/5307/entry.S +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/platform/5307/entry.S 2008-10-08 22:22:48.000000000 -0400 ++++ /dev/null 1970-01-01 00:00:00.000000000 +0000 +@@ -1,235 +0,0 @@ +-/* +- * linux/arch/m68knommu/platform/5307/entry.S +- * +- * Copyright (C) 1999-2007, Greg Ungerer (gerg@snapgear.com) +- * Copyright (C) 1998 D. Jeff Dionne , +- * Kenneth Albanowski , +- * Copyright (C) 2000 Lineo Inc. (www.lineo.com) +- * Copyright (C) 2004-2006 Macq Electronique SA. (www.macqel.com) +- * +- * Based on: +- * +- * linux/arch/m68k/kernel/entry.S +- * +- * Copyright (C) 1991, 1992 Linus Torvalds +- * +- * This file is subject to the terms and conditions of the GNU General Public +- * License. See the file README.legal in the main directory of this archive +- * for more details. +- * +- * Linux/m68k support by Hamish Macdonald +- * +- * 68060 fixes by Jesper Skov +- * ColdFire support by Greg Ungerer (gerg@snapgear.com) +- * 5307 fixes by David W. Miller +- * linux 2.4 support David McCullough +- * Bug, speed and maintainability fixes by Philippe De Muyter +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-.bss +- +-sw_ksp: +-.long 0 +- +-sw_usp: +-.long 0 +- +-.text +- +-.globl system_call +-.globl resume +-.globl ret_from_exception +-.globl ret_from_signal +-.globl sys_call_table +-.globl ret_from_interrupt +-.globl inthandler +-.globl fasthandler +- +-enosys: +- mov.l #sys_ni_syscall,%d3 +- bra 1f +- +-ENTRY(system_call) +- SAVE_ALL +- move #0x2000,%sr /* enable intrs again */ +- +- cmpl #NR_syscalls,%d0 +- jcc enosys +- lea sys_call_table,%a0 +- lsll #2,%d0 /* movel %a0@(%d0:l:4),%d3 */ +- movel %a0@(%d0),%d3 +- jeq enosys +- +-1: +- movel %sp,%d2 /* get thread_info pointer */ +- andl #-THREAD_SIZE,%d2 /* at start of kernel stack */ +- movel %d2,%a0 +- movel %a0@,%a1 /* save top of frame */ +- movel %sp,%a1@(TASK_THREAD+THREAD_ESP0) +- btst #(TIF_SYSCALL_TRACE%8),%a0@(TI_FLAGS+(31-TIF_SYSCALL_TRACE)/8) +- bnes 1f +- +- movel %d3,%a0 +- jbsr %a0@ +- movel %d0,%sp@(PT_D0) /* save the return value */ +- jra ret_from_exception +-1: +- movel #-ENOSYS,%d2 /* strace needs -ENOSYS in PT_D0 */ +- movel %d2,PT_D0(%sp) /* on syscall entry */ +- subql #4,%sp +- SAVE_SWITCH_STACK +- jbsr syscall_trace +- RESTORE_SWITCH_STACK +- addql #4,%sp +- movel %d3,%a0 +- jbsr %a0@ +- movel %d0,%sp@(PT_D0) /* save the return value */ +- subql #4,%sp /* dummy return address */ +- SAVE_SWITCH_STACK +- jbsr syscall_trace +- +-ret_from_signal: +- RESTORE_SWITCH_STACK +- addql #4,%sp +- +-ret_from_exception: +- btst #5,%sp@(PT_SR) /* check if returning to kernel */ +- jeq Luser_return /* if so, skip resched, signals */ +- +-Lkernel_return: +- moveml %sp@,%d1-%d5/%a0-%a2 +- lea %sp@(32),%sp /* space for 8 regs */ +- movel %sp@+,%d0 +- addql #4,%sp /* orig d0 */ +- addl %sp@+,%sp /* stk adj */ +- rte +- +-Luser_return: +- movel %sp,%d1 /* get thread_info pointer */ +- andl #-THREAD_SIZE,%d1 /* at base of kernel stack */ +- movel %d1,%a0 +- movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */ +- andl #_TIF_WORK_MASK,%d1 +- jne Lwork_to_do /* still work to do */ +- +-Lreturn: +- move #0x2700,%sr /* disable intrs */ +- movel sw_usp,%a0 /* get usp */ +- movel %sp@(PT_PC),%a0@- /* copy exception program counter */ +- movel %sp@(PT_FORMATVEC),%a0@-/* copy exception format/vector/sr */ +- moveml %sp@,%d1-%d5/%a0-%a2 +- lea %sp@(32),%sp /* space for 8 regs */ +- movel %sp@+,%d0 +- addql #4,%sp /* orig d0 */ +- addl %sp@+,%sp /* stk adj */ +- addql #8,%sp /* remove exception */ +- movel %sp,sw_ksp /* save ksp */ +- subql #8,sw_usp /* set exception */ +- movel sw_usp,%sp /* restore usp */ +- rte +- +-Lwork_to_do: +- movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */ +- btst #TIF_NEED_RESCHED,%d1 +- jne reschedule +- +- /* GERG: do we need something here for TRACEing?? */ +- +-Lsignal_return: +- subql #4,%sp /* dummy return address */ +- SAVE_SWITCH_STACK +- pea %sp@(SWITCH_STACK_SIZE) +- clrl %sp@- +- jsr do_signal +- addql #8,%sp +- RESTORE_SWITCH_STACK +- addql #4,%sp +- jmp Lreturn +- +-/* +- * This is the generic interrupt handler (for all hardware interrupt +- * sources). Calls upto high level code to do all the work. +- */ +-ENTRY(inthandler) +- SAVE_ALL +- moveq #-1,%d0 +- movel %d0,%sp@(PT_ORIG_D0) +- +- movew %sp@(PT_FORMATVEC),%d0 /* put exception # in d0 */ +- andl #0x03fc,%d0 /* mask out vector only */ +- +- movel %sp,%sp@- /* push regs arg */ +- lsrl #2,%d0 /* calculate real vector # */ +- movel %d0,%sp@- /* push vector number */ +- jbsr do_IRQ /* call high level irq handler */ +- lea %sp@(8),%sp /* pop args off stack */ +- +- bra ret_from_interrupt /* this was fallthrough */ +- +-/* +- * This is the fast interrupt handler (for certain hardware interrupt +- * sources). Unlike the normal interrupt handler it just uses the +- * current stack (doesn't care if it is user or kernel). It also +- * doesn't bother doing the bottom half handlers. +- */ +-ENTRY(fasthandler) +- SAVE_LOCAL +- +- movew %sp@(PT_FORMATVEC),%d0 +- andl #0x03fc,%d0 /* mask out vector only */ +- +- movel %sp,%sp@- /* push regs arg */ +- lsrl #2,%d0 /* calculate real vector # */ +- movel %d0,%sp@- /* push vector number */ +- jbsr do_IRQ /* call high level irq handler */ +- lea %sp@(8),%sp /* pop args off stack */ +- +- RESTORE_LOCAL +- +-ENTRY(ret_from_interrupt) +- jeq 2f +-1: +- RESTORE_ALL +-2: +- moveb %sp@(PT_SR),%d0 +- andl #0x7,%d0 +- jhi 1b +- +- /* check if we need to do software interrupts */ +- movel irq_stat+CPUSTAT_SOFTIRQ_PENDING,%d0 +- jeq ret_from_exception +- +- pea ret_from_exception +- jmp do_softirq +- +-/* +- * Beware - when entering resume, prev (the current task) is +- * in a0, next (the new task) is in a1,so don't change these +- * registers until their contents are no longer needed. +- * This is always called in supervisor mode, so don't bother to save +- * and restore sr; user's process sr is actually in the stack. +- */ +-ENTRY(resume) +- movel %a0, %d1 /* get prev thread in d1 */ +- +- movel sw_usp,%d0 /* save usp */ +- movel %d0,%a0@(TASK_THREAD+THREAD_USP) +- +- SAVE_SWITCH_STACK +- movel %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack pointer */ +- movel %a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new thread stack */ +- RESTORE_SWITCH_STACK +- +- movel %a1@(TASK_THREAD+THREAD_USP),%a0 /* restore thread user stack */ +- movel %a0, sw_usp +- rts +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/5307/head.S +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/platform/5307/head.S 2008-10-08 22:22:48.000000000 -0400 ++++ /dev/null 1970-01-01 00:00:00.000000000 +0000 +@@ -1,222 +0,0 @@ +-/*****************************************************************************/ +- +-/* +- * head.S -- common startup code for ColdFire CPUs. +- * +- * (C) Copyright 1999-2006, Greg Ungerer . +- */ +- +-/*****************************************************************************/ +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-/*****************************************************************************/ +- +-/* +- * If we don't have a fixed memory size, then lets build in code +- * to auto detect the DRAM size. Obviously this is the prefered +- * method, and should work for most boards. It won't work for those +- * that do not have their RAM starting at address 0, and it only +- * works on SDRAM (not boards fitted with SRAM). +- */ +-#if CONFIG_RAMSIZE != 0 +-.macro GET_MEM_SIZE +- movel #CONFIG_RAMSIZE,%d0 /* hard coded memory size */ +-.endm +- +-#elif defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ +- defined(CONFIG_M5249) || defined(CONFIG_M527x) || \ +- defined(CONFIG_M528x) || defined(CONFIG_M5307) || \ +- defined(CONFIG_M5407) +-/* +- * Not all these devices have exactly the same DRAM controller, +- * but the DCMR register is virtually identical - give or take +- * a couple of bits. The only exception is the 5272 devices, their +- * DRAM controller is quite different. +- */ +-.macro GET_MEM_SIZE +- movel MCF_MBAR+MCFSIM_DMR0,%d0 /* get mask for 1st bank */ +- btst #0,%d0 /* check if region enabled */ +- beq 1f +- andl #0xfffc0000,%d0 +- beq 1f +- addl #0x00040000,%d0 /* convert mask to size */ +-1: +- movel MCF_MBAR+MCFSIM_DMR1,%d1 /* get mask for 2nd bank */ +- btst #0,%d1 /* check if region enabled */ +- beq 2f +- andl #0xfffc0000, %d1 +- beq 2f +- addl #0x00040000,%d1 +- addl %d1,%d0 /* total mem size in d0 */ +-2: +-.endm +- +-#elif defined(CONFIG_M5272) +-.macro GET_MEM_SIZE +- movel MCF_MBAR+MCFSIM_CSOR7,%d0 /* get SDRAM address mask */ +- andil #0xfffff000,%d0 /* mask out chip select options */ +- negl %d0 /* negate bits */ +-.endm +- +-#elif defined(CONFIG_M520x) +-.macro GET_MEM_SIZE +- clrl %d0 +- movel MCF_MBAR+MCFSIM_SDCS0, %d2 /* Get SDRAM chip select 0 config */ +- andl #0x1f, %d2 /* Get only the chip select size */ +- beq 3f /* Check if it is enabled */ +- addql #1, %d2 /* Form exponent */ +- moveql #1, %d0 +- lsll %d2, %d0 /* 2 ^ exponent */ +-3: +- movel MCF_MBAR+MCFSIM_SDCS1, %d2 /* Get SDRAM chip select 1 config */ +- andl #0x1f, %d2 /* Get only the chip select size */ +- beq 4f /* Check if it is enabled */ +- addql #1, %d2 /* Form exponent */ +- moveql #1, %d1 +- lsll %d2, %d1 /* 2 ^ exponent */ +- addl %d1, %d0 /* Total size of SDRAM in d0 */ +-4: +-.endm +- +-#else +-#error "ERROR: I don't know how to probe your boards memory size?" +-#endif +- +-/*****************************************************************************/ +- +-/* +- * Boards and platforms can do specific early hardware setup if +- * they need to. Most don't need this, define away if not required. +- */ +-#ifndef PLATFORM_SETUP +-#define PLATFORM_SETUP +-#endif +- +-/*****************************************************************************/ +- +-.global _start +-.global _rambase +-.global _ramvec +-.global _ramstart +-.global _ramend +- +-/*****************************************************************************/ +- +-.data +- +-/* +- * During startup we store away the RAM setup. These are not in the +- * bss, since their values are determined and written before the bss +- * has been cleared. +- */ +-_rambase: +-.long 0 +-_ramvec: +-.long 0 +-_ramstart: +-.long 0 +-_ramend: +-.long 0 +- +-/*****************************************************************************/ +- +-.text +- +-/* +- * This is the codes first entry point. This is where it all +- * begins... +- */ +- +-_start: +- nop /* filler */ +- movew #0x2700, %sr /* no interrupts */ +- +- /* +- * Do any platform or board specific setup now. Most boards +- * don't need anything. Those exceptions are define this in +- * their board specific includes. +- */ +- PLATFORM_SETUP +- +- /* +- * Create basic memory configuration. Set VBR accordingly, +- * and size memory. +- */ +- movel #CONFIG_VECTORBASE,%a7 +- movec %a7,%VBR /* set vectors addr */ +- movel %a7,_ramvec +- +- movel #CONFIG_RAMBASE,%a7 /* mark the base of RAM */ +- movel %a7,_rambase +- +- GET_MEM_SIZE /* macro code determines size */ +- addl %a7,%d0 +- movel %d0,_ramend /* set end ram addr */ +- +- /* +- * Now that we know what the memory is, lets enable cache +- * and get things moving. This is Coldfire CPU specific. +- */ +- CACHE_ENABLE /* enable CPU cache */ +- +- +-#ifdef CONFIG_ROMFS_FS +- /* +- * Move ROM filesystem above bss :-) +- */ +- lea _sbss,%a0 /* get start of bss */ +- lea _ebss,%a1 /* set up destination */ +- movel %a0,%a2 /* copy of bss start */ +- +- movel 8(%a0),%d0 /* get size of ROMFS */ +- addql #8,%d0 /* allow for rounding */ +- andl #0xfffffffc, %d0 /* whole words */ +- +- addl %d0,%a0 /* copy from end */ +- addl %d0,%a1 /* copy from end */ +- movel %a1,_ramstart /* set start of ram */ +- +-_copy_romfs: +- movel -(%a0),%d0 /* copy dword */ +- movel %d0,-(%a1) +- cmpl %a0,%a2 /* check if at end */ +- bne _copy_romfs +- +-#else /* CONFIG_ROMFS_FS */ +- lea _ebss,%a1 +- movel %a1,_ramstart +-#endif /* CONFIG_ROMFS_FS */ +- +- +- /* +- * Zero out the bss region. +- */ +- lea _sbss,%a0 /* get start of bss */ +- lea _ebss,%a1 /* get end of bss */ +- clrl %d0 /* set value */ +-_clear_bss: +- movel %d0,(%a0)+ /* clear each word */ +- cmpl %a0,%a1 /* check if at end */ +- bne _clear_bss +- +- /* +- * Load the current task pointer and stack. +- */ +- lea init_thread_union,%a0 +- lea THREAD_SIZE(%a0),%sp +- +- /* +- * Assember start up done, start code proper. +- */ +- jsr start_kernel /* start Linux kernel */ +- +-_exit: +- jmp _exit /* should never get here */ +- +-/*****************************************************************************/ +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/5307/pit.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/platform/5307/pit.c 2008-10-08 22:22:48.000000000 -0400 ++++ /dev/null 1970-01-01 00:00:00.000000000 +0000 +@@ -1,97 +0,0 @@ +-/***************************************************************************/ +- +-/* +- * pit.c -- Freescale ColdFire PIT timer. Currently this type of +- * hardware timer only exists in the Freescale ColdFire +- * 5270/5271, 5282 and other CPUs. +- * +- * Copyright (C) 1999-2007, Greg Ungerer (gerg@snapgear.com) +- * Copyright (C) 2001-2004, SnapGear Inc. (www.snapgear.com) +- */ +- +-/***************************************************************************/ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-/***************************************************************************/ +- +-/* +- * By default use timer1 as the system clock timer. +- */ +-#define TA(a) (MCF_IPSBAR + MCFPIT_BASE1 + (a)) +- +-/***************************************************************************/ +- +-static irqreturn_t hw_tick(int irq, void *dummy) +-{ +- unsigned short pcsr; +- +- /* Reset the ColdFire timer */ +- pcsr = __raw_readw(TA(MCFPIT_PCSR)); +- __raw_writew(pcsr | MCFPIT_PCSR_PIF, TA(MCFPIT_PCSR)); +- +- return arch_timer_interrupt(irq, dummy); +-} +- +-/***************************************************************************/ +- +-static struct irqaction coldfire_pit_irq = { +- .name = "timer", +- .flags = IRQF_DISABLED | IRQF_TIMER, +- .handler = hw_tick, +-}; +- +-void hw_timer_init(void) +-{ +- volatile unsigned char *icrp; +- volatile unsigned long *imrp; +- +- setup_irq(MCFINT_VECBASE + MCFINT_PIT1, &coldfire_pit_irq); +- +- icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 + +- MCFINTC_ICR0 + MCFINT_PIT1); +- *icrp = ICR_INTRCONF; +- +- imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFPIT_IMR); +- *imrp &= ~MCFPIT_IMR_IBIT; +- +- /* Set up PIT timer 1 as poll clock */ +- __raw_writew(MCFPIT_PCSR_DISABLE, TA(MCFPIT_PCSR)); +- __raw_writew(((MCF_CLK / 2) / 64) / HZ, TA(MCFPIT_PMR)); +- __raw_writew(MCFPIT_PCSR_EN | MCFPIT_PCSR_PIE | MCFPIT_PCSR_OVW | +- MCFPIT_PCSR_RLD | MCFPIT_PCSR_CLK64, TA(MCFPIT_PCSR)); +-} +- +-/***************************************************************************/ +- +-unsigned long hw_timer_offset(void) +-{ +- volatile unsigned long *ipr; +- unsigned long pmr, pcntr, offset; +- +- ipr = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFPIT_IMR); +- +- pmr = __raw_readw(TA(MCFPIT_PMR)); +- pcntr = __raw_readw(TA(MCFPIT_PCNTR)); +- +- /* +- * If we are still in the first half of the upcount and a +- * timer interrupt is pending, then add on a ticks worth of time. +- */ +- offset = ((pmr - pcntr) * (1000000 / HZ)) / pmr; +- if ((offset < (1000000 / HZ / 2)) && (*ipr & MCFPIT_IMR_IBIT)) +- offset += 1000000 / HZ; +- return offset; +-} +- +-/***************************************************************************/ +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/5307/timers.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/platform/5307/timers.c 2008-10-08 22:22:48.000000000 -0400 ++++ /dev/null 1970-01-01 00:00:00.000000000 +0000 +@@ -1,155 +0,0 @@ +-/***************************************************************************/ +- +-/* +- * timers.c -- generic ColdFire hardware timer support. +- * +- * Copyright (C) 1999-2007, Greg Ungerer (gerg@snapgear.com) +- */ +- +-/***************************************************************************/ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-/***************************************************************************/ +- +-/* +- * By default use timer1 as the system clock timer. +- */ +-#define TA(a) (MCF_MBAR + MCFTIMER_BASE1 + (a)) +- +-/* +- * Default the timer and vector to use for ColdFire. Some ColdFire +- * CPU's and some boards may want different. Their sub-architecture +- * startup code (in config.c) can change these if they want. +- */ +-unsigned int mcf_timervector = 29; +-unsigned int mcf_profilevector = 31; +-unsigned int mcf_timerlevel = 5; +- +-/* +- * These provide the underlying interrupt vector support. +- * Unfortunately it is a little different on each ColdFire. +- */ +-extern void mcf_settimericr(int timer, int level); +-extern int mcf_timerirqpending(int timer); +- +-#if defined(CONFIG_M532x) +-#define __raw_readtrr __raw_readl +-#define __raw_writetrr __raw_writel +-#else +-#define __raw_readtrr __raw_readw +-#define __raw_writetrr __raw_writew +-#endif +- +-/***************************************************************************/ +- +-static irqreturn_t hw_tick(int irq, void *dummy) +-{ +- /* Reset the ColdFire timer */ +- __raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, TA(MCFTIMER_TER)); +- +- return arch_timer_interrupt(irq, dummy); +-} +- +-/***************************************************************************/ +- +-static struct irqaction coldfire_timer_irq = { +- .name = "timer", +- .flags = IRQF_DISABLED | IRQF_TIMER, +- .handler = hw_tick, +-}; +- +-/***************************************************************************/ +- +-static int ticks_per_intr; +- +-void hw_timer_init(void) +-{ +- setup_irq(mcf_timervector, &coldfire_timer_irq); +- +- __raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR)); +- ticks_per_intr = (MCF_BUSCLK / 16) / HZ; +- __raw_writetrr(ticks_per_intr - 1, TA(MCFTIMER_TRR)); +- __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | +- MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, TA(MCFTIMER_TMR)); +- +- mcf_settimericr(1, mcf_timerlevel); +- +-#ifdef CONFIG_HIGHPROFILE +- coldfire_profile_init(); +-#endif +-} +- +-/***************************************************************************/ +- +-unsigned long hw_timer_offset(void) +-{ +- unsigned long tcn, offset; +- +- tcn = __raw_readw(TA(MCFTIMER_TCN)); +- offset = ((tcn + 1) * (1000000 / HZ)) / ticks_per_intr; +- +- /* Check if we just wrapped the counters and maybe missed a tick */ +- if ((offset < (1000000 / HZ / 2)) && mcf_timerirqpending(1)) +- offset += 1000000 / HZ; +- return offset; +-} +- +-/***************************************************************************/ +-#ifdef CONFIG_HIGHPROFILE +-/***************************************************************************/ +- +-/* +- * By default use timer2 as the profiler clock timer. +- */ +-#define PA(a) (MCF_MBAR + MCFTIMER_BASE2 + (a)) +- +-/* +- * Choose a reasonably fast profile timer. Make it an odd value to +- * try and get good coverage of kernel operations. +- */ +-#define PROFILEHZ 1013 +- +-/* +- * Use the other timer to provide high accuracy profiling info. +- */ +-irqreturn_t coldfire_profile_tick(int irq, void *dummy) +-{ +- /* Reset ColdFire timer2 */ +- __raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, PA(MCFTIMER_TER)); +- if (current->pid) +- profile_tick(CPU_PROFILING, regs); +- return IRQ_HANDLED; +-} +- +-/***************************************************************************/ +- +-void coldfire_profile_init(void) +-{ +- printk(KERN_INFO "PROFILE: lodging TIMER2 @ %dHz as profile timer\n", PROFILEHZ); +- +- /* Set up TIMER 2 as high speed profile clock */ +- __raw_writew(MCFTIMER_TMR_DISABLE, PA(MCFTIMER_TMR)); +- +- __raw_writetrr(((MCF_CLK / 16) / PROFILEHZ), PA(MCFTIMER_TRR)); +- __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | +- MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, PA(MCFTIMER_TMR)); +- +- request_irq(mcf_profilevector, coldfire_profile_tick, +- (IRQF_DISABLED | IRQ_FLG_FAST), "profile timer", NULL); +- mcf_settimericr(2, 7); +-} +- +-/***************************************************************************/ +-#endif /* CONFIG_HIGHPROFILE */ +-/***************************************************************************/ +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/5307/vectors.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/platform/5307/vectors.c 2008-10-08 22:22:48.000000000 -0400 ++++ /dev/null 1970-01-01 00:00:00.000000000 +0000 +@@ -1,105 +0,0 @@ +-/***************************************************************************/ +- +-/* +- * linux/arch/m68knommu/platform/5307/vectors.c +- * +- * Copyright (C) 1999-2007, Greg Ungerer +- */ +- +-/***************************************************************************/ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-/***************************************************************************/ +- +-#ifdef TRAP_DBG_INTERRUPT +- +-asmlinkage void dbginterrupt_c(struct frame *fp) +-{ +- extern void dump(struct pt_regs *fp); +- printk(KERN_DEBUG "%s(%d): BUS ERROR TRAP\n", __FILE__, __LINE__); +- dump((struct pt_regs *) fp); +- asm("halt"); +-} +- +-#endif +- +-/***************************************************************************/ +- +-extern e_vector *_ramvec; +- +-void set_evector(int vecnum, void (*handler)(void)) +-{ +- if (vecnum >= 0 && vecnum <= 255) +- _ramvec[vecnum] = handler; +-} +- +-/***************************************************************************/ +- +-/* Assembler routines */ +-asmlinkage void buserr(void); +-asmlinkage void trap(void); +-asmlinkage void system_call(void); +-asmlinkage void inthandler(void); +- +-void __init init_vectors(void) +-{ +- int i; +- +- /* +- * There is a common trap handler and common interrupt +- * handler that handle almost every vector. We treat +- * the system call and bus error special, they get their +- * own first level handlers. +- */ +- for (i = 3; (i <= 23); i++) +- _ramvec[i] = trap; +- for (i = 33; (i <= 63); i++) +- _ramvec[i] = trap; +- for (i = 24; (i <= 31); i++) +- _ramvec[i] = inthandler; +- for (i = 64; (i < 255); i++) +- _ramvec[i] = inthandler; +- _ramvec[255] = 0; +- +- _ramvec[2] = buserr; +- _ramvec[32] = system_call; +- +-#ifdef TRAP_DBG_INTERRUPT +- _ramvec[12] = dbginterrupt; +-#endif +-} +- +-/***************************************************************************/ +- +-void enable_vector(unsigned int irq) +-{ +- /* Currently no action on ColdFire */ +-} +- +-void disable_vector(unsigned int irq) +-{ +- /* Currently no action on ColdFire */ +-} +- +-void ack_vector(unsigned int irq) +-{ +- /* Currently no action on ColdFire */ +-} +- +-/***************************************************************************/ +- +-void coldfire_reset(void) +-{ +- HARD_RESET_NOW(); +-} +- +-/***************************************************************************/ +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/532x/config.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/platform/532x/config.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/532x/config.c 2008-10-08 22:22:55.000000000 -0400 +@@ -21,10 +21,11 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include ++#include + #include + #include + +@@ -38,11 +39,75 @@ extern unsigned int mcf_timerlevel; + + /***************************************************************************/ + +-/* +- * DMA channel base address table. +- */ +-unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = { }; +-unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS]; ++int sys_clk_khz = 0; ++int sys_clk_mhz = 0; ++ ++void wtm_init(void); ++void scm_init(void); ++void gpio_init(void); ++void fbcs_init(void); ++void sdramc_init(void); ++int clock_pll (int fsys, int flags); ++int clock_limp (int); ++int clock_exit_limp (void); ++int get_sys_clock (void); ++ ++/***************************************************************************/ ++ ++static struct mcf_platform_uart m532x_uart_platform[] = { ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE1, ++ .irq = MCFINT_VECBASE + MCFINT_UART0, ++ }, ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE2, ++ .irq = MCFINT_VECBASE + MCFINT_UART1, ++ }, ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE3, ++ .irq = MCFINT_VECBASE + MCFINT_UART2, ++ }, ++ { }, ++}; ++ ++static struct platform_device m532x_uart = { ++ .name = "mcfuart", ++ .id = 0, ++ .dev.platform_data = m532x_uart_platform, ++}; ++ ++static struct platform_device *m532x_devices[] __initdata = { ++ &m532x_uart, ++}; ++ ++/***************************************************************************/ ++ ++static void __init m532x_uart_init_line(int line, int irq) ++{ ++ if (line == 0) { ++ MCF_INTC0_ICR26 = 0x3; ++ MCF_INTC0_CIMR = 26; ++ /* GPIO initialization */ ++ MCF_GPIO_PAR_UART |= 0x000F; ++ } else if (line == 1) { ++ MCF_INTC0_ICR27 = 0x3; ++ MCF_INTC0_CIMR = 27; ++ /* GPIO initialization */ ++ MCF_GPIO_PAR_UART |= 0x0FF0; ++ } else if (line == 2) { ++ MCF_INTC0_ICR28 = 0x3; ++ MCF_INTC0_CIMR = 28; ++ } ++} ++ ++static void __init m532x_uarts_init(void) ++{ ++ const int nrlines = ARRAY_SIZE(m532x_uart_platform); ++ int line; ++ ++ for (line = 0; (line < nrlines); line++) ++ m532x_uart_init_line(line, m532x_uart_platform[line].irq); ++} + + /***************************************************************************/ + +@@ -66,22 +131,11 @@ void mcf_settimericr(unsigned int timer, + + /***************************************************************************/ + +-int mcf_timerirqpending(int timer) ++void __init config_BSP(char *commandp, int size) + { +- unsigned int imr = 0; +- +- switch (timer) { +- case 1: imr = 0x1; break; +- case 2: imr = 0x2; break; +- default: break; +- } +- return (mcf_getiprh() & imr); +-} +- +-/***************************************************************************/ ++ sys_clk_khz = get_sys_clock(); ++ sys_clk_mhz = sys_clk_khz/1000; + +-void config_BSP(char *commandp, int size) +-{ + mcf_setimr(MCFSIM_IMR_MASKALL); + + #if !defined(CONFIG_BOOTPARAM) +@@ -99,7 +153,7 @@ void config_BSP(char *commandp, int size + mcf_profilevector = 64+33; + mach_reset = coldfire_reset; + +-#ifdef MCF_BDM_DISABLE ++#ifdef CONFIG_BDM_DISABLE + /* + * Disable the BDM clocking. This also turns off most of the rest of + * the BDM device. This is good for EMC reasons. This option is not +@@ -110,6 +164,17 @@ void config_BSP(char *commandp, int size + } + + /***************************************************************************/ ++ ++static int __init init_BSP(void) ++{ ++ m532x_uarts_init(); ++ platform_add_devices(m532x_devices, ARRAY_SIZE(m532x_devices)); ++ return 0; ++} ++ ++arch_initcall(init_BSP); ++ ++/***************************************************************************/ + /* Board initialization */ + + /********************************************************************/ +@@ -152,24 +217,9 @@ void config_BSP(char *commandp, int size + + #define NAND_FLASH_ADDRESS (0xD0000000) + +-int sys_clk_khz = 0; +-int sys_clk_mhz = 0; +- +-void wtm_init(void); +-void scm_init(void); +-void gpio_init(void); +-void fbcs_init(void); +-void sdramc_init(void); +-int clock_pll (int fsys, int flags); +-int clock_limp (int); +-int clock_exit_limp (void); +-int get_sys_clock (void); + + asmlinkage void __init sysinit(void) + { +- sys_clk_khz = clock_pll(0, 0); +- sys_clk_mhz = sys_clk_khz/1000; +- + wtm_init(); + scm_init(); + gpio_init(); +@@ -207,25 +257,61 @@ void scm_init(void) + + void fbcs_init(void) + { ++#if defined(CONFIG_COBRA5329) ++ /* The COBRA5329 by senTec needs this settings */ ++ ++ /* ++ * We need to give the LCD enough bandwidth ++ */ ++ ++ MCF_XBS_PRS1 = MCF_XBS_PRIO_LCD(MCF_PRIO_LVL_1) ++ | MCF_XBS_PRIO_CORE(MCF_PRIO_LVL_2) ++ | MCF_XBS_PRIO_FEC(MCF_PRIO_LVL_3) ++ | MCF_XBS_PRIO_USBHOST(MCF_PRIO_LVL_4) ++ | MCF_XBS_PRIO_EDMA(MCF_PRIO_LVL_5) ++ | MCF_XBS_PRIO_USBOTG(MCF_PRIO_LVL_6) ++ | MCF_XBS_PRIO_FACTTEST(MCF_PRIO_LVL_7); ++ ++ /* Boot Flash connected to FBCS0 */ ++ MCF_FBCS0_CSAR = FLASH_ADDRESS; ++ MCF_FBCS0_CSCR = (MCF_FBCS_CSCR_PS_16 ++ | MCF_FBCS_CSCR_BEM ++ | MCF_FBCS_CSCR_AA ++ | MCF_FBCS_CSCR_WS(8)); ++ ++ MCF_FBCS0_CSMR = (MCF_FBCS_CSMR_BAM_1G ++ | MCF_FBCS_CSMR_V); ++ ++ /* Fix bug #10 in the errata */ ++ MCF_FBCS1_CSAR = 0xC0000000; ++ MCF_FBCS1_CSCR = (MCF_FBCS_CSCR_PS_16 ++ | MCF_FBCS_CSCR_BEM ++ | MCF_FBCS_CSCR_AA ++ | MCF_FBCS_CSCR_WS(8)); ++ ++ MCF_FBCS1_CSMR = (0x30000000 ++ | MCF_FBCS_CSMR_V ++ | MCF_FBCS_CSMR_WP ); ++#else + MCF_GPIO_PAR_CS = 0x0000003E; + + /* Latch chip select */ + MCF_FBCS1_CSAR = 0x10080000; + +- MCF_FBCS1_CSCR = 0x002A3780; ++ MCF_FBCS1_CSCR = 0x002A3580 | (MCF_FBCS1_CSCR&0x200); + MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V); + + /* Initialize latch to drive signals to inactive states */ +- *((u16 *)(0x10080000)) = 0xFFFF; ++ *((u16 *)(0x10080000)) = 0xD3FF; + +- /* External SRAM */ +- MCF_FBCS1_CSAR = EXT_SRAM_ADDRESS; +- MCF_FBCS1_CSCR = (MCF_FBCS_CSCR_PS_16 +- | MCF_FBCS_CSCR_AA +- | MCF_FBCS_CSCR_SBM +- | MCF_FBCS_CSCR_WS(1)); +- MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_512K +- | MCF_FBCS_CSMR_V); ++// /* External SRAM */ ++// MCF_FBCS1_CSAR = EXT_SRAM_ADDRESS; ++// MCF_FBCS1_CSCR = (MCF_FBCS_CSCR_PS_16 ++// | MCF_FBCS_CSCR_AA ++// | MCF_FBCS_CSCR_SBM ++// | MCF_FBCS_CSCR_WS(1)); ++// MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_512K ++// | MCF_FBCS_CSMR_V); + + /* Boot Flash connected to FBCS0 */ + MCF_FBCS0_CSAR = FLASH_ADDRESS; +@@ -236,6 +322,7 @@ void fbcs_init(void) + | MCF_FBCS_CSCR_WS(7)); + MCF_FBCS0_CSMR = (MCF_FBCS_CSMR_BAM_32M + | MCF_FBCS_CSMR_V); ++#endif + } + + void sdramc_init(void) +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/532x/spi-mcf532x.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/532x/spi-mcf532x.c 2008-10-08 22:22:55.000000000 -0400 +@@ -0,0 +1,176 @@ ++/***************************************************************************/ ++/* ++ * linux/arch/m68knommu/platform/532x/spi-mcf532x.c ++ * ++ * Sub-architcture dependant initialization code for the Freescale ++ * 532x SPI module ++ * ++ * Yaroslav Vinogradov yaroslav.vinogradov@freescale.com ++ * Copyright Freescale Semiconductor, Inc 2006 ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++/***************************************************************************/ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define SPI_NUM_CHIPSELECTS 0x04 ++#define SPI_PAR_VAL 0xFFF0 /* Enable DIN, DOUT, CLK */ ++ ++#define MCF532x_QSPI_IRQ_SOURCE (31) ++#define MCF532x_QSPI_IRQ_VECTOR (64 + MCF532x_QSPI_IRQ_SOURCE) ++ ++#define MCF532x_QSPI_PAR (0xFC0A405A) ++#define MCF532x_QSPI_QMR (0xFC05C000) ++#define MCF532x_INTC0_ICR (0xFC048040) ++#define MCF532x_INTC0_IMRL (0xFC04800C) ++ ++/* on 5329 EVB ADS7843 is connected to IRQ4 */ ++#define ADS784x_IRQ_SOURCE 4 ++#define ADS784x_IRQ_VECTOR (64+ADS784x_IRQ_SOURCE) ++#define ADS7843_IRQ_LEVEL 2 ++ ++ ++void coldfire_qspi_cs_control(u8 cs, u8 command) ++{ ++} ++ ++#if defined(CONFIG_TOUCHSCREEN_ADS7843) ++static struct coldfire_spi_chip ads784x_chip_info = { ++ .mode = SPI_MODE_0, ++ .bits_per_word = 8, ++ .del_cs_to_clk = 17, ++ .del_after_trans = 1, ++ .void_write_data = 0 ++}; ++ ++static struct ads7843_platform_data ads784x_platform_data = { ++ .model = 7843, ++ .vref_delay_usecs = 0, ++ .x_plate_ohms = 580, ++ .y_plate_ohms = 410 ++}; ++#endif ++ ++ ++static struct spi_board_info spi_board_info[] = { ++#if defined(CONFIG_TOUCHSCREEN_ADS7843) ++ { ++ .modalias = "ads7843", ++ .max_speed_hz = 125000 * 16, ++ .bus_num = 1, ++ .chip_select = 1, ++ .irq = ADS784x_IRQ_VECTOR, ++ .platform_data = &ads784x_platform_data, ++ .controller_data = &ads784x_chip_info ++ } ++#endif ++}; ++ ++static struct coldfire_spi_master coldfire_master_info = { ++ .bus_num = 1, ++ .num_chipselect = SPI_NUM_CHIPSELECTS, ++ .irq_source = MCF532x_QSPI_IRQ_SOURCE, ++ .irq_vector = MCF532x_QSPI_IRQ_VECTOR, ++ .irq_mask = (0x01 << MCF532x_QSPI_IRQ_SOURCE), ++ .irq_lp = 0x5, /* Level */ ++ .par_val = 0, /* not used on 532x */ ++ .par_val16 = SPI_PAR_VAL, ++ .cs_control = coldfire_qspi_cs_control, ++}; ++ ++static struct resource coldfire_spi_resources[] = { ++ [0] = { ++ .name = "qspi-par", ++ .start = MCF532x_QSPI_PAR, ++ .end = MCF532x_QSPI_PAR, ++ .flags = IORESOURCE_MEM ++ }, ++ ++ [1] = { ++ .name = "qspi-module", ++ .start = MCF532x_QSPI_QMR, ++ .end = MCF532x_QSPI_QMR + 0x18, ++ .flags = IORESOURCE_MEM ++ }, ++ ++ [2] = { ++ .name = "qspi-int-level", ++ .start = MCF532x_INTC0_ICR + MCF532x_QSPI_IRQ_SOURCE, ++ .end = MCF532x_INTC0_ICR + MCF532x_QSPI_IRQ_SOURCE, ++ .flags = IORESOURCE_MEM ++ }, ++ ++ [3] = { ++ .name = "qspi-int-mask", ++ .start = MCF532x_INTC0_IMRL, ++ .end = MCF532x_INTC0_IMRL, ++ .flags = IORESOURCE_MEM ++ } ++}; ++ ++static struct platform_device coldfire_spi = { ++ .name = "coldfire-qspi", ++ .id = -1, ++ .resource = coldfire_spi_resources, ++ .num_resources = ARRAY_SIZE(coldfire_spi_resources), ++ .dev = { ++ .platform_data = &coldfire_master_info, ++ } ++}; ++ ++#if defined(CONFIG_TOUCHSCREEN_ADS7843) ++static int __init init_ads7843(void) ++{ ++ /* GPIO initiaalization */ ++ MCF_GPIO_PAR_IRQ = MCF_GPIO_PAR_IRQ_PAR_IRQ4(0); ++ /* EPORT initialization */ ++ MCF_EPORT_EPPAR = MCF_EPORT_EPPAR_EPPA4(MCF_EPORT_EPPAR_FALLING); ++ MCF_EPORT_EPDDR = 0; ++ MCF_EPORT_EPIER = MCF_EPORT_EPIER_EPIE4; ++ /* enable interrupt source */ ++ MCF_INTC0_ICR4 = ADS7843_IRQ_LEVEL; ++ MCF_INTC0_CIMR = ADS784x_IRQ_SOURCE; ++} ++#endif ++ ++static int __init spi_dev_init(void) ++{ ++ int retval = 0; ++#if defined(CONFIG_TOUCHSCREEN_ADS7843) ++ init_ads7843(); ++#endif ++ ++ retval = platform_device_register(&coldfire_spi); ++ if (retval < 0) ++ goto out; ++ ++ if (ARRAY_SIZE(spi_board_info)) ++ retval = spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); ++ ++ ++out: ++ return retval; ++} ++ ++arch_initcall(spi_dev_init); +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/532x/usb-mcf532x.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/532x/usb-mcf532x.c 2008-10-08 22:22:55.000000000 -0400 +@@ -0,0 +1,171 @@ ++/*************************************************************************** ++ * usb-mcf532x.c - Platform level (mcf532x) USB initialization. ++ * ++ * Andrey Butok Andrey.Butok@freescale.com. ++ * Copyright Freescale Semiconductor, Inc 2006 ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software Foundation, ++ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ *************************************************************************** ++ * Changes: ++ * v0.01 31 March 2006 Andrey Butok ++ * Initial Release - developed on uClinux with 2.6.15.6 kernel ++ * ++ * WARNING: The MCF532x USB functionality was tested ++ * only with low-speed USB devices (cause of HW bugs). ++ */ ++ ++#undef DEBUG ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Start address of HC registers.*/ ++#define MCF532x_USB_HOST_REG_START (0xfc0b4000) ++/* End address of HC registers */ ++#define MCF532x_USB_HOST_REG_END (MCF532x_USB_HOST_REG_START+0x200) ++/* USB Host Interrupt number */ ++#define MCF532x_USB_HOST_INT_NUMBER (128+48) ++ ++#ifdef CONFIG_USB_OTG ++/* Start address of OTG module registers.*/ ++#define MCF532x_USB_OTG_REG_START (0xfc0b0000) ++/* End address of OTG module registers */ ++#define MCF532x_USB_OTG_REG_END (MCF532x_USB_OTG_REG_START+0x200) ++/* USB OTG Interrupt number */ ++#define MCF532x_USB_OTG_INT_NUMBER (128+47) ++#endif ++ ++/*-------------------------------------------------------------------------*/ ++ ++static void ++usb_release(struct device *dev) ++{ ++ /* normally not freed */ ++} ++ ++/* ++ * USB Host module structures ++ */ ++static struct resource ehci_host_resources[] = { ++ { ++ .start = MCF532x_USB_HOST_REG_START, ++ .end = MCF532x_USB_HOST_REG_END, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = MCF532x_USB_HOST_INT_NUMBER, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device ehci_host_device = { ++ .name = "ehci", ++ .id = 1, ++ .dev = { ++ .release = usb_release, ++ .dma_mask = 0x0}, ++ .num_resources = ARRAY_SIZE(ehci_host_resources), ++ .resource = ehci_host_resources, ++}; ++ ++/* ++ * USB OTG module structures. ++ */ ++#ifdef CONFIG_USB_OTG ++static struct resource ehci_otg_resources[] = { ++ { ++ .start = MCF532x_USB_OTG_REG_START, ++ .end = MCF532x_USB_OTG_REG_END, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = MCF532x_USB_OTG_INT_NUMBER, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device ehci_otg_device = { ++ .name = "ehci", ++ .id = 0, ++ .dev = { ++ .release = usb_release, ++ .dma_mask = 0x0}, ++ .num_resources = ARRAY_SIZE(ehci_otg_resources), ++ .resource = ehci_otg_resources, ++}; ++#endif ++ ++typedef volatile u8 vuint8; /* 8 bits */ ++ ++static int __init ++mcf532x_usb_init(void) ++{ ++ int status; ++ ++ /* ++ * Initialize the clock divider for the USB: ++ */ ++#if CONFIG_CLOCK_FREQ == 240000000 ++ /* ++ * CPU oerating on 240Mhz (MISCCR[USBDIV]=1) ++ * this is the default ++ */ ++ (*(volatile u16 *) (0xFC0A0010)) |= (0x0002); ++#elif CONFIG_CLOCK_FREQ == 180000000 ++ /* ++ * CPU oerating on 180Mhz (MISCCR[USBDIV]=0) ++ */ ++ (*(volatile u16 *) (0xFC0A0010)) &= ~(0x0002); ++#else ++ #error "CLOCK must be 240MHz or 180Mhz" ++#endif ++ /* ++ * Register USB Host device: ++ */ ++ status = platform_device_register(&ehci_host_device); ++ if (status) { ++ pr_info ++ ("USB-MCF532x: Can't register MCF532x USB Host device, %d\n", ++ status); ++ return -ENODEV; ++ } ++ pr_info("USB-MCF532x: MCF532x USB Host device is registered\n"); ++ ++#ifdef CONFIG_USB_OTG ++ /* ++ * Register USB OTG device: ++ * Done only USB Host. ++ * TODO: Device and OTG functinality. ++ */ ++ status = platform_device_register(&ehci_otg_device); ++ if (status) { ++ pr_info ++ ("USB-MCF532x: Can't register MCF532x USB OTG device, %d\n", ++ status); ++ return -ENODEV; ++ } ++ pr_info("USB-MCF532x: MCF532x USB OTG device is registered\n"); ++#endif ++ ++ return 0; ++} ++ ++subsys_initcall(mcf532x_usb_init); +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/5407/config.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/platform/5407/config.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/5407/config.c 2008-10-08 22:22:55.000000000 -0400 +@@ -13,11 +13,11 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include +-#include ++#include + + /***************************************************************************/ + +@@ -29,17 +29,51 @@ extern unsigned int mcf_timerlevel; + + /***************************************************************************/ + +-/* +- * DMA channel base address table. +- */ +-unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = { +- MCF_MBAR + MCFDMA_BASE0, +- MCF_MBAR + MCFDMA_BASE1, +- MCF_MBAR + MCFDMA_BASE2, +- MCF_MBAR + MCFDMA_BASE3, ++static struct mcf_platform_uart m5407_uart_platform[] = { ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE1, ++ .irq = 73, ++ }, ++ { ++ .mapbase = MCF_MBAR + MCFUART_BASE2, ++ .irq = 74, ++ }, ++ { }, + }; + +-unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS]; ++static struct platform_device m5407_uart = { ++ .name = "mcfuart", ++ .id = 0, ++ .dev.platform_data = m5407_uart_platform, ++}; ++ ++static struct platform_device *m5407_devices[] __initdata = { ++ &m5407_uart, ++}; ++ ++/***************************************************************************/ ++ ++static void __init m5407_uart_init_line(int line, int irq) ++{ ++ if (line == 0) { ++ writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR); ++ writeb(irq, MCFUART_BASE1 + MCFUART_UIVR); ++ mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1); ++ } else if (line == 1) { ++ writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR); ++ writeb(irq, MCFUART_BASE2 + MCFUART_UIVR); ++ mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2); ++ } ++} ++ ++static void __init m5407_uarts_init(void) ++{ ++ const int nrlines = ARRAY_SIZE(m5407_uart_platform); ++ int line; ++ ++ for (line = 0; (line < nrlines); line++) ++ m5407_uart_init_line(line, m5407_uart_platform[line].irq); ++} + + /***************************************************************************/ + +@@ -76,21 +110,7 @@ void mcf_settimericr(unsigned int timer, + + /***************************************************************************/ + +-int mcf_timerirqpending(int timer) +-{ +- unsigned int imr = 0; +- +- switch (timer) { +- case 1: imr = MCFSIM_IMR_TIMER1; break; +- case 2: imr = MCFSIM_IMR_TIMER2; break; +- default: break; +- } +- return (mcf_getipr() & imr); +-} +- +-/***************************************************************************/ +- +-void config_BSP(char *commandp, int size) ++void __init config_BSP(char *commandp, int size) + { + mcf_setimr(MCFSIM_IMR_MASKALL); + +@@ -105,3 +125,14 @@ void config_BSP(char *commandp, int size + } + + /***************************************************************************/ ++ ++static int __init init_BSP(void) ++{ ++ m5407_uarts_init(); ++ platform_add_devices(m5407_devices, ARRAY_SIZE(m5407_devices)); ++ return 0; ++} ++ ++arch_initcall(init_BSP); ++ ++/***************************************************************************/ +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/68328/ints.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/platform/68328/ints.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/68328/ints.c 2008-10-08 22:22:55.000000000 -0400 +@@ -101,6 +101,8 @@ void __init init_vectors(void) + IMR = ~0; + } + ++void do_IRQ(int irq, struct pt_regs *fp); ++ + /* The 68k family did not have a good way to determine the source + * of interrupts until later in the family. The EC000 core does + * not provide the vector number on the stack, we vector everything +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/68328/timers.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/platform/68328/timers.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/68328/timers.c 2008-10-08 22:22:55.000000000 -0400 +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -51,6 +52,19 @@ + #define TICKS_PER_JIFFY 10 + #endif + ++static u32 m68328_tick_cnt; ++ ++/***************************************************************************/ ++ ++static irqreturn_t hw_tick(int irq, void *dummy) ++{ ++ /* Reset Timer1 */ ++ TSTAT &= 0; ++ ++ m68328_tick_cnt += TICKS_PER_JIFFY; ++ return arch_timer_interrupt(irq, dummy); ++} ++ + /***************************************************************************/ + + static irqreturn_t hw_tick(int irq, void *dummy) +@@ -69,6 +83,33 @@ static struct irqaction m68328_timer_irq + .handler = hw_tick, + }; + ++/***************************************************************************/ ++ ++static cycle_t m68328_read_clk(void) ++{ ++ unsigned long flags; ++ u32 cycles; ++ ++ local_irq_save(flags); ++ cycles = m68328_tick_cnt + TCN; ++ local_irq_restore(flags); ++ ++ return cycles; ++} ++ ++/***************************************************************************/ ++ ++static struct clocksource m68328_clk = { ++ .name = "timer", ++ .rating = 250, ++ .read = m68328_read_clk, ++ .shift = 20, ++ .mask = CLOCKSOURCE_MASK(32), ++ .flags = CLOCK_SOURCE_IS_CONTINUOUS, ++}; ++ ++/***************************************************************************/ ++ + void hw_timer_init(void) + { + /* disable timer 1 */ +@@ -84,19 +125,8 @@ void hw_timer_init(void) + + /* Enable timer 1 */ + TCTL |= TCTL_TEN; +-} +- +-/***************************************************************************/ +- +-unsigned long hw_timer_offset(void) +-{ +- unsigned long ticks = TCN, offset = 0; +- +- /* check for pending interrupt */ +- if (ticks < (TICKS_PER_JIFFY >> 1) && (ISR & (1 << TMR_IRQ_NUM))) +- offset = 1000000 / HZ; +- ticks = (ticks * 1000000 / HZ) / TICKS_PER_JIFFY; +- return ticks + offset; ++ m68328_clk.mult = clocksource_hz2mult(TICKS_PER_JIFFY*HZ, m68328_clk.shift); ++ clocksource_register(&m68328_clk); + } + + /***************************************************************************/ +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/68360/config.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/platform/68360/config.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/68360/config.c 2008-10-08 22:22:55.000000000 -0400 +@@ -103,11 +103,6 @@ void hw_timer_init(void) + pquicc->timer_tgcr = tgcr_save; + } + +-unsigned long hw_timer_offset(void) +-{ +- return 0; +-} +- + void BSP_gettod (int *yearp, int *monp, int *dayp, + int *hourp, int *minp, int *secp) + { +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/coldfire/Makefile +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/coldfire/Makefile 2008-10-08 22:22:55.000000000 -0400 +@@ -0,0 +1,32 @@ ++# ++# Makefile for the m68knommu kernel. ++# ++ ++# ++# If you want to play with the HW breakpoints then you will ++# need to add define this, which will give you a stack backtrace ++# on the console port whenever a DBG interrupt occurs. You have to ++# set up you HW breakpoints to trigger a DBG interrupt: ++# ++# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT ++# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT ++# ++ ++ifdef CONFIG_FULLDEBUG ++AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 ++endif ++ ++obj-$(CONFIG_COLDFIRE) += dma.o entry.o vectors.o ++obj-$(CONFIG_M5206) += timers.o ++obj-$(CONFIG_M5206e) += timers.o ++obj-$(CONFIG_M520x) += pit.o ++obj-$(CONFIG_M523x) += pit.o dma_timer.o irq_chip.o ++obj-$(CONFIG_M5249) += timers.o ++obj-$(CONFIG_M527x) += pit.o ++obj-$(CONFIG_M5272) += timers.o ++obj-$(CONFIG_M528x) += pit.o ++obj-$(CONFIG_M5307) += timers.o ++obj-$(CONFIG_M532x) += timers.o ++obj-$(CONFIG_M5407) += timers.o ++ ++extra-y := head.o +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/coldfire/dma.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/coldfire/dma.c 2008-10-08 22:22:55.000000000 -0400 +@@ -0,0 +1,39 @@ ++/***************************************************************************/ ++ ++/* ++ * dma.c -- Freescale ColdFire DMA support ++ * ++ * Copyright (C) 2007, Greg Ungerer (gerg@snapgear.com) ++ */ ++ ++/***************************************************************************/ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/***************************************************************************/ ++ ++/* ++ * DMA channel base address table. ++ */ ++unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = { ++#ifdef MCFDMA_BASE0 ++ MCF_MBAR + MCFDMA_BASE0, ++#endif ++#ifdef MCFDMA_BASE1 ++ MCF_MBAR + MCFDMA_BASE1, ++#endif ++#ifdef MCFDMA_BASE2 ++ MCF_MBAR + MCFDMA_BASE2, ++#endif ++#ifdef MCFDMA_BASE3 ++ MCF_MBAR + MCFDMA_BASE3, ++#endif ++}; ++ ++unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS]; ++ ++/***************************************************************************/ +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/coldfire/dma_timer.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/coldfire/dma_timer.c 2008-10-08 22:22:55.000000000 -0400 +@@ -0,0 +1,84 @@ ++/* ++ * dma_timer.c -- Freescale ColdFire DMA Timer. ++ * ++ * Copyright (C) 2007, Benedikt Spranger ++ * Copyright (C) 2008. Sebastian Siewior, Linutronix ++ * ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#define DMA_TIMER_0 (0x00) ++#define DMA_TIMER_1 (0x40) ++#define DMA_TIMER_2 (0x80) ++#define DMA_TIMER_3 (0xc0) ++ ++#define DTMR0 (MCF_IPSBAR + DMA_TIMER_0 + 0x400) ++#define DTXMR0 (MCF_IPSBAR + DMA_TIMER_0 + 0x402) ++#define DTER0 (MCF_IPSBAR + DMA_TIMER_0 + 0x403) ++#define DTRR0 (MCF_IPSBAR + DMA_TIMER_0 + 0x404) ++#define DTCR0 (MCF_IPSBAR + DMA_TIMER_0 + 0x408) ++#define DTCN0 (MCF_IPSBAR + DMA_TIMER_0 + 0x40c) ++ ++#define DMA_FREQ ((MCF_CLK / 2) / 16) ++ ++/* DTMR */ ++#define DMA_DTMR_RESTART (1 << 3) ++#define DMA_DTMR_CLK_DIV_1 (1 << 1) ++#define DMA_DTMR_CLK_DIV_16 (2 << 1) ++#define DMA_DTMR_ENABLE (1 << 0) ++ ++static cycle_t cf_dt_get_cycles(void) ++{ ++ return __raw_readl(DTCN0); ++} ++ ++static struct clocksource clocksource_cf_dt = { ++ .name = "coldfire_dma_timer", ++ .rating = 200, ++ .read = cf_dt_get_cycles, ++ .mask = CLOCKSOURCE_MASK(32), ++ .shift = 20, ++ .flags = CLOCK_SOURCE_IS_CONTINUOUS, ++}; ++ ++static int __init init_cf_dt_clocksource(void) ++{ ++ /* ++ * We setup DMA timer 0 in free run mode. This incrementing counter is ++ * used as a highly precious clock source. With MCF_CLOCK = 150 MHz we ++ * get a ~213 ns resolution and the 32bit register will overflow almost ++ * every 15 minutes. ++ */ ++ __raw_writeb(0x00, DTXMR0); ++ __raw_writeb(0x00, DTER0); ++ __raw_writel(0x00000000, DTRR0); ++ __raw_writew(DMA_DTMR_CLK_DIV_16 | DMA_DTMR_ENABLE, DTMR0); ++ clocksource_cf_dt.mult = clocksource_hz2mult(DMA_FREQ, ++ clocksource_cf_dt.shift); ++ return clocksource_register(&clocksource_cf_dt); ++} ++ ++arch_initcall(init_cf_dt_clocksource); ++ ++#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen in tsc / x86 */ ++#define CYC2NS_SCALE ((1000000 << CYC2NS_SCALE_FACTOR) / (DMA_FREQ / 1000)) ++ ++static unsigned long long cycles2ns(unsigned long cycl) ++{ ++ return (unsigned long long) ((unsigned long long)cycl * CYC2NS_SCALE) ++ >> CYC2NS_SCALE_FACTOR; ++} ++ ++unsigned long long sched_clock(void) ++{ ++ unsigned long cycl = __raw_readl(DTCN0); ++ ++ return cycles2ns(cycl); ++} +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/coldfire/entry.S +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/coldfire/entry.S 2008-10-08 22:22:55.000000000 -0400 +@@ -0,0 +1,241 @@ ++/* ++ * linux/arch/m68knommu/platform/5307/entry.S ++ * ++ * Copyright (C) 1999-2007, Greg Ungerer (gerg@snapgear.com) ++ * Copyright (C) 1998 D. Jeff Dionne , ++ * Kenneth Albanowski , ++ * Copyright (C) 2000 Lineo Inc. (www.lineo.com) ++ * Copyright (C) 2004-2006 Macq Electronique SA. (www.macqel.com) ++ * ++ * Based on: ++ * ++ * linux/arch/m68k/kernel/entry.S ++ * ++ * Copyright (C) 1991, 1992 Linus Torvalds ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file README.legal in the main directory of this archive ++ * for more details. ++ * ++ * Linux/m68k support by Hamish Macdonald ++ * ++ * 68060 fixes by Jesper Skov ++ * ColdFire support by Greg Ungerer (gerg@snapgear.com) ++ * 5307 fixes by David W. Miller ++ * linux 2.4 support David McCullough ++ * Bug, speed and maintainability fixes by Philippe De Muyter ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++.bss ++ ++sw_ksp: ++.long 0 ++ ++sw_usp: ++.long 0 ++ ++.text ++ ++.globl system_call ++.globl resume ++.globl ret_from_exception ++.globl ret_from_signal ++.globl sys_call_table ++.globl ret_from_interrupt ++.globl inthandler ++.globl fasthandler ++ ++enosys: ++ mov.l #sys_ni_syscall,%d3 ++ bra 1f ++ ++ENTRY(system_call) ++ SAVE_ALL ++ move #0x2000,%sr /* enable intrs again */ ++ ++ cmpl #NR_syscalls,%d0 ++ jcc enosys ++ lea sys_call_table,%a0 ++ lsll #2,%d0 /* movel %a0@(%d0:l:4),%d3 */ ++ movel %a0@(%d0),%d3 ++ jeq enosys ++ ++1: ++ movel %sp,%d2 /* get thread_info pointer */ ++ andl #-THREAD_SIZE,%d2 /* at start of kernel stack */ ++ movel %d2,%a0 ++ movel %a0@,%a1 /* save top of frame */ ++ movel %sp,%a1@(TASK_THREAD+THREAD_ESP0) ++ btst #(TIF_SYSCALL_TRACE%8),%a0@(TI_FLAGS+(31-TIF_SYSCALL_TRACE)/8) ++ bnes 1f ++ ++ movel %d3,%a0 ++ jbsr %a0@ ++ movel %d0,%sp@(PT_D0) /* save the return value */ ++ jra ret_from_exception ++1: ++ movel #-ENOSYS,%d2 /* strace needs -ENOSYS in PT_D0 */ ++ movel %d2,PT_D0(%sp) /* on syscall entry */ ++ subql #4,%sp ++ SAVE_SWITCH_STACK ++ jbsr syscall_trace ++ RESTORE_SWITCH_STACK ++ addql #4,%sp ++ movel %d3,%a0 ++ jbsr %a0@ ++ movel %d0,%sp@(PT_D0) /* save the return value */ ++ subql #4,%sp /* dummy return address */ ++ SAVE_SWITCH_STACK ++ jbsr syscall_trace ++ ++ret_from_signal: ++ RESTORE_SWITCH_STACK ++ addql #4,%sp ++ ++ret_from_exception: ++ move #0x2700,%sr /* disable intrs */ ++ btst #5,%sp@(PT_SR) /* check if returning to kernel */ ++ jeq Luser_return /* if so, skip resched, signals */ ++ ++#ifdef CONFIG_PREEMPT ++ movel %sp,%d1 /* get thread_info pointer */ ++ andl #-THREAD_SIZE,%d1 /* at base of kernel stack */ ++ movel %d1,%a0 ++ movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */ ++ andl #_TIF_NEED_RESCHED,%d1 ++ jeq Lkernel_return ++ ++ movel %a0@(TI_PREEMPTCOUNT),%d1 ++ cmpl #0,%d1 ++ jne Lkernel_return ++ ++ pea Lkernel_return ++ jmp preempt_schedule_irq /* preempt the kernel */ ++#endif ++ ++Lkernel_return: ++ moveml %sp@,%d1-%d5/%a0-%a2 ++ lea %sp@(32),%sp /* space for 8 regs */ ++ movel %sp@+,%d0 ++ addql #4,%sp /* orig d0 */ ++ addl %sp@+,%sp /* stk adj */ ++ rte ++ ++Luser_return: ++ movel %sp,%d1 /* get thread_info pointer */ ++ andl #-THREAD_SIZE,%d1 /* at base of kernel stack */ ++ movel %d1,%a0 ++ movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */ ++ andl #_TIF_WORK_MASK,%d1 ++ jne Lwork_to_do /* still work to do */ ++ ++Lreturn: ++ move #0x2700,%sr /* disable intrs */ ++ movel sw_usp,%a0 /* get usp */ ++ movel %sp@(PT_PC),%a0@- /* copy exception program counter */ ++ movel %sp@(PT_FORMATVEC),%a0@-/* copy exception format/vector/sr */ ++ moveml %sp@,%d1-%d5/%a0-%a2 ++ lea %sp@(32),%sp /* space for 8 regs */ ++ movel %sp@+,%d0 ++ addql #4,%sp /* orig d0 */ ++ addl %sp@+,%sp /* stk adj */ ++ addql #8,%sp /* remove exception */ ++ movel %sp,sw_ksp /* save ksp */ ++ subql #8,sw_usp /* set exception */ ++ movel sw_usp,%sp /* restore usp */ ++ rte ++ ++Lwork_to_do: ++ movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */ ++ move #0x2000,%sr /* enable intrs again */ ++ btst #TIF_NEED_RESCHED,%d1 ++ jne reschedule ++ ++ /* GERG: do we need something here for TRACEing?? */ ++ ++Lsignal_return: ++ subql #4,%sp /* dummy return address */ ++ SAVE_SWITCH_STACK ++ pea %sp@(SWITCH_STACK_SIZE) ++ clrl %sp@- ++ jsr do_signal ++ addql #8,%sp ++ RESTORE_SWITCH_STACK ++ addql #4,%sp ++ jmp Lreturn ++ ++/* ++ * This is the generic interrupt handler (for all hardware interrupt ++ * sources). Calls upto high level code to do all the work. ++ */ ++ENTRY(inthandler) ++ SAVE_ALL ++ moveq #-1,%d0 ++ movel %d0,%sp@(PT_ORIG_D0) ++ ++ movew %sp@(PT_FORMATVEC),%d0 /* put exception # in d0 */ ++ andl #0x03fc,%d0 /* mask out vector only */ ++ ++ movel %sp,%sp@- /* push regs arg */ ++ lsrl #2,%d0 /* calculate real vector # */ ++ movel %d0,%sp@- /* push vector number */ ++ jbsr do_IRQ /* call high level irq handler */ ++ lea %sp@(8),%sp /* pop args off stack */ ++ ++ bra ret_from_interrupt /* this was fallthrough */ ++ ++/* ++ * This is the fast interrupt handler (for certain hardware interrupt ++ * sources). Unlike the normal interrupt handler it just uses the ++ * current stack (doesn't care if it is user or kernel). It also ++ * doesn't bother doing the bottom half handlers. ++ */ ++ENTRY(fasthandler) ++ SAVE_LOCAL ++ ++ movew %sp@(PT_FORMATVEC),%d0 ++ andl #0x03fc,%d0 /* mask out vector only */ ++ ++ movel %sp,%sp@- /* push regs arg */ ++ lsrl #2,%d0 /* calculate real vector # */ ++ movel %d0,%sp@- /* push vector number */ ++ jbsr do_IRQ /* call high level irq handler */ ++ lea %sp@(8),%sp /* pop args off stack */ ++ ++ RESTORE_LOCAL ++ ++ENTRY(ret_from_interrupt) ++ /* the fasthandler is confusing me, haven't seen any user */ ++ jmp ret_from_exception ++ ++/* ++ * Beware - when entering resume, prev (the current task) is ++ * in a0, next (the new task) is in a1,so don't change these ++ * registers until their contents are no longer needed. ++ * This is always called in supervisor mode, so don't bother to save ++ * and restore sr; user's process sr is actually in the stack. ++ */ ++ENTRY(resume) ++ movel %a0, %d1 /* get prev thread in d1 */ ++ ++ movel sw_usp,%d0 /* save usp */ ++ movel %d0,%a0@(TASK_THREAD+THREAD_USP) ++ ++ SAVE_SWITCH_STACK ++ movel %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack pointer */ ++ movel %a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new thread stack */ ++ RESTORE_SWITCH_STACK ++ ++ movel %a1@(TASK_THREAD+THREAD_USP),%a0 /* restore thread user stack */ ++ movel %a0, sw_usp ++ rts +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/coldfire/head.S +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/coldfire/head.S 2008-10-08 22:22:55.000000000 -0400 +@@ -0,0 +1,222 @@ ++/*****************************************************************************/ ++ ++/* ++ * head.S -- common startup code for ColdFire CPUs. ++ * ++ * (C) Copyright 1999-2006, Greg Ungerer . ++ */ ++ ++/*****************************************************************************/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/*****************************************************************************/ ++ ++/* ++ * If we don't have a fixed memory size, then lets build in code ++ * to auto detect the DRAM size. Obviously this is the prefered ++ * method, and should work for most boards. It won't work for those ++ * that do not have their RAM starting at address 0, and it only ++ * works on SDRAM (not boards fitted with SRAM). ++ */ ++#if CONFIG_RAMSIZE != 0 ++.macro GET_MEM_SIZE ++ movel #CONFIG_RAMSIZE,%d0 /* hard coded memory size */ ++.endm ++ ++#elif defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ ++ defined(CONFIG_M5249) || defined(CONFIG_M527x) || \ ++ defined(CONFIG_M528x) || defined(CONFIG_M5307) || \ ++ defined(CONFIG_M5407) ++/* ++ * Not all these devices have exactly the same DRAM controller, ++ * but the DCMR register is virtually identical - give or take ++ * a couple of bits. The only exception is the 5272 devices, their ++ * DRAM controller is quite different. ++ */ ++.macro GET_MEM_SIZE ++ movel MCF_MBAR+MCFSIM_DMR0,%d0 /* get mask for 1st bank */ ++ btst #0,%d0 /* check if region enabled */ ++ beq 1f ++ andl #0xfffc0000,%d0 ++ beq 1f ++ addl #0x00040000,%d0 /* convert mask to size */ ++1: ++ movel MCF_MBAR+MCFSIM_DMR1,%d1 /* get mask for 2nd bank */ ++ btst #0,%d1 /* check if region enabled */ ++ beq 2f ++ andl #0xfffc0000, %d1 ++ beq 2f ++ addl #0x00040000,%d1 ++ addl %d1,%d0 /* total mem size in d0 */ ++2: ++.endm ++ ++#elif defined(CONFIG_M5272) ++.macro GET_MEM_SIZE ++ movel MCF_MBAR+MCFSIM_CSOR7,%d0 /* get SDRAM address mask */ ++ andil #0xfffff000,%d0 /* mask out chip select options */ ++ negl %d0 /* negate bits */ ++.endm ++ ++#elif defined(CONFIG_M520x) ++.macro GET_MEM_SIZE ++ clrl %d0 ++ movel MCF_MBAR+MCFSIM_SDCS0, %d2 /* Get SDRAM chip select 0 config */ ++ andl #0x1f, %d2 /* Get only the chip select size */ ++ beq 3f /* Check if it is enabled */ ++ addql #1, %d2 /* Form exponent */ ++ moveql #1, %d0 ++ lsll %d2, %d0 /* 2 ^ exponent */ ++3: ++ movel MCF_MBAR+MCFSIM_SDCS1, %d2 /* Get SDRAM chip select 1 config */ ++ andl #0x1f, %d2 /* Get only the chip select size */ ++ beq 4f /* Check if it is enabled */ ++ addql #1, %d2 /* Form exponent */ ++ moveql #1, %d1 ++ lsll %d2, %d1 /* 2 ^ exponent */ ++ addl %d1, %d0 /* Total size of SDRAM in d0 */ ++4: ++.endm ++ ++#else ++#error "ERROR: I don't know how to probe your boards memory size?" ++#endif ++ ++/*****************************************************************************/ ++ ++/* ++ * Boards and platforms can do specific early hardware setup if ++ * they need to. Most don't need this, define away if not required. ++ */ ++#ifndef PLATFORM_SETUP ++#define PLATFORM_SETUP ++#endif ++ ++/*****************************************************************************/ ++ ++.global _start ++.global _rambase ++.global _ramvec ++.global _ramstart ++.global _ramend ++ ++/*****************************************************************************/ ++ ++.data ++ ++/* ++ * During startup we store away the RAM setup. These are not in the ++ * bss, since their values are determined and written before the bss ++ * has been cleared. ++ */ ++_rambase: ++.long 0 ++_ramvec: ++.long 0 ++_ramstart: ++.long 0 ++_ramend: ++.long 0 ++ ++/*****************************************************************************/ ++ ++.text ++ ++/* ++ * This is the codes first entry point. This is where it all ++ * begins... ++ */ ++ ++_start: ++ nop /* filler */ ++ movew #0x2700, %sr /* no interrupts */ ++ ++ /* ++ * Do any platform or board specific setup now. Most boards ++ * don't need anything. Those exceptions are define this in ++ * their board specific includes. ++ */ ++ PLATFORM_SETUP ++ ++ /* ++ * Create basic memory configuration. Set VBR accordingly, ++ * and size memory. ++ */ ++ movel #CONFIG_VECTORBASE,%a7 ++ movec %a7,%VBR /* set vectors addr */ ++ movel %a7,_ramvec ++ ++ movel #CONFIG_RAMBASE,%a7 /* mark the base of RAM */ ++ movel %a7,_rambase ++ ++ GET_MEM_SIZE /* macro code determines size */ ++ addl %a7,%d0 ++ movel %d0,_ramend /* set end ram addr */ ++ ++ /* ++ * Now that we know what the memory is, lets enable cache ++ * and get things moving. This is Coldfire CPU specific. ++ */ ++ CACHE_ENABLE /* enable CPU cache */ ++ ++ ++#ifdef CONFIG_ROMFS_FS ++ /* ++ * Move ROM filesystem above bss :-) ++ */ ++ lea _sbss,%a0 /* get start of bss */ ++ lea _ebss,%a1 /* set up destination */ ++ movel %a0,%a2 /* copy of bss start */ ++ ++ movel 8(%a0),%d0 /* get size of ROMFS */ ++ addql #8,%d0 /* allow for rounding */ ++ andl #0xfffffffc, %d0 /* whole words */ ++ ++ addl %d0,%a0 /* copy from end */ ++ addl %d0,%a1 /* copy from end */ ++ movel %a1,_ramstart /* set start of ram */ ++ ++_copy_romfs: ++ movel -(%a0),%d0 /* copy dword */ ++ movel %d0,-(%a1) ++ cmpl %a0,%a2 /* check if at end */ ++ bne _copy_romfs ++ ++#else /* CONFIG_ROMFS_FS */ ++ lea _ebss,%a1 ++ movel %a1,_ramstart ++#endif /* CONFIG_ROMFS_FS */ ++ ++ ++ /* ++ * Zero out the bss region. ++ */ ++ lea _sbss,%a0 /* get start of bss */ ++ lea _ebss,%a1 /* get end of bss */ ++ clrl %d0 /* set value */ ++_clear_bss: ++ movel %d0,(%a0)+ /* clear each word */ ++ cmpl %a0,%a1 /* check if at end */ ++ bne _clear_bss ++ ++ /* ++ * Load the current task pointer and stack. ++ */ ++ lea init_thread_union,%a0 ++ lea THREAD_SIZE(%a0),%sp ++ ++ /* ++ * Assember start up done, start code proper. ++ */ ++ jsr start_kernel /* start Linux kernel */ ++ ++_exit: ++ jmp _exit /* should never get here */ ++ ++/*****************************************************************************/ +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/coldfire/irq_chip.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/coldfire/irq_chip.c 2008-10-08 22:22:55.000000000 -0400 +@@ -0,0 +1,110 @@ ++/* ++ * IRQ-Chip implementation for Coldfire ++ * ++ * Author: Sebastian Siewior ++ */ ++ ++#include ++#include ++#include ++#include ++ ++static inline void *coldfire_irqnum_to_mem(unsigned int irq) ++{ ++ u32 imrp; ++ ++ imrp = MCF_IPSBAR; ++#if defined(MCFINT_INTC1_VECBASE) ++ if (irq > MCFINT_INTC1_VECBASE) { ++ imrp += MCFICM_INTC1; ++ irq -= MCFINT_PER_INTC; ++ } else ++#endif ++ imrp += MCFICM_INTC0; ++ ++ irq -= MCFINT_VECBASE; ++ ++ if (irq > 32) ++ imrp += MCFINTC_IMRH; ++ else ++ imrp += MCFINTC_IMRL; ++ ++ return (void *)imrp; ++} ++ ++static inline unsigned int coldfire_irqnum_to_bit(unsigned int irq) ++{ ++ irq -= MCFINT_VECBASE; ++ ++ if (irq > 32) ++ irq -= 32; ++ ++ return irq; ++} ++ ++static void coldfire_mask(unsigned int irq) ++{ ++ volatile unsigned long *imrp; ++ u32 mask; ++ u32 irq_bit; ++ ++ imrp = coldfire_irqnum_to_mem(irq); ++ irq_bit = coldfire_irqnum_to_bit(irq); ++ ++ mask = 1 << irq_bit; ++ *imrp |= mask; ++} ++ ++static void coldfire_unmask(unsigned int irq) ++{ ++ volatile unsigned long *imrp; ++ u32 mask; ++ u32 irq_bit; ++ ++ imrp = coldfire_irqnum_to_mem(irq); ++ irq_bit = coldfire_irqnum_to_bit(irq); ++ ++ mask = 1 << irq_bit; ++ *imrp &= ~mask; ++} ++ ++static void coldfire_nop(unsigned int irq) ++{ ++} ++ ++static struct irq_chip m_irq_chip = { ++ .name = "M68K-INTC", ++ .ack = coldfire_nop, ++ .mask = coldfire_mask, ++ .unmask = coldfire_unmask, ++}; ++ ++void __init coldfire_init_irq_chip(void) ++{ ++ volatile u32 *imrp; ++ volatile u8 *icrp; ++ u32 irq; ++ u32 i; ++ ++ for (irq = 0; irq < NR_IRQS; irq++) ++ set_irq_chip_and_handler_name(irq, &m_irq_chip, ++ handle_level_irq, m_irq_chip.name); ++ ++ /* setup prios for interrupt sources (first field is reserved) */ ++ icrp = (u8 *)MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0; ++ for (i = 1; i <= 63; i++) ++ icrp[i] = i; ++ ++ /* remove the disable all flag, disable all interrupt sources */ ++ imrp = coldfire_irqnum_to_mem(MCFINT_VECBASE); ++ *imrp = 0xfffffffe; ++ ++#if defined(MCFINT_INTC1_VECBASE) ++ icrp = (u8 *)MCF_IPSBAR + MCFICM_INTC1 + MCFINTC_ICR0; ++ for (i = 1; i <= 63; i++) ++ icrp[i] = i; ++ ++ imrp = coldfire_irqnum_to_mem(MCFINT_INTC1_VECBASE); ++ *imrp = 0xfffffffe; ++#endif ++} +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/coldfire/pit.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/coldfire/pit.c 2008-10-08 22:22:55.000000000 -0400 +@@ -0,0 +1,180 @@ ++/***************************************************************************/ ++ ++/* ++ * pit.c -- Freescale ColdFire PIT timer. Currently this type of ++ * hardware timer only exists in the Freescale ColdFire ++ * 5270/5271, 5282 and 5208 CPUs. No doubt newer ColdFire ++ * family members will probably use it too. ++ * ++ * Copyright (C) 1999-2008, Greg Ungerer (gerg@snapgear.com) ++ * Copyright (C) 2001-2004, SnapGear Inc. (www.snapgear.com) ++ */ ++ ++/***************************************************************************/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/***************************************************************************/ ++ ++/* ++ * By default use timer1 as the system clock timer. ++ */ ++#define FREQ ((MCF_CLK / 2) / 64) ++#define TA(a) (MCF_IPSBAR + MCFPIT_BASE1 + (a)) ++#define INTC0 (MCF_IPSBAR + MCFICM_INTC0) ++#define PIT_CYCLES_PER_JIFFY (FREQ / HZ) ++ ++static u32 pit_cnt; ++ ++/* ++ * Initialize the PIT timer. ++ * ++ * This is also called after resume to bring the PIT into operation again. ++ */ ++ ++static void init_cf_pit_timer(enum clock_event_mode mode, ++ struct clock_event_device *evt) ++{ ++ switch (mode) { ++ case CLOCK_EVT_MODE_PERIODIC: ++ ++ __raw_writew(MCFPIT_PCSR_DISABLE, TA(MCFPIT_PCSR)); ++ __raw_writew(PIT_CYCLES_PER_JIFFY, TA(MCFPIT_PMR)); ++ __raw_writew(MCFPIT_PCSR_EN | MCFPIT_PCSR_PIE | \ ++ MCFPIT_PCSR_OVW | MCFPIT_PCSR_RLD | \ ++ MCFPIT_PCSR_CLK64, TA(MCFPIT_PCSR)); ++ break; ++ ++ case CLOCK_EVT_MODE_SHUTDOWN: ++ case CLOCK_EVT_MODE_UNUSED: ++ ++ __raw_writew(MCFPIT_PCSR_DISABLE, TA(MCFPIT_PCSR)); ++ break; ++ ++ case CLOCK_EVT_MODE_ONESHOT: ++ ++ __raw_writew(MCFPIT_PCSR_DISABLE, TA(MCFPIT_PCSR)); ++ __raw_writew(MCFPIT_PCSR_EN | MCFPIT_PCSR_PIE | \ ++ MCFPIT_PCSR_OVW | MCFPIT_PCSR_CLK64, \ ++ TA(MCFPIT_PCSR)); ++ break; ++ ++ case CLOCK_EVT_MODE_RESUME: ++ /* Nothing to do here */ ++ break; ++ } ++} ++ ++/* ++ * Program the next event in oneshot mode ++ * ++ * Delta is given in PIT ticks ++ */ ++static int cf_pit_next_event(unsigned long delta, ++ struct clock_event_device *evt) ++{ ++ __raw_writew(delta, TA(MCFPIT_PMR)); ++ return 0; ++} ++ ++struct clock_event_device cf_pit_clockevent = { ++ .name = "pit", ++ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, ++ .set_mode = init_cf_pit_timer, ++ .set_next_event = cf_pit_next_event, ++ .shift = 32, ++ .irq = MCFINT_VECBASE + MCFINT_PIT1, ++}; ++ ++ ++ ++/***************************************************************************/ ++ ++static irqreturn_t pit_tick(int irq, void *dummy) ++{ ++ struct clock_event_device *evt = &cf_pit_clockevent; ++ u16 pcsr; ++ ++ /* Reset the ColdFire timer */ ++ pcsr = __raw_readw(TA(MCFPIT_PCSR)); ++ __raw_writew(pcsr | MCFPIT_PCSR_PIF, TA(MCFPIT_PCSR)); ++ ++ pit_cnt += PIT_CYCLES_PER_JIFFY; ++ evt->event_handler(evt); ++ return IRQ_HANDLED; ++} ++ ++/***************************************************************************/ ++ ++static struct irqaction pit_irq = { ++ .name = "timer", ++ .flags = IRQF_DISABLED | IRQF_TIMER, ++ .handler = pit_tick, ++}; ++ ++/***************************************************************************/ ++ ++static cycle_t pit_read_clk(void) ++{ ++ unsigned long flags; ++ u32 cycles; ++ u16 pcntr; ++ ++ local_irq_save(flags); ++ pcntr = __raw_readw(TA(MCFPIT_PCNTR)); ++ cycles = pit_cnt; ++ local_irq_restore(flags); ++ ++ return cycles + PIT_CYCLES_PER_JIFFY - pcntr; ++} ++ ++/***************************************************************************/ ++ ++static struct clocksource pit_clk = { ++ .name = "pit", ++ .rating = 100, ++ .read = pit_read_clk, ++ .shift = 20, ++ .mask = CLOCKSOURCE_MASK(32), ++ .flags = CLOCK_SOURCE_IS_CONTINUOUS, ++}; ++ ++/***************************************************************************/ ++ ++void hw_timer_init(void) ++{ ++ u32 imr; ++ ++ cf_pit_clockevent.cpumask = cpumask_of_cpu(smp_processor_id()); ++ cf_pit_clockevent.mult = div_sc(FREQ, NSEC_PER_SEC, 32); ++ cf_pit_clockevent.max_delta_ns = ++ clockevent_delta2ns(0xFFFF, &cf_pit_clockevent); ++ cf_pit_clockevent.min_delta_ns = ++ clockevent_delta2ns(0x3f, &cf_pit_clockevent); ++ clockevents_register_device(&cf_pit_clockevent); ++ ++ setup_irq(MCFINT_VECBASE + MCFINT_PIT1, &pit_irq); ++ ++#if !defined(CONFIG_M523x) ++ __raw_writeb(ICR_INTRCONF, INTC0 + MCFINTC_ICR0 + MCFINT_PIT1); ++ imr = __raw_readl(INTC0 + MCFPIT_IMR); ++ imr &= ~MCFPIT_IMR_IBIT; ++ __raw_writel(imr, INTC0 + MCFPIT_IMR); ++ ++#endif ++ pit_clk.mult = clocksource_hz2mult(FREQ, pit_clk.shift); ++ clocksource_register(&pit_clk); ++} ++ ++/***************************************************************************/ +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/coldfire/timers.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/coldfire/timers.c 2008-10-08 22:22:55.000000000 -0400 +@@ -0,0 +1,182 @@ ++/***************************************************************************/ ++ ++/* ++ * timers.c -- generic ColdFire hardware timer support. ++ * ++ * Copyright (C) 1999-2008, Greg Ungerer ++ */ ++ ++/***************************************************************************/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/***************************************************************************/ ++ ++/* ++ * By default use timer1 as the system clock timer. ++ */ ++#define FREQ (MCF_BUSCLK / 16) ++#define TA(a) (MCF_MBAR + MCFTIMER_BASE1 + (a)) ++ ++/* ++ * Default the timer and vector to use for ColdFire. Some ColdFire ++ * CPU's and some boards may want different. Their sub-architecture ++ * startup code (in config.c) can change these if they want. ++ */ ++unsigned int mcf_timervector = 29; ++unsigned int mcf_profilevector = 31; ++unsigned int mcf_timerlevel = 5; ++ ++/* ++ * These provide the underlying interrupt vector support. ++ * Unfortunately it is a little different on each ColdFire. ++ */ ++extern void mcf_settimericr(int timer, int level); ++void coldfire_profile_init(void); ++ ++#if defined(CONFIG_M532x) ++#define __raw_readtrr __raw_readl ++#define __raw_writetrr __raw_writel ++#else ++#define __raw_readtrr __raw_readw ++#define __raw_writetrr __raw_writew ++#endif ++ ++static u32 mcftmr_cycles_per_jiffy; ++static u32 mcftmr_cnt; ++ ++/***************************************************************************/ ++ ++static irqreturn_t mcftmr_tick(int irq, void *dummy) ++{ ++ /* Reset the ColdFire timer */ ++ __raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, TA(MCFTIMER_TER)); ++ ++ mcftmr_cnt += mcftmr_cycles_per_jiffy; ++ return arch_timer_interrupt(irq, dummy); ++} ++ ++/***************************************************************************/ ++ ++static struct irqaction mcftmr_timer_irq = { ++ .name = "timer", ++ .flags = IRQF_DISABLED | IRQF_TIMER, ++ .handler = mcftmr_tick, ++}; ++ ++/***************************************************************************/ ++ ++static cycle_t mcftmr_read_clk(void) ++{ ++ unsigned long flags; ++ u32 cycles; ++ u16 tcn; ++ ++ local_irq_save(flags); ++ tcn = __raw_readw(TA(MCFTIMER_TCN)); ++ cycles = mcftmr_cnt; ++ local_irq_restore(flags); ++ ++ return cycles + tcn; ++} ++ ++/***************************************************************************/ ++ ++static struct clocksource mcftmr_clk = { ++ .name = "tmr", ++ .rating = 250, ++ .read = mcftmr_read_clk, ++ .shift = 20, ++ .mask = CLOCKSOURCE_MASK(32), ++ .flags = CLOCK_SOURCE_IS_CONTINUOUS, ++}; ++ ++/***************************************************************************/ ++ ++void hw_timer_init(void) ++{ ++ setup_irq(mcf_timervector, &mcftmr_timer_irq); ++ ++ __raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR)); ++ mcftmr_cycles_per_jiffy = FREQ / HZ; ++ __raw_writetrr(mcftmr_cycles_per_jiffy, TA(MCFTIMER_TRR)); ++ __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | ++ MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, TA(MCFTIMER_TMR)); ++ ++ mcftmr_clk.mult = clocksource_hz2mult(FREQ, mcftmr_clk.shift); ++ clocksource_register(&mcftmr_clk); ++ ++ mcf_settimericr(1, mcf_timerlevel); ++ ++#ifdef CONFIG_HIGHPROFILE ++ coldfire_profile_init(); ++#endif ++} ++ ++/***************************************************************************/ ++#ifdef CONFIG_HIGHPROFILE ++/***************************************************************************/ ++ ++/* ++ * By default use timer2 as the profiler clock timer. ++ */ ++#define PA(a) (MCF_MBAR + MCFTIMER_BASE2 + (a)) ++ ++/* ++ * Choose a reasonably fast profile timer. Make it an odd value to ++ * try and get good coverage of kernel operations. ++ */ ++#define PROFILEHZ 1013 ++ ++/* ++ * Use the other timer to provide high accuracy profiling info. ++ */ ++irqreturn_t coldfire_profile_tick(int irq, void *dummy) ++{ ++ /* Reset ColdFire timer2 */ ++ __raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, PA(MCFTIMER_TER)); ++ if (current->pid) ++ profile_tick(CPU_PROFILING); ++ return IRQ_HANDLED; ++} ++ ++/***************************************************************************/ ++ ++static struct irqaction coldfire_profile_irq = { ++ .name = "profile timer", ++ .flags = IRQF_DISABLED | IRQF_TIMER, ++ .handler = coldfire_profile_tick, ++}; ++ ++void coldfire_profile_init(void) ++{ ++ printk(KERN_INFO "PROFILE: lodging TIMER2 @ %dHz as profile timer\n", ++ PROFILEHZ); ++ ++ setup_irq(mcf_profilevector, &coldfire_profile_irq); ++ ++ /* Set up TIMER 2 as high speed profile clock */ ++ __raw_writew(MCFTIMER_TMR_DISABLE, PA(MCFTIMER_TMR)); ++ ++ __raw_writetrr(((MCF_BUSCLK / 16) / PROFILEHZ), PA(MCFTIMER_TRR)); ++ __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | ++ MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, PA(MCFTIMER_TMR)); ++ ++ mcf_settimericr(2, 7); ++} ++ ++/***************************************************************************/ ++#endif /* CONFIG_HIGHPROFILE */ ++/***************************************************************************/ +Index: linux-2.6.24.7-rt21/arch/m68knommu/platform/coldfire/vectors.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24.7-rt21/arch/m68knommu/platform/coldfire/vectors.c 2008-10-08 22:22:55.000000000 -0400 +@@ -0,0 +1,105 @@ ++/***************************************************************************/ ++ ++/* ++ * linux/arch/m68knommu/platform/5307/vectors.c ++ * ++ * Copyright (C) 1999-2007, Greg Ungerer ++ */ ++ ++/***************************************************************************/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/***************************************************************************/ ++ ++#ifdef TRAP_DBG_INTERRUPT ++ ++asmlinkage void dbginterrupt_c(struct frame *fp) ++{ ++ extern void dump(struct pt_regs *fp); ++ printk(KERN_DEBUG "%s(%d): BUS ERROR TRAP\n", __FILE__, __LINE__); ++ dump((struct pt_regs *) fp); ++ asm("halt"); ++} ++ ++#endif ++ ++/***************************************************************************/ ++ ++extern e_vector *_ramvec; ++ ++void set_evector(int vecnum, void (*handler)(void)) ++{ ++ if (vecnum >= 0 && vecnum <= 255) ++ _ramvec[vecnum] = handler; ++} ++ ++/***************************************************************************/ ++ ++/* Assembler routines */ ++asmlinkage void buserr(void); ++asmlinkage void trap(void); ++asmlinkage void system_call(void); ++asmlinkage void inthandler(void); ++ ++void __init init_vectors(void) ++{ ++ int i; ++ ++ /* ++ * There is a common trap handler and common interrupt ++ * handler that handle almost every vector. We treat ++ * the system call and bus error special, they get their ++ * own first level handlers. ++ */ ++ for (i = 3; (i <= 23); i++) ++ _ramvec[i] = trap; ++ for (i = 33; (i <= 63); i++) ++ _ramvec[i] = trap; ++ for (i = 24; (i <= 31); i++) ++ _ramvec[i] = inthandler; ++ for (i = 64; (i < 255); i++) ++ _ramvec[i] = inthandler; ++ _ramvec[255] = 0; ++ ++ _ramvec[2] = buserr; ++ _ramvec[32] = system_call; ++ ++#ifdef TRAP_DBG_INTERRUPT ++ _ramvec[12] = dbginterrupt; ++#endif ++} ++ ++/***************************************************************************/ ++ ++void enable_vector(unsigned int irq) ++{ ++ /* Currently no action on ColdFire */ ++} ++ ++void disable_vector(unsigned int irq) ++{ ++ /* Currently no action on ColdFire */ ++} ++ ++void ack_vector(unsigned int irq) ++{ ++ /* Currently no action on ColdFire */ ++} ++ ++/***************************************************************************/ ++ ++void coldfire_reset(void) ++{ ++ HARD_RESET_NOW(); ++} ++ ++/***************************************************************************/ +Index: linux-2.6.24.7-rt21/drivers/net/fec.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/net/fec.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/net/fec.c 2008-10-08 22:22:55.000000000 -0400 +@@ -2,12 +2,6 @@ + * Fast Ethernet Controller (FEC) driver for Motorola MPC8xx. + * Copyright (c) 1997 Dan Malek (dmalek@jlc.net) + * +- * This version of the driver is specific to the FADS implementation, +- * since the board contains control registers external to the processor +- * for the control of the LevelOne LXT970 transceiver. The MPC860T manual +- * describes connections using the internal parallel port I/O, which +- * is basically all of Port D. +- * + * Right now, I am very wasteful with the buffers. I allocate memory + * pages and then divide them into 2K frame buffers. This way I know I + * have buffers large enough to hold one frame within one buffer descriptor. +@@ -49,17 +43,9 @@ + #include + #include + +-#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \ +- defined(CONFIG_M5272) || defined(CONFIG_M528x) || \ +- defined(CONFIG_M520x) || defined(CONFIG_M532x) + #include + #include + #include "fec.h" +-#else +-#include +-#include +-#include "commproc.h" +-#endif + + #if defined(CONFIG_FEC2) + #define FEC_MAX_PORTS 2 +@@ -67,6 +53,7 @@ + #define FEC_MAX_PORTS 1 + #endif + ++ + /* + * Define the fixed address of the FEC hardware. + */ +@@ -79,15 +66,15 @@ static unsigned int fec_hw[] = { + #elif defined(CONFIG_M523x) || defined(CONFIG_M528x) + (MCF_MBAR + 0x1000), + #elif defined(CONFIG_M520x) +- (MCF_MBAR+0x30000), ++ (MCF_MBAR + 0x30000), + #elif defined(CONFIG_M532x) +- (MCF_MBAR+0xfc030000), ++ (MCF_MBAR + 0xfc030000), + #else +- &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec), ++ &(((immap_t *) IMAP_ADDR)->im_cpm.cp_fec), + #endif + }; + +-static unsigned char fec_mac_default[] = { ++static unsigned char fec_mac_default[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + +@@ -101,20 +88,20 @@ static unsigned char fec_mac_default[] = + #define FEC_FLASHMAC 0xf0006000 + #elif defined(CONFIG_CANCam) + #define FEC_FLASHMAC 0xf0020000 +-#elif defined (CONFIG_M5272C3) ++#elif defined(CONFIG_M5272C3) + #define FEC_FLASHMAC (0xffe04000 + 4) + #elif defined(CONFIG_MOD5272) +-#define FEC_FLASHMAC 0xffc0406b ++#define FEC_FLASHMAC 0xffc0406b + #else + #define FEC_FLASHMAC 0 + #endif + + /* Forward declarations of some structures to support different PHYs + */ +- ++typedef void (mii_func)(uint val, struct net_device *dev); + typedef struct { + uint mii_data; +- void (*funct)(uint mii_reg, struct net_device *dev); ++ mii_func *funct; + } phy_cmd_t; + + typedef struct { +@@ -165,7 +152,6 @@ typedef struct { + #define PKT_MINBUF_SIZE 64 + #define PKT_MAXBLR_SIZE 1520 + +- + /* + * The 5270/5271/5280/5282/532x RX control register also contains maximum frame + * size bits. Other FEC hardware does not, so we need to take that into +@@ -188,75 +174,67 @@ typedef struct { + */ + struct fec_enet_private { + /* Hardware registers of the FEC device */ +- volatile fec_t *hwp; ++ volatile fec_t *hwp; + + struct net_device *netdev; + + /* The saved address of a sent-in-place packet/buffer, for skfree(). */ + unsigned char *tx_bounce[TX_RING_SIZE]; +- struct sk_buff* tx_skbuff[TX_RING_SIZE]; +- ushort skb_cur; +- ushort skb_dirty; ++ struct sk_buff *tx_skbuff[TX_RING_SIZE]; ++ ushort skb_cur; ++ ushort skb_dirty; + + /* CPM dual port RAM relative addresses. +- */ +- cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */ +- cbd_t *tx_bd_base; +- cbd_t *cur_rx, *cur_tx; /* The next free ring entry */ +- cbd_t *dirty_tx; /* The ring entries to be free()ed. */ +- uint tx_full; +- spinlock_t lock; +- +- uint phy_id; +- uint phy_id_done; +- uint phy_status; +- uint phy_speed; +- phy_info_t const *phy; ++ */ ++ cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */ ++ cbd_t *tx_bd_base; ++ cbd_t *cur_rx, *cur_tx; /* The next free ring entry */ ++ cbd_t *dirty_tx; /* The ring entries to be free()ed. */ ++ uint tx_full; ++ /* hold while accessing the HW like ringbuffer for tx/rx but not MAC */ ++ spinlock_t hw_lock; ++ /* hold while accessing the mii_list_t() elements */ ++ spinlock_t mii_lock; ++ ++ uint phy_id; ++ uint phy_id_done; ++ uint phy_status; ++ uint phy_speed; ++ phy_info_t const *phy; + struct work_struct phy_task; + +- uint sequence_done; +- uint mii_phy_task_queued; ++ uint sequence_done; ++ uint mii_phy_task_queued; ++ ++ uint phy_addr; + +- uint phy_addr; ++ int index; ++ int opened; ++ int link; ++ int old_link; ++ int full_duplex; ++}; + +- int index; +- int opened; +- int link; +- int old_link; +- int full_duplex; +-}; +- +-static int fec_enet_open(struct net_device *dev); +-static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev); +-static void fec_enet_mii(struct net_device *dev); +-static irqreturn_t fec_enet_interrupt(int irq, void * dev_id); +-static void fec_enet_tx(struct net_device *dev); +-static void fec_enet_rx(struct net_device *dev); +-static int fec_enet_close(struct net_device *dev); +-static void set_multicast_list(struct net_device *dev); + static void fec_restart(struct net_device *dev, int duplex); + static void fec_stop(struct net_device *dev); +-static void fec_set_mac_address(struct net_device *dev); +- + + /* MII processing. We keep this as simple as possible. Requests are + * placed on the list (if there is room). When the request is finished + * by the MII, an optional function may be called. + */ + typedef struct mii_list { +- uint mii_regval; +- void (*mii_func)(uint val, struct net_device *dev); +- struct mii_list *mii_next; ++ uint mii_regval; ++ void (*mii_func)(uint val, struct net_device *dev); ++ struct mii_list *mii_next; + } mii_list_t; + +-#define NMII 20 +-static mii_list_t mii_cmds[NMII]; +-static mii_list_t *mii_free; +-static mii_list_t *mii_head; +-static mii_list_t *mii_tail; ++#define NMII 20 ++static mii_list_t mii_cmds[NMII]; ++static mii_list_t *mii_free; ++static mii_list_t *mii_head; ++static mii_list_t *mii_tail; + +-static int mii_queue(struct net_device *dev, int request, +- void (*func)(uint, struct net_device *)); ++static int mii_queue(struct net_device *dev, int request, mii_func *funct); + + /* Make MII read/write commands for the FEC. + */ +@@ -272,52 +250,52 @@ static int mii_queue(struct net_device * + /* Register definitions for the PHY. + */ + +-#define MII_REG_CR 0 /* Control Register */ +-#define MII_REG_SR 1 /* Status Register */ +-#define MII_REG_PHYIR1 2 /* PHY Identification Register 1 */ +-#define MII_REG_PHYIR2 3 /* PHY Identification Register 2 */ +-#define MII_REG_ANAR 4 /* A-N Advertisement Register */ +-#define MII_REG_ANLPAR 5 /* A-N Link Partner Ability Register */ +-#define MII_REG_ANER 6 /* A-N Expansion Register */ +-#define MII_REG_ANNPTR 7 /* A-N Next Page Transmit Register */ +-#define MII_REG_ANLPRNPR 8 /* A-N Link Partner Received Next Page Reg. */ ++#define MII_REG_CR 0 /* Control Register */ ++#define MII_REG_SR 1 /* Status Register */ ++#define MII_REG_PHYIR1 2 /* PHY Identification Register 1 */ ++#define MII_REG_PHYIR2 3 /* PHY Identification Register 2 */ ++#define MII_REG_ANAR 4 /* A-N Advertisement Register */ ++#define MII_REG_ANLPAR 5 /* A-N Link Partner Ability Register */ ++#define MII_REG_ANER 6 /* A-N Expansion Register */ ++#define MII_REG_ANNPTR 7 /* A-N Next Page Transmit Register */ ++#define MII_REG_ANLPRNPR 8 /* A-N Link Partner Received Next Page Reg. */ + + /* values for phy_status */ + +-#define PHY_CONF_ANE 0x0001 /* 1 auto-negotiation enabled */ +-#define PHY_CONF_LOOP 0x0002 /* 1 loopback mode enabled */ +-#define PHY_CONF_SPMASK 0x00f0 /* mask for speed */ +-#define PHY_CONF_10HDX 0x0010 /* 10 Mbit half duplex supported */ +-#define PHY_CONF_10FDX 0x0020 /* 10 Mbit full duplex supported */ +-#define PHY_CONF_100HDX 0x0040 /* 100 Mbit half duplex supported */ +-#define PHY_CONF_100FDX 0x0080 /* 100 Mbit full duplex supported */ +- +-#define PHY_STAT_LINK 0x0100 /* 1 up - 0 down */ +-#define PHY_STAT_FAULT 0x0200 /* 1 remote fault */ +-#define PHY_STAT_ANC 0x0400 /* 1 auto-negotiation complete */ +-#define PHY_STAT_SPMASK 0xf000 /* mask for speed */ +-#define PHY_STAT_10HDX 0x1000 /* 10 Mbit half duplex selected */ +-#define PHY_STAT_10FDX 0x2000 /* 10 Mbit full duplex selected */ +-#define PHY_STAT_100HDX 0x4000 /* 100 Mbit half duplex selected */ +-#define PHY_STAT_100FDX 0x8000 /* 100 Mbit full duplex selected */ ++#define PHY_CONF_ANE 0x0001 /* 1 auto-negotiation enabled */ ++#define PHY_CONF_LOOP 0x0002 /* 1 loopback mode enabled */ ++#define PHY_CONF_SPMASK 0x00f0 /* mask for speed */ ++#define PHY_CONF_10HDX 0x0010 /* 10 Mbit half duplex supported */ ++#define PHY_CONF_10FDX 0x0020 /* 10 Mbit full duplex supported */ ++#define PHY_CONF_100HDX 0x0040 /* 100 Mbit half duplex supported */ ++#define PHY_CONF_100FDX 0x0080 /* 100 Mbit full duplex supported */ ++ ++#define PHY_STAT_LINK 0x0100 /* 1 up - 0 down */ ++#define PHY_STAT_FAULT 0x0200 /* 1 remote fault */ ++#define PHY_STAT_ANC 0x0400 /* 1 auto-negotiation complete */ ++#define PHY_STAT_SPMASK 0xf000 /* mask for speed */ ++#define PHY_STAT_10HDX 0x1000 /* 10 Mbit half duplex selected */ ++#define PHY_STAT_10FDX 0x2000 /* 10 Mbit full duplex selected */ ++#define PHY_STAT_100HDX 0x4000 /* 100 Mbit half duplex selected */ ++#define PHY_STAT_100FDX 0x8000 /* 100 Mbit full duplex selected */ + +- +-static int +-fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) ++static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) + { + struct fec_enet_private *fep; +- volatile fec_t *fecp; +- volatile cbd_t *bdp; +- unsigned short status; ++ volatile fec_t *fecp; ++ volatile cbd_t *bdp; ++ unsigned short status; ++ unsigned long flags; + + fep = netdev_priv(dev); +- fecp = (volatile fec_t*)dev->base_addr; ++ fecp = (volatile fec_t *)dev->base_addr; + + if (!fep->link) { + /* Link is down or autonegotiation is in progress. */ + return 1; + } + ++ spin_lock_irqsave(&fep->hw_lock, flags); + /* Fill in a Tx ring entry */ + bdp = fep->cur_tx; + +@@ -328,6 +306,7 @@ fec_enet_start_xmit(struct sk_buff *skb, + * This should not happen, since dev->tbusy should be set. + */ + printk("%s: tx queue full!.\n", dev->name); ++ spin_unlock_irqrestore(&fep->hw_lock, flags); + return 1; + } + #endif +@@ -337,28 +316,29 @@ fec_enet_start_xmit(struct sk_buff *skb, + status &= ~BD_ENET_TX_STATS; + + /* Set buffer length and buffer pointer. +- */ ++ */ + bdp->cbd_bufaddr = __pa(skb->data); + bdp->cbd_datlen = skb->len; + + /* +- * On some FEC implementations data must be aligned on +- * 4-byte boundaries. Use bounce buffers to copy data +- * and get it aligned. Ugh. ++ * On some FEC implementations data must be aligned on ++ * 4-byte boundaries. Use bounce buffers to copy data ++ * and get it aligned. Ugh. + */ + if (bdp->cbd_bufaddr & 0x3) { + unsigned int index; + index = bdp - fep->tx_bd_base; +- memcpy(fep->tx_bounce[index], (void *) bdp->cbd_bufaddr, bdp->cbd_datlen); ++ memcpy(fep->tx_bounce[index], (void *)bdp->cbd_bufaddr, ++ bdp->cbd_datlen); + bdp->cbd_bufaddr = __pa(fep->tx_bounce[index]); + } + + /* Save skb pointer. +- */ ++ */ + fep->tx_skbuff[fep->skb_cur] = skb; + + dev->stats.tx_bytes += skb->len; +- fep->skb_cur = (fep->skb_cur+1) & TX_RING_MOD_MASK; ++ fep->skb_cur = (fep->skb_cur + 1) & TX_RING_MOD_MASK; + + /* Push the data cache so the CPM does not get stale memory + * data. +@@ -366,14 +346,13 @@ fec_enet_start_xmit(struct sk_buff *skb, + flush_dcache_range((unsigned long)skb->data, + (unsigned long)skb->data + skb->len); + +- spin_lock_irq(&fep->lock); + + /* Send it on its way. Tell FEC it's ready, interrupt when done, + * it's the last BD of the frame, and to put the CRC on the end. + */ + + status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR +- | BD_ENET_TX_LAST | BD_ENET_TX_TC); ++ | BD_ENET_TX_LAST | BD_ENET_TX_TC); + bdp->cbd_sc = status; + + dev->trans_start = jiffies; +@@ -382,7 +361,7 @@ fec_enet_start_xmit(struct sk_buff *skb, + fecp->fec_x_des_active = 0; + + /* If this was the last BD in the ring, start at the beginning again. +- */ ++ */ + if (status & BD_ENET_TX_WRAP) { + bdp = fep->tx_bd_base; + } else { +@@ -394,15 +373,14 @@ fec_enet_start_xmit(struct sk_buff *skb, + netif_stop_queue(dev); + } + +- fep->cur_tx = (cbd_t *)bdp; ++ fep->cur_tx = (cbd_t *) bdp; + +- spin_unlock_irq(&fep->lock); ++ spin_unlock_irqrestore(&fep->hw_lock, flags); + + return 0; + } + +-static void +-fec_timeout(struct net_device *dev) ++static void fec_timeout(struct net_device *dev) + { + struct fec_enet_private *fep = netdev_priv(dev); + +@@ -410,115 +388,200 @@ fec_timeout(struct net_device *dev) + dev->stats.tx_errors++; + #ifndef final_version + { +- int i; +- cbd_t *bdp; ++ int i; ++ cbd_t *bdp; + +- printk("Ring data dump: cur_tx %lx%s, dirty_tx %lx cur_rx: %lx\n", +- (unsigned long)fep->cur_tx, fep->tx_full ? " (full)" : "", +- (unsigned long)fep->dirty_tx, +- (unsigned long)fep->cur_rx); ++ printk ++ ("Ring data dump: cur_tx %lx%s, dirty_tx %lx cur_rx: %lx\n", ++ (unsigned long)fep->cur_tx, fep->tx_full ? " (full)" : "", ++ (unsigned long)fep->dirty_tx, (unsigned long)fep->cur_rx); + +- bdp = fep->tx_bd_base; +- printk(" tx: %u buffers\n", TX_RING_SIZE); +- for (i = 0 ; i < TX_RING_SIZE; i++) { +- printk(" %08x: %04x %04x %08x\n", +- (uint) bdp, +- bdp->cbd_sc, +- bdp->cbd_datlen, +- (int) bdp->cbd_bufaddr); +- bdp++; +- } ++ bdp = fep->tx_bd_base; ++ printk(" tx: %u buffers\n", TX_RING_SIZE); ++ for (i = 0; i < TX_RING_SIZE; i++) { ++ printk(" %08x: %04x %04x %08x\n", ++ (uint) bdp, ++ bdp->cbd_sc, ++ bdp->cbd_datlen, (int)bdp->cbd_bufaddr); ++ bdp++; ++ } + +- bdp = fep->rx_bd_base; +- printk(" rx: %lu buffers\n", (unsigned long) RX_RING_SIZE); +- for (i = 0 ; i < RX_RING_SIZE; i++) { +- printk(" %08x: %04x %04x %08x\n", +- (uint) bdp, +- bdp->cbd_sc, +- bdp->cbd_datlen, +- (int) bdp->cbd_bufaddr); +- bdp++; +- } ++ bdp = fep->rx_bd_base; ++ printk(" rx: %lu buffers\n", (unsigned long)RX_RING_SIZE); ++ for (i = 0; i < RX_RING_SIZE; i++) { ++ printk(" %08x: %04x %04x %08x\n", ++ (uint) bdp, ++ bdp->cbd_sc, ++ bdp->cbd_datlen, (int)bdp->cbd_bufaddr); ++ bdp++; ++ } + } + #endif + fec_restart(dev, fep->full_duplex); + netif_wake_queue(dev); + } + +-/* The interrupt handler. +- * This is called from the MPC core interrupt. ++/* During a receive, the cur_rx points to the current incoming buffer. ++ * When we update through the ring, if the next incoming buffer has ++ * not been given to the system, we just set the empty indicator, ++ * effectively tossing the packet. + */ +-static irqreturn_t +-fec_enet_interrupt(int irq, void * dev_id) ++static void fec_enet_rx(struct net_device *dev) + { +- struct net_device *dev = dev_id; +- volatile fec_t *fecp; +- uint int_events; +- int handled = 0; ++ struct fec_enet_private *fep; ++ volatile fec_t *fecp; ++ volatile cbd_t *bdp; ++ unsigned short status; ++ struct sk_buff *skb; ++ ushort pkt_len; ++ __u8 *data; + +- fecp = (volatile fec_t*)dev->base_addr; ++#ifdef CONFIG_M532x ++ flush_cache_all(); ++#endif + +- /* Get the interrupt events that caused us to be here. +- */ +- while ((int_events = fecp->fec_ievent) != 0) { +- fecp->fec_ievent = int_events; ++ fep = netdev_priv(dev); ++ spin_lock_irq(&fep->hw_lock); ++ fecp = (volatile fec_t *)dev->base_addr; + +- /* Handle receive event in its own function. ++ /* First, grab all of the stats for the incoming packet. ++ * These get messed up if we get called due to a busy condition. ++ */ ++ bdp = fep->cur_rx; ++ ++ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { ++ ++#ifndef final_version ++ /* Since we have allocated space to hold a complete frame, ++ * the last indicator should be set. + */ +- if (int_events & FEC_ENET_RXF) { +- handled = 1; +- fec_enet_rx(dev); ++ if ((status & BD_ENET_RX_LAST) == 0) ++ printk("FEC ENET: rcv is not +last\n"); ++#endif ++ ++ if (!fep->opened) ++ goto rx_processing_done; ++ ++ /* Check for errors. */ ++ if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO | ++ BD_ENET_RX_CR | BD_ENET_RX_OV)) { ++ dev->stats.rx_errors++; ++ if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) { ++ /* Frame too long or too short. */ ++ dev->stats.rx_length_errors++; ++ } ++ if (status & BD_ENET_RX_NO) /* Frame alignment */ ++ dev->stats.rx_frame_errors++; ++ if (status & BD_ENET_RX_CR) /* CRC Error */ ++ dev->stats.rx_crc_errors++; ++ if (status & BD_ENET_RX_OV) /* FIFO overrun */ ++ dev->stats.rx_fifo_errors++; + } + +- /* Transmit OK, or non-fatal error. Update the buffer +- descriptors. FEC handles all errors, we just discover +- them as part of the transmit process. +- */ +- if (int_events & FEC_ENET_TXF) { +- handled = 1; +- fec_enet_tx(dev); ++ /* Report late collisions as a frame error. ++ * On this error, the BD is closed, but we don't know what we ++ * have in the buffer. So, just drop this frame on the floor. ++ */ ++ if (status & BD_ENET_RX_CL) { ++ dev->stats.rx_errors++; ++ dev->stats.rx_frame_errors++; ++ goto rx_processing_done; + } + +- if (int_events & FEC_ENET_MII) { +- handled = 1; +- fec_enet_mii(dev); ++ /* Process the incoming frame. ++ */ ++ dev->stats.rx_packets++; ++ pkt_len = bdp->cbd_datlen; ++ dev->stats.rx_bytes += pkt_len; ++ data = (__u8 *) __va(bdp->cbd_bufaddr); ++ ++ /* This does 16 byte alignment, exactly what we need. ++ * The packet length includes FCS, but we don't want to ++ * include that when passing upstream as it messes up ++ * bridging applications. ++ */ ++ skb = dev_alloc_skb(pkt_len - 4); ++ ++ if (skb == NULL) { ++ printk("%s: Memory squeeze, dropping packet.\n", ++ dev->name); ++ dev->stats.rx_dropped++; ++ } else { ++ skb_put(skb, pkt_len - 4); /* Make room */ ++ skb_copy_to_linear_data(skb, data, pkt_len - 4); ++ skb->protocol = eth_type_trans(skb, dev); ++ netif_rx(skb); + } ++rx_processing_done: + +- } +- return IRQ_RETVAL(handled); +-} ++ /* Clear the status flags for this buffer. ++ */ ++ status &= ~BD_ENET_RX_STATS; + ++ /* Mark the buffer empty. ++ */ ++ status |= BD_ENET_RX_EMPTY; ++ bdp->cbd_sc = status; + +-static void +-fec_enet_tx(struct net_device *dev) ++ /* Update BD pointer to next entry. ++ */ ++ if (status & BD_ENET_RX_WRAP) ++ bdp = fep->rx_bd_base; ++ else ++ bdp++; ++ ++#if 1 ++ /* Doing this here will keep the FEC running while we process ++ * incoming frames. On a heavily loaded network, we should be ++ * able to keep up at the expense of system resources. ++ */ ++ fecp->fec_r_des_active = 0; ++#endif ++ } /* while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) */ ++ fep->cur_rx = (cbd_t *) bdp; ++ ++#if 0 ++ /* Doing this here will allow us to process all frames in the ++ * ring before the FEC is allowed to put more there. On a heavily ++ * loaded network, some frames may be lost. Unfortunately, this ++ * increases the interrupt overhead since we can potentially work ++ * our way back to the interrupt return only to come right back ++ * here. ++ */ ++ fecp->fec_r_des_active = 0; ++#endif ++ spin_unlock_irq(&fep->hw_lock); ++} ++ ++static void fec_enet_tx(struct net_device *dev) + { +- struct fec_enet_private *fep; +- volatile cbd_t *bdp; ++ struct fec_enet_private *fep; ++ volatile cbd_t *bdp; + unsigned short status; +- struct sk_buff *skb; ++ struct sk_buff *skb; + + fep = netdev_priv(dev); +- spin_lock(&fep->lock); ++ spin_lock_irq(&fep->hw_lock); + bdp = fep->dirty_tx; + + while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) { +- if (bdp == fep->cur_tx && fep->tx_full == 0) break; ++ if (bdp == fep->cur_tx && fep->tx_full == 0) ++ break; + + skb = fep->tx_skbuff[fep->skb_dirty]; + /* Check for errors. */ + if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC | +- BD_ENET_TX_RL | BD_ENET_TX_UN | +- BD_ENET_TX_CSL)) { ++ BD_ENET_TX_RL | BD_ENET_TX_UN | BD_ENET_TX_CSL)) { + dev->stats.tx_errors++; +- if (status & BD_ENET_TX_HB) /* No heartbeat */ ++ if (status & BD_ENET_TX_HB) /* No heartbeat */ + dev->stats.tx_heartbeat_errors++; +- if (status & BD_ENET_TX_LC) /* Late collision */ ++ if (status & BD_ENET_TX_LC) /* Late collision */ + dev->stats.tx_window_errors++; +- if (status & BD_ENET_TX_RL) /* Retrans limit */ ++ if (status & BD_ENET_TX_RL) /* Retrans limit */ + dev->stats.tx_aborted_errors++; +- if (status & BD_ENET_TX_UN) /* Underrun */ ++ if (status & BD_ENET_TX_UN) /* Underrun */ + dev->stats.tx_fifo_errors++; +- if (status & BD_ENET_TX_CSL) /* Carrier lost */ ++ if (status & BD_ENET_TX_CSL) /* Carrier lost */ + dev->stats.tx_carrier_errors++; + } else { + dev->stats.tx_packets++; +@@ -556,164 +619,32 @@ fec_enet_tx(struct net_device *dev) + netif_wake_queue(dev); + } + } +- fep->dirty_tx = (cbd_t *)bdp; +- spin_unlock(&fep->lock); +-} +- +- +-/* During a receive, the cur_rx points to the current incoming buffer. +- * When we update through the ring, if the next incoming buffer has +- * not been given to the system, we just set the empty indicator, +- * effectively tossing the packet. +- */ +-static void +-fec_enet_rx(struct net_device *dev) +-{ +- struct fec_enet_private *fep; +- volatile fec_t *fecp; +- volatile cbd_t *bdp; +- unsigned short status; +- struct sk_buff *skb; +- ushort pkt_len; +- __u8 *data; +- +-#ifdef CONFIG_M532x +- flush_cache_all(); +-#endif +- +- fep = netdev_priv(dev); +- fecp = (volatile fec_t*)dev->base_addr; +- +- /* First, grab all of the stats for the incoming packet. +- * These get messed up if we get called due to a busy condition. +- */ +- bdp = fep->cur_rx; +- +-while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { +- +-#ifndef final_version +- /* Since we have allocated space to hold a complete frame, +- * the last indicator should be set. +- */ +- if ((status & BD_ENET_RX_LAST) == 0) +- printk("FEC ENET: rcv is not +last\n"); +-#endif +- +- if (!fep->opened) +- goto rx_processing_done; +- +- /* Check for errors. */ +- if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO | +- BD_ENET_RX_CR | BD_ENET_RX_OV)) { +- dev->stats.rx_errors++; +- if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) { +- /* Frame too long or too short. */ +- dev->stats.rx_length_errors++; +- } +- if (status & BD_ENET_RX_NO) /* Frame alignment */ +- dev->stats.rx_frame_errors++; +- if (status & BD_ENET_RX_CR) /* CRC Error */ +- dev->stats.rx_crc_errors++; +- if (status & BD_ENET_RX_OV) /* FIFO overrun */ +- dev->stats.rx_fifo_errors++; +- } +- +- /* Report late collisions as a frame error. +- * On this error, the BD is closed, but we don't know what we +- * have in the buffer. So, just drop this frame on the floor. +- */ +- if (status & BD_ENET_RX_CL) { +- dev->stats.rx_errors++; +- dev->stats.rx_frame_errors++; +- goto rx_processing_done; +- } +- +- /* Process the incoming frame. +- */ +- dev->stats.rx_packets++; +- pkt_len = bdp->cbd_datlen; +- dev->stats.rx_bytes += pkt_len; +- data = (__u8*)__va(bdp->cbd_bufaddr); +- +- /* This does 16 byte alignment, exactly what we need. +- * The packet length includes FCS, but we don't want to +- * include that when passing upstream as it messes up +- * bridging applications. +- */ +- skb = dev_alloc_skb(pkt_len-4); +- +- if (skb == NULL) { +- printk("%s: Memory squeeze, dropping packet.\n", dev->name); +- dev->stats.rx_dropped++; +- } else { +- skb_put(skb,pkt_len-4); /* Make room */ +- skb_copy_to_linear_data(skb, data, pkt_len-4); +- skb->protocol=eth_type_trans(skb,dev); +- netif_rx(skb); +- } +- rx_processing_done: +- +- /* Clear the status flags for this buffer. +- */ +- status &= ~BD_ENET_RX_STATS; +- +- /* Mark the buffer empty. +- */ +- status |= BD_ENET_RX_EMPTY; +- bdp->cbd_sc = status; +- +- /* Update BD pointer to next entry. +- */ +- if (status & BD_ENET_RX_WRAP) +- bdp = fep->rx_bd_base; +- else +- bdp++; +- +-#if 1 +- /* Doing this here will keep the FEC running while we process +- * incoming frames. On a heavily loaded network, we should be +- * able to keep up at the expense of system resources. +- */ +- fecp->fec_r_des_active = 0; +-#endif +- } /* while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) */ +- fep->cur_rx = (cbd_t *)bdp; +- +-#if 0 +- /* Doing this here will allow us to process all frames in the +- * ring before the FEC is allowed to put more there. On a heavily +- * loaded network, some frames may be lost. Unfortunately, this +- * increases the interrupt overhead since we can potentially work +- * our way back to the interrupt return only to come right back +- * here. +- */ +- fecp->fec_r_des_active = 0; +-#endif ++ fep->dirty_tx = (cbd_t *) bdp; ++ spin_unlock_irq(&fep->hw_lock); + } + +- + /* called from interrupt context */ +-static void +-fec_enet_mii(struct net_device *dev) ++static void fec_enet_mii(struct net_device *dev) + { +- struct fec_enet_private *fep; +- volatile fec_t *ep; +- mii_list_t *mip; +- uint mii_reg; ++ struct fec_enet_private *fep; ++ volatile fec_t *ep; ++ mii_list_t *mip; ++ uint mii_reg; ++ mii_func *mii_func = NULL; + + fep = netdev_priv(dev); ++ spin_lock_irq(&fep->mii_lock); ++ + ep = fep->hwp; + mii_reg = ep->fec_mii_data; + +- spin_lock(&fep->lock); +- + if ((mip = mii_head) == NULL) { + printk("MII and no head!\n"); + goto unlock; + } + + if (mip->mii_func != NULL) +- (*(mip->mii_func))(mii_reg, dev); ++ mii_func = *(mip->mii_func); + + mii_head = mip->mii_next; + mip->mii_next = mii_free; +@@ -723,26 +654,71 @@ fec_enet_mii(struct net_device *dev) + ep->fec_mii_data = mip->mii_regval; + + unlock: +- spin_unlock(&fep->lock); ++ spin_unlock_irq(&fep->mii_lock); ++ if (mii_func) ++ mii_func(mii_reg, dev); + } + +-static int +-mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_device *)) ++/* The interrupt handler. ++ * This is called from the MPC core interrupt. ++ */ ++static irqreturn_t fec_enet_interrupt(int irq, void *dev_id) ++{ ++ struct net_device *dev = dev_id; ++ volatile fec_t *fecp; ++ uint int_events; ++ irqreturn_t ret = IRQ_NONE; ++ ++ fecp = (volatile fec_t *)dev->base_addr; ++ ++ /* Get the interrupt events that caused us to be here. ++ */ ++ do { ++ int_events = fecp->fec_ievent; ++ fecp->fec_ievent = int_events; ++ ++ /* Handle receive event in its own function. ++ */ ++ if (int_events & FEC_ENET_RXF) { ++ ret = IRQ_HANDLED; ++ fec_enet_rx(dev); ++ } ++ ++ /* Transmit OK, or non-fatal error. Update the buffer ++ descriptors. FEC handles all errors, we just discover ++ them as part of the transmit process. ++ */ ++ if (int_events & FEC_ENET_TXF) { ++ ret = IRQ_HANDLED; ++ fec_enet_tx(dev); ++ } ++ ++ if (int_events & FEC_ENET_MII) { ++ ret = IRQ_HANDLED; ++ fec_enet_mii(dev); ++ } ++ ++ } while (int_events); ++ ++ return ret; ++} ++ ++ ++static int mii_queue(struct net_device *dev, int regval, mii_func *func) + { + struct fec_enet_private *fep; +- unsigned long flags; +- mii_list_t *mip; +- int retval; ++ unsigned long flags; ++ mii_list_t *mip; ++ int retval; + + /* Add PHY address to register command. +- */ ++ */ + fep = netdev_priv(dev); +- regval |= fep->phy_addr << 23; ++ spin_lock_irqsave(&fep->mii_lock, flags); + ++ regval |= fep->phy_addr << 23; + retval = 0; + +- spin_lock_irqsave(&fep->lock,flags); +- + if ((mip = mii_free) != NULL) { + mii_free = mip->mii_next; + mip->mii_regval = regval; +@@ -759,14 +735,13 @@ mii_queue(struct net_device *dev, int re + retval = 1; + } + +- spin_unlock_irqrestore(&fep->lock,flags); +- +- return(retval); ++ spin_unlock_irqrestore(&fep->mii_lock, flags); ++ return retval; + } + + static void mii_do_cmd(struct net_device *dev, const phy_cmd_t *c) + { +- if(!c) ++ if (!c) + return; + + for (; c->mii_data != mk_mii_end; c++) +@@ -827,11 +802,11 @@ static void mii_parse_anar(uint mii_reg, + /* ------------------------------------------------------------------------- */ + /* The Level one LXT970 is used by many boards */ + +-#define MII_LXT970_MIRROR 16 /* Mirror register */ +-#define MII_LXT970_IER 17 /* Interrupt Enable Register */ +-#define MII_LXT970_ISR 18 /* Interrupt Status Register */ +-#define MII_LXT970_CONFIG 19 /* Configuration Register */ +-#define MII_LXT970_CSR 20 /* Chip Status Register */ ++#define MII_LXT970_MIRROR 16 /* Mirror register */ ++#define MII_LXT970_IER 17 /* Interrupt Enable Register */ ++#define MII_LXT970_ISR 18 /* Interrupt Status Register */ ++#define MII_LXT970_CONFIG 19 /* Configuration Register */ ++#define MII_LXT970_CSR 20 /* Chip Status Register */ + + static void mii_parse_lxt970_csr(uint mii_reg, struct net_device *dev) + { +@@ -855,28 +830,28 @@ static void mii_parse_lxt970_csr(uint mi + } + + static phy_cmd_t const phy_cmd_lxt970_config[] = { +- { mk_mii_read(MII_REG_CR), mii_parse_cr }, +- { mk_mii_read(MII_REG_ANAR), mii_parse_anar }, +- { mk_mii_end, } +- }; +-static phy_cmd_t const phy_cmd_lxt970_startup[] = { /* enable interrupts */ +- { mk_mii_write(MII_LXT970_IER, 0x0002), NULL }, +- { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ +- { mk_mii_end, } +- }; ++ {mk_mii_read(MII_REG_CR), mii_parse_cr}, ++ {mk_mii_read(MII_REG_ANAR), mii_parse_anar}, ++ {mk_mii_end,} ++}; ++static phy_cmd_t const phy_cmd_lxt970_startup[] = { /* enable interrupts */ ++ {mk_mii_write(MII_LXT970_IER, 0x0002), NULL}, ++ {mk_mii_write(MII_REG_CR, 0x1200), NULL}, /* autonegotiate */ ++ {mk_mii_end,} ++}; + static phy_cmd_t const phy_cmd_lxt970_ack_int[] = { +- /* read SR and ISR to acknowledge */ +- { mk_mii_read(MII_REG_SR), mii_parse_sr }, +- { mk_mii_read(MII_LXT970_ISR), NULL }, +- +- /* find out the current status */ +- { mk_mii_read(MII_LXT970_CSR), mii_parse_lxt970_csr }, +- { mk_mii_end, } +- }; +-static phy_cmd_t const phy_cmd_lxt970_shutdown[] = { /* disable interrupts */ +- { mk_mii_write(MII_LXT970_IER, 0x0000), NULL }, +- { mk_mii_end, } +- }; ++ /* read SR and ISR to acknowledge */ ++ {mk_mii_read(MII_REG_SR), mii_parse_sr}, ++ {mk_mii_read(MII_LXT970_ISR), NULL}, ++ ++ /* find out the current status */ ++ {mk_mii_read(MII_LXT970_CSR), mii_parse_lxt970_csr}, ++ {mk_mii_end,} ++}; ++static phy_cmd_t const phy_cmd_lxt970_shutdown[] = { /* disable interrupts */ ++ {mk_mii_write(MII_LXT970_IER, 0x0000), NULL}, ++ {mk_mii_end,} ++}; + static phy_info_t const phy_info_lxt970 = { + .id = 0x07810000, + .name = "LXT970", +@@ -891,12 +866,12 @@ static phy_info_t const phy_info_lxt970 + + /* register definitions for the 971 */ + +-#define MII_LXT971_PCR 16 /* Port Control Register */ +-#define MII_LXT971_SR2 17 /* Status Register 2 */ +-#define MII_LXT971_IER 18 /* Interrupt Enable Register */ +-#define MII_LXT971_ISR 19 /* Interrupt Status Register */ +-#define MII_LXT971_LCR 20 /* LED Control Register */ +-#define MII_LXT971_TCR 30 /* Transmit Control Register */ ++#define MII_LXT971_PCR 16 /* Port Control Register */ ++#define MII_LXT971_SR2 17 /* Status Register 2 */ ++#define MII_LXT971_IER 18 /* Interrupt Enable Register */ ++#define MII_LXT971_ISR 19 /* Interrupt Status Register */ ++#define MII_LXT971_LCR 20 /* LED Control Register */ ++#define MII_LXT971_TCR 30 /* Transmit Control Register */ + + /* + * I had some nice ideas of running the MDIO faster... +@@ -938,35 +913,35 @@ static void mii_parse_lxt971_sr2(uint mi + } + + static phy_cmd_t const phy_cmd_lxt971_config[] = { +- /* limit to 10MBit because my prototype board +- * doesn't work with 100. */ +- { mk_mii_read(MII_REG_CR), mii_parse_cr }, +- { mk_mii_read(MII_REG_ANAR), mii_parse_anar }, +- { mk_mii_read(MII_LXT971_SR2), mii_parse_lxt971_sr2 }, +- { mk_mii_end, } +- }; +-static phy_cmd_t const phy_cmd_lxt971_startup[] = { /* enable interrupts */ +- { mk_mii_write(MII_LXT971_IER, 0x00f2), NULL }, +- { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ +- { mk_mii_write(MII_LXT971_LCR, 0xd422), NULL }, /* LED config */ +- /* Somehow does the 971 tell me that the link is down +- * the first read after power-up. +- * read here to get a valid value in ack_int */ +- { mk_mii_read(MII_REG_SR), mii_parse_sr }, +- { mk_mii_end, } +- }; ++ /* limit to 10MBit because my prototype board ++ * doesn't work with 100. */ ++ {mk_mii_read(MII_REG_CR), mii_parse_cr}, ++ {mk_mii_read(MII_REG_ANAR), mii_parse_anar}, ++ {mk_mii_read(MII_LXT971_SR2), mii_parse_lxt971_sr2}, ++ {mk_mii_end,} ++}; ++static phy_cmd_t const phy_cmd_lxt971_startup[] = { /* enable interrupts */ ++ {mk_mii_write(MII_LXT971_IER, 0x00f2), NULL}, ++ {mk_mii_write(MII_REG_CR, 0x1200), NULL}, /* autonegotiate */ ++ {mk_mii_write(MII_LXT971_LCR, 0xd422), NULL}, /* LED config */ ++ /* Somehow does the 971 tell me that the link is down ++ * the first read after power-up. ++ * read here to get a valid value in ack_int */ ++ {mk_mii_read(MII_REG_SR), mii_parse_sr}, ++ {mk_mii_end,} ++}; + static phy_cmd_t const phy_cmd_lxt971_ack_int[] = { +- /* acknowledge the int before reading status ! */ +- { mk_mii_read(MII_LXT971_ISR), NULL }, +- /* find out the current status */ +- { mk_mii_read(MII_REG_SR), mii_parse_sr }, +- { mk_mii_read(MII_LXT971_SR2), mii_parse_lxt971_sr2 }, +- { mk_mii_end, } +- }; +-static phy_cmd_t const phy_cmd_lxt971_shutdown[] = { /* disable interrupts */ +- { mk_mii_write(MII_LXT971_IER, 0x0000), NULL }, +- { mk_mii_end, } +- }; ++ /* acknowledge the int before reading status ! */ ++ {mk_mii_read(MII_LXT971_ISR), NULL}, ++ /* find out the current status */ ++ {mk_mii_read(MII_REG_SR), mii_parse_sr}, ++ {mk_mii_read(MII_LXT971_SR2), mii_parse_lxt971_sr2}, ++ {mk_mii_end,} ++}; ++static phy_cmd_t const phy_cmd_lxt971_shutdown[] = { /* disable interrupts */ ++ {mk_mii_write(MII_LXT971_IER, 0x0000), NULL}, ++ {mk_mii_end,} ++}; + static phy_info_t const phy_info_lxt971 = { + .id = 0x0001378e, + .name = "LXT971", +@@ -981,12 +956,12 @@ static phy_info_t const phy_info_lxt971 + + /* register definitions */ + +-#define MII_QS6612_MCR 17 /* Mode Control Register */ +-#define MII_QS6612_FTR 27 /* Factory Test Register */ +-#define MII_QS6612_MCO 28 /* Misc. Control Register */ +-#define MII_QS6612_ISR 29 /* Interrupt Source Register */ +-#define MII_QS6612_IMR 30 /* Interrupt Mask Register */ +-#define MII_QS6612_PCR 31 /* 100BaseTx PHY Control Reg. */ ++#define MII_QS6612_MCR 17 /* Mode Control Register */ ++#define MII_QS6612_FTR 27 /* Factory Test Register */ ++#define MII_QS6612_MCO 28 /* Misc. Control Register */ ++#define MII_QS6612_ISR 29 /* Interrupt Source Register */ ++#define MII_QS6612_IMR 30 /* Interrupt Mask Register */ ++#define MII_QS6612_PCR 31 /* 100BaseTx PHY Control Reg. */ + + static void mii_parse_qs6612_pcr(uint mii_reg, struct net_device *dev) + { +@@ -996,46 +971,54 @@ static void mii_parse_qs6612_pcr(uint mi + + status = *s & ~(PHY_STAT_SPMASK); + +- switch((mii_reg >> 2) & 7) { +- case 1: status |= PHY_STAT_10HDX; break; +- case 2: status |= PHY_STAT_100HDX; break; +- case 5: status |= PHY_STAT_10FDX; break; +- case 6: status |= PHY_STAT_100FDX; break; +-} ++ switch ((mii_reg >> 2) & 7) { ++ case 1: ++ status |= PHY_STAT_10HDX; ++ break; ++ case 2: ++ status |= PHY_STAT_100HDX; ++ break; ++ case 5: ++ status |= PHY_STAT_10FDX; ++ break; ++ case 6: ++ status |= PHY_STAT_100FDX; ++ break; ++ } + + *s = status; + } + + static phy_cmd_t const phy_cmd_qs6612_config[] = { +- /* The PHY powers up isolated on the RPX, +- * so send a command to allow operation. +- */ +- { mk_mii_write(MII_QS6612_PCR, 0x0dc0), NULL }, ++ /* The PHY powers up isolated on the RPX, ++ * so send a command to allow operation. ++ */ ++ {mk_mii_write(MII_QS6612_PCR, 0x0dc0), NULL}, + +- /* parse cr and anar to get some info */ +- { mk_mii_read(MII_REG_CR), mii_parse_cr }, +- { mk_mii_read(MII_REG_ANAR), mii_parse_anar }, +- { mk_mii_end, } +- }; +-static phy_cmd_t const phy_cmd_qs6612_startup[] = { /* enable interrupts */ +- { mk_mii_write(MII_QS6612_IMR, 0x003a), NULL }, +- { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ +- { mk_mii_end, } +- }; ++ /* parse cr and anar to get some info */ ++ {mk_mii_read(MII_REG_CR), mii_parse_cr}, ++ {mk_mii_read(MII_REG_ANAR), mii_parse_anar}, ++ {mk_mii_end,} ++}; ++static phy_cmd_t const phy_cmd_qs6612_startup[] = { /* enable interrupts */ ++ {mk_mii_write(MII_QS6612_IMR, 0x003a), NULL}, ++ {mk_mii_write(MII_REG_CR, 0x1200), NULL}, /* autonegotiate */ ++ {mk_mii_end,} ++}; + static phy_cmd_t const phy_cmd_qs6612_ack_int[] = { +- /* we need to read ISR, SR and ANER to acknowledge */ +- { mk_mii_read(MII_QS6612_ISR), NULL }, +- { mk_mii_read(MII_REG_SR), mii_parse_sr }, +- { mk_mii_read(MII_REG_ANER), NULL }, +- +- /* read pcr to get info */ +- { mk_mii_read(MII_QS6612_PCR), mii_parse_qs6612_pcr }, +- { mk_mii_end, } +- }; +-static phy_cmd_t const phy_cmd_qs6612_shutdown[] = { /* disable interrupts */ +- { mk_mii_write(MII_QS6612_IMR, 0x0000), NULL }, +- { mk_mii_end, } +- }; ++ /* we need to read ISR, SR and ANER to acknowledge */ ++ {mk_mii_read(MII_QS6612_ISR), NULL}, ++ {mk_mii_read(MII_REG_SR), mii_parse_sr}, ++ {mk_mii_read(MII_REG_ANER), NULL}, ++ ++ /* read pcr to get info */ ++ {mk_mii_read(MII_QS6612_PCR), mii_parse_qs6612_pcr}, ++ {mk_mii_end,} ++}; ++static phy_cmd_t const phy_cmd_qs6612_shutdown[] = { /* disable interrupts */ ++ {mk_mii_write(MII_QS6612_IMR, 0x0000), NULL}, ++ {mk_mii_end,} ++}; + static phy_info_t const phy_info_qs6612 = { + .id = 0x00181440, + .name = "QS6612", +@@ -1050,13 +1033,13 @@ static phy_info_t const phy_info_qs6612 + + /* register definitions for the 874 */ + +-#define MII_AM79C874_MFR 16 /* Miscellaneous Feature Register */ +-#define MII_AM79C874_ICSR 17 /* Interrupt/Status Register */ +-#define MII_AM79C874_DR 18 /* Diagnostic Register */ +-#define MII_AM79C874_PMLR 19 /* Power and Loopback Register */ +-#define MII_AM79C874_MCR 21 /* ModeControl Register */ +-#define MII_AM79C874_DC 23 /* Disconnect Counter */ +-#define MII_AM79C874_REC 24 /* Recieve Error Counter */ ++#define MII_AM79C874_MFR 16 /* Miscellaneous Feature Register */ ++#define MII_AM79C874_ICSR 17 /* Interrupt/Status Register */ ++#define MII_AM79C874_DR 18 /* Diagnostic Register */ ++#define MII_AM79C874_PMLR 19 /* Power and Loopback Register */ ++#define MII_AM79C874_MCR 21 /* ModeControl Register */ ++#define MII_AM79C874_DC 23 /* Disconnect Counter */ ++#define MII_AM79C874_REC 24 /* Recieve Error Counter */ + + static void mii_parse_am79c874_dr(uint mii_reg, struct net_device *dev) + { +@@ -1069,37 +1052,39 @@ static void mii_parse_am79c874_dr(uint m + if (mii_reg & 0x0080) + status |= PHY_STAT_ANC; + if (mii_reg & 0x0400) +- status |= ((mii_reg & 0x0800) ? PHY_STAT_100FDX : PHY_STAT_100HDX); ++ status |= ++ ((mii_reg & 0x0800) ? PHY_STAT_100FDX : PHY_STAT_100HDX); + else +- status |= ((mii_reg & 0x0800) ? PHY_STAT_10FDX : PHY_STAT_10HDX); ++ status |= ++ ((mii_reg & 0x0800) ? PHY_STAT_10FDX : PHY_STAT_10HDX); + + *s = status; + } + + static phy_cmd_t const phy_cmd_am79c874_config[] = { +- { mk_mii_read(MII_REG_CR), mii_parse_cr }, +- { mk_mii_read(MII_REG_ANAR), mii_parse_anar }, +- { mk_mii_read(MII_AM79C874_DR), mii_parse_am79c874_dr }, +- { mk_mii_end, } +- }; +-static phy_cmd_t const phy_cmd_am79c874_startup[] = { /* enable interrupts */ +- { mk_mii_write(MII_AM79C874_ICSR, 0xff00), NULL }, +- { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ +- { mk_mii_read(MII_REG_SR), mii_parse_sr }, +- { mk_mii_end, } +- }; ++ {mk_mii_read(MII_REG_CR), mii_parse_cr}, ++ {mk_mii_read(MII_REG_ANAR), mii_parse_anar}, ++ {mk_mii_read(MII_AM79C874_DR), mii_parse_am79c874_dr}, ++ {mk_mii_end,} ++}; ++static phy_cmd_t const phy_cmd_am79c874_startup[] = { /* enable interrupts */ ++ {mk_mii_write(MII_AM79C874_ICSR, 0xff00), NULL}, ++ {mk_mii_write(MII_REG_CR, 0x1200), NULL}, /* autonegotiate */ ++ {mk_mii_read(MII_REG_SR), mii_parse_sr}, ++ {mk_mii_end,} ++}; + static phy_cmd_t const phy_cmd_am79c874_ack_int[] = { +- /* find out the current status */ +- { mk_mii_read(MII_REG_SR), mii_parse_sr }, +- { mk_mii_read(MII_AM79C874_DR), mii_parse_am79c874_dr }, +- /* we only need to read ISR to acknowledge */ +- { mk_mii_read(MII_AM79C874_ICSR), NULL }, +- { mk_mii_end, } +- }; +-static phy_cmd_t const phy_cmd_am79c874_shutdown[] = { /* disable interrupts */ +- { mk_mii_write(MII_AM79C874_ICSR, 0x0000), NULL }, +- { mk_mii_end, } +- }; ++ /* find out the current status */ ++ {mk_mii_read(MII_REG_SR), mii_parse_sr}, ++ {mk_mii_read(MII_AM79C874_DR), mii_parse_am79c874_dr}, ++ /* we only need to read ISR to acknowledge */ ++ {mk_mii_read(MII_AM79C874_ICSR), NULL}, ++ {mk_mii_end,} ++}; ++static phy_cmd_t const phy_cmd_am79c874_shutdown[] = { /* disable interrupts */ ++ {mk_mii_write(MII_AM79C874_ICSR, 0x0000), NULL}, ++ {mk_mii_end,} ++}; + static phy_info_t const phy_info_am79c874 = { + .id = 0x00022561, + .name = "AM79C874", +@@ -1109,7 +1094,6 @@ static phy_info_t const phy_info_am79c87 + .shutdown = phy_cmd_am79c874_shutdown + }; + +- + /* ------------------------------------------------------------------------- */ + /* Kendin KS8721BL phy */ + +@@ -1120,27 +1104,27 @@ static phy_info_t const phy_info_am79c87 + #define MII_KS8721BL_PHYCR 31 + + static phy_cmd_t const phy_cmd_ks8721bl_config[] = { +- { mk_mii_read(MII_REG_CR), mii_parse_cr }, +- { mk_mii_read(MII_REG_ANAR), mii_parse_anar }, +- { mk_mii_end, } +- }; +-static phy_cmd_t const phy_cmd_ks8721bl_startup[] = { /* enable interrupts */ +- { mk_mii_write(MII_KS8721BL_ICSR, 0xff00), NULL }, +- { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ +- { mk_mii_read(MII_REG_SR), mii_parse_sr }, +- { mk_mii_end, } +- }; ++ {mk_mii_read(MII_REG_CR), mii_parse_cr}, ++ {mk_mii_read(MII_REG_ANAR), mii_parse_anar}, ++ {mk_mii_end,} ++}; ++static phy_cmd_t const phy_cmd_ks8721bl_startup[] = { /* enable interrupts */ ++ {mk_mii_write(MII_KS8721BL_ICSR, 0xff00), NULL}, ++ {mk_mii_write(MII_REG_CR, 0x1200), NULL}, /* autonegotiate */ ++ {mk_mii_read(MII_REG_SR), mii_parse_sr}, ++ {mk_mii_end,} ++}; + static phy_cmd_t const phy_cmd_ks8721bl_ack_int[] = { +- /* find out the current status */ +- { mk_mii_read(MII_REG_SR), mii_parse_sr }, +- /* we only need to read ISR to acknowledge */ +- { mk_mii_read(MII_KS8721BL_ICSR), NULL }, +- { mk_mii_end, } +- }; +-static phy_cmd_t const phy_cmd_ks8721bl_shutdown[] = { /* disable interrupts */ +- { mk_mii_write(MII_KS8721BL_ICSR, 0x0000), NULL }, +- { mk_mii_end, } +- }; ++ /* find out the current status */ ++ {mk_mii_read(MII_REG_SR), mii_parse_sr}, ++ /* we only need to read ISR to acknowledge */ ++ {mk_mii_read(MII_KS8721BL_ICSR), NULL}, ++ {mk_mii_end,} ++}; ++static phy_cmd_t const phy_cmd_ks8721bl_shutdown[] = { /* disable interrupts */ ++ {mk_mii_write(MII_KS8721BL_ICSR, 0x0000), NULL}, ++ {mk_mii_end,} ++}; + static phy_info_t const phy_info_ks8721bl = { + .id = 0x00022161, + .name = "KS8721BL", +@@ -1153,7 +1137,7 @@ static phy_info_t const phy_info_ks8721b + /* ------------------------------------------------------------------------- */ + /* register definitions for the DP83848 */ + +-#define MII_DP8384X_PHYSTST 16 /* PHY Status Register */ ++#define MII_DP8384X_PHYSTST 16 /* PHY Status Register */ + + static void mii_parse_dp8384x_sr2(uint mii_reg, struct net_device *dev) + { +@@ -1169,15 +1153,19 @@ static void mii_parse_dp8384x_sr2(uint m + } else + fep->link = 0; + /* Status of link */ +- if (mii_reg & 0x0010) /* Autonegotioation complete */ ++ if (mii_reg & 0x0010) /* Autonegotioation complete */ + *s |= PHY_STAT_ANC; +- if (mii_reg & 0x0002) { /* 10MBps? */ +- if (mii_reg & 0x0004) /* Full Duplex? */ ++ /* 10MBps? */ ++ if (mii_reg & 0x0002) { ++ /* Full Duplex? */ ++ if (mii_reg & 0x0004) + *s |= PHY_STAT_10FDX; + else + *s |= PHY_STAT_10HDX; +- } else { /* 100 Mbps? */ +- if (mii_reg & 0x0004) /* Full Duplex? */ ++ } else { ++ /* 100 Mbps then */ ++ /* Full Duplex? */ ++ if (mii_reg & 0x0004) + *s |= PHY_STAT_100FDX; + else + *s |= PHY_STAT_100HDX; +@@ -1186,32 +1174,33 @@ static void mii_parse_dp8384x_sr2(uint m + *s |= PHY_STAT_FAULT; + } + +-static phy_info_t phy_info_dp83848= { ++static phy_info_t phy_info_dp83848 = { + 0x020005c9, + "DP83848", + +- (const phy_cmd_t []) { /* config */ +- { mk_mii_read(MII_REG_CR), mii_parse_cr }, +- { mk_mii_read(MII_REG_ANAR), mii_parse_anar }, +- { mk_mii_read(MII_DP8384X_PHYSTST), mii_parse_dp8384x_sr2 }, +- { mk_mii_end, } ++ (const phy_cmd_t[]){ /* config */ ++ {mk_mii_read(MII_REG_CR), mii_parse_cr}, ++ {mk_mii_read(MII_REG_ANAR), mii_parse_anar}, ++ {mk_mii_read(MII_DP8384X_PHYSTST), ++ mii_parse_dp8384x_sr2}, ++ {mk_mii_end,} + }, +- (const phy_cmd_t []) { /* startup - enable interrupts */ +- { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ +- { mk_mii_read(MII_REG_SR), mii_parse_sr }, +- { mk_mii_end, } ++ (const phy_cmd_t[]){ /* startup - enable interrupts */ ++ {mk_mii_write(MII_REG_CR, 0x1200), NULL}, /* autonegotiate */ ++ {mk_mii_read(MII_REG_SR), mii_parse_sr}, ++ {mk_mii_end,} + }, +- (const phy_cmd_t []) { /* ack_int - never happens, no interrupt */ +- { mk_mii_end, } ++ (const phy_cmd_t[]){ /* ack_int - never happens, no interrupt */ ++ {mk_mii_end,} + }, +- (const phy_cmd_t []) { /* shutdown */ +- { mk_mii_end, } ++ (const phy_cmd_t[]){ /* shutdown */ ++ {mk_mii_end,} + }, + }; + + /* ------------------------------------------------------------------------- */ + +-static phy_info_t const * const phy_info[] = { ++static phy_info_t const *const phy_info[] = { + &phy_info_lxt970, + &phy_info_lxt971, + &phy_info_qs6612, +@@ -1221,22 +1210,38 @@ static phy_info_t const * const phy_info + NULL + }; + +-/* ------------------------------------------------------------------------- */ +-#if !defined(CONFIG_M532x) +-#ifdef CONFIG_RPXCLASSIC +-static void +-mii_link_interrupt(void *dev_id); +-#else +-static irqreturn_t +-mii_link_interrupt(int irq, void * dev_id); +-#endif ++#if defined(CONFIG_M5272) ++static void fec_phy_ack_intr(void) ++{ ++ volatile unsigned long *icrp; ++ /* Acknowledge the interrupt */ ++ icrp = (volatile unsigned long *)(MCF_MBAR + MCFSIM_ICR1); ++ *icrp = 0x0d000000; ++} ++ ++/* This interrupt occurs when the PHY detects a link change. ++*/ ++static irqreturn_t mii_link_interrupt(int irq, void *dev_id) ++{ ++ struct net_device *dev = dev_id; ++ struct fec_enet_private *fep = netdev_priv(dev); ++ ++ fec_phy_ack_intr(); ++ ++#if 0 ++ disable_irq(fep->mii_irq); /* disable now, enable later */ + #endif + +-#if defined(CONFIG_M5272) ++ mii_do_cmd(dev, fep->phy->ack_int); ++ mii_do_cmd(dev, phy_cmd_relink); /* restart and display status */ ++ ++ return IRQ_HANDLED; ++} ++ + /* + * Code specific to Coldfire 5272 setup. + */ +-static void __inline__ fec_request_intrs(struct net_device *dev) ++static void __init fec_request_intrs(struct net_device *dev) + { + volatile unsigned long *icrp; + static const struct idesc { +@@ -1244,27 +1249,36 @@ static void __inline__ fec_request_intrs + unsigned short irq; + irq_handler_t handler; + } *idp, id[] = { +- { "fec(RX)", 86, fec_enet_interrupt }, +- { "fec(TX)", 87, fec_enet_interrupt }, +- { "fec(OTHER)", 88, fec_enet_interrupt }, +- { "fec(MII)", 66, mii_link_interrupt }, +- { NULL }, ++ /* ++ * Available but not allocated because not handled: ++ * fec(OTHER) 88 ++ */ ++ { "fec(RX)", 86, fec_enet_interrupt}, ++ { "fec(TX)", 87, fec_enet_interrupt}, ++ { "fec(MII)", 66, mii_link_interrupt}, ++ { NULL, 0 }, + }; + + /* Setup interrupt handlers. */ + for (idp = id; idp->name; idp++) { +- if (request_irq(idp->irq, idp->handler, 0, idp->name, dev) != 0) +- printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, idp->irq); ++ int ret; ++ ++ ret =request_irq(idp->irq, idp->handler, IRQF_DISABLED, idp->name, ++ dev); ++ if (ret) ++ printk("FEC: Could not allocate %s IRQ(%d)!\n", ++ idp->name, idp->irq); + } + + /* Unmask interrupt at ColdFire 5272 SIM */ +- icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR3); ++ icrp = (volatile unsigned long *)(MCF_MBAR + MCFSIM_ICR3); + *icrp = 0x00000ddd; +- icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1); ++ icrp = (volatile unsigned long *)(MCF_MBAR + MCFSIM_ICR1); + *icrp = 0x0d000000; + } + +-static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep) ++static void __init fec_set_mii(struct net_device *dev, ++ struct fec_enet_private *fep) + { + volatile fec_t *fecp; + +@@ -1282,7 +1296,7 @@ static void __inline__ fec_set_mii(struc + fec_restart(dev, 0); + } + +-static void __inline__ fec_get_mac(struct net_device *dev) ++static void __init fec_get_mac(struct net_device *dev) + { + struct fec_enet_private *fep = netdev_priv(dev); + volatile fec_t *fecp; +@@ -1303,8 +1317,8 @@ static void __inline__ fec_get_mac(struc + (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff)) + iap = fec_mac_default; + } else { +- *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low; +- *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16); ++ *((unsigned long *)&tmpaddr[0]) = fecp->fec_addr_low; ++ *((unsigned short *)&tmpaddr[4]) = (fecp->fec_addr_high >> 16); + iap = &tmpaddr[0]; + } + +@@ -1312,36 +1326,29 @@ static void __inline__ fec_get_mac(struc + + /* Adjust MAC if using default MAC address */ + if (iap == fec_mac_default) +- dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index; ++ dev->dev_addr[ETH_ALEN - 1] = ++ fec_mac_default[ETH_ALEN - 1] + fep->index; + } + +-static void __inline__ fec_enable_phy_intr(void) ++static void fec_enable_phy_intr(void) + { + } + +-static void __inline__ fec_disable_phy_intr(void) ++static void fec_disable_phy_intr(void) + { + volatile unsigned long *icrp; +- icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1); ++ icrp = (volatile unsigned long *)(MCF_MBAR + MCFSIM_ICR1); + *icrp = 0x08000000; + } + +-static void __inline__ fec_phy_ack_intr(void) +-{ +- volatile unsigned long *icrp; +- /* Acknowledge the interrupt */ +- icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1); +- *icrp = 0x0d000000; +-} +- +-static void __inline__ fec_localhw_setup(void) ++static void fec_localhw_setup(void) + { + } + + /* + * Do not need to make region uncached on 5272. + */ +-static void __inline__ fec_uncache(unsigned long addr) ++static void __init fec_uncache(unsigned long addr) + { + } + +@@ -1353,7 +1360,7 @@ static void __inline__ fec_uncache(unsig + * Code specific to Coldfire 5230/5231/5232/5234/5235, + * the 5270/5271/5274/5275 and 5280/5282 setups. + */ +-static void __inline__ fec_request_intrs(struct net_device *dev) ++static void __init fec_request_intrs(struct net_device *dev) + { + struct fec_enet_private *fep; + int b; +@@ -1361,20 +1368,16 @@ static void __inline__ fec_request_intrs + char *name; + unsigned short irq; + } *idp, id[] = { +- { "fec(TXF)", 23 }, +- { "fec(TXB)", 24 }, +- { "fec(TXFIFO)", 25 }, +- { "fec(TXCR)", 26 }, +- { "fec(RXF)", 27 }, +- { "fec(RXB)", 28 }, +- { "fec(MII)", 29 }, +- { "fec(LC)", 30 }, +- { "fec(HBERR)", 31 }, +- { "fec(GRA)", 32 }, +- { "fec(EBERR)", 33 }, +- { "fec(BABT)", 34 }, +- { "fec(BABR)", 35 }, +- { NULL }, ++ /* ++ * Available but not allocated because not handled: ++ * fec(TXB) 24, fec(TXFIFO) 25, fec(TXCR) 26, fec(RXB) 28, ++ * fec(LC) 30, fec(HBERR) 31, fec(GRA) 32, fec(EBERR) 33, ++ * fec(BABT) 34, fec(BABR), 35 ++ */ ++ { "fec(TXF)", 23}, ++ { "fec(RXF)", 27}, ++ { "fec(MII)", 29}, ++ { NULL, 0}, + }; + + fep = netdev_priv(dev); +@@ -1382,43 +1385,47 @@ static void __inline__ fec_request_intrs + + /* Setup interrupt handlers. */ + for (idp = id; idp->name; idp++) { +- if (request_irq(b+idp->irq, fec_enet_interrupt, 0, idp->name, dev) != 0) +- printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq); +- } ++ int ret; + ++ ret = request_irq(b + idp->irq, fec_enet_interrupt, IRQF_DISABLED, ++ idp->name, dev); ++ if (ret) ++ printk("FEC: Could not allocate %s IRQ(%d)!\n", ++ idp->name, b + idp->irq); ++ } ++#if defined(CONFIG_M527x) || defined(CONFIG_M528x) + /* Unmask interrupts at ColdFire 5280/5282 interrupt controller */ + { +- volatile unsigned char *icrp; +- volatile unsigned long *imrp; ++ volatile unsigned char *icrp; ++ volatile unsigned long *imrp; + int i, ilip; + + b = (fep->index) ? MCFICM_INTC1 : MCFICM_INTC0; +- icrp = (volatile unsigned char *) (MCF_IPSBAR + b + +- MCFINTC_ICR0); ++ icrp = (volatile unsigned char *)(MCF_IPSBAR + b + ++ MCFINTC_ICR0); + for (i = 23, ilip = 0x28; (i < 36); i++) + icrp[i] = ilip--; + +- imrp = (volatile unsigned long *) (MCF_IPSBAR + b + +- MCFINTC_IMRH); ++ imrp = (volatile unsigned long *)(MCF_IPSBAR + b + ++ MCFINTC_IMRH); + *imrp &= ~0x0000000f; +- imrp = (volatile unsigned long *) (MCF_IPSBAR + b + +- MCFINTC_IMRL); ++ imrp = (volatile unsigned long *)(MCF_IPSBAR + b + ++ MCFINTC_IMRL); + *imrp &= ~0xff800001; + } +- ++#endif + #if defined(CONFIG_M528x) + /* Set up gpio outputs for MII lines */ + { + volatile u16 *gpio_paspar; + volatile u8 *gpio_pehlpar; + +- gpio_paspar = (volatile u16 *) (MCF_IPSBAR + 0x100056); +- gpio_pehlpar = (volatile u16 *) (MCF_IPSBAR + 0x100058); ++ gpio_paspar = (volatile u16 *)(MCF_IPSBAR + 0x100056); ++ gpio_pehlpar = (volatile u16 *)(MCF_IPSBAR + 0x100058); + *gpio_paspar |= 0x0f00; + *gpio_pehlpar = 0xc0; + } + #endif +- + #if defined(CONFIG_M527x) + /* Set up gpio outputs for MII lines */ + { +@@ -1443,7 +1450,8 @@ static void __inline__ fec_request_intrs + #endif /* CONFIG_M527x */ + } + +-static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep) ++static void __init fec_set_mii(struct net_device *dev, ++ struct fec_enet_private *fep) + { + volatile fec_t *fecp; + +@@ -1461,7 +1469,7 @@ static void __inline__ fec_set_mii(struc + fec_restart(dev, 0); + } + +-static void __inline__ fec_get_mac(struct net_device *dev) ++static void __init fec_get_mac(struct net_device *dev) + { + struct fec_enet_private *fep = netdev_priv(dev); + volatile fec_t *fecp; +@@ -1482,8 +1490,8 @@ static void __inline__ fec_get_mac(struc + (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff)) + iap = fec_mac_default; + } else { +- *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low; +- *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16); ++ *((unsigned long *)&tmpaddr[0]) = fecp->fec_addr_low; ++ *((unsigned short *)&tmpaddr[4]) = (fecp->fec_addr_high >> 16); + iap = &tmpaddr[0]; + } + +@@ -1491,29 +1499,26 @@ static void __inline__ fec_get_mac(struc + + /* Adjust MAC if using default MAC address */ + if (iap == fec_mac_default) +- dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index; ++ dev->dev_addr[ETH_ALEN - 1] = ++ fec_mac_default[ETH_ALEN - 1] + fep->index; + } + +-static void __inline__ fec_enable_phy_intr(void) ++static void fec_enable_phy_intr(void) + { + } + +-static void __inline__ fec_disable_phy_intr(void) ++static void fec_disable_phy_intr(void) + { + } + +-static void __inline__ fec_phy_ack_intr(void) +-{ +-} +- +-static void __inline__ fec_localhw_setup(void) ++static void fec_localhw_setup(void) + { + } + + /* + * Do not need to make region uncached on 5272. + */ +-static void __inline__ fec_uncache(unsigned long addr) ++static void __init fec_uncache(unsigned long addr) + { + } + +@@ -1524,7 +1529,7 @@ static void __inline__ fec_uncache(unsig + /* + * Code specific to Coldfire 520x + */ +-static void __inline__ fec_request_intrs(struct net_device *dev) ++static void __init fec_request_intrs(struct net_device *dev) + { + struct fec_enet_private *fep; + int b; +@@ -1532,20 +1537,16 @@ static void __inline__ fec_request_intrs + char *name; + unsigned short irq; + } *idp, id[] = { +- { "fec(TXF)", 23 }, +- { "fec(TXB)", 24 }, +- { "fec(TXFIFO)", 25 }, +- { "fec(TXCR)", 26 }, +- { "fec(RXF)", 27 }, +- { "fec(RXB)", 28 }, +- { "fec(MII)", 29 }, +- { "fec(LC)", 30 }, +- { "fec(HBERR)", 31 }, +- { "fec(GRA)", 32 }, +- { "fec(EBERR)", 33 }, +- { "fec(BABT)", 34 }, +- { "fec(BABR)", 35 }, +- { NULL }, ++ /* ++ * Available but not allocated because not handled: ++ * fec(TXB) 24, fec(TXFIFO) 25, fec(TXCR) 26, fec(RXB) 28, ++ * fec(LC) 30, fec(HBERR) 31, fec(GRA) 32, fec(EBERR) 33, ++ * fec(BABT) 34, fec(BABR) 35 ++ */ ++ { "fec(TXF)", 23}, ++ { "fec(RXF)", 27}, ++ { "fec(MII)", 29}, ++ { NULL, 0}, + }; + + fep = netdev_priv(dev); +@@ -1553,28 +1554,34 @@ static void __inline__ fec_request_intrs + + /* Setup interrupt handlers. */ + for (idp = id; idp->name; idp++) { +- if (request_irq(b+idp->irq,fec_enet_interrupt,0,idp->name,dev)!=0) +- printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq); ++ int ret; ++ ++ ret = request_irq(b + idp->irq, fec_enet_interrupt, IRQF_DISABLED, ++ idp->name, dev); ++ if (ret) ++ printk("FEC: Could not allocate %s IRQ(%d)!\n", ++ idp->name, b + idp->irq); + } + + /* Unmask interrupts at ColdFire interrupt controller */ + { +- volatile unsigned char *icrp; +- volatile unsigned long *imrp; ++ volatile unsigned char *icrp; ++ volatile unsigned long *imrp; + +- icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 + +- MCFINTC_ICR0); ++ icrp = (volatile unsigned char *)(MCF_IPSBAR + MCFICM_INTC0 + ++ MCFINTC_ICR0); + for (b = 36; (b < 49); b++) + icrp[b] = 0x04; +- imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + +- MCFINTC_IMRH); ++ imrp = (volatile unsigned long *)(MCF_IPSBAR + MCFICM_INTC0 + ++ MCFINTC_IMRH); + *imrp &= ~0x0001FFF0; + } + *(volatile unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FEC) |= 0xf0; + *(volatile unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C) |= 0x0f; + } + +-static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep) ++static void __init fec_set_mii(struct net_device *dev, ++ struct fec_enet_private *fep) + { + volatile fec_t *fecp; + +@@ -1592,7 +1599,7 @@ static void __inline__ fec_set_mii(struc + fec_restart(dev, 0); + } + +-static void __inline__ fec_get_mac(struct net_device *dev) ++static void __init fec_get_mac(struct net_device *dev) + { + struct fec_enet_private *fep = netdev_priv(dev); + volatile fec_t *fecp; +@@ -1607,14 +1614,14 @@ static void __inline__ fec_get_mac(struc + */ + iap = FEC_FLASHMAC; + if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) && +- (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0)) ++ (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0)) + iap = fec_mac_default; + if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) && +- (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff)) ++ (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff)) + iap = fec_mac_default; + } else { +- *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low; +- *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16); ++ *((unsigned long *)&tmpaddr[0]) = fecp->fec_addr_low; ++ *((unsigned short *)&tmpaddr[4]) = (fecp->fec_addr_high >> 16); + iap = &tmpaddr[0]; + } + +@@ -1622,26 +1629,23 @@ static void __inline__ fec_get_mac(struc + + /* Adjust MAC if using default MAC address */ + if (iap == fec_mac_default) +- dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index; +-} +- +-static void __inline__ fec_enable_phy_intr(void) +-{ ++ dev->dev_addr[ETH_ALEN - 1] = ++ fec_mac_default[ETH_ALEN - 1] + fep->index; + } + +-static void __inline__ fec_disable_phy_intr(void) ++static void fec_enable_phy_intr(void) + { + } + +-static void __inline__ fec_phy_ack_intr(void) ++static void fec_disable_phy_intr(void) + { + } + +-static void __inline__ fec_localhw_setup(void) ++static void fec_localhw_setup(void) + { + } + +-static void __inline__ fec_uncache(unsigned long addr) ++static void __init fec_uncache(unsigned long addr) + { + } + +@@ -1651,7 +1655,7 @@ static void __inline__ fec_uncache(unsig + /* + * Code specific for M532x + */ +-static void __inline__ fec_request_intrs(struct net_device *dev) ++static void __init fec_request_intrs(struct net_device *dev) + { + struct fec_enet_private *fep; + int b; +@@ -1659,20 +1663,16 @@ static void __inline__ fec_request_intrs + char *name; + unsigned short irq; + } *idp, id[] = { +- { "fec(TXF)", 36 }, +- { "fec(TXB)", 37 }, +- { "fec(TXFIFO)", 38 }, +- { "fec(TXCR)", 39 }, +- { "fec(RXF)", 40 }, +- { "fec(RXB)", 41 }, +- { "fec(MII)", 42 }, +- { "fec(LC)", 43 }, +- { "fec(HBERR)", 44 }, +- { "fec(GRA)", 45 }, +- { "fec(EBERR)", 46 }, +- { "fec(BABT)", 47 }, +- { "fec(BABR)", 48 }, +- { NULL }, ++ /* ++ * Available but not allocated because not handled: ++ * fec(TXB) 37, fec(TXFIFO) 38, fec(TXCR) 39, fec(RXB) 41, ++ * fec(LC) 43, fec(HBERR) 44, fec(GRA) 45, fec(EBERR) 46, ++ * fec(BABT) 47, fec(BABR) 48 ++ */ ++ { "fec(TXF)", 36}, ++ { "fec(RXF)", 40}, ++ { "fec(MII)", 42}, ++ { NULL, 0}, + }; + + fep = netdev_priv(dev); +@@ -1680,9 +1680,13 @@ static void __inline__ fec_request_intrs + + /* Setup interrupt handlers. */ + for (idp = id; idp->name; idp++) { +- if (request_irq(b+idp->irq,fec_enet_interrupt,0,idp->name,dev)!=0) +- printk("FEC: Could not allocate %s IRQ(%d)!\n", +- idp->name, b+idp->irq); ++ int ret; ++ ++ ret = request_irq(b + idp->irq, fec_enet_interrupt, IRQF_DISABLED, ++ idp->name, dev); ++ if (ret) ++ printk("FEC: Could not allocate %s IRQ(%d)!\n", ++ idp->name, b + idp->irq); + } + + /* Unmask interrupts */ +@@ -1700,31 +1704,31 @@ static void __inline__ fec_request_intrs + MCF_INTC0_ICR47 = 0x2; + MCF_INTC0_ICR48 = 0x2; + +- MCF_INTC0_IMRH &= ~( +- MCF_INTC_IMRH_INT_MASK36 | +- MCF_INTC_IMRH_INT_MASK37 | +- MCF_INTC_IMRH_INT_MASK38 | +- MCF_INTC_IMRH_INT_MASK39 | +- MCF_INTC_IMRH_INT_MASK40 | +- MCF_INTC_IMRH_INT_MASK41 | +- MCF_INTC_IMRH_INT_MASK42 | +- MCF_INTC_IMRH_INT_MASK43 | +- MCF_INTC_IMRH_INT_MASK44 | +- MCF_INTC_IMRH_INT_MASK45 | +- MCF_INTC_IMRH_INT_MASK46 | +- MCF_INTC_IMRH_INT_MASK47 | +- MCF_INTC_IMRH_INT_MASK48 ); ++ MCF_INTC0_IMRH &= ~(MCF_INTC_IMRH_INT_MASK36 | ++ MCF_INTC_IMRH_INT_MASK37 | ++ MCF_INTC_IMRH_INT_MASK38 | ++ MCF_INTC_IMRH_INT_MASK39 | ++ MCF_INTC_IMRH_INT_MASK40 | ++ MCF_INTC_IMRH_INT_MASK41 | ++ MCF_INTC_IMRH_INT_MASK42 | ++ MCF_INTC_IMRH_INT_MASK43 | ++ MCF_INTC_IMRH_INT_MASK44 | ++ MCF_INTC_IMRH_INT_MASK45 | ++ MCF_INTC_IMRH_INT_MASK46 | ++ MCF_INTC_IMRH_INT_MASK47 | ++ MCF_INTC_IMRH_INT_MASK48); + + /* Set up gpio outputs for MII lines */ + MCF_GPIO_PAR_FECI2C |= (0 | +- MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC | +- MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO); ++ MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC | ++ MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO); + MCF_GPIO_PAR_FEC = (0 | +- MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC | +- MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC); ++ MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC | ++ MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC); + } + +-static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep) ++static void __init fec_set_mii(struct net_device *dev, ++ struct fec_enet_private *fep) + { + volatile fec_t *fecp; + +@@ -1741,7 +1745,7 @@ static void __inline__ fec_set_mii(struc + fec_restart(dev, 0); + } + +-static void __inline__ fec_get_mac(struct net_device *dev) ++static void __init fec_get_mac(struct net_device *dev) + { + struct fec_enet_private *fep = netdev_priv(dev); + volatile fec_t *fecp; +@@ -1762,8 +1766,8 @@ static void __inline__ fec_get_mac(struc + (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff)) + iap = fec_mac_default; + } else { +- *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low; +- *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16); ++ *((unsigned long *)&tmpaddr[0]) = fecp->fec_addr_low; ++ *((unsigned short *)&tmpaddr[4]) = (fecp->fec_addr_high >> 16); + iap = &tmpaddr[0]; + } + +@@ -1771,143 +1775,109 @@ static void __inline__ fec_get_mac(struc + + /* Adjust MAC if using default MAC address */ + if (iap == fec_mac_default) +- dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index; +-} +- +-static void __inline__ fec_enable_phy_intr(void) +-{ ++ dev->dev_addr[ETH_ALEN - 1] = ++ fec_mac_default[ETH_ALEN - 1] + fep->index; + } + +-static void __inline__ fec_disable_phy_intr(void) ++static void fec_enable_phy_intr(void) + { + } + +-static void __inline__ fec_phy_ack_intr(void) ++static void fec_disable_phy_intr(void) + { + } + +-static void __inline__ fec_localhw_setup(void) ++static void fec_localhw_setup(void) + { + } + + /* + * Do not need to make region uncached on 532x. + */ +-static void __inline__ fec_uncache(unsigned long addr) ++static void __init fec_uncache(unsigned long addr) + { + } + + /* ------------------------------------------------------------------------- */ + +- + #else + + /* + * Code specific to the MPC860T setup. + */ +-static void __inline__ fec_request_intrs(struct net_device *dev) ++static void __init fec_request_intrs(struct net_device *dev) + { + volatile immap_t *immap; + +- immap = (immap_t *)IMAP_ADDR; /* pointer to internal registers */ ++ immap = (immap_t *) IMAP_ADDR; /* pointer to internal registers */ + +- if (request_8xxirq(FEC_INTERRUPT, fec_enet_interrupt, 0, "fec", dev) != 0) ++ if (request_8xxirq(FEC_INTERRUPT, fec_enet_interrupt, 0, "fec", dev) != ++ 0) + panic("Could not allocate FEC IRQ!"); +- +-#ifdef CONFIG_RPXCLASSIC +- /* Make Port C, bit 15 an input that causes interrupts. +- */ +- immap->im_ioport.iop_pcpar &= ~0x0001; +- immap->im_ioport.iop_pcdir &= ~0x0001; +- immap->im_ioport.iop_pcso &= ~0x0001; +- immap->im_ioport.iop_pcint |= 0x0001; +- cpm_install_handler(CPMVEC_PIO_PC15, mii_link_interrupt, dev); +- +- /* Make LEDS reflect Link status. +- */ +- *((uint *) RPX_CSR_ADDR) &= ~BCSR2_FETHLEDMODE; +-#endif +-#ifdef CONFIG_FADS +- if (request_8xxirq(SIU_IRQ2, mii_link_interrupt, 0, "mii", dev) != 0) +- panic("Could not allocate MII IRQ!"); +-#endif + } + +-static void __inline__ fec_get_mac(struct net_device *dev) ++static void __init fec_get_mac(struct net_device *dev) + { + bd_t *bd; + +- bd = (bd_t *)__res; ++ bd = (bd_t *) __res; + memcpy(dev->dev_addr, bd->bi_enetaddr, ETH_ALEN); +- +-#ifdef CONFIG_RPXCLASSIC +- /* The Embedded Planet boards have only one MAC address in +- * the EEPROM, but can have two Ethernet ports. For the +- * FEC port, we create another address by setting one of +- * the address bits above something that would have (up to +- * now) been allocated. +- */ +- dev->dev_adrd[3] |= 0x80; +-#endif + } + +-static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep) ++static void __init fec_set_mii(struct net_device *dev, ++ struct fec_enet_private *fep) + { + extern uint _get_IMMR(void); + volatile immap_t *immap; + volatile fec_t *fecp; + + fecp = fep->hwp; +- immap = (immap_t *)IMAP_ADDR; /* pointer to internal registers */ ++ immap = (immap_t *) IMAP_ADDR; /* pointer to internal registers */ + + /* Configure all of port D for MII. +- */ ++ */ + immap->im_ioport.iop_pdpar = 0x1fff; + + /* Bits moved from Rev. D onward. +- */ ++ */ + if ((_get_IMMR() & 0xffff) < 0x0501) + immap->im_ioport.iop_pddir = 0x1c58; /* Pre rev. D */ + else + immap->im_ioport.iop_pddir = 0x1fff; /* Rev. D and later */ + + /* Set MII speed to 2.5 MHz +- */ ++ */ + fecp->fec_mii_speed = fep->phy_speed = +- ((bd->bi_busfreq * 1000000) / 2500000) & 0x7e; ++ ((bd->bi_busfreq * 1000000) / 2500000) & 0x7e; + } + +-static void __inline__ fec_enable_phy_intr(void) ++static void fec_enable_phy_intr(void) + { + volatile fec_t *fecp; + + fecp = fep->hwp; + + /* Enable MII command finished interrupt +- */ +- fecp->fec_ivec = (FEC_INTERRUPT/2) << 29; +-} +- +-static void __inline__ fec_disable_phy_intr(void) +-{ ++ */ ++ fecp->fec_ivec = (FEC_INTERRUPT / 2) << 29; + } + +-static void __inline__ fec_phy_ack_intr(void) ++static void fec_disable_phy_intr(void) + { + } + +-static void __inline__ fec_localhw_setup(void) ++static void fec_localhw_setup(void) + { + volatile fec_t *fecp; + + fecp = fep->hwp; + fecp->fec_r_hash = PKT_MAXBUF_SIZE; + /* Enable big endian and don't care about SDMA FC. +- */ ++ */ + fecp->fec_fun_code = 0x78000000; + } + +-static void __inline__ fec_uncache(unsigned long addr) ++static void __init fec_uncache(unsigned long addr) + { + pte_t *pte; + pte = va_to_pte(mem_addr); +@@ -1936,11 +1906,19 @@ static void mii_display_status(struct ne + } else { + printk("link up"); + +- switch(*s & PHY_STAT_SPMASK) { +- case PHY_STAT_100FDX: printk(", 100MBit Full Duplex"); break; +- case PHY_STAT_100HDX: printk(", 100MBit Half Duplex"); break; +- case PHY_STAT_10FDX: printk(", 10MBit Full Duplex"); break; +- case PHY_STAT_10HDX: printk(", 10MBit Half Duplex"); break; ++ switch (*s & PHY_STAT_SPMASK) { ++ case PHY_STAT_100FDX: ++ printk(", 100MBit Full Duplex"); ++ break; ++ case PHY_STAT_100HDX: ++ printk(", 100MBit Half Duplex"); ++ break; ++ case PHY_STAT_10FDX: ++ printk(", 10MBit Full Duplex"); ++ break; ++ case PHY_STAT_10HDX: ++ printk(", 10MBit Half Duplex"); ++ break; + default: + printk(", Unknown speed/duplex"); + } +@@ -1957,14 +1935,15 @@ static void mii_display_status(struct ne + + static void mii_display_config(struct work_struct *work) + { +- struct fec_enet_private *fep = container_of(work, struct fec_enet_private, phy_task); ++ struct fec_enet_private *fep = ++ container_of(work, struct fec_enet_private, phy_task); + struct net_device *dev = fep->netdev; + uint status = fep->phy_status; + + /* +- ** When we get here, phy_task is already removed from +- ** the workqueue. It is thus safe to allow to reuse it. +- */ ++ ** When we get here, phy_task is already removed from ++ ** the workqueue. It is thus safe to allow to reuse it. ++ */ + fep->mii_phy_task_queued = 0; + printk("%s: config: auto-negotiation ", dev->name); + +@@ -1994,14 +1973,15 @@ static void mii_display_config(struct wo + + static void mii_relink(struct work_struct *work) + { +- struct fec_enet_private *fep = container_of(work, struct fec_enet_private, phy_task); ++ struct fec_enet_private *fep = ++ container_of(work, struct fec_enet_private, phy_task); + struct net_device *dev = fep->netdev; + int duplex; + + /* +- ** When we get here, phy_task is already removed from +- ** the workqueue. It is thus safe to allow to reuse it. +- */ ++ ** When we get here, phy_task is already removed from ++ ** the workqueue. It is thus safe to allow to reuse it. ++ */ + fep->mii_phy_task_queued = 0; + fep->link = (fep->phy_status & PHY_STAT_LINK) ? 1 : 0; + mii_display_status(dev); +@@ -2009,8 +1989,7 @@ static void mii_relink(struct work_struc + + if (fep->link) { + duplex = 0; +- if (fep->phy_status +- & (PHY_STAT_100FDX | PHY_STAT_10FDX)) ++ if (fep->phy_status & (PHY_STAT_100FDX | PHY_STAT_10FDX)) + duplex = 1; + fec_restart(dev, duplex); + } else +@@ -2028,12 +2007,12 @@ static void mii_queue_relink(uint mii_re + struct fec_enet_private *fep = netdev_priv(dev); + + /* +- ** We cannot queue phy_task twice in the workqueue. It +- ** would cause an endless loop in the workqueue. +- ** Fortunately, if the last mii_relink entry has not yet been +- ** executed now, it will do the job for the current interrupt, +- ** which is just what we want. +- */ ++ ** We cannot queue phy_task twice in the workqueue. It ++ ** would cause an endless loop in the workqueue. ++ ** Fortunately, if the last mii_relink entry has not yet been ++ ** executed now, it will do the job for the current interrupt, ++ ** which is just what we want. ++ */ + if (fep->mii_phy_task_queued) + return; + +@@ -2056,18 +2035,17 @@ static void mii_queue_config(uint mii_re + } + + phy_cmd_t const phy_cmd_relink[] = { +- { mk_mii_read(MII_REG_CR), mii_queue_relink }, +- { mk_mii_end, } +- }; ++ {mk_mii_read(MII_REG_CR), mii_queue_relink}, ++ {mk_mii_end,} ++}; + phy_cmd_t const phy_cmd_config[] = { +- { mk_mii_read(MII_REG_CR), mii_queue_config }, +- { mk_mii_end, } +- }; ++ {mk_mii_read(MII_REG_CR), mii_queue_config}, ++ {mk_mii_end,} ++}; + + /* Read remainder of PHY ID. + */ +-static void +-mii_discover_phy3(uint mii_reg, struct net_device *dev) ++static void mii_discover_phy3(uint mii_reg, struct net_device *dev) + { + struct fec_enet_private *fep; + int i; +@@ -2076,8 +2054,8 @@ mii_discover_phy3(uint mii_reg, struct n + fep->phy_id |= (mii_reg & 0xffff); + printk("fec: PHY @ 0x%x, ID 0x%08x", fep->phy_addr, fep->phy_id); + +- for(i = 0; phy_info[i]; i++) { +- if(phy_info[i]->id == (fep->phy_id >> 4)) ++ for (i = 0; phy_info[i]; i++) { ++ if (phy_info[i]->id == (fep->phy_id >> 4)) + break; + } + +@@ -2093,8 +2071,7 @@ mii_discover_phy3(uint mii_reg, struct n + /* Scan all of the MII PHY addresses looking for someone to respond + * with a valid ID. This usually happens quickly. + */ +-static void +-mii_discover_phy(uint mii_reg, struct net_device *dev) ++static void mii_discover_phy(uint mii_reg, struct net_device *dev) + { + struct fec_enet_private *fep; + volatile fec_t *fecp; +@@ -2107,14 +2084,14 @@ mii_discover_phy(uint mii_reg, struct ne + if ((phytype = (mii_reg & 0xffff)) != 0xffff && phytype != 0) { + + /* Got first part of ID, now get remainder. +- */ ++ */ + fep->phy_id = phytype << 16; + mii_queue(dev, mk_mii_read(MII_REG_PHYIR2), +- mii_discover_phy3); ++ mii_discover_phy3); + } else { + fep->phy_addr++; + mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), +- mii_discover_phy); ++ mii_discover_phy); + } + } else { + printk("FEC: No PHY device found.\n"); +@@ -2124,33 +2101,23 @@ mii_discover_phy(uint mii_reg, struct ne + } + } + +-/* This interrupt occurs when the PHY detects a link change. +-*/ +-#ifdef CONFIG_RPXCLASSIC +-static void +-mii_link_interrupt(void *dev_id) +-#else +-static irqreturn_t +-mii_link_interrupt(int irq, void * dev_id) +-#endif ++/* Set a MAC change in hardware. ++ */ ++static void fec_set_mac_address(struct net_device *dev) + { +- struct net_device *dev = dev_id; +- struct fec_enet_private *fep = netdev_priv(dev); +- +- fec_phy_ack_intr(); ++ volatile fec_t *fecp; + +-#if 0 +- disable_irq(fep->mii_irq); /* disable now, enable later */ +-#endif ++ fecp = ((struct fec_enet_private *)netdev_priv(dev))->hwp; + +- mii_do_cmd(dev, fep->phy->ack_int); +- mii_do_cmd(dev, phy_cmd_relink); /* restart and display status */ ++ /* Set station address. */ ++ fecp->fec_addr_low = dev->dev_addr[3] | (dev->dev_addr[2] << 8) | ++ (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24); ++ fecp->fec_addr_high = (dev->dev_addr[5] << 16) | ++ (dev->dev_addr[4] << 24); + +- return IRQ_HANDLED; + } + +-static int +-fec_enet_open(struct net_device *dev) ++static int fec_enet_open(struct net_device *dev) + { + struct fec_enet_private *fep = netdev_priv(dev); + +@@ -2165,7 +2132,7 @@ fec_enet_open(struct net_device *dev) + if (fep->phy) { + mii_do_cmd(dev, fep->phy->ack_int); + mii_do_cmd(dev, fep->phy->config); +- mii_do_cmd(dev, phy_cmd_config); /* display configuration */ ++ mii_do_cmd(dev, phy_cmd_config); /* display configuration */ + + /* Poll until the PHY tells us its configuration + * (not link state). +@@ -2174,7 +2141,7 @@ fec_enet_open(struct net_device *dev) + * This should take about 25 usec per register at 2.5 MHz, + * and we read approximately 5 registers. + */ +- while(!fep->sequence_done) ++ while (!fep->sequence_done) + schedule(); + + mii_do_cmd(dev, fep->phy->startup); +@@ -2185,7 +2152,7 @@ fec_enet_open(struct net_device *dev) + */ + fep->link = 1; + } else { +- fep->link = 1; /* lets just try it and see */ ++ fep->link = 1; /* lets just try it and see */ + /* no phy, go full duplex, it's most likely a hub chip */ + fec_restart(dev, 1); + } +@@ -2195,13 +2162,12 @@ fec_enet_open(struct net_device *dev) + return 0; /* Success */ + } + +-static int +-fec_enet_close(struct net_device *dev) ++static int fec_enet_close(struct net_device *dev) + { + struct fec_enet_private *fep = netdev_priv(dev); + + /* Don't know what to do yet. +- */ ++ */ + fep->opened = 0; + netif_stop_queue(dev); + fec_stop(dev); +@@ -2219,7 +2185,7 @@ fec_enet_close(struct net_device *dev) + * this kind of feature?). + */ + +-#define HASH_BITS 6 /* #bits in hash */ ++#define HASH_BITS 6 /* #bits in hash */ + #define CRC32_POLY 0xEDB88320 + + static void set_multicast_list(struct net_device *dev) +@@ -2233,76 +2199,61 @@ static void set_multicast_list(struct ne + fep = netdev_priv(dev); + ep = fep->hwp; + +- if (dev->flags&IFF_PROMISC) { ++ if (dev->flags & IFF_PROMISC) { + ep->fec_r_cntrl |= 0x0008; +- } else { ++ return ; ++ } + +- ep->fec_r_cntrl &= ~0x0008; ++ ep->fec_r_cntrl &= ~0x0008; + +- if (dev->flags & IFF_ALLMULTI) { +- /* Catch all multicast addresses, so set the +- * filter to all 1's. +- */ +- ep->fec_hash_table_high = 0xffffffff; +- ep->fec_hash_table_low = 0xffffffff; +- } else { +- /* Clear filter and add the addresses in hash register. +- */ +- ep->fec_hash_table_high = 0; +- ep->fec_hash_table_low = 0; +- +- dmi = dev->mc_list; +- +- for (j = 0; j < dev->mc_count; j++, dmi = dmi->next) +- { +- /* Only support group multicast for now. +- */ +- if (!(dmi->dmi_addr[0] & 1)) +- continue; +- +- /* calculate crc32 value of mac address +- */ +- crc = 0xffffffff; +- +- for (i = 0; i < dmi->dmi_addrlen; i++) +- { +- data = dmi->dmi_addr[i]; +- for (bit = 0; bit < 8; bit++, data >>= 1) +- { +- crc = (crc >> 1) ^ +- (((crc ^ data) & 1) ? CRC32_POLY : 0); +- } +- } +- +- /* only upper 6 bits (HASH_BITS) are used +- which point to specific bit in he hash registers +- */ +- hash = (crc >> (32 - HASH_BITS)) & 0x3f; +- +- if (hash > 31) +- ep->fec_hash_table_high |= 1 << (hash - 32); +- else +- ep->fec_hash_table_low |= 1 << hash; +- } +- } ++ if (dev->flags & IFF_ALLMULTI) { ++ /* Catch all multicast addresses, so set the ++ * filter to all 1's. ++ */ ++ ep->fec_hash_table_high = 0xffffffff; ++ ep->fec_hash_table_low = 0xffffffff; ++ return ; + } +-} ++ /* ++ * Clear filter and add the addresses in hash register. ++ */ ++ ep->fec_hash_table_high = 0; ++ ep->fec_hash_table_low = 0; + +-/* Set a MAC change in hardware. +- */ +-static void +-fec_set_mac_address(struct net_device *dev) +-{ +- volatile fec_t *fecp; ++ dmi = dev->mc_list; + +- fecp = ((struct fec_enet_private *)netdev_priv(dev))->hwp; ++ for (j = 0; j < dev->mc_count; j++, dmi = dmi->next) { ++ /* Only support group multicast for now. ++ */ ++ if (!(dmi->dmi_addr[0] & 1)) ++ continue; + +- /* Set station address. */ +- fecp->fec_addr_low = dev->dev_addr[3] | (dev->dev_addr[2] << 8) | +- (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24); +- fecp->fec_addr_high = (dev->dev_addr[5] << 16) | +- (dev->dev_addr[4] << 24); ++ /* calculate crc32 value of mac address ++ */ ++ crc = 0xffffffff; ++ ++ for (i = 0; i < dmi->dmi_addrlen; i++) { ++ data = dmi->dmi_addr[i]; ++ for (bit = 0; bit < 8; ++ bit++, data >>= 1) { ++ crc = ++ (crc >> 1) ^ ++ (((crc ^ data) & 1) ? ++ CRC32_POLY : 0); ++ } ++ } + ++ /* only upper 6 bits (HASH_BITS) are used ++ which point to specific bit in he hash registers ++ */ ++ hash = (crc >> (32 - HASH_BITS)) & 0x3f; ++ ++ if (hash > 31) ++ ep->fec_hash_table_high |= ++ 1 << (hash - 32); ++ else ++ ep->fec_hash_table_low |= 1 << hash; ++ } + } + + /* Initialize the FEC Ethernet on 860T (or ColdFire 5272). +@@ -2310,38 +2261,40 @@ fec_set_mac_address(struct net_device *d + /* + * XXX: We need to clean up on failure exits here. + */ ++static int index; + int __init fec_enet_init(struct net_device *dev) + { + struct fec_enet_private *fep = netdev_priv(dev); +- unsigned long mem_addr; +- volatile cbd_t *bdp; +- cbd_t *cbd_base; +- volatile fec_t *fecp; +- int i, j; +- static int index = 0; ++ unsigned long mem_addr; ++ volatile cbd_t *bdp; ++ cbd_t *cbd_base; ++ volatile fec_t *fecp; ++ int i, j; + + /* Only allow us to be probed once. */ + if (index >= FEC_MAX_PORTS) + return -ENXIO; + + /* Allocate memory for buffer descriptors. +- */ ++ */ + mem_addr = __get_free_page(GFP_KERNEL); + if (mem_addr == 0) { + printk("FEC: allocate descriptor memory failed?\n"); + return -ENOMEM; + } + ++ spin_lock_init(&fep->hw_lock); ++ spin_lock_init(&fep->mii_lock); + /* Create an Ethernet device instance. +- */ +- fecp = (volatile fec_t *) fec_hw[index]; ++ */ ++ fecp = (volatile fec_t *)fec_hw[index]; + + fep->index = index; + fep->hwp = fecp; + fep->netdev = dev; + + /* Whack a reset. We should wait for this. +- */ ++ */ + fecp->fec_ecntrl = 1; + udelay(10); + +@@ -2353,13 +2306,12 @@ int __init fec_enet_init(struct net_devi + */ + fec_get_mac(dev); + +- cbd_base = (cbd_t *)mem_addr; +- /* XXX: missing check for allocation failure */ ++ cbd_base = (cbd_t *) mem_addr; + + fec_uncache(mem_addr); + + /* Set receive and transmit descriptor base. +- */ ++ */ + fep->rx_bd_base = cbd_base; + fep->tx_bd_base = cbd_base + RX_RING_SIZE; + +@@ -2369,20 +2321,20 @@ int __init fec_enet_init(struct net_devi + fep->skb_cur = fep->skb_dirty = 0; + + /* Initialize the receive buffer descriptors. +- */ ++ */ + bdp = fep->rx_bd_base; +- for (i=0; icbd_sc = BD_ENET_RX_EMPTY; + bdp->cbd_bufaddr = __pa(mem_addr); + mem_addr += FEC_ENET_RX_FRSIZE; +@@ -2391,43 +2343,44 @@ int __init fec_enet_init(struct net_devi + } + + /* Set the last buffer to wrap. +- */ ++ */ + bdp--; + bdp->cbd_sc |= BD_SC_WRAP; + + /* ...and the same for transmmit. +- */ ++ */ + bdp = fep->tx_bd_base; +- for (i=0, j=FEC_ENET_TX_FRPPG; i= FEC_ENET_TX_FRPPG) { ++ /* XXX: missing check for allocation failure */ + mem_addr = __get_free_page(GFP_KERNEL); + j = 1; + } else { + mem_addr += FEC_ENET_TX_FRSIZE; + j++; + } +- fep->tx_bounce[i] = (unsigned char *) mem_addr; ++ fep->tx_bounce[i] = (unsigned char *)mem_addr; + + /* Initialize the BD for every fragment in the page. +- */ ++ */ + bdp->cbd_sc = 0; + bdp->cbd_bufaddr = 0; + bdp++; + } + + /* Set the last buffer to wrap. +- */ ++ */ + bdp--; + bdp->cbd_sc |= BD_SC_WRAP; + + /* Set receive and transmit descriptor base. +- */ +- fecp->fec_r_des_start = __pa((uint)(fep->rx_bd_base)); +- fecp->fec_x_des_start = __pa((uint)(fep->tx_bd_base)); ++ */ ++ fecp->fec_r_des_start = __pa((uint) (fep->rx_bd_base)); ++ fecp->fec_x_des_start = __pa((uint) (fep->tx_bd_base)); + + /* Install our interrupt handlers. This varies depending on + * the architecture. +- */ ++ */ + fec_request_intrs(dev); + + fecp->fec_hash_table_high = 0; +@@ -2446,8 +2399,8 @@ int __init fec_enet_init(struct net_devi + dev->stop = fec_enet_close; + dev->set_multicast_list = set_multicast_list; + +- for (i=0; ifec_ievent = 0xffc00000; +- fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | +- FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); ++ fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII); + + /* Queue up command to detect the PHY and initialize the + * remainder of the interface. +@@ -2473,8 +2425,7 @@ int __init fec_enet_init(struct net_devi + * change. This only happens when switching between half and full + * duplex. + */ +-static void +-fec_restart(struct net_device *dev, int duplex) ++static void fec_restart(struct net_device *dev, int duplex) + { + struct fec_enet_private *fep; + volatile cbd_t *bdp; +@@ -2485,42 +2436,42 @@ fec_restart(struct net_device *dev, int + fecp = fep->hwp; + + /* Whack a reset. We should wait for this. +- */ ++ */ + fecp->fec_ecntrl = 1; + udelay(10); + + /* Clear any outstanding interrupt. +- */ ++ */ + fecp->fec_ievent = 0xffc00000; + fec_enable_phy_intr(); + + /* Set station address. +- */ ++ */ + fec_set_mac_address(dev); + + /* Reset all multicast. +- */ ++ */ + fecp->fec_hash_table_high = 0; + fecp->fec_hash_table_low = 0; + + /* Set maximum receive buffer size. +- */ ++ */ + fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; + + fec_localhw_setup(); + + /* Set receive and transmit descriptor base. +- */ +- fecp->fec_r_des_start = __pa((uint)(fep->rx_bd_base)); +- fecp->fec_x_des_start = __pa((uint)(fep->tx_bd_base)); ++ */ ++ fecp->fec_r_des_start = __pa((uint) (fep->rx_bd_base)); ++ fecp->fec_x_des_start = __pa((uint) (fep->tx_bd_base)); + + fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; + fep->cur_rx = fep->rx_bd_base; + + /* Reset SKB transmit buffers. +- */ ++ */ + fep->skb_cur = fep->skb_dirty = 0; +- for (i=0; i<=TX_RING_MOD_MASK; i++) { ++ for (i = 0; i <= TX_RING_MOD_MASK; i++) { + if (fep->tx_skbuff[i] != NULL) { + dev_kfree_skb_any(fep->tx_skbuff[i]); + fep->tx_skbuff[i] = NULL; +@@ -2528,43 +2479,43 @@ fec_restart(struct net_device *dev, int + } + + /* Initialize the receive buffer descriptors. +- */ ++ */ + bdp = fep->rx_bd_base; +- for (i=0; icbd_sc = BD_ENET_RX_EMPTY; + bdp++; + } + + /* Set the last buffer to wrap. +- */ ++ */ + bdp--; + bdp->cbd_sc |= BD_SC_WRAP; + + /* ...and the same for transmmit. +- */ ++ */ + bdp = fep->tx_bd_base; +- for (i=0; icbd_sc = 0; + bdp->cbd_bufaddr = 0; + bdp++; + } + + /* Set the last buffer to wrap. +- */ ++ */ + bdp--; + bdp->cbd_sc |= BD_SC_WRAP; + + /* Enable MII mode. +- */ ++ */ + if (duplex) { +- fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;/* MII enable */ +- fecp->fec_x_cntrl = 0x04; /* FD enable */ ++ fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04; /* MII enable */ ++ fecp->fec_x_cntrl = 0x04; /* FD enable */ + } else { + /* MII enable|No Rcv on Xmit */ + fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x06; +@@ -2573,22 +2524,20 @@ fec_restart(struct net_device *dev, int + fep->full_duplex = duplex; + + /* Set MII speed. +- */ ++ */ + fecp->fec_mii_speed = fep->phy_speed; + + /* And last, enable the transmit and receive processing. +- */ ++ */ + fecp->fec_ecntrl = 2; + fecp->fec_r_des_active = 0; + + /* Enable interrupts we wish to service. +- */ +- fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | +- FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); ++ */ ++ fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII); + } + +-static void +-fec_stop(struct net_device *dev) ++static void fec_stop(struct net_device *dev) + { + volatile fec_t *fecp; + struct fec_enet_private *fep; +@@ -2597,23 +2546,23 @@ fec_stop(struct net_device *dev) + fecp = fep->hwp; + + /* +- ** We cannot expect a graceful transmit stop without link !!! +- */ +- if (fep->link) +- { ++ ** We cannot expect a graceful transmit stop without link !!! ++ */ ++ if (fep->link) { + fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */ + udelay(10); + if (!(fecp->fec_ievent & FEC_ENET_GRA)) +- printk("fec_stop : Graceful transmit stop did not complete !\n"); +- } ++ printk ++ ("fec_stop : Graceful transmit stop did not complete !\n"); ++ } + + /* Whack a reset. We should wait for this. +- */ ++ */ + fecp->fec_ecntrl = 1; + udelay(10); + + /* Clear outstanding MII command interrupts. +- */ ++ */ + fecp->fec_ievent = FEC_ENET_MII; + fec_enable_phy_intr(); + +@@ -2624,7 +2573,7 @@ fec_stop(struct net_device *dev) + static int __init fec_enet_module_init(void) + { + struct net_device *dev; +- int i, j, err; ++ int i, err; + DECLARE_MAC_BUF(mac); + + printk("FEC ENET Version 0.2\n"); +@@ -2651,5 +2600,4 @@ static int __init fec_enet_module_init(v + } + + module_init(fec_enet_module_init); +- + MODULE_LICENSE("GPL"); +Index: linux-2.6.24.7-rt21/drivers/serial/68328serial.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/serial/68328serial.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/serial/68328serial.c 2008-10-08 22:22:55.000000000 -0400 +@@ -1410,7 +1410,7 @@ rs68328_init(void) + + if (request_irq(uart_irqs[i], + rs_interrupt, +- IRQ_FLG_STD, ++ IRQF_DISABLED, + "M68328_UART", NULL)) + panic("Unable to attach 68328 serial interrupt\n"); + } +Index: linux-2.6.24.7-rt21/drivers/serial/mcf.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/serial/mcf.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/serial/mcf.c 2008-10-08 22:22:55.000000000 -0400 +@@ -69,7 +69,7 @@ static unsigned int mcf_tx_empty(struct + + static unsigned int mcf_get_mctrl(struct uart_port *port) + { +- struct mcf_uart *pp = (struct mcf_uart *) port; ++ struct mcf_uart *pp = container_of(port, struct mcf_uart, port); + unsigned long flags; + unsigned int sigs; + +@@ -87,7 +87,7 @@ static unsigned int mcf_get_mctrl(struct + + static void mcf_set_mctrl(struct uart_port *port, unsigned int sigs) + { +- struct mcf_uart *pp = (struct mcf_uart *) port; ++ struct mcf_uart *pp = container_of(port, struct mcf_uart, port); + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); +@@ -104,7 +104,7 @@ static void mcf_set_mctrl(struct uart_po + + static void mcf_start_tx(struct uart_port *port) + { +- struct mcf_uart *pp = (struct mcf_uart *) port; ++ struct mcf_uart *pp = container_of(port, struct mcf_uart, port); + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); +@@ -117,7 +117,7 @@ static void mcf_start_tx(struct uart_por + + static void mcf_stop_tx(struct uart_port *port) + { +- struct mcf_uart *pp = (struct mcf_uart *) port; ++ struct mcf_uart *pp = container_of(port, struct mcf_uart, port); + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); +@@ -130,7 +130,7 @@ static void mcf_stop_tx(struct uart_port + + static void mcf_stop_rx(struct uart_port *port) + { +- struct mcf_uart *pp = (struct mcf_uart *) port; ++ struct mcf_uart *pp = container_of(port, struct mcf_uart, port); + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); +@@ -163,7 +163,7 @@ static void mcf_enable_ms(struct uart_po + + static int mcf_startup(struct uart_port *port) + { +- struct mcf_uart *pp = (struct mcf_uart *) port; ++ struct mcf_uart *pp = container_of(port, struct mcf_uart, port); + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); +@@ -189,7 +189,7 @@ static int mcf_startup(struct uart_port + + static void mcf_shutdown(struct uart_port *port) + { +- struct mcf_uart *pp = (struct mcf_uart *) port; ++ struct mcf_uart *pp = container_of(port, struct mcf_uart, port); + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); +@@ -273,7 +273,7 @@ static void mcf_set_termios(struct uart_ + + static void mcf_rx_chars(struct mcf_uart *pp) + { +- struct uart_port *port = (struct uart_port *) pp; ++ struct uart_port *port = &pp->port; + unsigned char status, ch, flag; + + while ((status = readb(port->membase + MCFUART_USR)) & MCFUART_USR_RXREADY) { +@@ -319,7 +319,7 @@ static void mcf_rx_chars(struct mcf_uart + + static void mcf_tx_chars(struct mcf_uart *pp) + { +- struct uart_port *port = (struct uart_port *) pp; ++ struct uart_port *port = &pp->port; + struct circ_buf *xmit = &port->info->xmit; + + if (port->x_char) { +@@ -352,7 +352,7 @@ static void mcf_tx_chars(struct mcf_uart + static irqreturn_t mcf_interrupt(int irq, void *data) + { + struct uart_port *port = data; +- struct mcf_uart *pp = (struct mcf_uart *) port; ++ struct mcf_uart *pp = container_of(port, struct mcf_uart, port); + unsigned int isr; + + isr = readb(port->membase + MCFUART_UISR) & pp->imr; +@@ -434,7 +434,7 @@ static struct uart_ops mcf_uart_ops = { + + static struct mcf_uart mcf_ports[3]; + +-#define MCF_MAXPORTS (sizeof(mcf_ports) / sizeof(struct mcf_uart)) ++#define MCF_MAXPORTS ARRAY_SIZE(mcf_ports) + + /****************************************************************************/ + #if defined(CONFIG_SERIAL_MCF_CONSOLE) +Index: linux-2.6.24.7-rt21/drivers/serial/mcfserial.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/serial/mcfserial.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/serial/mcfserial.c 2008-10-08 22:22:55.000000000 -0400 +@@ -65,7 +65,8 @@ struct timer_list mcfrs_timer_struct; + #define CONSOLE_BAUD_RATE 115200 + #define DEFAULT_CBAUD B115200 + #elif defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \ +- defined(CONFIG_senTec) || defined(CONFIG_SNEHA) || defined(CONFIG_AVNET) ++ defined(CONFIG_senTec) || defined(CONFIG_SNEHA) || defined(CONFIG_AVNET) || \ ++ defined(CONFIG_SAVANT) + #define CONSOLE_BAUD_RATE 19200 + #define DEFAULT_CBAUD B19200 + #endif +@@ -324,7 +325,7 @@ static void mcfrs_start(struct tty_struc + * ----------------------------------------------------------------------- + */ + +-static inline void receive_chars(struct mcf_serial *info) ++static noinline void receive_chars(struct mcf_serial *info) + { + volatile unsigned char *uartp; + struct tty_struct *tty = info->tty; +@@ -369,7 +370,7 @@ static inline void receive_chars(struct + return; + } + +-static inline void transmit_chars(struct mcf_serial *info) ++static noinline void transmit_chars(struct mcf_serial *info) + { + volatile unsigned char *uartp; + +@@ -1489,14 +1490,28 @@ int mcfrs_open(struct tty_struct *tty, s + /* + * Based on the line number set up the internal interrupt stuff. + */ +-static void mcfrs_irqinit(struct mcf_serial *info) ++static int mcfrs_irqinit(struct mcf_serial *info) + { ++ volatile unsigned char *uartp; ++ int ret; ++ ++ uartp = info->addr; ++ /* Clear mask, so no surprise interrupts. */ ++ uartp[MCFUART_UIMR] = 0; ++ ++ ret = request_irq(info->irq, mcfrs_interrupt, IRQF_DISABLED, ++ "ColdFire UART", NULL); ++ if (ret) { ++ printk("MCFRS: Unable to attach ColdFire UART %d interrupt " ++ "vector=%d, error: %d\n", info->line, ++ info->irq, ret); ++ return ret; ++ } ++ + #if defined(CONFIG_M5272) + volatile unsigned long *icrp; + volatile unsigned long *portp; +- volatile unsigned char *uartp; + +- uartp = info->addr; + icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR2); + + switch (info->line) { +@@ -1518,11 +1533,10 @@ static void mcfrs_irqinit(struct mcf_ser + portp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PDCNT); + *portp = (*portp & ~0x000003fc) | 0x000002a8; + #elif defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) +- volatile unsigned char *icrp, *uartp; ++#if !defined(CONFIG_M523x) ++ volatile unsigned char *icrp; + volatile unsigned long *imrp; + +- uartp = info->addr; +- + icrp = (volatile unsigned char *) (MCF_MBAR + MCFICM_INTC0 + + MCFINTC_ICR0 + MCFINT_UART0 + info->line); + *icrp = 0x30 + info->line; /* level 6, line based priority */ +@@ -1530,6 +1544,14 @@ static void mcfrs_irqinit(struct mcf_ser + imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 + + MCFINTC_IMRL); + *imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1); ++#endif ++#if defined(CONFIG_M523x) ++ { ++ volatile unsigned short *par_uartp; ++ par_uartp = (volatile unsigned short *) (MCF_MBAR + MCF523x_GPIO_PAR_UART); ++ *par_uartp = 0x3FFF; /* setup GPIO for UART0, UART1 & UART2 */ ++ } ++#endif + #if defined(CONFIG_M527x) + { + /* +@@ -1554,37 +1576,38 @@ static void mcfrs_irqinit(struct mcf_ser + } + #endif + #elif defined(CONFIG_M520x) +- volatile unsigned char *icrp, *uartp; +- volatile unsigned long *imrp; +- +- uartp = info->addr; +- +- icrp = (volatile unsigned char *) (MCF_MBAR + MCFICM_INTC0 + +- MCFINTC_ICR0 + MCFINT_UART0 + info->line); +- *icrp = 0x03; ++ { ++ volatile unsigned char *icrp; ++ volatile unsigned long *imrp; + +- imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 + +- MCFINTC_IMRL); +- *imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1); +- if (info->line < 2) { +- unsigned short *uart_par; +- uart_par = (unsigned short *)(MCF_IPSBAR + MCF_GPIO_PAR_UART); +- if (info->line == 0) +- *uart_par |= MCF_GPIO_PAR_UART_PAR_UTXD0 +- | MCF_GPIO_PAR_UART_PAR_URXD0; +- else if (info->line == 1) +- *uart_par |= MCF_GPIO_PAR_UART_PAR_UTXD1 +- | MCF_GPIO_PAR_UART_PAR_URXD1; ++ icrp = (volatile unsigned char *) (MCF_MBAR + MCFICM_INTC0 + ++ MCFINTC_ICR0 + MCFINT_UART0 + info->line); ++ *icrp = 0x03; ++ ++ imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 + ++ MCFINTC_IMRL); ++ *imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1); ++ if (info->line < 2) { ++ unsigned short *uart_par; ++ uart_par = (unsigned short *)(MCF_IPSBAR + ++ MCF_GPIO_PAR_UART); ++ if (info->line == 0) ++ *uart_par |= MCF_GPIO_PAR_UART_PAR_UTXD0 ++ | MCF_GPIO_PAR_UART_PAR_URXD0; ++ else if (info->line == 1) ++ *uart_par |= MCF_GPIO_PAR_UART_PAR_UTXD1 ++ | MCF_GPIO_PAR_UART_PAR_URXD1; + } else if (info->line == 2) { + unsigned char *feci2c_par; +- feci2c_par = (unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C); ++ feci2c_par = (unsigned char *)(MCF_IPSBAR + ++ MCF_GPIO_PAR_FECI2C); + *feci2c_par &= ~0x0F; + *feci2c_par |= MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2 +- | MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2; ++ | MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2; + } ++ } + #elif defined(CONFIG_M532x) +- volatile unsigned char *uartp; +- uartp = info->addr; ++ + switch (info->line) { + case 0: + MCF_INTC0_ICR26 = 0x3; +@@ -1605,7 +1628,6 @@ static void mcfrs_irqinit(struct mcf_ser + break; + } + #else +- volatile unsigned char *icrp, *uartp; + + switch (info->line) { + case 0: +@@ -1623,23 +1645,12 @@ static void mcfrs_irqinit(struct mcf_ser + default: + printk("MCFRS: don't know how to handle UART %d interrupt?\n", + info->line); +- return; ++ return -ENODEV; + } + +- uartp = info->addr; + uartp[MCFUART_UIVR] = info->irq; + #endif +- +- /* Clear mask, so no surprise interrupts. */ +- uartp[MCFUART_UIMR] = 0; +- +- if (request_irq(info->irq, mcfrs_interrupt, IRQF_DISABLED, +- "ColdFire UART", NULL)) { +- printk("MCFRS: Unable to attach ColdFire UART %d interrupt " +- "vector=%d\n", info->line, info->irq); +- } +- +- return; ++ return 0; + } + + +@@ -1729,7 +1740,6 @@ static int __init + mcfrs_init(void) + { + struct mcf_serial *info; +- unsigned long flags; + int i; + + /* Setup base handler, and timer table. */ +@@ -1769,12 +1779,12 @@ mcfrs_init(void) + return(-EBUSY); + } + +- local_irq_save(flags); +- + /* + * Configure all the attached serial ports. + */ + for (i = 0, info = mcfrs_table; (i < NR_PORTS); i++, info++) { ++ int ret; ++ + info->magic = SERIAL_MAGIC; + info->line = i; + info->tty = 0; +@@ -1792,14 +1802,11 @@ mcfrs_init(void) + + info->imr = 0; + mcfrs_setsignals(info, 0, 0); +- mcfrs_irqinit(info); +- +- printk("ttyS%d at 0x%04x (irq = %d)", info->line, +- (unsigned int) info->addr, info->irq); +- printk(" is a builtin ColdFire UART\n"); ++ ret = mcfrs_irqinit(info); ++ if (!ret) ++ printk("ttyS%d at 0x%p (irq = %d) is a builtin " ++ "ColdFire UART\n", info->line, info->addr, info->irq); + } +- +- local_irq_restore(flags); + return 0; + } + +Index: linux-2.6.24.7-rt21/fs/nfs/file.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/nfs/file.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/nfs/file.c 2008-10-08 22:22:55.000000000 -0400 +@@ -64,7 +64,11 @@ const struct file_operations nfs_file_op + .write = do_sync_write, + .aio_read = nfs_file_read, + .aio_write = nfs_file_write, ++#ifdef CONFIG_MMU + .mmap = nfs_file_mmap, ++#else ++ .mmap = generic_file_mmap, ++#endif + .open = nfs_file_open, + .flush = nfs_file_flush, + .release = nfs_file_release, +Index: linux-2.6.24.7-rt21/include/asm-generic/vmlinux.lds.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-generic/vmlinux.lds.h 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-generic/vmlinux.lds.h 2008-10-08 22:22:55.000000000 -0400 +@@ -6,6 +6,10 @@ + #define VMLINUX_SYMBOL(_sym_) _sym_ + #endif + ++#ifndef OUTPUT_DATA_SECTION ++#define OUTPUT_DATA_SECTION ++#endif ++ + /* Align . to a 8 byte boundary equals to maximum function alignment. */ + #define ALIGN_FUNCTION() . = ALIGN(8) + +@@ -25,11 +29,11 @@ + *(.rodata) *(.rodata.*) \ + *(__vermagic) /* Kernel version magic */ \ + *(__markers_strings) /* Markers: strings */ \ +- } \ ++ } OUTPUT_DATA_SECTION \ + \ + .rodata1 : AT(ADDR(.rodata1) - LOAD_OFFSET) { \ + *(.rodata1) \ +- } \ ++ } OUTPUT_DATA_SECTION \ + \ + /* PCI quirks */ \ + .pci_fixup : AT(ADDR(.pci_fixup) - LOAD_OFFSET) { \ +@@ -48,89 +52,89 @@ + VMLINUX_SYMBOL(__start_pci_fixups_resume) = .; \ + *(.pci_fixup_resume) \ + VMLINUX_SYMBOL(__end_pci_fixups_resume) = .; \ +- } \ ++ } OUTPUT_DATA_SECTION \ + \ + /* RapidIO route ops */ \ + .rio_route : AT(ADDR(.rio_route) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start_rio_route_ops) = .; \ + *(.rio_route_ops) \ + VMLINUX_SYMBOL(__end_rio_route_ops) = .; \ +- } \ ++ } OUTPUT_DATA_SECTION \ + \ + /* Kernel symbol table: Normal symbols */ \ + __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start___ksymtab) = .; \ + *(__ksymtab) \ + VMLINUX_SYMBOL(__stop___ksymtab) = .; \ +- } \ ++ } OUTPUT_DATA_SECTION \ + \ + /* Kernel symbol table: GPL-only symbols */ \ + __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start___ksymtab_gpl) = .; \ + *(__ksymtab_gpl) \ + VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .; \ +- } \ ++ } OUTPUT_DATA_SECTION \ + \ + /* Kernel symbol table: Normal unused symbols */ \ + __ksymtab_unused : AT(ADDR(__ksymtab_unused) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start___ksymtab_unused) = .; \ + *(__ksymtab_unused) \ + VMLINUX_SYMBOL(__stop___ksymtab_unused) = .; \ +- } \ ++ } OUTPUT_DATA_SECTION \ + \ + /* Kernel symbol table: GPL-only unused symbols */ \ + __ksymtab_unused_gpl : AT(ADDR(__ksymtab_unused_gpl) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start___ksymtab_unused_gpl) = .; \ + *(__ksymtab_unused_gpl) \ + VMLINUX_SYMBOL(__stop___ksymtab_unused_gpl) = .; \ +- } \ ++ } OUTPUT_DATA_SECTION \ + \ + /* Kernel symbol table: GPL-future-only symbols */ \ + __ksymtab_gpl_future : AT(ADDR(__ksymtab_gpl_future) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start___ksymtab_gpl_future) = .; \ + *(__ksymtab_gpl_future) \ + VMLINUX_SYMBOL(__stop___ksymtab_gpl_future) = .; \ +- } \ ++ } OUTPUT_DATA_SECTION \ + \ + /* Kernel symbol table: Normal symbols */ \ + __kcrctab : AT(ADDR(__kcrctab) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start___kcrctab) = .; \ + *(__kcrctab) \ + VMLINUX_SYMBOL(__stop___kcrctab) = .; \ +- } \ ++ } OUTPUT_DATA_SECTION \ + \ + /* Kernel symbol table: GPL-only symbols */ \ + __kcrctab_gpl : AT(ADDR(__kcrctab_gpl) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start___kcrctab_gpl) = .; \ + *(__kcrctab_gpl) \ + VMLINUX_SYMBOL(__stop___kcrctab_gpl) = .; \ +- } \ ++ } OUTPUT_DATA_SECTION \ + \ + /* Kernel symbol table: Normal unused symbols */ \ + __kcrctab_unused : AT(ADDR(__kcrctab_unused) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start___kcrctab_unused) = .; \ + *(__kcrctab_unused) \ + VMLINUX_SYMBOL(__stop___kcrctab_unused) = .; \ +- } \ ++ } OUTPUT_DATA_SECTION \ + \ + /* Kernel symbol table: GPL-only unused symbols */ \ + __kcrctab_unused_gpl : AT(ADDR(__kcrctab_unused_gpl) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start___kcrctab_unused_gpl) = .; \ + *(__kcrctab_unused_gpl) \ + VMLINUX_SYMBOL(__stop___kcrctab_unused_gpl) = .; \ +- } \ ++ } OUTPUT_DATA_SECTION \ + \ + /* Kernel symbol table: GPL-future-only symbols */ \ + __kcrctab_gpl_future : AT(ADDR(__kcrctab_gpl_future) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start___kcrctab_gpl_future) = .; \ + *(__kcrctab_gpl_future) \ + VMLINUX_SYMBOL(__stop___kcrctab_gpl_future) = .; \ +- } \ ++ } OUTPUT_DATA_SECTION \ + \ + /* Kernel symbol table: strings */ \ + __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \ + *(__ksymtab_strings) \ +- } \ ++ } OUTPUT_DATA_SECTION \ + \ + /* Built-in module parameters. */ \ + __param : AT(ADDR(__param) - LOAD_OFFSET) { \ +@@ -138,7 +142,7 @@ + *(__param) \ + VMLINUX_SYMBOL(__stop___param) = .; \ + VMLINUX_SYMBOL(__end_rodata) = .; \ +- } \ ++ } OUTPUT_DATA_SECTION \ + \ + . = ALIGN((align)); + +@@ -227,7 +231,7 @@ + __start___bug_table = .; \ + *(__bug_table) \ + __stop___bug_table = .; \ +- } ++ } OUTPUT_DATA_SECTION + + #define NOTES \ + .notes : AT(ADDR(.notes) - LOAD_OFFSET) { \ +@@ -261,5 +265,5 @@ + .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { \ + *(.data.percpu) \ + *(.data.percpu.shared_aligned) \ +- } \ ++ } OUTPUT_DATA_SECTION \ + __per_cpu_end = .; +Index: linux-2.6.24.7-rt21/include/asm-m68knommu/bitops.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-m68knommu/bitops.h 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-m68knommu/bitops.h 2008-10-08 22:22:55.000000000 -0400 +@@ -14,8 +14,38 @@ + #error only can be included directly + #endif + ++#if defined (__mcfisaaplus__) || defined (__mcfisac__) ++static inline int ffs(unsigned int val) ++{ ++ if (!val) ++ return 0; ++ ++ asm volatile( ++ "bitrev %0\n\t" ++ "ff1 %0\n\t" ++ : "=d" (val) ++ : "0" (val) ++ ); ++ val++; ++ return val; ++} ++ ++static inline int __ffs(unsigned int val) ++{ ++ asm volatile( ++ "bitrev %0\n\t" ++ "ff1 %0\n\t" ++ : "=d" (val) ++ : "0" (val) ++ ); ++ return val; ++} ++ ++#else + #include + #include ++#endif ++ + #include + #include + +Index: linux-2.6.24.7-rt21/include/asm-m68knommu/byteorder.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-m68knommu/byteorder.h 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-m68knommu/byteorder.h 2008-10-08 22:22:55.000000000 -0400 +@@ -1,13 +1,27 @@ + #ifndef _M68KNOMMU_BYTEORDER_H + #define _M68KNOMMU_BYTEORDER_H + +-#include ++#include + + #if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__) + # define __BYTEORDER_HAS_U64__ + # define __SWAB_64_THRU_32__ + #endif + ++#if defined (__mcfisaaplus__) || defined (__mcfisac__) ++static inline __attribute_const__ __u32 ___arch__swab32(__u32 val) ++{ ++ asm( ++ "byterev %0" ++ : "=d" (val) ++ : "0" (val) ++ ); ++ return val; ++} ++ ++#define __arch__swab32(x) ___arch__swab32(x) ++#endif ++ + #include + + #endif /* _M68KNOMMU_BYTEORDER_H */ +Index: linux-2.6.24.7-rt21/include/asm-m68knommu/cacheflush.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-m68knommu/cacheflush.h 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-m68knommu/cacheflush.h 2008-10-08 22:22:55.000000000 -0400 +@@ -53,7 +53,7 @@ static inline void __flush_cache_all(voi + #endif /* CONFIG_M5407 */ + #if defined(CONFIG_M527x) || defined(CONFIG_M528x) + __asm__ __volatile__ ( +- "movel #0x81400100, %%d0\n\t" ++ "movel #0x81000200, %%d0\n\t" + "movec %%d0, %%CACR\n\t" + "nop\n\t" + : : : "d0" ); +Index: linux-2.6.24.7-rt21/include/asm-m68knommu/commproc.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-m68knommu/commproc.h 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-m68knommu/commproc.h 2008-10-08 22:22:55.000000000 -0400 +@@ -519,25 +519,6 @@ typedef struct scc_enet { + #define SICR_ENET_CLKRT ((uint)0x00002c00) + #endif + +-#ifdef CONFIG_RPXCLASSIC +-/* Bits in parallel I/O port registers that have to be set/cleared +- * to configure the pins for SCC1 use. +- */ +-#define PA_ENET_RXD ((ushort)0x0001) +-#define PA_ENET_TXD ((ushort)0x0002) +-#define PA_ENET_TCLK ((ushort)0x0200) +-#define PA_ENET_RCLK ((ushort)0x0800) +-#define PB_ENET_TENA ((uint)0x00001000) +-#define PC_ENET_CLSN ((ushort)0x0010) +-#define PC_ENET_RENA ((ushort)0x0020) +- +-/* Control bits in the SICR to route TCLK (CLK2) and RCLK (CLK4) to +- * SCC1. Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero. +- */ +-#define SICR_ENET_MASK ((uint)0x000000ff) +-#define SICR_ENET_CLKRT ((uint)0x0000003d) +-#endif +- + /* SCC Event register as used by Ethernet. + */ + #define SCCE_ENET_GRA ((ushort)0x0080) /* Graceful stop complete */ +Index: linux-2.6.24.7-rt21/include/asm-m68knommu/dma.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-m68knommu/dma.h 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-m68knommu/dma.h 2008-10-08 22:22:55.000000000 -0400 +@@ -35,7 +35,8 @@ + /* + * Set number of channels of DMA on ColdFire for different implementations. + */ +-#if defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) ++#if defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) || \ ++ defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) + #define MAX_M68K_DMA_CHANNELS 4 + #elif defined(CONFIG_M5272) + #define MAX_M68K_DMA_CHANNELS 1 +Index: linux-2.6.24.7-rt21/include/asm-m68knommu/m523xsim.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-m68knommu/m523xsim.h 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-m68knommu/m523xsim.h 2008-10-08 22:22:55.000000000 -0400 +@@ -11,7 +11,6 @@ + #define m523xsim_h + /****************************************************************************/ + +- + /* + * Define the 523x SIM register set addresses. + */ +@@ -27,10 +26,35 @@ + #define MCFINTC_IACKL 0x19 /* */ + #define MCFINTC_ICR0 0x40 /* Base ICR register */ + ++/* INTC0 - interrupt numbers */ + #define MCFINT_VECBASE 64 /* Vector base number */ +-#define MCFINT_UART0 13 /* Interrupt number for UART0 */ +-#define MCFINT_PIT1 36 /* Interrupt number for PIT1 */ +-#define MCFINT_QSPI 18 /* Interrupt number for QSPI */ ++#define MCFINT_EPF4 4 /* EPORT4 */ ++#define MCFINT_EPF5 5 /* EPORT5 */ ++#define MCFINT_EPF6 6 /* EPORT6 */ ++#define MCFINT_EPF7 7 /* EPORT7 */ ++#define MCFINT_UART0 13 /* UART0 */ ++#define MCFINT_QSPI 18 /* QSPI */ ++#define MCFINT_PIT1 36 /* PIT1 */ ++#define MCFINT_PER_INTC 64 ++ ++/* INTC1 - interrupt numbers */ ++#define MCFINT_INTC1_VECBASE (MCFINT_VECBASE + MCFINT_PER_INTC) ++#define MCFINT_TC0F 27 /* eTPU Channel 0 */ ++#define MCFINT_TC1F 28 /* eTPU Channel 1 */ ++#define MCFINT_TC2F 29 /* eTPU Channel 2 */ ++#define MCFINT_TC3F 30 /* eTPU Channel 3 */ ++#define MCFINT_TC4F 31 /* eTPU Channel 4 */ ++#define MCFINT_TC5F 32 /* eTPU Channel 5 */ ++#define MCFINT_TC6F 33 /* eTPU Channel 6 */ ++#define MCFINT_TC7F 34 /* eTPU Channel 7 */ ++#define MCFINT_TC8F 35 /* eTPU Channel 8 */ ++#define MCFINT_TC9F 36 /* eTPU Channel 9 */ ++#define MCFINT_TC10F 37 /* eTPU Channel 10 */ ++#define MCFINT_TC11F 38 /* eTPU Channel 11 */ ++#define MCFINT_TC12F 39 /* eTPU Channel 12 */ ++#define MCFINT_TC13F 40 /* eTPU Channel 13 */ ++#define MCFINT_TC14F 41 /* eTPU Channel 14 */ ++#define MCFINT_TC15F 42 /* eTPU Channel 15 */ + + /* + * SDRAM configuration registers. +@@ -41,5 +65,120 @@ + #define MCFSIM_DACR1 0x50 /* SDRAM base address 1 */ + #define MCFSIM_DMR1 0x54 /* SDRAM address mask 1 */ + ++/* ++ * GPIO Registers and Pin Assignments ++ */ ++#define MCF_GPIO_PAR_FECI2C 0x100047 /* FEC Pin Assignment reg */ ++#define MCF523x_GPIO_PAR_UART 0x100048 /* UART Pin Assignment reg */ ++#define MCF523x_GPIO_PAR_QSPI 0x10004a /* QSPI Pin Assignment reg */ ++#define MCF523x_GPIO_PAR_TIMER 0x10004c /* TIMER Pin Assignment reg */ ++#define MCF523x_GPIO_PDDR_QSPI 0x10001a /* QSPI Pin Direction reg */ ++#define MCF523x_GPIO_PDDR_TIMER 0x10001b /* TIMER Pin Direction reg */ ++#define MCF523x_GPIO_PPDSDR_QSPI 0x10002a /* QSPI Pin Data reg */ ++#define MCF523x_GPIO_PPDSDR_TIMER 0x10002b /* TIMER Pin Data reg */ ++ ++#define MCF_GPIO_PAR_FECI2C_PAR_SDA(x) (((x) & 0x03) << 0) ++#define MCF_GPIO_PAR_FECI2C_PAR_SCL(x) (((x) & 0x03) << 2) ++ ++/* ++ * eTPU Registers ++ */ ++#define MCF523x_ETPU 0x1d0000 /* eTPU Base */ ++#define MCF523x_ETPU_CIOSR 0x00220 /* eTPU Intr Overflow Status */ ++#define MCF523x_ETPU_CIER 0x00240 /* eTPU Intr Enable */ ++#define MCF523x_ETPU_CR(c) (0x00400 + ((c) * 0x10)) /* eTPU c Config */ ++#define MCF523x_ETPU_SCR(c) (0x00404 + ((c) * 0x10)) /* eTPU c Status & Ctrl */ ++#define MCF523x_ETPU_SDM 0x08000 /* eTPU Shared Data Memory */ ++ ++/* ++ * WDOG registers ++ */ ++#define MCF523x_WCR ((volatile uint16_t *) (MCF_IPSBAR + 0x140000)) /* control register 16 bits */ ++#define MCF523x_WMR ((volatile uint16_t *) (MCF_IPSBAR + 0x140002)) /* modulus status 16 bits */ ++#define MCF523x_MCNTR ((volatile uint16_t *) (MCF_IPSBAR + 0x140004)) /* count register 16 bits */ ++#define MCF523x_WSR ((volatile uint16_t *) (MCF_IPSBAR + 0x140006)) /* service register 16 bits */ ++ ++/* ++ * Reset registers ++ */ ++#define MCF523x_RSR ((volatile uint8_t *) (MCF_IPSBAR + 0x110001)) /* reset reason codes */ ++ ++/* ++ * WDOG bit level definitions and macros. ++ */ ++#define MCF523x_WCR_ENABLE_BIT 0x0001 ++ ++#define MCF523x_WCR_ENABLE 0x0001 ++#define MCF523x_WCR_DISABLE 0x0000 ++#define MCF523x_WCR_HALTEDSTOP 0x0002 ++#define MCF523x_WCR_HALTEDRUN 0x0000 ++#define MCF523x_WCR_DOZESTOP 0x0004 ++#define MCF523x_WCR_DOZERUN 0x0000 ++#define MCF523x_WCR_WAITSTOP 0x0008 ++#define MCF523x_WCR_WAITRUN 0x0000 ++ ++#define MCF523x_WMR_DEFAULT_VALUE 0xffff ++ ++/* ++ * Inter-IC (I2C) Module ++ * Read/Write access macros for general use ++ */ ++#define MCF_I2C_I2ADR ((volatile u8 *) (MCF_IPSBAR + 0x0300)) /* Address */ ++#define MCF_I2C_I2FDR ((volatile u8 *) (MCF_IPSBAR + 0x0304)) /* Freq Divider */ ++#define MCF_I2C_I2CR ((volatile u8 *) (MCF_IPSBAR + 0x0308)) /* Control */ ++#define MCF_I2C_I2SR ((volatile u8 *) (MCF_IPSBAR + 0x030C)) /* Status */ ++#define MCF_I2C_I2DR ((volatile u8 *) (MCF_IPSBAR + 0x0310)) /* Data I/O */ ++ ++/* ++ * Bit level definitions and macros ++ */ ++#define MCF_I2C_I2ADR_ADDR(x) (((x) & 0x7F) << 0x01) ++#define MCF_I2C_I2FDR_IC(x) ((x) & 0x3F) ++ ++#define MCF_I2C_I2CR_IEN 0x80 /* I2C enable */ ++#define MCF_I2C_I2CR_IIEN 0x40 /* interrupt enable */ ++#define MCF_I2C_I2CR_MSTA 0x20 /* master/slave mode */ ++#define MCF_I2C_I2CR_MTX 0x10 /* transmit/receive mode */ ++#define MCF_I2C_I2CR_TXAK 0x08 /* transmit acknowledge enable */ ++#define MCF_I2C_I2CR_RSTA 0x04 /* repeat start */ ++ ++#define MCF_I2C_I2SR_ICF 0x80 /* data transfer bit */ ++#define MCF_I2C_I2SR_IAAS 0x40 /* I2C addressed as a slave */ ++#define MCF_I2C_I2SR_IBB 0x20 /* I2C bus busy */ ++#define MCF_I2C_I2SR_IAL 0x10 /* aribitration lost */ ++#define MCF_I2C_I2SR_SRW 0x04 /* slave read/write */ ++#define MCF_I2C_I2SR_IIF 0x02 /* I2C interrupt */ ++#define MCF_I2C_I2SR_RXAK 0x01 /* received acknowledge */ ++ ++/* ++ * Edge Port (EPORT) Module ++ */ ++#define MCF523x_EPPAR 0x130000 ++#define MCF523x_EPDDR 0x130002 ++#define MCF523x_EPIER 0x130003 ++#define MCF523x_EPDR 0x130004 ++#define MCF523x_EPPDR 0x130005 ++#define MCF523x_EPFR 0x130006 ++ ++/* ++ * Chip Select (CS) Module ++ */ ++#define MCF523x_CSAR0 0x80 ++#define MCF523x_CSAR3 0xA4 ++#define MCF523x_CSMR3 0xA8 ++ ++/* ++ * System Access Control Unit (SACU) ++ */ ++#define MCF523x_PACR1 0x25 ++#define MCF523x_PACR2 0x26 ++#define MCF523x_PACR3 0x27 ++#define MCF523x_PACR4 0x28 ++#define MCF523x_PACR5 0x2A ++#define MCF523x_PACR6 0x2B ++#define MCF523x_PACR7 0x2C ++#define MCF523x_PACR8 0x2E ++#define MCF523x_GPACR 0x30 ++ + /****************************************************************************/ + #endif /* m523xsim_h */ +Index: linux-2.6.24.7-rt21/include/asm-m68knommu/m528xsim.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-m68knommu/m528xsim.h 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-m68knommu/m528xsim.h 2008-10-08 22:22:55.000000000 -0400 +@@ -30,6 +30,9 @@ + #define MCFINT_VECBASE 64 /* Vector base number */ + #define MCFINT_UART0 13 /* Interrupt number for UART0 */ + #define MCFINT_PIT1 55 /* Interrupt number for PIT1 */ ++#define MCFINT_QSPI 18 /* Interrupt number for QSPI */ ++ ++#define MCF5282_INTC0 (MCF_IPSBAR + MCFICM_INTC0) + + /* + * SDRAM configuration registers. +@@ -50,44 +53,53 @@ + /* Port UA Pin Assignment Register (8 Bit) */ + #define MCF5282_GPIO_PUAPAR 0x10005C + ++#define MCF5282_GPIO_PORTQS (*(volatile u8 *) (MCF_IPSBAR + 0x0010000D)) ++#define MCF5282_GPIO_DDRQS (*(volatile u8 *) (MCF_IPSBAR + 0x00100021)) ++#define MCF5282_GPIO_PORTQSP (*(volatile u8 *) (MCF_IPSBAR + 0x00100035)) ++#define MCF5282_GPIO_PQSPAR (*(volatile u8 *) (MCF_IPSBAR + 0x00100059)) ++ ++#define MCF5282_GPIO_PEPAR (*(volatile u16 *) (MCF_IPSBAR + 0x00100052)) ++ ++#define MCF5282_GPIO_PORTE (*(volatile u8 *) (MCF_IPSBAR + 0x00100004)) ++#define MCF5282_GPIO_DDRE (*(volatile u8 *) (MCF_IPSBAR + 0x00100018)) ++#define MCF5282_GPIO_PORTEP (*(volatile u8 *) (MCF_IPSBAR + 0x0010002C)) ++ + /* Interrupt Mask Register Register Low */ + #define MCF5282_INTC0_IMRL (volatile u32 *) (MCF_IPSBAR + 0x0C0C) + /* Interrupt Control Register 7 */ + #define MCF5282_INTC0_ICR17 (volatile u8 *) (MCF_IPSBAR + 0x0C51) + +- +- + /********************************************************************* + * + * Inter-IC (I2C) Module + * + *********************************************************************/ + /* Read/Write access macros for general use */ +-#define MCF5282_I2C_I2ADR (volatile u8 *) (MCF_IPSBAR + 0x0300) // Address +-#define MCF5282_I2C_I2FDR (volatile u8 *) (MCF_IPSBAR + 0x0304) // Freq Divider +-#define MCF5282_I2C_I2CR (volatile u8 *) (MCF_IPSBAR + 0x0308) // Control +-#define MCF5282_I2C_I2SR (volatile u8 *) (MCF_IPSBAR + 0x030C) // Status +-#define MCF5282_I2C_I2DR (volatile u8 *) (MCF_IPSBAR + 0x0310) // Data I/O ++#define MCF_I2C_I2ADR (volatile u8 *) (MCF_IPSBAR + 0x0300) // Address ++#define MCF_I2C_I2FDR (volatile u8 *) (MCF_IPSBAR + 0x0304) // Freq Divider ++#define MCF_I2C_I2CR (volatile u8 *) (MCF_IPSBAR + 0x0308) // Control ++#define MCF_I2C_I2SR (volatile u8 *) (MCF_IPSBAR + 0x030C) // Status ++#define MCF_I2C_I2DR (volatile u8 *) (MCF_IPSBAR + 0x0310) // Data I/O + + /* Bit level definitions and macros */ +-#define MCF5282_I2C_I2ADR_ADDR(x) (((x)&0x7F)<<0x01) ++#define MCF_I2C_I2ADR_ADDR(x) (((x)&0x7F)<<0x01) + +-#define MCF5282_I2C_I2FDR_IC(x) (((x)&0x3F)) ++#define MCF_I2C_I2FDR_IC(x) (((x)&0x3F)) + +-#define MCF5282_I2C_I2CR_IEN (0x80) // I2C enable +-#define MCF5282_I2C_I2CR_IIEN (0x40) // interrupt enable +-#define MCF5282_I2C_I2CR_MSTA (0x20) // master/slave mode +-#define MCF5282_I2C_I2CR_MTX (0x10) // transmit/receive mode +-#define MCF5282_I2C_I2CR_TXAK (0x08) // transmit acknowledge enable +-#define MCF5282_I2C_I2CR_RSTA (0x04) // repeat start +- +-#define MCF5282_I2C_I2SR_ICF (0x80) // data transfer bit +-#define MCF5282_I2C_I2SR_IAAS (0x40) // I2C addressed as a slave +-#define MCF5282_I2C_I2SR_IBB (0x20) // I2C bus busy +-#define MCF5282_I2C_I2SR_IAL (0x10) // aribitration lost +-#define MCF5282_I2C_I2SR_SRW (0x04) // slave read/write +-#define MCF5282_I2C_I2SR_IIF (0x02) // I2C interrupt +-#define MCF5282_I2C_I2SR_RXAK (0x01) // received acknowledge ++#define MCF_I2C_I2CR_IEN (0x80) // I2C enable ++#define MCF_I2C_I2CR_IIEN (0x40) // interrupt enable ++#define MCF_I2C_I2CR_MSTA (0x20) // master/slave mode ++#define MCF_I2C_I2CR_MTX (0x10) // transmit/receive mode ++#define MCF_I2C_I2CR_TXAK (0x08) // transmit acknowledge enable ++#define MCF_I2C_I2CR_RSTA (0x04) // repeat start ++ ++#define MCF_I2C_I2SR_ICF (0x80) // data transfer bit ++#define MCF_I2C_I2SR_IAAS (0x40) // I2C addressed as a slave ++#define MCF_I2C_I2SR_IBB (0x20) // I2C bus busy ++#define MCF_I2C_I2SR_IAL (0x10) // aribitration lost ++#define MCF_I2C_I2SR_SRW (0x04) // slave read/write ++#define MCF_I2C_I2SR_IIF (0x02) // I2C interrupt ++#define MCF_I2C_I2SR_RXAK (0x01) // received acknowledge + + + +@@ -107,6 +119,11 @@ + #define MCF5282_QSPI_QDR MCF_IPSBAR + 0x0354 + #define MCF5282_QSPI_QCR MCF_IPSBAR + 0x0354 + ++#define MCF5282_QSPI_PAR (MCF_IPSBAR + 0x00100059) ++ ++#define MCF5282_QSPI_IRQ_SOURCE 18 ++#define MCF5282_QSPI_IRQ_VECTOR (64 + MCF5282_QSPI_IRQ_SOURCE) ++ + /* Bit level definitions and macros */ + #define MCF5282_QSPI_QMR_MSTR (0x8000) + #define MCF5282_QSPI_QMR_DOHIE (0x4000) +Index: linux-2.6.24.7-rt21/include/asm-m68knommu/m532xsim.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-m68knommu/m532xsim.h 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-m68knommu/m532xsim.h 2008-10-08 22:22:55.000000000 -0400 +@@ -16,6 +16,7 @@ + #define MCFINT_VECBASE 64 + #define MCFINT_UART0 26 /* Interrupt number for UART0 */ + #define MCFINT_UART1 27 /* Interrupt number for UART1 */ ++#define MCFINT_UART2 28 /* Interrupt number for UART2 */ + + #define MCF_WTM_WCR MCF_REG16(0xFC098000) + +@@ -72,9 +73,21 @@ + #define mcf_getimr() \ + *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) + ++#define mcf_getimrh() \ ++ *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMRH)) ++ ++#define mcf_getimrl() \ ++ *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMRL)) ++ + #define mcf_setimr(imr) \ + *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr); + ++#define mcf_setimrh(imr) \ ++ *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMRH)) = (imr); ++ ++#define mcf_setimrl(imr) \ ++ *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMRL)) = (imr); ++ + #define mcf_getipr() \ + *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR)) + +@@ -131,31 +144,31 @@ + *********************************************************************/ + + /* Read/Write access macros for general use */ +-#define MCF532x_I2C_I2ADR (volatile u8 *) (0xFC058000) // Address +-#define MCF532x_I2C_I2FDR (volatile u8 *) (0xFC058004) // Freq Divider +-#define MCF532x_I2C_I2CR (volatile u8 *) (0xFC058008) // Control +-#define MCF532x_I2C_I2SR (volatile u8 *) (0xFC05800C) // Status +-#define MCF532x_I2C_I2DR (volatile u8 *) (0xFC058010) // Data I/O ++#define MCF_I2C_I2ADR (volatile u8 *) (0xFC058000) /* Address */ ++#define MCF_I2C_I2FDR (volatile u8 *) (0xFC058004) /* Freq Divider */ ++#define MCF_I2C_I2CR (volatile u8 *) (0xFC058008) /* Control */ ++#define MCF_I2C_I2SR (volatile u8 *) (0xFC05800C) /* Status */ ++#define MCF_I2C_I2DR (volatile u8 *) (0xFC058010) /* Data I/O */ + + /* Bit level definitions and macros */ +-#define MCF532x_I2C_I2ADR_ADDR(x) (((x)&0x7F)<<0x01) ++#define MCF_I2C_I2ADR_ADDR(x) (((x)&0x7F)<<0x01) + +-#define MCF532x_I2C_I2FDR_IC(x) (((x)&0x3F)) ++#define MCF_I2C_I2FDR_IC(x) (((x)&0x3F)) + +-#define MCF532x_I2C_I2CR_IEN (0x80) // I2C enable +-#define MCF532x_I2C_I2CR_IIEN (0x40) // interrupt enable +-#define MCF532x_I2C_I2CR_MSTA (0x20) // master/slave mode +-#define MCF532x_I2C_I2CR_MTX (0x10) // transmit/receive mode +-#define MCF532x_I2C_I2CR_TXAK (0x08) // transmit acknowledge enable +-#define MCF532x_I2C_I2CR_RSTA (0x04) // repeat start +- +-#define MCF532x_I2C_I2SR_ICF (0x80) // data transfer bit +-#define MCF532x_I2C_I2SR_IAAS (0x40) // I2C addressed as a slave +-#define MCF532x_I2C_I2SR_IBB (0x20) // I2C bus busy +-#define MCF532x_I2C_I2SR_IAL (0x10) // aribitration lost +-#define MCF532x_I2C_I2SR_SRW (0x04) // slave read/write +-#define MCF532x_I2C_I2SR_IIF (0x02) // I2C interrupt +-#define MCF532x_I2C_I2SR_RXAK (0x01) // received acknowledge ++#define MCF_I2C_I2CR_IEN (0x80) /* I2C enable */ ++#define MCF_I2C_I2CR_IIEN (0x40) /* interrupt enable */ ++#define MCF_I2C_I2CR_MSTA (0x20) /* master/slave mode */ ++#define MCF_I2C_I2CR_MTX (0x10) /* transmit/receive mode */ ++#define MCF_I2C_I2CR_TXAK (0x08) /* transmit acknowledge enable */ ++#define MCF_I2C_I2CR_RSTA (0x04) /* repeat start */ ++ ++#define MCF_I2C_I2SR_ICF (0x80) /* data transfer bit */ ++#define MCF_I2C_I2SR_IAAS (0x40) /* I2C addressed as a slave */ ++#define MCF_I2C_I2SR_IBB (0x20) /* I2C bus busy */ ++#define MCF_I2C_I2SR_IAL (0x10) /* aribitration lost */ ++#define MCF_I2C_I2SR_SRW (0x04) /* slave read/write */ ++#define MCF_I2C_I2SR_IIF (0x02) /* I2C interrupt */ ++#define MCF_I2C_I2SR_RXAK (0x01) /* received acknowledge */ + + #define MCF532x_PAR_FECI2C (volatile u8 *) (0xFC0A4053) + +@@ -2234,5 +2247,36 @@ + #define MCF_EPORT_EPFR_EPF6 (0x40) + #define MCF_EPORT_EPFR_EPF7 (0x80) + ++/********************************************************************* ++ * ++ * Cross-Bar Switch (XBS) ++ * ++ *********************************************************************/ ++#define MCF_XBS_PRS1 MCF_REG32(0xFC004100) ++#define MCF_XBS_CRS1 MCF_REG32(0xFC004110) ++#define MCF_XBS_PRS4 MCF_REG32(0xFC004400) ++#define MCF_XBS_CRS4 MCF_REG32(0xFC004410) ++#define MCF_XBS_PRS6 MCF_REG32(0xFC004600) ++#define MCF_XBS_CRS6 MCF_REG32(0xFC004610) ++#define MCF_XBS_PRS7 MCF_REG32(0xFC004700) ++#define MCF_XBS_CRS7 MCF_REG32(0xFC004710) ++ ++#define MCF_XBS_PRIO_FACTTEST(x) (((x)&0x7) << 28) ++#define MCF_XBS_PRIO_USBOTG(x) (((x)&0x7) << 24) ++#define MCF_XBS_PRIO_USBHOST(x) (((x)&0x7) << 20) ++#define MCF_XBS_PRIO_LCD(x) (((x)&0x7) << 16) ++#define MCF_XBS_PRIO_FEC(x) (((x)&0x7) << 8) ++#define MCF_XBS_PRIO_EDMA(x) (((x)&0x7) << 4) ++#define MCF_XBS_PRIO_CORE(x) (((x)&0x7) << 0) ++ ++#define MCF_PRIO_LVL_1 (0) ++#define MCF_PRIO_LVL_2 (1) ++#define MCF_PRIO_LVL_3 (2) ++#define MCF_PRIO_LVL_4 (3) ++#define MCF_PRIO_LVL_5 (4) ++#define MCF_PRIO_LVL_6 (5) ++#define MCF_PRIO_LVL_7 (6) ++ ++ + /********************************************************************/ + #endif /* m532xsim_h */ +Index: linux-2.6.24.7-rt21/include/asm-m68knommu/mcfcache.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-m68knommu/mcfcache.h 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-m68knommu/mcfcache.h 2008-10-08 22:22:55.000000000 -0400 +@@ -60,7 +60,7 @@ + nop + movel #0x0000c020, %d0 /* Set SDRAM cached only */ + movec %d0, %ACR0 +- movel #0xff00c000, %d0 /* Cache Flash also */ ++ movel #0x00000000, %d0 /* No other regions cached */ + movec %d0, %ACR1 + movel #0x80000200, %d0 /* Setup cache mask */ + movec %d0, %CACR /* Enable cache */ +Index: linux-2.6.24.7-rt21/include/asm-m68knommu/mcfuart.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-m68knommu/mcfuart.h 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-m68knommu/mcfuart.h 2008-10-08 22:22:55.000000000 -0400 +@@ -12,7 +12,6 @@ + #define mcfuart_h + /****************************************************************************/ + +- + /* + * Define the base address of the UARTS within the MBAR address + * space. +@@ -33,7 +32,7 @@ + #define MCFUART_BASE2 0x240 /* Base address of UART2 */ + #define MCFUART_BASE3 0x280 /* Base address of UART3 */ + #elif defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) +-#if defined(CONFIG_NETtel) || defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3) ++#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3) + #define MCFUART_BASE1 0x200 /* Base address of UART1 */ + #define MCFUART_BASE2 0x1c0 /* Base address of UART2 */ + #else +Index: linux-2.6.24.7-rt21/mm/nommu.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/mm/nommu.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/mm/nommu.c 2008-10-08 22:22:55.000000000 -0400 +@@ -952,6 +952,16 @@ unsigned long do_mmap_pgoff(struct file + if (ret < 0) + goto error; + ++ /* ++ * If the driver implemented his own mmap(), the ++ * base addr could have changed. Therefor ++ * vm_end musst be updated to. ++ * ++ * See comment of DaveM in mm/mmap.c as reference ++ */ ++ if(addr != vma->vm_start) ++ vma->vm_end = vma->vm_start + len; ++ + /* okay... we have a mapping; now we have to register it */ + result = (void *) vma->vm_start; + +Index: linux-2.6.24.7-rt21/mm/page_alloc.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/mm/page_alloc.c 2008-10-08 22:22:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/mm/page_alloc.c 2008-10-08 22:22:55.000000000 -0400 +@@ -4317,6 +4317,14 @@ void *__init alloc_large_system_hash(con + if (numentries > max) + numentries = max; + ++ /* ++ * we will allocate at least a page (even on low memory systems) ++ * so do a fixup here to ensure we utilise the space that will be ++ * allocated, this also prevents us reporting -ve orders ++ */ ++ if (bucketsize * numentries < PAGE_SIZE) ++ numentries = (PAGE_SIZE + bucketsize - 1) / bucketsize; ++ + log2qty = ilog2(numentries); + + do { --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0344-lockdep-rt-recursion-limit-fix.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0344-lockdep-rt-recursion-limit-fix.patch @@ -0,0 +1,88 @@ + +OK, I sent this out once before but it must have slipped under the radar. +http://lkml.org/lkml/2007/6/28/325 + +My config fails miserably with lockdep: + +kernel/lockdep.c: In function 'find_usage_forwards': +kernel/lockdep.c:814: error: 'RECURSION_LIMIT' undeclared (first use in +this function) +kernel/lockdep.c:814: error: (Each undeclared identifier is reported only +once +kernel/lockdep.c:814: error: for each function it appears in.) +kernel/lockdep.c:815: warning: implicit declaration of function +'print_infinite_recursion_bug' +kernel/lockdep.c: In function 'find_usage_backwards': +kernel/lockdep.c:856: error: 'RECURSION_LIMIT' undeclared (first use in +this function) +make[1]: *** [kernel/lockdep.o] Error 1 + +But this patch fixes it nicely. + +Signed-off-by: Steven Rostedt + +--- + kernel/lockdep.c | 29 +++++++++++++++++------------ + 1 file changed, 17 insertions(+), 12 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/lockdep.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/lockdep.c 2008-10-08 22:24:11.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/lockdep.c 2008-10-08 22:24:26.000000000 -0400 +@@ -817,6 +817,21 @@ out_unlock_set: + return class; + } + ++#if defined(CONFIG_PROVE_LOCKING) || defined(CONFIG_TRACE_IRQFLAGS) ++ ++#define RECURSION_LIMIT 40 ++ ++static int noinline print_infinite_recursion_bug(void) ++{ ++ if (!debug_locks_off_graph_unlock()) ++ return 0; ++ ++ WARN_ON(1); ++ ++ return 0; ++} ++#endif /* CONFIG_PROVE_LOCKING || CONFIG_TRACE_IRQFLAGS */ ++ + #ifdef CONFIG_PROVE_LOCKING + /* + * Allocate a lockdep entry. (assumes the graph_lock held, returns +@@ -947,18 +962,6 @@ static noinline int print_circular_bug_t + return 0; + } + +-#define RECURSION_LIMIT 40 +- +-static int noinline print_infinite_recursion_bug(void) +-{ +- if (!debug_locks_off_graph_unlock()) +- return 0; +- +- WARN_ON(1); +- +- return 0; +-} +- + /* + * Prove that the dependency graph starting at can not + * lead to . Print an error and return 0 if it does. +@@ -1076,6 +1079,7 @@ find_usage_backwards(struct lock_class * + return 1; + } + ++#ifdef CONFIG_PROVE_LOCKING + static int + print_bad_irq_dependency(struct task_struct *curr, + struct held_lock *prev, +@@ -1136,6 +1140,7 @@ print_bad_irq_dependency(struct task_str + + return 0; + } ++#endif /* CONFIG_PROVE_LOCKING */ + + static int + check_usage(struct task_struct *curr, struct held_lock *prev, --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0495-ftrace-wakeup-rawspinlock.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0495-ftrace-wakeup-rawspinlock.patch @@ -0,0 +1,106 @@ +From: Steven Rostedt +Subject: ftrace: user raw spin lock for wakeup function trace + +Lockdep gets hung up by function traces that call spinlocks. Change +wakeup spin lock used in the wake up function tracing to raw. + +Signed-off-by: Steven Rostedt +--- + kernel/trace/trace_sched_wakeup.c | 27 ++++++++++++++++----------- + 1 file changed, 16 insertions(+), 11 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/trace/trace_sched_wakeup.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/trace_sched_wakeup.c 2008-10-08 22:23:57.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/trace_sched_wakeup.c 2008-10-08 22:25:03.000000000 -0400 +@@ -26,7 +26,8 @@ static struct task_struct *wakeup_task; + static int wakeup_cpu; + static unsigned wakeup_prio = -1; + +-static DEFINE_RAW_SPINLOCK(wakeup_lock); ++static __raw_spinlock_t wakeup_lock = ++ (__raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; + + static void __wakeup_reset(struct trace_array *tr); + +@@ -56,7 +57,8 @@ wakeup_tracer_call(unsigned long ip, uns + if (unlikely(disabled != 1)) + goto out; + +- spin_lock_irqsave(&wakeup_lock, flags); ++ raw_local_irq_save(flags); ++ __raw_spin_lock(&wakeup_lock); + + if (unlikely(!wakeup_task)) + goto unlock; +@@ -71,7 +73,8 @@ wakeup_tracer_call(unsigned long ip, uns + trace_function(tr, data, ip, parent_ip, flags); + + unlock: +- spin_unlock_irqrestore(&wakeup_lock, flags); ++ __raw_spin_unlock(&wakeup_lock); ++ raw_local_irq_restore(flags); + + out: + atomic_dec(&data->disabled); +@@ -145,7 +148,8 @@ wakeup_sched_switch(void *private, void + if (likely(disabled != 1)) + goto out; + +- spin_lock_irqsave(&wakeup_lock, flags); ++ local_irq_save(flags); ++ __raw_spin_lock(&wakeup_lock); + + /* We could race with grabbing wakeup_lock */ + if (unlikely(!tracer_enabled || next != wakeup_task)) +@@ -174,7 +178,8 @@ wakeup_sched_switch(void *private, void + + out_unlock: + __wakeup_reset(tr); +- spin_unlock_irqrestore(&wakeup_lock, flags); ++ __raw_spin_unlock(&wakeup_lock); ++ local_irq_restore(flags); + out: + atomic_dec(&tr->data[cpu]->disabled); + } +@@ -209,8 +214,6 @@ static void __wakeup_reset(struct trace_ + struct trace_array_cpu *data; + int cpu; + +- assert_spin_locked(&wakeup_lock); +- + for_each_possible_cpu(cpu) { + data = tr->data[cpu]; + tracing_reset(data); +@@ -229,9 +232,11 @@ static void wakeup_reset(struct trace_ar + { + unsigned long flags; + +- spin_lock_irqsave(&wakeup_lock, flags); ++ local_irq_save(flags); ++ __raw_spin_lock(&wakeup_lock); + __wakeup_reset(tr); +- spin_unlock_irqrestore(&wakeup_lock, flags); ++ __raw_spin_unlock(&wakeup_lock); ++ local_irq_restore(flags); + } + + static void +@@ -252,7 +257,7 @@ wakeup_check_start(struct trace_array *t + goto out; + + /* interrupts should be off from try_to_wake_up */ +- spin_lock(&wakeup_lock); ++ __raw_spin_lock(&wakeup_lock); + + /* check for races. */ + if (!tracer_enabled || p->prio >= wakeup_prio) +@@ -274,7 +279,7 @@ wakeup_check_start(struct trace_array *t + CALLER_ADDR1, CALLER_ADDR2, flags); + + out_locked: +- spin_unlock(&wakeup_lock); ++ __raw_spin_unlock(&wakeup_lock); + out: + atomic_dec(&tr->data[cpu]->disabled); + } --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0487-nmi-show-regs-fix.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0487-nmi-show-regs-fix.patch @@ -0,0 +1,183 @@ +From h-shimamoto@ct.jp.nec.com Tue May 27 19:37:24 2008 +Date: Tue, 27 May 2008 15:45:00 -0700 +From: Hiroshi Shimamoto +To: Steven Rostedt , Ingo Molnar , + Thomas Gleixner +Cc: linux-kernel@vger.kernel.org, linux-rt-users@vger.kernel.org +Subject: [PATCH -rt] fix sysrq+l when nmi_watchdog disabled + +From: Hiroshi Shimamoto + +In nmi_show_all_regs(), set nmi_show_regs for all cpus but NMI never come +to itself when nmi_watchdog is disabled. It means the kernel hangs up when +sysrq+l is issued. + +Call irq_show_regs_callback() itself before calling smp_send_nmi_allbutself(). + +Signed-off-by: Hiroshi Shimamoto +--- +Steven, this is a fix for what you pointed. +http://lkml.org/lkml/2008/4/28/455 + + arch/x86/kernel/nmi_32.c | 51 ++++++++++++++++++++++++++++------------------- + arch/x86/kernel/nmi_64.c | 49 +++++++++++++++++++++++++++++---------------- + 2 files changed, 63 insertions(+), 37 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/nmi_32.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/nmi_32.c 2008-10-08 22:24:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/nmi_32.c 2008-10-08 22:25:01.000000000 -0400 +@@ -326,21 +326,49 @@ extern void die_nmi(struct pt_regs *, co + + int nmi_show_regs[NR_CPUS]; + ++static DEFINE_RAW_SPINLOCK(nmi_print_lock); ++ ++notrace int irq_show_regs_callback(int cpu, struct pt_regs *regs) ++{ ++ if (!nmi_show_regs[cpu]) ++ return 0; ++ ++ spin_lock(&nmi_print_lock); ++ printk(KERN_WARNING "NMI show regs on CPU#%d:\n", cpu); ++ printk(KERN_WARNING "apic_timer_irqs: %d\n", ++ per_cpu(irq_stat, cpu).apic_timer_irqs); ++ show_regs(regs); ++ spin_unlock(&nmi_print_lock); ++ nmi_show_regs[cpu] = 0; ++ return 1; ++} ++ + void nmi_show_all_regs(void) + { +- int i; ++ struct pt_regs *regs; ++ int i, cpu; + + if (system_state == SYSTEM_BOOTING) + return; + +- printk(KERN_WARNING "nmi_show_all_regs(): start on CPU#%d.\n", +- raw_smp_processor_id()); ++ preempt_disable(); ++ ++ regs = get_irq_regs(); ++ cpu = smp_processor_id(); ++ ++ printk(KERN_WARNING "nmi_show_all_regs(): start on CPU#%d.\n", cpu); + dump_stack(); + + for_each_online_cpu(i) + nmi_show_regs[i] = 1; + ++ if (regs) ++ irq_show_regs_callback(cpu, regs); ++ else ++ nmi_show_regs[cpu] = 0; ++ + smp_send_nmi_allbutself(); ++ preempt_enable(); + + for_each_online_cpu(i) { + while (nmi_show_regs[i] == 1) +@@ -348,23 +376,6 @@ void nmi_show_all_regs(void) + } + } + +-static DEFINE_RAW_SPINLOCK(nmi_print_lock); +- +-notrace int irq_show_regs_callback(int cpu, struct pt_regs *regs) +-{ +- if (!nmi_show_regs[cpu]) +- return 0; +- +- spin_lock(&nmi_print_lock); +- printk(KERN_WARNING "NMI show regs on CPU#%d:\n", cpu); +- printk(KERN_WARNING "apic_timer_irqs: %d\n", +- per_cpu(irq_stat, cpu).apic_timer_irqs); +- show_regs(regs); +- spin_unlock(&nmi_print_lock); +- nmi_show_regs[cpu] = 0; +- return 1; +-} +- + notrace __kprobes int + nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) + { +Index: linux-2.6.24.7-rt21/arch/x86/kernel/nmi_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/nmi_64.c 2008-10-08 22:24:48.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/nmi_64.c 2008-10-08 22:25:01.000000000 -0400 +@@ -320,17 +320,48 @@ void touch_nmi_watchdog(void) + + int nmi_show_regs[NR_CPUS]; + ++static DEFINE_RAW_SPINLOCK(nmi_print_lock); ++ ++notrace int irq_show_regs_callback(int cpu, struct pt_regs *regs) ++{ ++ if (!nmi_show_regs[cpu]) ++ return 0; ++ ++ spin_lock(&nmi_print_lock); ++ printk(KERN_WARNING "NMI show regs on CPU#%d:\n", cpu); ++ printk(KERN_WARNING "apic_timer_irqs: %d\n", read_pda(apic_timer_irqs)); ++ show_regs(regs); ++ spin_unlock(&nmi_print_lock); ++ nmi_show_regs[cpu] = 0; ++ return 1; ++} ++ + void nmi_show_all_regs(void) + { +- int i; ++ struct pt_regs *regs; ++ int i, cpu; + + if (system_state == SYSTEM_BOOTING) + return; + ++ preempt_disable(); ++ ++ regs = get_irq_regs(); ++ cpu = smp_processor_id(); ++ ++ printk(KERN_WARNING "nmi_show_all_regs(): start on CPU#%d.\n", cpu); ++ dump_stack(); ++ + for_each_online_cpu(i) + nmi_show_regs[i] = 1; + ++ if (regs) ++ irq_show_regs_callback(cpu, regs); ++ else ++ nmi_show_regs[cpu] = 0; ++ + smp_send_nmi_allbutself(); ++ preempt_enable(); + + for_each_online_cpu(i) { + while (nmi_show_regs[i] == 1) +@@ -338,22 +369,6 @@ void nmi_show_all_regs(void) + } + } + +-static DEFINE_RAW_SPINLOCK(nmi_print_lock); +- +-notrace int irq_show_regs_callback(int cpu, struct pt_regs *regs) +-{ +- if (!nmi_show_regs[cpu]) +- return 0; +- +- spin_lock(&nmi_print_lock); +- printk(KERN_WARNING "NMI show regs on CPU#%d:\n", cpu); +- printk(KERN_WARNING "apic_timer_irqs: %d\n", read_pda(apic_timer_irqs)); +- show_regs(regs); +- spin_unlock(&nmi_print_lock); +- nmi_show_regs[cpu] = 0; +- return 1; +-} +- + notrace int __kprobes + nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) + { --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0277-rcu-various-fixups.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0277-rcu-various-fixups.patch @@ -0,0 +1,66 @@ +--- + security/selinux/avc.c | 9 +++++++++ + security/selinux/netif.c | 2 ++ + 2 files changed, 11 insertions(+) + +Index: linux-2.6.24.7-rt21/security/selinux/avc.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/security/selinux/avc.c 2008-10-08 22:22:26.000000000 -0400 ++++ linux-2.6.24.7-rt21/security/selinux/avc.c 2008-10-08 22:24:10.000000000 -0400 +@@ -312,6 +312,7 @@ static inline int avc_reclaim_node(void) + if (!spin_trylock_irqsave(&avc_cache.slots_lock[hvalue], flags)) + continue; + ++ rcu_read_lock(); + list_for_each_entry(node, &avc_cache.slots[hvalue], list) { + if (atomic_dec_and_test(&node->ae.used)) { + /* Recently Unused */ +@@ -319,11 +320,13 @@ static inline int avc_reclaim_node(void) + avc_cache_stats_incr(reclaims); + ecx++; + if (ecx >= AVC_CACHE_RECLAIM) { ++ rcu_read_unlock(); + spin_unlock_irqrestore(&avc_cache.slots_lock[hvalue], flags); + goto out; + } + } + } ++ rcu_read_unlock(); + spin_unlock_irqrestore(&avc_cache.slots_lock[hvalue], flags); + } + out: +@@ -807,8 +810,14 @@ int avc_ss_reset(u32 seqno) + + for (i = 0; i < AVC_CACHE_SLOTS; i++) { + spin_lock_irqsave(&avc_cache.slots_lock[i], flag); ++ /* ++ * On -rt the outer spinlock does not prevent RCU ++ * from being performed: ++ */ ++ rcu_read_lock(); + list_for_each_entry(node, &avc_cache.slots[i], list) + avc_node_delete(node); ++ rcu_read_unlock(); + spin_unlock_irqrestore(&avc_cache.slots_lock[i], flag); + } + +Index: linux-2.6.24.7-rt21/security/selinux/netif.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/security/selinux/netif.c 2008-10-08 22:22:26.000000000 -0400 ++++ linux-2.6.24.7-rt21/security/selinux/netif.c 2008-10-08 22:24:10.000000000 -0400 +@@ -210,6 +210,7 @@ static void sel_netif_flush(void) + { + int idx; + ++ rcu_read_lock(); + spin_lock_bh(&sel_netif_lock); + for (idx = 0; idx < SEL_NETIF_HASH_SIZE; idx++) { + struct sel_netif *netif; +@@ -218,6 +219,7 @@ static void sel_netif_flush(void) + sel_netif_destroy(netif); + } + spin_unlock_bh(&sel_netif_lock); ++ rcu_read_unlock(); + } + + static int sel_netif_avc_callback(u32 event, u32 ssid, u32 tsid, --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0423-root-domain-kfree-in-atomic.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0423-root-domain-kfree-in-atomic.patch @@ -0,0 +1,53 @@ +From ghaskins@novell.com Tue Feb 26 13:05:53 2008 +Date: Tue, 26 Feb 2008 12:14:27 -0500 +From: Gregory Haskins +To: rostedt@goodmis.org +Cc: ghaskins@novell.com +Subject: [PATCH] fix oops in root-domain code during repartitioning + + [ The following text is in the "utf-8" character set. ] + [ Your display is set for the "iso-8859-1" character set. ] + [ Some characters may be displayed incorrectly. ] + +we cannot kfree while in_atomic in -rt, and we currently hold the +(raw_spinlock_t)rq->lock while we try. So defer the operation until +we are out of the critical section. + +Signed-off-by: Gregory Haskins +--- + + kernel/sched.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/kernel/sched.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched.c 2008-10-08 22:24:40.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched.c 2008-10-08 22:24:45.000000000 -0400 +@@ -6325,6 +6325,7 @@ static void rq_attach_root(struct rq *rq + { + unsigned long flags; + const struct sched_class *class; ++ struct root_domain *reap = NULL; + + spin_lock_irqsave(&rq->lock, flags); + +@@ -6340,7 +6341,7 @@ static void rq_attach_root(struct rq *rq + cpu_clear(rq->cpu, old_rd->online); + + if (atomic_dec_and_test(&old_rd->refcount)) +- kfree(old_rd); ++ reap = old_rd; + } + + atomic_inc(&rd->refcount); +@@ -6356,6 +6357,10 @@ static void rq_attach_root(struct rq *rq + } + + spin_unlock_irqrestore(&rq->lock, flags); ++ ++ /* Don't try to free the memory while in-atomic() */ ++ if (unlikely(reap)) ++ kfree(reap); + } + + static void init_rootdomain(struct root_domain *rd) --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0540-seqlocks-handle-rwlock-and-spin.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0540-seqlocks-handle-rwlock-and-spin.patch @@ -0,0 +1,55 @@ +From: Steven Rostedt +Subject: seqlock - fix for both PREEMPT_RT and non PREEMPT_RT + +The change to have two different types of locks (spinlocks for raw seqlocks +and rwlocks for preempt seqlocks), caused the non PREEMPT_RT build to fail. + +This patch cleans up the code a bit to allow for both types of locks. + +Signed-off-by: Steven Rostedt +--- + include/linux/seqlock.h | 23 +++++++++++++++++++---- + 1 file changed, 19 insertions(+), 4 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/seqlock.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/seqlock.h 2008-10-08 22:25:13.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/seqlock.h 2008-10-08 22:25:14.000000000 -0400 +@@ -30,6 +30,7 @@ + * Priority inheritance and live-lock avoidance by Gregory Haskins + */ + ++#include + #include + #include + +@@ -69,11 +70,25 @@ typedef __raw_seqlock_t raw_seqlock_t; + #define SEQLOCK_UNLOCKED \ + __SEQLOCK_UNLOCKED(old_style_seqlock_init) + +-#define raw_seqlock_init(x) \ +- do { *(x) = (raw_seqlock_t) __RAW_SEQLOCK_UNLOCKED(x); spin_lock_init(&(x)->lock); } while (0) ++static inline void __raw_seqlock_init(raw_seqlock_t *seqlock) ++{ ++ *seqlock = (raw_seqlock_t) __RAW_SEQLOCK_UNLOCKED(x); ++ spin_lock_init(&seqlock->lock); ++} ++ ++#ifdef CONFIG_PREEMPT_RT ++static inline void __seqlock_init(seqlock_t *seqlock) ++{ ++ *seqlock = (seqlock_t) __SEQLOCK_UNLOCKED(seqlock); ++ rwlock_init(&seqlock->lock); ++} ++#else ++extern void __seqlock_init(seqlock_t *seqlock); ++#endif + +-#define seqlock_init(x) \ +- do { *(x) = (seqlock_t) __SEQLOCK_UNLOCKED(x); rwlock_init(&(x)->lock); } while (0) ++#define seqlock_init(seq) \ ++ PICK_FUNCTION(raw_seqlock_t *, seqlock_t *, \ ++ __raw_seqlock_init, __seqlock_init, seq); + + #define DEFINE_SEQLOCK(x) \ + seqlock_t x = __SEQLOCK_UNLOCKED(x) --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0140-preempt-irqs-core.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0140-preempt-irqs-core.patch @@ -0,0 +1,1000 @@ +--- + include/linux/interrupt.h | 19 ++ + include/linux/irq.h | 26 +++- + include/linux/sched.h | 14 ++ + init/main.c | 5 + kernel/irq/autoprobe.c | 1 + kernel/irq/chip.c | 38 +++++ + kernel/irq/handle.c | 37 +++++ + kernel/irq/internals.h | 4 + kernel/irq/manage.c | 292 +++++++++++++++++++++++++++++++++++++++++++++- + kernel/irq/proc.c | 129 ++++++++++++++------ + kernel/irq/spurious.c | 11 + + kernel/sched.c | 23 +++ + 12 files changed, 543 insertions(+), 56 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/interrupt.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/interrupt.h 2008-10-08 22:23:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/interrupt.h 2008-10-08 22:23:30.000000000 -0400 +@@ -50,10 +50,12 @@ + #define IRQF_SAMPLE_RANDOM 0x00000040 + #define IRQF_SHARED 0x00000080 + #define IRQF_PROBE_SHARED 0x00000100 +-#define IRQF_TIMER 0x00000200 ++#define __IRQF_TIMER 0x00000200 + #define IRQF_PERCPU 0x00000400 + #define IRQF_NOBALANCING 0x00000800 + #define IRQF_IRQPOLL 0x00001000 ++#define IRQF_NODELAY 0x00002000 ++#define IRQF_TIMER (__IRQF_TIMER | IRQF_NODELAY) + + typedef irqreturn_t (*irq_handler_t)(int, void *); + +@@ -65,7 +67,7 @@ struct irqaction { + void *dev_id; + struct irqaction *next; + int irq; +- struct proc_dir_entry *dir; ++ struct proc_dir_entry *dir, *threaded; + }; + + extern irqreturn_t no_action(int cpl, void *dev_id); +@@ -196,6 +198,7 @@ static inline int disable_irq_wake(unsig + + #ifndef __ARCH_SET_SOFTIRQ_PENDING + #define set_softirq_pending(x) (local_softirq_pending() = (x)) ++// FIXME: PREEMPT_RT: set_bit()? + #define or_softirq_pending(x) (local_softirq_pending() |= (x)) + #endif + +@@ -271,12 +274,18 @@ struct softirq_action + void *data; + }; + +-#define __raise_softirq_irqoff(nr) do { or_softirq_pending(1UL << (nr)); } while (0) +-#define __do_raise_softirq_irqoff(nr) __raise_softirq_irqoff(nr) +- + asmlinkage void do_softirq(void); + extern void open_softirq(int nr, void (*action)(struct softirq_action*), void *data); + extern void softirq_init(void); ++ ++#ifdef CONFIG_PREEMPT_HARDIRQS ++# define __raise_softirq_irqoff(nr) raise_softirq_irqoff(nr) ++# define __do_raise_softirq_irqoff(nr) do { or_softirq_pending(1UL << (nr)); } while (0) ++#else ++# define __raise_softirq_irqoff(nr) do { or_softirq_pending(1UL << (nr)); } while (0) ++# define __do_raise_softirq_irqoff(nr) __raise_softirq_irqoff(nr) ++#endif ++ + extern void FASTCALL(raise_softirq_irqoff(unsigned int nr)); + extern void FASTCALL(raise_softirq(unsigned int nr)); + extern void wakeup_irqd(void); +Index: linux-2.6.24.7-rt21/include/linux/irq.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/irq.h 2008-10-08 22:22:38.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/irq.h 2008-10-08 22:23:30.000000000 -0400 +@@ -19,10 +19,12 @@ + #include + #include + #include ++#include + + #include + #include + #include ++#include + + struct irq_desc; + typedef void fastcall (*irq_flow_handler_t)(unsigned int irq, +@@ -61,6 +63,7 @@ typedef void fastcall (*irq_flow_handler + #define IRQ_WAKEUP 0x00100000 /* IRQ triggers system wakeup */ + #define IRQ_MOVE_PENDING 0x00200000 /* need to re-target IRQ destination */ + #define IRQ_NO_BALANCING 0x00400000 /* IRQ is excluded from balancing */ ++#define IRQ_NODELAY 0x40000000 /* IRQ must run immediately */ + + #ifdef CONFIG_IRQ_PER_CPU + # define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU) +@@ -141,6 +144,9 @@ struct irq_chip { + * @irq_count: stats field to detect stalled irqs + * @irqs_unhandled: stats field for spurious unhandled interrupts + * @last_unhandled: aging timer for unhandled count ++ * @thread: Thread pointer for threaded preemptible irq handling ++ * @wait_for_handler: Waitqueue to wait for a running preemptible handler ++ * @cycles: Timestamp for stats and debugging + * @lock: locking for SMP + * @affinity: IRQ affinity on SMP + * @cpu: cpu index useful for balancing +@@ -163,6 +169,9 @@ struct irq_desc { + unsigned int irq_count; /* For detecting broken IRQs */ + unsigned int irqs_unhandled; + unsigned long last_unhandled; /* Aging timer for unhandled count */ ++ struct task_struct *thread; ++ wait_queue_head_t wait_for_handler; ++ cycles_t timestamp; + spinlock_t lock; + #ifdef CONFIG_SMP + cpumask_t affinity; +@@ -397,7 +406,22 @@ extern int set_irq_msi(unsigned int irq, + #define get_irq_data(irq) (irq_desc[irq].handler_data) + #define get_irq_msi(irq) (irq_desc[irq].msi_desc) + +-#endif /* CONFIG_GENERIC_HARDIRQS */ ++/* Early initialization of irqs */ ++extern void early_init_hardirqs(void); ++extern cycles_t irq_timestamp(unsigned int irq); ++ ++#if defined(CONFIG_PREEMPT_HARDIRQS) ++extern void init_hardirqs(void); ++#else ++static inline void init_hardirqs(void) { } ++#endif ++ ++#else /* end GENERIC HARDIRQS */ ++ ++static inline void early_init_hardirqs(void) { } ++static inline void init_hardirqs(void) { } ++ ++#endif /* !CONFIG_GENERIC_HARDIRQS */ + + #endif /* !CONFIG_S390 */ + +Index: linux-2.6.24.7-rt21/include/linux/sched.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/sched.h 2008-10-08 22:23:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/sched.h 2008-10-08 22:23:30.000000000 -0400 +@@ -96,6 +96,11 @@ extern int softirq_preemption; + #else + # define softirq_preemption 0 + #endif ++#ifdef CONFIG_PREEMPT_HARDIRQS ++extern int hardirq_preemption; ++#else ++# define hardirq_preemption 0 ++#endif + + struct exec_domain; + struct futex_pi_state; +@@ -1417,6 +1422,7 @@ static inline void put_task_struct(struc + #define PF_SPREAD_PAGE 0x01000000 /* Spread page cache over cpuset */ + #define PF_SPREAD_SLAB 0x02000000 /* Spread some slab caches over cpuset */ + #define PF_SOFTIRQ 0x04000000 /* softirq context */ ++#define PF_HARDIRQ 0x08000000 /* hardirq context */ + #define PF_MEMPOLICY 0x10000000 /* Non-default NUMA mempolicy */ + #define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */ + #define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezeable */ +@@ -1897,6 +1903,7 @@ extern int cond_resched(void); + extern int cond_resched_lock(spinlock_t * lock); + extern int cond_resched_softirq(void); + extern int cond_resched_softirq_context(void); ++extern int cond_resched_hardirq_context(void); + + /* + * Does a critical section need to be broken due to another +@@ -1922,6 +1929,13 @@ static inline int softirq_need_resched(v + return 0; + } + ++static inline int hardirq_need_resched(void) ++{ ++ if (hardirq_preemption && (current->flags & PF_HARDIRQ)) ++ return need_resched(); ++ return 0; ++} ++ + /* + * Reevaluate whether the task has signals pending delivery. + * Wake the task if so. +Index: linux-2.6.24.7-rt21/init/main.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/init/main.c 2008-10-08 22:22:38.000000000 -0400 ++++ linux-2.6.24.7-rt21/init/main.c 2008-10-08 22:23:30.000000000 -0400 +@@ -47,6 +47,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -550,8 +551,10 @@ asmlinkage void __init start_kernel(void + * fragile until we cpu_idle() for the first time. + */ + preempt_disable(); ++ + build_all_zonelists(); + page_alloc_init(); ++ early_init_hardirqs(); + printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line); + parse_early_param(); + parse_args("Booting kernel", static_command_line, __start___param, +@@ -825,6 +828,8 @@ static int __init kernel_init(void * unu + + smp_prepare_cpus(max_cpus); + ++ init_hardirqs(); ++ + do_pre_smp_initcalls(); + + smp_init(); +Index: linux-2.6.24.7-rt21/kernel/irq/autoprobe.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/irq/autoprobe.c 2008-10-08 22:22:38.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/irq/autoprobe.c 2008-10-08 22:23:30.000000000 -0400 +@@ -7,6 +7,7 @@ + */ + + #include ++#include + #include + #include + #include +Index: linux-2.6.24.7-rt21/kernel/irq/chip.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/irq/chip.c 2008-10-08 22:22:38.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/irq/chip.c 2008-10-08 22:23:30.000000000 -0400 +@@ -287,8 +287,10 @@ static inline void mask_ack_irq(struct i + if (desc->chip->mask_ack) + desc->chip->mask_ack(irq); + else { +- desc->chip->mask(irq); +- desc->chip->ack(irq); ++ if (desc->chip->mask) ++ desc->chip->mask(irq); ++ if (desc->chip->ack) ++ desc->chip->ack(irq); + } + } + +@@ -313,8 +315,10 @@ handle_simple_irq(unsigned int irq, stru + + spin_lock(&desc->lock); + +- if (unlikely(desc->status & IRQ_INPROGRESS)) ++ if (unlikely(desc->status & IRQ_INPROGRESS)) { ++ desc->status |= IRQ_PENDING; + goto out_unlock; ++ } + desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); + kstat_cpu(cpu).irqs[irq]++; + +@@ -323,6 +327,11 @@ handle_simple_irq(unsigned int irq, stru + goto out_unlock; + + desc->status |= IRQ_INPROGRESS; ++ /* ++ * hardirq redirection to the irqd process context: ++ */ ++ if (redirect_hardirq(desc)) ++ goto out_unlock; + spin_unlock(&desc->lock); + + action_ret = handle_IRQ_event(irq, action); +@@ -369,6 +378,13 @@ handle_level_irq(unsigned int irq, struc + goto out_unlock; + + desc->status |= IRQ_INPROGRESS; ++ ++ /* ++ * hardirq redirection to the irqd process context: ++ */ ++ if (redirect_hardirq(desc)) ++ goto out_unlock; ++ + spin_unlock(&desc->lock); + + action_ret = handle_IRQ_event(irq, action); +@@ -421,6 +437,15 @@ handle_fasteoi_irq(unsigned int irq, str + } + + desc->status |= IRQ_INPROGRESS; ++ /* ++ * In the threaded case we fall back to a mask+eoi sequence: ++ */ ++ if (redirect_hardirq(desc)) { ++ if (desc->chip->mask) ++ desc->chip->mask(irq); ++ goto out; ++ } ++ + desc->status &= ~IRQ_PENDING; + spin_unlock(&desc->lock); + +@@ -432,7 +457,6 @@ handle_fasteoi_irq(unsigned int irq, str + desc->status &= ~IRQ_INPROGRESS; + out: + desc->chip->eoi(irq); +- + spin_unlock(&desc->lock); + } + +@@ -481,6 +505,12 @@ handle_edge_irq(unsigned int irq, struct + /* Mark the IRQ currently in progress.*/ + desc->status |= IRQ_INPROGRESS; + ++ /* ++ * hardirq redirection to the irqd process context: ++ */ ++ if (redirect_hardirq(desc)) ++ goto out_unlock; ++ + do { + struct irqaction *action = desc->action; + irqreturn_t action_ret; +Index: linux-2.6.24.7-rt21/kernel/irq/handle.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/irq/handle.c 2008-10-08 22:22:38.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/irq/handle.c 2008-10-08 22:23:30.000000000 -0400 +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -133,24 +134,54 @@ irqreturn_t handle_IRQ_event(unsigned in + + handle_dynamic_tick(action); + +- if (!(action->flags & IRQF_DISABLED)) +- local_irq_enable_in_hardirq(); ++ /* ++ * Unconditionally enable interrupts for threaded ++ * IRQ handlers: ++ */ ++ if (!hardirq_count() || !(action->flags & IRQF_DISABLED)) ++ local_irq_enable(); + + do { ++ unsigned int preempt_count = preempt_count(); ++ + ret = action->handler(irq, action->dev_id); ++ if (preempt_count() != preempt_count) { ++ print_symbol("BUG: unbalanced irq-handler preempt count in %s!\n", (unsigned long) action->handler); ++ printk("entered with %08x, exited with %08x.\n", preempt_count, preempt_count()); ++ dump_stack(); ++ preempt_count() = preempt_count; ++ } + if (ret == IRQ_HANDLED) + status |= action->flags; + retval |= ret; + action = action->next; + } while (action); + +- if (status & IRQF_SAMPLE_RANDOM) ++ if (status & IRQF_SAMPLE_RANDOM) { ++ local_irq_enable(); + add_interrupt_randomness(irq); ++ } + local_irq_disable(); + + return retval; + } + ++int redirect_hardirq(struct irq_desc *desc) ++{ ++ /* ++ * Direct execution: ++ */ ++ if (!hardirq_preemption || (desc->status & IRQ_NODELAY) || ++ !desc->thread) ++ return 0; ++ ++ BUG_ON(!irqs_disabled()); ++ if (desc->thread && desc->thread->state != TASK_RUNNING) ++ wake_up_process(desc->thread); ++ ++ return 1; ++} ++ + #ifndef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ + /** + * __do_IRQ - original all in one highlevel IRQ handler +Index: linux-2.6.24.7-rt21/kernel/irq/internals.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/irq/internals.h 2008-10-08 22:22:38.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/irq/internals.h 2008-10-08 22:23:30.000000000 -0400 +@@ -10,6 +10,10 @@ extern void irq_chip_set_defaults(struct + /* Set default handler: */ + extern void compat_irq_chip_set_default_handler(struct irq_desc *desc); + ++extern int redirect_hardirq(struct irq_desc *desc); ++ ++void recalculate_desc_flags(struct irq_desc *desc); ++ + #ifdef CONFIG_PROC_FS + extern void register_irq_proc(unsigned int irq); + extern void register_handler_proc(unsigned int irq, struct irqaction *action); +Index: linux-2.6.24.7-rt21/kernel/irq/manage.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/irq/manage.c 2008-10-08 22:22:38.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/irq/manage.c 2008-10-08 22:23:30.000000000 -0400 +@@ -8,8 +8,10 @@ + */ + + #include +-#include + #include ++#include ++#include ++#include + #include + + #include "internals.h" +@@ -41,8 +43,12 @@ void synchronize_irq(unsigned int irq) + * Wait until we're out of the critical section. This might + * give the wrong answer due to the lack of memory barriers. + */ +- while (desc->status & IRQ_INPROGRESS) +- cpu_relax(); ++ if (hardirq_preemption && !(desc->status & IRQ_NODELAY)) ++ wait_event(desc->wait_for_handler, ++ !(desc->status & IRQ_INPROGRESS)); ++ else ++ while (desc->status & IRQ_INPROGRESS) ++ cpu_relax(); + + /* Ok, that indicated we're done: double-check carefully. */ + spin_lock_irqsave(&desc->lock, flags); +@@ -234,6 +240,21 @@ int set_irq_wake(unsigned int irq, unsig + EXPORT_SYMBOL(set_irq_wake); + + /* ++ * If any action has IRQF_NODELAY then turn IRQ_NODELAY on: ++ */ ++void recalculate_desc_flags(struct irq_desc *desc) ++{ ++ struct irqaction *action; ++ ++ desc->status &= ~IRQ_NODELAY; ++ for (action = desc->action ; action; action = action->next) ++ if (action->flags & IRQF_NODELAY) ++ desc->status |= IRQ_NODELAY; ++} ++ ++static int start_irq_thread(int irq, struct irq_desc *desc); ++ ++/* + * Internal function that tells the architecture code whether a + * particular irq has been exclusively allocated or is available + * for driver use. +@@ -298,6 +319,9 @@ int setup_irq(unsigned int irq, struct i + rand_initialize_irq(irq); + } + ++ if (!(new->flags & IRQF_NODELAY)) ++ if (start_irq_thread(irq, desc)) ++ return -ENOMEM; + /* + * The following block of code has to be executed atomically + */ +@@ -338,6 +362,11 @@ int setup_irq(unsigned int irq, struct i + if (new->flags & IRQF_NOBALANCING) + desc->status |= IRQ_NO_BALANCING; + ++ /* ++ * Propagate any possible IRQF_NODELAY flag into IRQ_NODELAY: ++ */ ++ recalculate_desc_flags(desc); ++ + if (!shared) { + irq_chip_set_defaults(desc->chip); + +@@ -384,7 +413,7 @@ int setup_irq(unsigned int irq, struct i + + new->irq = irq; + register_irq_proc(irq); +- new->dir = NULL; ++ new->dir = new->threaded = NULL; + register_handler_proc(irq, new); + + return 0; +@@ -455,6 +484,7 @@ void free_irq(unsigned int irq, void *de + else + desc->chip->disable(irq); + } ++ recalculate_desc_flags(desc); + spin_unlock_irqrestore(&desc->lock, flags); + unregister_handler_proc(irq, action); + +@@ -577,3 +607,257 @@ int request_irq(unsigned int irq, irq_ha + return retval; + } + EXPORT_SYMBOL(request_irq); ++ ++#ifdef CONFIG_PREEMPT_HARDIRQS ++ ++int hardirq_preemption = 1; ++ ++EXPORT_SYMBOL(hardirq_preemption); ++ ++static int __init hardirq_preempt_setup (char *str) ++{ ++ if (!strncmp(str, "off", 3)) ++ hardirq_preemption = 0; ++ else ++ get_option(&str, &hardirq_preemption); ++ if (!hardirq_preemption) ++ printk("turning off hardirq preemption!\n"); ++ ++ return 1; ++} ++ ++__setup("hardirq-preempt=", hardirq_preempt_setup); ++ ++ ++/* ++ * threaded simple handler ++ */ ++static void thread_simple_irq(irq_desc_t *desc) ++{ ++ struct irqaction *action = desc->action; ++ unsigned int irq = desc - irq_desc; ++ irqreturn_t action_ret; ++ ++ if (action && !desc->depth) { ++ spin_unlock(&desc->lock); ++ action_ret = handle_IRQ_event(irq, action); ++ cond_resched_hardirq_context(); ++ spin_lock_irq(&desc->lock); ++ if (!noirqdebug) ++ note_interrupt(irq, desc, action_ret); ++ } ++ desc->status &= ~IRQ_INPROGRESS; ++} ++ ++/* ++ * threaded level type irq handler ++ */ ++static void thread_level_irq(irq_desc_t *desc) ++{ ++ unsigned int irq = desc - irq_desc; ++ ++ thread_simple_irq(desc); ++ if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) ++ desc->chip->unmask(irq); ++} ++ ++/* ++ * threaded fasteoi type irq handler ++ */ ++static void thread_fasteoi_irq(irq_desc_t *desc) ++{ ++ unsigned int irq = desc - irq_desc; ++ ++ thread_simple_irq(desc); ++ if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) ++ desc->chip->unmask(irq); ++} ++ ++/* ++ * threaded edge type IRQ handler ++ */ ++static void thread_edge_irq(irq_desc_t *desc) ++{ ++ unsigned int irq = desc - irq_desc; ++ ++ do { ++ struct irqaction *action = desc->action; ++ irqreturn_t action_ret; ++ ++ if (unlikely(!action)) { ++ desc->status &= ~IRQ_INPROGRESS; ++ desc->chip->mask(irq); ++ return; ++ } ++ ++ /* ++ * When another irq arrived while we were handling ++ * one, we could have masked the irq. ++ * Renable it, if it was not disabled in meantime. ++ */ ++ if (unlikely(((desc->status & (IRQ_PENDING | IRQ_MASKED)) == ++ (IRQ_PENDING | IRQ_MASKED)) && !desc->depth)) ++ desc->chip->unmask(irq); ++ ++ desc->status &= ~IRQ_PENDING; ++ spin_unlock(&desc->lock); ++ action_ret = handle_IRQ_event(irq, action); ++ cond_resched_hardirq_context(); ++ spin_lock_irq(&desc->lock); ++ if (!noirqdebug) ++ note_interrupt(irq, desc, action_ret); ++ } while ((desc->status & IRQ_PENDING) && !desc->depth); ++ ++ desc->status &= ~IRQ_INPROGRESS; ++} ++ ++/* ++ * threaded edge type IRQ handler ++ */ ++static void thread_do_irq(irq_desc_t *desc) ++{ ++ unsigned int irq = desc - irq_desc; ++ ++ do { ++ struct irqaction *action = desc->action; ++ irqreturn_t action_ret; ++ ++ if (unlikely(!action)) { ++ desc->status &= ~IRQ_INPROGRESS; ++ desc->chip->disable(irq); ++ return; ++ } ++ ++ desc->status &= ~IRQ_PENDING; ++ spin_unlock(&desc->lock); ++ action_ret = handle_IRQ_event(irq, action); ++ cond_resched_hardirq_context(); ++ spin_lock_irq(&desc->lock); ++ if (!noirqdebug) ++ note_interrupt(irq, desc, action_ret); ++ } while ((desc->status & IRQ_PENDING) && !desc->depth); ++ ++ desc->status &= ~IRQ_INPROGRESS; ++ desc->chip->end(irq); ++} ++ ++static void do_hardirq(struct irq_desc *desc) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&desc->lock, flags); ++ ++ if (!(desc->status & IRQ_INPROGRESS)) ++ goto out; ++ ++ if (desc->handle_irq == handle_simple_irq) ++ thread_simple_irq(desc); ++ else if (desc->handle_irq == handle_level_irq) ++ thread_level_irq(desc); ++ else if (desc->handle_irq == handle_fasteoi_irq) ++ thread_fasteoi_irq(desc); ++ else if (desc->handle_irq == handle_edge_irq) ++ thread_edge_irq(desc); ++ else ++ thread_do_irq(desc); ++ out: ++ spin_unlock_irqrestore(&desc->lock, flags); ++ ++ if (waitqueue_active(&desc->wait_for_handler)) ++ wake_up(&desc->wait_for_handler); ++} ++ ++extern asmlinkage void __do_softirq(void); ++ ++static int do_irqd(void * __desc) ++{ ++ struct sched_param param = { 0, }; ++ struct irq_desc *desc = __desc; ++ ++#ifdef CONFIG_SMP ++ set_cpus_allowed(current, desc->affinity); ++#endif ++ current->flags |= PF_NOFREEZE | PF_HARDIRQ; ++ ++ /* ++ * Set irq thread priority to SCHED_FIFO/50: ++ */ ++ param.sched_priority = MAX_USER_RT_PRIO/2; ++ ++ sys_sched_setscheduler(current->pid, SCHED_FIFO, ¶m); ++ ++ while (!kthread_should_stop()) { ++ local_irq_disable(); ++ set_current_state(TASK_INTERRUPTIBLE); ++ irq_enter(); ++ do_hardirq(desc); ++ irq_exit(); ++ local_irq_enable(); ++ cond_resched(); ++#ifdef CONFIG_SMP ++ /* ++ * Did IRQ affinities change? ++ */ ++ if (!cpus_equal(current->cpus_allowed, desc->affinity)) ++ set_cpus_allowed(current, desc->affinity); ++#endif ++ schedule(); ++ } ++ __set_current_state(TASK_RUNNING); ++ ++ return 0; ++} ++ ++static int ok_to_create_irq_threads; ++ ++static int start_irq_thread(int irq, struct irq_desc *desc) ++{ ++ if (desc->thread || !ok_to_create_irq_threads) ++ return 0; ++ ++ desc->thread = kthread_create(do_irqd, desc, "IRQ-%d", irq); ++ if (!desc->thread) { ++ printk(KERN_ERR "irqd: could not create IRQ thread %d!\n", irq); ++ return -ENOMEM; ++ } ++ ++ /* ++ * An interrupt may have come in before the thread pointer was ++ * stored in desc->thread; make sure the thread gets woken up in ++ * such a case: ++ */ ++ smp_mb(); ++ wake_up_process(desc->thread); ++ ++ return 0; ++} ++ ++void __init init_hardirqs(void) ++{ ++ int i; ++ ok_to_create_irq_threads = 1; ++ ++ for (i = 0; i < NR_IRQS; i++) { ++ irq_desc_t *desc = irq_desc + i; ++ ++ if (desc->action && !(desc->status & IRQ_NODELAY)) ++ start_irq_thread(i, desc); ++ } ++} ++ ++#else ++ ++static int start_irq_thread(int irq, struct irq_desc *desc) ++{ ++ return 0; ++} ++ ++#endif ++ ++void __init early_init_hardirqs(void) ++{ ++ int i; ++ ++ for (i = 0; i < NR_IRQS; i++) ++ init_waitqueue_head(&irq_desc[i].wait_for_handler); ++} +Index: linux-2.6.24.7-rt21/kernel/irq/proc.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/irq/proc.c 2008-10-08 22:22:38.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/irq/proc.c 2008-10-08 22:23:30.000000000 -0400 +@@ -7,6 +7,8 @@ + */ + + #include ++#include ++#include + #include + #include + +@@ -75,44 +77,6 @@ static int irq_affinity_write_proc(struc + + #endif + +-#define MAX_NAMELEN 128 +- +-static int name_unique(unsigned int irq, struct irqaction *new_action) +-{ +- struct irq_desc *desc = irq_desc + irq; +- struct irqaction *action; +- unsigned long flags; +- int ret = 1; +- +- spin_lock_irqsave(&desc->lock, flags); +- for (action = desc->action ; action; action = action->next) { +- if ((action != new_action) && action->name && +- !strcmp(new_action->name, action->name)) { +- ret = 0; +- break; +- } +- } +- spin_unlock_irqrestore(&desc->lock, flags); +- return ret; +-} +- +-void register_handler_proc(unsigned int irq, struct irqaction *action) +-{ +- char name [MAX_NAMELEN]; +- +- if (!irq_desc[irq].dir || action->dir || !action->name || +- !name_unique(irq, action)) +- return; +- +- memset(name, 0, MAX_NAMELEN); +- snprintf(name, MAX_NAMELEN, "%s", action->name); +- +- /* create /proc/irq/1234/handler/ */ +- action->dir = proc_mkdir(name, irq_desc[irq].dir); +-} +- +-#undef MAX_NAMELEN +- + #define MAX_NAMELEN 10 + + void register_irq_proc(unsigned int irq) +@@ -150,10 +114,96 @@ void register_irq_proc(unsigned int irq) + + void unregister_handler_proc(unsigned int irq, struct irqaction *action) + { ++ if (action->threaded) ++ remove_proc_entry(action->threaded->name, action->dir); + if (action->dir) + remove_proc_entry(action->dir->name, irq_desc[irq].dir); + } + ++#ifndef CONFIG_PREEMPT_RT ++ ++static int threaded_read_proc(char *page, char **start, off_t off, ++ int count, int *eof, void *data) ++{ ++ return sprintf(page, "%c\n", ++ ((struct irqaction *)data)->flags & IRQF_NODELAY ? '0' : '1'); ++} ++ ++static int threaded_write_proc(struct file *file, const char __user *buffer, ++ unsigned long count, void *data) ++{ ++ int c; ++ struct irqaction *action = data; ++ irq_desc_t *desc = irq_desc + action->irq; ++ ++ if (get_user(c, buffer)) ++ return -EFAULT; ++ if (c != '0' && c != '1') ++ return -EINVAL; ++ ++ spin_lock_irq(&desc->lock); ++ ++ if (c == '0') ++ action->flags |= IRQF_NODELAY; ++ if (c == '1') ++ action->flags &= ~IRQF_NODELAY; ++ recalculate_desc_flags(desc); ++ ++ spin_unlock_irq(&desc->lock); ++ ++ return 1; ++} ++ ++#endif ++ ++#define MAX_NAMELEN 128 ++ ++static int name_unique(unsigned int irq, struct irqaction *new_action) ++{ ++ struct irq_desc *desc = irq_desc + irq; ++ struct irqaction *action; ++ ++ for (action = desc->action ; action; action = action->next) ++ if ((action != new_action) && action->name && ++ !strcmp(new_action->name, action->name)) ++ return 0; ++ return 1; ++} ++ ++void register_handler_proc(unsigned int irq, struct irqaction *action) ++{ ++ char name [MAX_NAMELEN]; ++ ++ if (!irq_desc[irq].dir || action->dir || !action->name || ++ !name_unique(irq, action)) ++ return; ++ ++ memset(name, 0, MAX_NAMELEN); ++ snprintf(name, MAX_NAMELEN, "%s", action->name); ++ ++ /* create /proc/irq/1234/handler/ */ ++ action->dir = proc_mkdir(name, irq_desc[irq].dir); ++ ++ if (!action->dir) ++ return; ++#ifndef CONFIG_PREEMPT_RT ++ { ++ struct proc_dir_entry *entry; ++ /* create /proc/irq/1234/handler/threaded */ ++ entry = create_proc_entry("threaded", 0600, action->dir); ++ if (!entry) ++ return; ++ entry->nlink = 1; ++ entry->data = (void *)action; ++ entry->read_proc = threaded_read_proc; ++ entry->write_proc = threaded_write_proc; ++ action->threaded = entry; ++ } ++#endif ++} ++ ++#undef MAX_NAMELEN ++ + void init_irq_proc(void) + { + int i; +@@ -163,6 +213,9 @@ void init_irq_proc(void) + if (!root_irq_dir) + return; + ++ /* create /proc/irq/prof_cpu_mask */ ++ create_prof_cpu_mask(root_irq_dir); ++ + /* + * Create entries for all existing IRQs. + */ +Index: linux-2.6.24.7-rt21/kernel/irq/spurious.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/irq/spurious.c 2008-10-08 22:22:38.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/irq/spurious.c 2008-10-08 22:23:30.000000000 -0400 +@@ -10,6 +10,10 @@ + #include + #include + #include ++#ifdef CONFIG_X86_IO_APIC ++# include ++# include ++#endif + + static int irqfixup __read_mostly; + +@@ -203,6 +207,12 @@ void note_interrupt(unsigned int irq, st + * The interrupt is stuck + */ + __report_bad_irq(irq, desc, action_ret); ++#ifdef CONFIG_X86_IO_APIC ++ if (!sis_apic_bug) { ++ sis_apic_bug = 1; ++ printk(KERN_ERR "turning off IO-APIC fast mode.\n"); ++ } ++#else + /* + * Now kill the IRQ + */ +@@ -210,6 +220,7 @@ void note_interrupt(unsigned int irq, st + desc->status |= IRQ_DISABLED; + desc->depth = 1; + desc->chip->disable(irq); ++#endif + } + desc->irqs_unhandled = 0; + } +Index: linux-2.6.24.7-rt21/kernel/sched.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched.c 2008-10-08 22:23:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched.c 2008-10-08 22:23:30.000000000 -0400 +@@ -3459,7 +3459,7 @@ void account_system_time(struct task_str + + /* Add system time to cpustat. */ + tmp = cputime_to_cputime64(cputime); +- if (hardirq_count() - hardirq_offset) ++ if (hardirq_count() - hardirq_offset || (p->flags & PF_HARDIRQ)) + cpustat->irq = cputime64_add(cpustat->irq, tmp); + else if (softirq_count() || (p->flags & PF_SOFTIRQ)) + cpustat->softirq = cputime64_add(cpustat->softirq, tmp); +@@ -4817,6 +4817,27 @@ int __sched cond_resched_softirq_context + } + EXPORT_SYMBOL(cond_resched_softirq_context); + ++/* ++ * Preempt a hardirq context if necessary (possible with hardirq threading): ++ */ ++int cond_resched_hardirq_context(void) ++{ ++ WARN_ON_ONCE(!in_irq()); ++ WARN_ON_ONCE(!irqs_disabled()); ++ ++ if (hardirq_need_resched()) { ++ irq_exit(); ++ local_irq_enable(); ++ __cond_resched(); ++ local_irq_disable(); ++ __irq_enter(); ++ ++ return 1; ++ } ++ return 0; ++} ++EXPORT_SYMBOL(cond_resched_hardirq_context); ++ + /** + * yield - yield the current processor to other threads. + * --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0530-powerpc-make-the-irq-reverse-mapping-radix-tree-lockless.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0530-powerpc-make-the-irq-reverse-mapping-radix-tree-lockless.patch @@ -0,0 +1,207 @@ +Subject: powerpc - Make the irq reverse mapping radix tree + lockless +From: Sebastien Dugue +Date: Wed, 23 Jul 2008 17:01:02 +0200 +From: Sebastien Dugue +Date: Tue, 22 Jul 2008 11:56:41 +0200 +Subject: [PATCH][RT] powerpc - Make the irq reverse mapping radix tree lockless + + The radix tree used by interrupt controllers for their irq reverse mapping +(currently only the XICS found on pSeries) have a complex locking scheme +dating back to before the advent of the concurrent radix tree on preempt-rt. + + Take advantage of this and of the fact that the items of the tree are +pointers to a static array (irq_map) elements which can never go under us +to simplify the locking. + + Concurrency between readers and writers are handled by the intrinsic +properties of the concurrent radix tree. Concurrency between the tree +initialization which is done asynchronously with readers and writers access is +handled via an atomic variable (revmap_trees_allocated) set when the tree +has been initialized and checked before any reader or writer access just +like we used to check for tree.gfp_mask != 0 before. + +Signed-off-by: Sebastien Dugue +Cc: Tim Chavez +Cc: Jean Pierre Dion +Cc: linuxppc-dev@ozlabs.org +Cc: paulus@samba.org +Cc: Gilles Carry +Signed-off-by: Thomas Gleixner +Cc: Benjamin Herrenschmidt +Cc: Paul Mackerras + +--- + arch/powerpc/kernel/irq.c | 102 ++++++++++++---------------------------------- + 1 file changed, 27 insertions(+), 75 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/powerpc/kernel/irq.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/kernel/irq.c 2008-10-08 22:23:54.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/kernel/irq.c 2008-10-08 22:25:11.000000000 -0400 +@@ -404,8 +404,7 @@ void do_softirq(void) + + static LIST_HEAD(irq_hosts); + static DEFINE_RAW_SPINLOCK(irq_big_lock); +-static DEFINE_PER_CPU(unsigned int, irq_radix_reader); +-static unsigned int irq_radix_writer; ++static atomic_t revmap_trees_allocated = ATOMIC_INIT(0); + struct irq_map_entry irq_map[NR_IRQS]; + static unsigned int irq_virq_count = NR_IRQS; + static struct irq_host *irq_default_host; +@@ -548,57 +547,6 @@ void irq_set_virq_count(unsigned int cou + irq_virq_count = count; + } + +-/* radix tree not lockless safe ! we use a brlock-type mecanism +- * for now, until we can use a lockless radix tree +- */ +-static void irq_radix_wrlock(unsigned long *flags) +-{ +- unsigned int cpu, ok; +- +- spin_lock_irqsave(&irq_big_lock, *flags); +- irq_radix_writer = 1; +- smp_mb(); +- do { +- barrier(); +- ok = 1; +- for_each_possible_cpu(cpu) { +- if (per_cpu(irq_radix_reader, cpu)) { +- ok = 0; +- break; +- } +- } +- if (!ok) +- cpu_relax(); +- } while(!ok); +-} +- +-static void irq_radix_wrunlock(unsigned long flags) +-{ +- smp_wmb(); +- irq_radix_writer = 0; +- spin_unlock_irqrestore(&irq_big_lock, flags); +-} +- +-static void irq_radix_rdlock(unsigned long *flags) +-{ +- local_irq_save(*flags); +- __get_cpu_var(irq_radix_reader) = 1; +- smp_mb(); +- if (likely(irq_radix_writer == 0)) +- return; +- __get_cpu_var(irq_radix_reader) = 0; +- smp_wmb(); +- spin_lock(&irq_big_lock); +- __get_cpu_var(irq_radix_reader) = 1; +- spin_unlock(&irq_big_lock); +-} +- +-static void irq_radix_rdunlock(unsigned long flags) +-{ +- __get_cpu_var(irq_radix_reader) = 0; +- local_irq_restore(flags); +-} +- + static int irq_setup_virq(struct irq_host *host, unsigned int virq, + irq_hw_number_t hwirq) + { +@@ -753,7 +701,6 @@ void irq_dispose_mapping(unsigned int vi + { + struct irq_host *host; + irq_hw_number_t hwirq; +- unsigned long flags; + + if (virq == NO_IRQ) + return; +@@ -785,15 +732,20 @@ void irq_dispose_mapping(unsigned int vi + if (hwirq < host->revmap_data.linear.size) + host->revmap_data.linear.revmap[hwirq] = NO_IRQ; + break; +- case IRQ_HOST_MAP_TREE: ++ case IRQ_HOST_MAP_TREE: { ++ DEFINE_RADIX_TREE_CONTEXT(ctx, &host->revmap_data.tree); ++ + /* Check if radix tree allocated yet */ +- if (host->revmap_data.tree.gfp_mask == 0) ++ if (atomic_read(&revmap_trees_allocated) == 0) + break; +- irq_radix_wrlock(&flags); +- radix_tree_delete(&host->revmap_data.tree, hwirq); +- irq_radix_wrunlock(flags); ++ ++ radix_tree_lock(&ctx); ++ radix_tree_delete(ctx.tree, hwirq); ++ radix_tree_unlock(&ctx); ++ + break; + } ++ } + + /* Destroy map */ + smp_mb(); +@@ -846,22 +798,20 @@ unsigned int irq_radix_revmap(struct irq + struct radix_tree_root *tree; + struct irq_map_entry *ptr; + unsigned int virq; +- unsigned long flags; + + WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE); + +- /* Check if the radix tree exist yet. We test the value of +- * the gfp_mask for that. Sneaky but saves another int in the +- * structure. If not, we fallback to slow mode +- */ +- tree = &host->revmap_data.tree; +- if (tree->gfp_mask == 0) ++ /* Check if the radix tree exist yet. */ ++ if (atomic_read(&revmap_trees_allocated) == 0) + return irq_find_mapping(host, hwirq); + +- /* Now try to resolve */ +- irq_radix_rdlock(&flags); ++ /* ++ * Now try to resolve ++ * No rcu_read_lock(ing) needed, the ptr returned can't go under us ++ * as it's referencing an entry in the static irq_map table. ++ */ ++ tree = &host->revmap_data.tree; + ptr = radix_tree_lookup(tree, hwirq); +- irq_radix_rdunlock(flags); + + /* Found it, return */ + if (ptr) { +@@ -872,9 +822,10 @@ unsigned int irq_radix_revmap(struct irq + /* If not there, try to insert it */ + virq = irq_find_mapping(host, hwirq); + if (virq != NO_IRQ) { +- irq_radix_wrlock(&flags); +- radix_tree_insert(tree, hwirq, &irq_map[virq]); +- irq_radix_wrunlock(flags); ++ DEFINE_RADIX_TREE_CONTEXT(ctx, tree); ++ radix_tree_lock(&ctx); ++ radix_tree_insert(ctx.tree, hwirq, &irq_map[virq]); ++ radix_tree_unlock(&ctx); + } + return virq; + } +@@ -985,14 +936,15 @@ void irq_early_init(void) + static int irq_late_init(void) + { + struct irq_host *h; +- unsigned long flags; + +- irq_radix_wrlock(&flags); + list_for_each_entry(h, &irq_hosts, link) { + if (h->revmap_type == IRQ_HOST_MAP_TREE) + INIT_RADIX_TREE(&h->revmap_data.tree, GFP_ATOMIC); + } +- irq_radix_wrunlock(flags); ++ ++ /* Make sure the radix trees inits are visible before setting the flag */ ++ smp_mb(); ++ atomic_set(&revmap_trees_allocated, 1); + + return 0; + } --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0124-rcu-new-5.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0124-rcu-new-5.patch @@ -0,0 +1,223 @@ +From paulmck@linux.vnet.ibm.com Thu Sep 27 00:10:09 2007 +Date: Mon, 10 Sep 2007 11:36:22 -0700 +From: Paul E. McKenney +To: linux-kernel@vger.kernel.org +Cc: linux-rt-users@vger.kernel.org, mingo@elte.hu, akpm@linux-foundation.org, + dipankar@in.ibm.com, josht@linux.vnet.ibm.com, tytso@us.ibm.com, + dvhltc@us.ibm.com, tglx@linutronix.de, a.p.zijlstra@chello.nl, + bunk@kernel.org, ego@in.ibm.com, oleg@tv-sign.ru, srostedt@redhat.com +Subject: [PATCH RFC 5/9] RCU: CPU hotplug support for preemptible RCU + +Work in progress, not for inclusion. + +This patch allows preemptible RCU to tolerate CPU-hotplug operations. +It accomplishes this by maintaining a local copy of a map of online +CPUs, which it accesses under its own lock. + +Signed-off-by: Paul E. McKenney +--- + + include/linux/rcuclassic.h | 2 + include/linux/rcupreempt.h | 2 + kernel/rcuclassic.c | 8 +++ + kernel/rcupreempt.c | 93 +++++++++++++++++++++++++++++++++++++++++++-- + 4 files changed, 100 insertions(+), 5 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/rcuclassic.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/rcuclassic.h 2008-10-08 22:23:26.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/rcuclassic.h 2008-10-08 22:23:26.000000000 -0400 +@@ -82,6 +82,8 @@ static inline void rcu_bh_qsctr_inc(int + #define rcu_check_callbacks_rt(cpu, user) do { } while (0) + #define rcu_init_rt() do { } while (0) + #define rcu_needs_cpu_rt(cpu) 0 ++#define rcu_offline_cpu_rt(cpu) ++#define rcu_online_cpu_rt(cpu) + #define rcu_pending_rt(cpu) 0 + #define rcu_process_callbacks_rt(unused) do { } while (0) + +Index: linux-2.6.24.7-rt21/include/linux/rcupreempt.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/rcupreempt.h 2008-10-08 22:23:26.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/rcupreempt.h 2008-10-08 22:23:26.000000000 -0400 +@@ -59,6 +59,8 @@ extern void rcu_advance_callbacks_rt(int + extern void rcu_check_callbacks_rt(int cpu, int user); + extern void rcu_init_rt(void); + extern int rcu_needs_cpu_rt(int cpu); ++extern void rcu_offline_cpu_rt(int cpu); ++extern void rcu_online_cpu_rt(int cpu); + extern int rcu_pending_rt(int cpu); + struct softirq_action; + extern void rcu_process_callbacks_rt(struct softirq_action *unused); +Index: linux-2.6.24.7-rt21/kernel/rcuclassic.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rcuclassic.c 2008-10-08 22:23:26.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rcuclassic.c 2008-10-08 22:23:26.000000000 -0400 +@@ -414,14 +414,19 @@ static void __rcu_offline_cpu(struct rcu + static void rcu_offline_cpu(int cpu) + { + struct rcu_data *this_rdp = &get_cpu_var(rcu_data); ++#ifdef CONFIG_CLASSIC_RCU + struct rcu_data *this_bh_rdp = &get_cpu_var(rcu_bh_data); ++#endif /* #ifdef CONFIG_CLASSIC_RCU */ + + __rcu_offline_cpu(this_rdp, &rcu_ctrlblk, + &per_cpu(rcu_data, cpu)); ++#ifdef CONFIG_CLASSIC_RCU + __rcu_offline_cpu(this_bh_rdp, &rcu_bh_ctrlblk, + &per_cpu(rcu_bh_data, cpu)); +- put_cpu_var(rcu_data); + put_cpu_var(rcu_bh_data); ++#endif /* #ifdef CONFIG_CLASSIC_RCU */ ++ put_cpu_var(rcu_data); ++ rcu_offline_cpu_rt(cpu); + } + + #else +@@ -571,6 +576,7 @@ static void __cpuinit rcu_online_cpu(int + rdp->passed_quiesc = &per_cpu(rcu_data_passed_quiesc, cpu); + rcu_init_percpu_data(cpu, &rcu_bh_ctrlblk, bh_rdp); + bh_rdp->passed_quiesc = &per_cpu(rcu_data_bh_passed_quiesc, cpu); ++ rcu_online_cpu_rt(cpu); + } + + static int __cpuinit rcu_cpu_notify(struct notifier_block *self, +Index: linux-2.6.24.7-rt21/kernel/rcupreempt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rcupreempt.c 2008-10-08 22:23:26.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rcupreempt.c 2008-10-08 22:23:26.000000000 -0400 +@@ -125,6 +125,8 @@ enum rcu_mb_flag_values { + }; + static DEFINE_PER_CPU(enum rcu_mb_flag_values, rcu_mb_flag) = rcu_mb_done; + ++static cpumask_t rcu_cpu_online_map = CPU_MASK_NONE; ++ + /* + * Macro that prevents the compiler from reordering accesses, but does + * absolutely -nothing- to prevent CPUs from reordering. This is used +@@ -404,7 +406,7 @@ rcu_try_flip_idle(void) + + /* Now ask each CPU for acknowledgement of the flip. */ + +- for_each_possible_cpu(cpu) ++ for_each_cpu_mask(cpu, rcu_cpu_online_map) + per_cpu(rcu_flip_flag, cpu) = rcu_flipped; + + return 1; +@@ -420,7 +422,7 @@ rcu_try_flip_waitack(void) + int cpu; + + RCU_TRACE_ME(rcupreempt_trace_try_flip_a1); +- for_each_possible_cpu(cpu) ++ for_each_cpu_mask(cpu, rcu_cpu_online_map) + if (per_cpu(rcu_flip_flag, cpu) != rcu_flip_seen) { + RCU_TRACE_ME(rcupreempt_trace_try_flip_ae1); + return 0; +@@ -462,7 +464,7 @@ rcu_try_flip_waitzero(void) + + /* Call for a memory barrier from each CPU. */ + +- for_each_possible_cpu(cpu) ++ for_each_cpu_mask(cpu, rcu_cpu_online_map) + per_cpu(rcu_mb_flag, cpu) = rcu_mb_needed; + + RCU_TRACE_ME(rcupreempt_trace_try_flip_z2); +@@ -480,7 +482,7 @@ rcu_try_flip_waitmb(void) + int cpu; + + RCU_TRACE_ME(rcupreempt_trace_try_flip_m1); +- for_each_possible_cpu(cpu) ++ for_each_cpu_mask(cpu, rcu_cpu_online_map) + if (per_cpu(rcu_mb_flag, cpu) != rcu_mb_done) { + RCU_TRACE_ME(rcupreempt_trace_try_flip_me1); + return 0; +@@ -583,6 +585,89 @@ void rcu_advance_callbacks_rt(int cpu, i + spin_unlock_irqrestore(&rdp->lock, oldirq); + } + ++#ifdef CONFIG_HOTPLUG_CPU ++ ++#define rcu_offline_cpu_rt_enqueue(srclist, srctail, dstlist, dsttail) do { \ ++ *dsttail = srclist; \ ++ if (srclist != NULL) { \ ++ dsttail = srctail; \ ++ srclist = NULL; \ ++ srctail = &srclist;\ ++ } \ ++ } while (0) ++ ++ ++void rcu_offline_cpu_rt(int cpu) ++{ ++ int i; ++ struct rcu_head *list = NULL; ++ unsigned long oldirq; ++ struct rcu_data *rdp = RCU_DATA_CPU(cpu); ++ struct rcu_head **tail = &list; ++ ++ /* Remove all callbacks from the newly dead CPU, retaining order. */ ++ ++ spin_lock_irqsave(&rdp->lock, oldirq); ++ rcu_offline_cpu_rt_enqueue(rdp->donelist, rdp->donetail, list, tail); ++ for (i = GP_STAGES - 1; i >= 0; i--) ++ rcu_offline_cpu_rt_enqueue(rdp->waitlist[i], rdp->waittail[i], ++ list, tail); ++ rcu_offline_cpu_rt_enqueue(rdp->nextlist, rdp->nexttail, list, tail); ++ spin_unlock_irqrestore(&rdp->lock, oldirq); ++ rdp->waitlistcount = 0; ++ ++ /* Disengage the newly dead CPU from grace-period computation. */ ++ ++ spin_lock_irqsave(&rcu_ctrlblk.fliplock, oldirq); ++ rcu_check_mb(cpu); ++ if (per_cpu(rcu_flip_flag, cpu) == rcu_flipped) { ++ smp_mb(); /* Subsequent counter accesses must see new value */ ++ per_cpu(rcu_flip_flag, cpu) = rcu_flip_seen; ++ smp_mb(); /* Subsequent RCU read-side critical sections */ ++ /* seen -after- acknowledgement. */ ++ } ++ cpu_clear(cpu, rcu_cpu_online_map); ++ spin_unlock_irqrestore(&rcu_ctrlblk.fliplock, oldirq); ++ ++ /* ++ * Place the removed callbacks on the current CPU's queue. ++ * Make them all start a new grace period: simple approach, ++ * in theory could starve a given set of callbacks, but ++ * you would need to be doing some serious CPU hotplugging ++ * to make this happen. If this becomes a problem, adding ++ * a synchronize_rcu() to the hotplug path would be a simple ++ * fix. ++ */ ++ ++ rdp = RCU_DATA_ME(); ++ spin_lock_irqsave(&rdp->lock, oldirq); ++ *rdp->nexttail = list; ++ if (list) ++ rdp->nexttail = tail; ++ spin_unlock_irqrestore(&rdp->lock, oldirq); ++} ++ ++void __devinit rcu_online_cpu_rt(int cpu) ++{ ++ unsigned long oldirq; ++ ++ spin_lock_irqsave(&rcu_ctrlblk.fliplock, oldirq); ++ cpu_set(cpu, rcu_cpu_online_map); ++ spin_unlock_irqrestore(&rcu_ctrlblk.fliplock, oldirq); ++} ++ ++#else /* #ifdef CONFIG_HOTPLUG_CPU */ ++ ++void rcu_offline_cpu(int cpu) ++{ ++} ++ ++void __devinit rcu_online_cpu_rt(int cpu) ++{ ++} ++ ++#endif /* #else #ifdef CONFIG_HOTPLUG_CPU */ ++ + void rcu_process_callbacks_rt(struct softirq_action *unused) + { + unsigned long flags; --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0264-preempt-realtime-supress-cpulock-warning.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0264-preempt-realtime-supress-cpulock-warning.patch @@ -0,0 +1,23 @@ +--- + kernel/cpu.c | 2 ++ + 1 file changed, 2 insertions(+) + +Index: linux-2.6.24.7-rt21/kernel/cpu.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/cpu.c 2008-10-08 22:22:27.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/cpu.c 2008-10-08 22:24:07.000000000 -0400 +@@ -37,12 +37,14 @@ void lock_cpu_hotplug(void) + struct task_struct *tsk = current; + + if (tsk == recursive) { ++#ifdef CONFIG_PREEMPT_RT + static int warnings = 10; + if (warnings) { + printk(KERN_ERR "Lukewarm IQ detected in hotplug locking\n"); + WARN_ON(1); + warnings--; + } ++#endif + recursive_depth++; + return; + } --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0095-msi-suspend-resume-workaround.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0095-msi-suspend-resume-workaround.patch @@ -0,0 +1,19 @@ +--- + drivers/pci/msi.c | 4 ++++ + 1 file changed, 4 insertions(+) + +Index: linux-2.6.24.7-rt21/drivers/pci/msi.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/pci/msi.c 2008-10-08 22:22:41.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/pci/msi.c 2008-10-08 22:23:19.000000000 -0400 +@@ -241,6 +241,10 @@ static void __pci_restore_msi_state(stru + return; + + entry = get_irq_msi(dev->irq); ++ if (!entry) { ++ WARN_ON(1); ++ return; ++ } + pos = entry->msi_attrib.pos; + + pci_intx_for_msi(dev, 0); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0337-sched-rt-stats.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0337-sched-rt-stats.patch @@ -0,0 +1,48 @@ +On Wed, Jul 25, 2007 at 10:05:04AM +0200, Ingo Molnar wrote: +> +> * Ankita Garg wrote: +> +> > Hi, +> > +> > This patch adds support to display captured -rt stats under +> > /proc/schedstat. +> +> hm, could you add it to /proc/sched_debug instead? That's where all the +> runqueue values are showing up normally. I'm also a bit wary about +> introducing a new schedstats version for -rt. + +So, I have merged my previous patch (to display rt_nr_running info in +sched_debug.c) with this one. + + +Signed-off-by: Ankita Garg +[mingo@elte.hu: fix it to work on !SCHEDSTATS too] +Signed-off-by: Ingo Molnar +-- + kernel/sched_debug.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +Index: linux-2.6.24.7-rt21/kernel/sched_debug.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sched_debug.c 2008-10-08 22:22:21.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sched_debug.c 2008-10-08 22:24:25.000000000 -0400 +@@ -186,6 +186,19 @@ static void print_cpu(struct seq_file *m + P(cpu_load[2]); + P(cpu_load[3]); + P(cpu_load[4]); ++#ifdef CONFIG_PREEMPT_RT ++ /* Print rt related rq stats */ ++ P(rt.rt_nr_running); ++ P(rt.rt_nr_uninterruptible); ++# ifdef CONFIG_SCHEDSTATS ++ P(rto_schedule); ++ P(rto_schedule_tail); ++ P(rto_wakeup); ++ P(rto_pulled); ++ P(rto_pushed); ++# endif ++#endif ++ + #undef P + #undef PN + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0443-rtmutex-lateral-steal.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0443-rtmutex-lateral-steal.patch @@ -0,0 +1,136 @@ +allow rt-mutex lock-stealing to include lateral priority + +From: Gregory Haskins + +The current logic only allows lock stealing to occur if the current task +is of higher priority than the pending owner. We can gain signficant +throughput improvements (200%+) by allowing the lock-stealing code to +include tasks of equal priority. The theory is that the system will make +faster progress by allowing the task already on the CPU to take the lock +rather than waiting for the system to wake-up a different task. + +This does add a degree of unfairness, yes. But also note that the users +of these locks under non -rt environments have already been using unfair +raw spinlocks anyway so the tradeoff is probably worth it. + +The way I like to think of this is that higher priority tasks should +clearly preempt, and lower priority tasks should clearly block. However, +if tasks have an identical priority value, then we can think of the +scheduler decisions as the tie-breaking parameter. (e.g. tasks that the +scheduler picked to run first have a logically higher priority amoung tasks +of the same prio). This helps to keep the system "primed" with tasks doing +useful work, and the end result is higher throughput. + +Thanks to Steven Rostedt for pointing out that RT tasks should be excluded +to prevent the introduction of an unnatural unbounded latency. + +[ Steven Rostedt - removed config option to disable ] + +Signed-off-by: Gregory Haskins +Signed-off-by: Steven Rostedt +--- + + kernel/rtmutex.c | 17 +++++++++++------ + kernel/rtmutex_common.h | 19 +++++++++++++++++++ + 2 files changed, 30 insertions(+), 6 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/rtmutex.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rtmutex.c 2008-10-08 22:24:45.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rtmutex.c 2008-10-08 22:24:50.000000000 -0400 +@@ -318,7 +318,7 @@ static int rt_mutex_adjust_prio_chain(st + * assigned pending owner [which might not have taken the + * lock yet]: + */ +-static inline int try_to_steal_lock(struct rt_mutex *lock) ++static inline int try_to_steal_lock(struct rt_mutex *lock, int mode) + { + struct task_struct *pendowner = rt_mutex_owner(lock); + struct rt_mutex_waiter *next; +@@ -330,7 +330,7 @@ static inline int try_to_steal_lock(stru + return 1; + + spin_lock(&pendowner->pi_lock); +- if (current->prio >= pendowner->prio) { ++ if (!lock_is_stealable(pendowner, mode)) { + spin_unlock(&pendowner->pi_lock); + return 0; + } +@@ -383,7 +383,7 @@ static inline int try_to_steal_lock(stru + * + * Must be called with lock->wait_lock held. + */ +-static int try_to_take_rt_mutex(struct rt_mutex *lock) ++static int do_try_to_take_rt_mutex(struct rt_mutex *lock, int mode) + { + /* + * We have to be careful here if the atomic speedups are +@@ -406,7 +406,7 @@ static int try_to_take_rt_mutex(struct r + */ + mark_rt_mutex_waiters(lock); + +- if (rt_mutex_owner(lock) && !try_to_steal_lock(lock)) ++ if (rt_mutex_owner(lock) && !try_to_steal_lock(lock, mode)) + return 0; + + /* We got the lock. */ +@@ -419,6 +419,11 @@ static int try_to_take_rt_mutex(struct r + return 1; + } + ++static inline int try_to_take_rt_mutex(struct rt_mutex *lock) ++{ ++ return do_try_to_take_rt_mutex(lock, STEAL_NORMAL); ++} ++ + /* + * Task blocks on lock. + * +@@ -684,7 +689,7 @@ rt_spin_lock_slowlock(struct rt_mutex *l + init_lists(lock); + + /* Try to acquire the lock again: */ +- if (try_to_take_rt_mutex(lock)) { ++ if (do_try_to_take_rt_mutex(lock, STEAL_LATERAL)) { + spin_unlock_irqrestore(&lock->wait_lock, flags); + return; + } +@@ -707,7 +712,7 @@ rt_spin_lock_slowlock(struct rt_mutex *l + int saved_lock_depth = current->lock_depth; + + /* Try to acquire the lock */ +- if (try_to_take_rt_mutex(lock)) ++ if (do_try_to_take_rt_mutex(lock, STEAL_LATERAL)) + break; + /* + * waiter.task is NULL the first time we come here and +Index: linux-2.6.24.7-rt21/kernel/rtmutex_common.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rtmutex_common.h 2008-10-08 22:22:15.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rtmutex_common.h 2008-10-08 22:24:50.000000000 -0400 +@@ -121,6 +121,25 @@ extern void rt_mutex_init_proxy_locked(s + extern void rt_mutex_proxy_unlock(struct rt_mutex *lock, + struct task_struct *proxy_owner); + ++ ++#define STEAL_LATERAL 1 ++#define STEAL_NORMAL 0 ++ ++/* ++ * Note that RT tasks are excluded from lateral-steals to prevent the ++ * introduction of an unbounded latency ++ */ ++static inline int lock_is_stealable(struct task_struct *pendowner, int mode) ++{ ++ if (mode == STEAL_NORMAL || rt_task(current)) { ++ if (current->prio >= pendowner->prio) ++ return 0; ++ } else if (current->prio > pendowner->prio) ++ return 0; ++ ++ return 1; ++} ++ + #ifdef CONFIG_DEBUG_RT_MUTEXES + # include "rtmutex-debug.h" + #else --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0433-nmi-watchdog-fix-1.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0433-nmi-watchdog-fix-1.patch @@ -0,0 +1,35 @@ +From h-shimamoto@ct.jp.nec.com Thu May 15 10:14:15 2008 +Date: Mon, 28 Apr 2008 11:14:39 -0700 +From: Hiroshi Shimamoto +To: Ingo Molnar , Steven Rostedt , + Thomas Gleixner +Cc: linux-kernel@vger.kernel.org, linux-rt-users@vger.kernel.org +Subject: [PATCH -rt 1/4] x86_64: send NMI after nmi_show_regs on + +From: Hiroshi Shimamoto + +The flags nmi_show_regs should be set before send NMI. + +Signed-off-by: Hiroshi Shimamoto +--- + arch/x86/kernel/nmi_64.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/nmi_64.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/nmi_64.c 2008-10-08 22:24:38.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/nmi_64.c 2008-10-08 22:24:47.000000000 -0400 +@@ -327,11 +327,11 @@ void nmi_show_all_regs(void) + if (system_state == SYSTEM_BOOTING) + return; + +- smp_send_nmi_allbutself(); +- + for_each_online_cpu(i) + nmi_show_regs[i] = 1; + ++ smp_send_nmi_allbutself(); ++ + for_each_online_cpu(i) { + while (nmi_show_regs[i] == 1) + barrier(); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0298-radix-tree-optimistic-hist.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0298-radix-tree-optimistic-hist.patch @@ -0,0 +1,171 @@ +Subject: debug: optimistic lock histogram + +A simple histogram measuring the efficiency of the optimistic locking + +Signed-off-by: Peter Zijlstra +--- + fs/proc/proc_misc.c | 22 +++++++++++ + lib/radix-tree.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 124 insertions(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/fs/proc/proc_misc.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/proc/proc_misc.c 2008-10-08 22:24:00.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/proc/proc_misc.c 2008-10-08 22:24:15.000000000 -0400 +@@ -302,6 +302,25 @@ static const struct file_operations proc + .release = seq_release, + }; + ++#ifdef CONFIG_RADIX_TREE_OPTIMISTIC ++extern struct seq_operations optimistic_op; ++static int optimistic_open(struct inode *inode, struct file *file) ++{ ++ (void)inode; ++ return seq_open(file, &optimistic_op); ++} ++ ++extern ssize_t optimistic_write(struct file *, const char __user *, size_t, loff_t *); ++ ++static struct file_operations optimistic_file_operations = { ++ .open = optimistic_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = seq_release, ++ .write = optimistic_write, ++}; ++#endif ++ + static int devinfo_show(struct seq_file *f, void *v) + { + int i = *(loff_t *) v; +@@ -788,6 +807,9 @@ void __init proc_misc_init(void) + entry->proc_fops = &proc_kmsg_operations; + } + #endif ++#ifdef CONFIG_RADIX_TREE_OPTIMISTIC ++ create_seq_entry("radix_optimistic", 0, &optimistic_file_operations); ++#endif + create_seq_entry("locks", 0, &proc_locks_operations); + create_seq_entry("devices", 0, &proc_devinfo_operations); + create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations); +Index: linux-2.6.24.7-rt21/lib/radix-tree.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/lib/radix-tree.c 2008-10-08 22:24:15.000000000 -0400 ++++ linux-2.6.24.7-rt21/lib/radix-tree.c 2008-10-08 22:24:15.000000000 -0400 +@@ -80,6 +80,105 @@ static unsigned long height_to_maxindex[ + static struct lock_class_key radix_node_class[RADIX_TREE_MAX_PATH]; + #endif + ++#ifdef CONFIG_RADIX_TREE_OPTIMISTIC ++static DEFINE_PER_CPU(unsigned long[RADIX_TREE_MAX_PATH+1], optimistic_histogram); ++ ++static void optimistic_hit(unsigned long height) ++{ ++ if (height > RADIX_TREE_MAX_PATH) ++ height = RADIX_TREE_MAX_PATH; ++ ++ __get_cpu_var(optimistic_histogram)[height]++; ++} ++ ++#ifdef CONFIG_PROC_FS ++ ++#include ++#include ++ ++static void *frag_start(struct seq_file *m, loff_t *pos) ++{ ++ if (*pos < 0 || *pos > RADIX_TREE_MAX_PATH) ++ return NULL; ++ ++ m->private = (void *)(unsigned long)*pos; ++ return pos; ++} ++ ++static void *frag_next(struct seq_file *m, void *arg, loff_t *pos) ++{ ++ if (*pos < RADIX_TREE_MAX_PATH) { ++ (*pos)++; ++ (*((unsigned long *)&m->private))++; ++ return pos; ++ } ++ return NULL; ++} ++ ++static void frag_stop(struct seq_file *m, void *arg) ++{ ++} ++ ++unsigned long get_optimistic_stat(unsigned long index) ++{ ++ unsigned long total = 0; ++ int cpu; ++ ++ for_each_possible_cpu(cpu) { ++ total += per_cpu(optimistic_histogram, cpu)[index]; ++ } ++ return total; ++} ++ ++static int frag_show(struct seq_file *m, void *arg) ++{ ++ unsigned long index = (unsigned long)m->private; ++ unsigned long hits = get_optimistic_stat(index); ++ ++ if (index == 0) ++ seq_printf(m, "levels skipped\thits\n"); ++ ++ if (index < RADIX_TREE_MAX_PATH) ++ seq_printf(m, "%9lu\t%9lu\n", index, hits); ++ else ++ seq_printf(m, "failed\t%9lu\n", hits); ++ ++ return 0; ++} ++ ++struct seq_operations optimistic_op = { ++ .start = frag_start, ++ .next = frag_next, ++ .stop = frag_stop, ++ .show = frag_show, ++}; ++ ++static void optimistic_reset(void) ++{ ++ int cpu; ++ int height; ++ for_each_possible_cpu(cpu) { ++ for (height = 0; height <= RADIX_TREE_MAX_PATH; height++) ++ per_cpu(optimistic_histogram, cpu)[height] = 0; ++ } ++} ++ ++ssize_t optimistic_write(struct file *file, const char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ if (count) { ++ char c; ++ if (get_user(c, buf)) ++ return -EFAULT; ++ if (c == '0') ++ optimistic_reset(); ++ } ++ return count; ++} ++ ++#endif // CONFIG_PROC_FS ++#endif // CONFIG_RADIX_TREE_OPTIMISTIC ++ + /* + * Radix tree node cache. + */ +@@ -468,7 +567,9 @@ radix_optimistic_lock(struct radix_tree_ + BUG_ON(context->locked); + spin_lock(&context->root->lock); + context->locked = &context->root->lock; +- } ++ optimistic_hit(RADIX_TREE_MAX_PATH); ++ } else ++ optimistic_hit(context->root->height - node->height); + } + return node; + } --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0083-ep93xx-timer-accuracy.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0083-ep93xx-timer-accuracy.patch @@ -0,0 +1,53 @@ + +The ep93xx has a weird timer tick base (983.04 kHz.) This experimental +patch tries to increase time of day accuracy by keeping the number of +ticks until the next jiffy in a fractional value representation. + +Signed-off-by: Lennert Buytenhek + +--- + arch/arm/mach-ep93xx/core.c | 23 ++++++++++++++++++----- + 1 file changed, 18 insertions(+), 5 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/arm/mach-ep93xx/core.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/arm/mach-ep93xx/core.c 2008-10-08 22:22:42.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/arm/mach-ep93xx/core.c 2008-10-08 22:23:13.000000000 -0400 +@@ -94,19 +94,32 @@ void __init ep93xx_map_io(void) + * track of lost jiffies. + */ + static unsigned int last_jiffy_time; ++static unsigned int next_jiffy_time; ++static unsigned int accumulator; + +-#define TIMER4_TICKS_PER_JIFFY ((CLOCK_TICK_RATE + (HZ/2)) / HZ) ++#define TIMER4_TICKS_PER_JIFFY (983040 / HZ) ++#define TIMER4_TICKS_MOD_JIFFY (983040 % HZ) ++ ++static int after_eq(unsigned long a, unsigned long b) ++{ ++ return ((signed long)(a - b)) >= 0; ++} + + static int ep93xx_timer_interrupt(int irq, void *dev_id) + { + write_seqlock(&xtime_lock); + + __raw_writel(1, EP93XX_TIMER1_CLEAR); +- while ((signed long) +- (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time) +- >= TIMER4_TICKS_PER_JIFFY) { +- last_jiffy_time += TIMER4_TICKS_PER_JIFFY; ++ while (after_eq(__raw_readl(EP93XX_TIMER4_VALUE_LOW), next_jiffy_time)) { + timer_tick(); ++ ++ last_jiffy_time = next_jiffy_time; ++ next_jiffy_time += TIMER4_TICKS_PER_JIFFY; ++ accumulator += TIMER4_TICKS_MOD_JIFFY; ++ if (accumulator >= HZ) { ++ next_jiffy_time++; ++ accumulator -= HZ; ++ } + } + + write_sequnlock(&xtime_lock); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0440-trace-fix-hist-name-spellings.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0440-trace-fix-hist-name-spellings.patch @@ -0,0 +1,60 @@ +From c.emde@osadl.org Thu May 15 09:56:37 2008 +Date: Tue, 01 Apr 2008 00:34:59 +0200 +From: Carsten Emde +To: Thomas Gleixner +Subject: Label missplaced in kernel/trace/Kconfig +Resent-Date: Wed, 9 Apr 2008 17:43:50 +0200 (CEST) +Resent-From: tglx@linutronix.de +Resent-To: Steven Rostedt +Resent-Subject: Label missplaced in kernel/trace/Kconfig + +Hi Thomas, + +there is a strange problem in kernel/trace/Kconfig: + +Here + +config INTERRUPT_OFF_HIST + bool "Interrupts off critical timings histogram" + +and here + +config WAKEUP_LATENCY_HIST + bool "Interrupts off critical timings histogram" + +the same label is used, but at the second occurrence the label should +most probably read + +config WAKEUP_LATENCY_HIST + bool "Wakeup latencies histogram" + +or similar. Patch see below. + +I called it a "strange" problem, because it is so obvious and everybody +who was editing this kernel configuration, must have seen it. Any idea +what happened here? + + +Carsten. + + + + + +--- + kernel/trace/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/kernel/trace/Kconfig +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/trace/Kconfig 2008-10-08 22:23:09.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/trace/Kconfig 2008-10-08 22:24:49.000000000 -0400 +@@ -150,7 +150,7 @@ config PREEMPT_OFF_HIST + preemption off timings to create a histogram of latencies. + + config WAKEUP_LATENCY_HIST +- bool "Interrupts off critical timings histogram" ++ bool "Wakeup latencies histogram" + select TRACING + select MARKERS + help --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0078-powerpc-ftrace-store-mcount.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0078-powerpc-ftrace-store-mcount.patch @@ -0,0 +1,169 @@ +--- + arch/powerpc/kernel/entry_32.S | 4 ++++ + arch/powerpc/kernel/entry_64.S | 5 ++++- + arch/powerpc/kernel/ftrace.c | 21 +++++++-------------- + include/asm-powerpc/ftrace.h | 8 ++++++++ + 4 files changed, 23 insertions(+), 15 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/powerpc/kernel/entry_32.S +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/kernel/entry_32.S 2008-10-08 22:23:10.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/kernel/entry_32.S 2008-10-08 22:23:11.000000000 -0400 +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + #undef SHOW_SYSCALLS + #undef SHOW_SYSCALLS_TASK +@@ -1040,6 +1041,7 @@ _GLOBAL(_mcount) + stw r10,40(r1) + stw r3, 44(r1) + stw r5, 8(r1) ++ subi r3, r3, MCOUNT_INSN_SIZE + .globl mcount_call + mcount_call: + bl ftrace_stub +@@ -1077,6 +1079,7 @@ _GLOBAL(ftrace_caller) + stw r10,40(r1) + stw r3, 44(r1) + stw r5, 8(r1) ++ subi r3, r3, MCOUNT_INSN_SIZE + .globl ftrace_call + ftrace_call: + bl ftrace_stub +@@ -1115,6 +1118,7 @@ _GLOBAL(_mcount) + stw r3, 44(r1) + stw r5, 8(r1) + ++ subi r3, r3, MCOUNT_INSN_SIZE + LOAD_REG_ADDR(r5, ftrace_trace_function) + lwz r5,0(r5) + +Index: linux-2.6.24.7-rt21/arch/powerpc/kernel/entry_64.S +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/kernel/entry_64.S 2008-10-08 22:23:10.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/kernel/entry_64.S 2008-10-08 22:23:11.000000000 -0400 +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + + /* + * System calls. +@@ -855,6 +856,7 @@ _GLOBAL(_mcount) + mflr r3 + stdu r1, -112(r1) + std r3, 128(r1) ++ subi r3, r3, MCOUNT_INSN_SIZE + .globl mcount_call + mcount_call: + bl ftrace_stub +@@ -871,6 +873,7 @@ _GLOBAL(ftrace_caller) + stdu r1, -112(r1) + std r3, 128(r1) + ld r4, 16(r11) ++ subi r3, r3, MCOUNT_INSN_SIZE + .globl ftrace_call + ftrace_call: + bl ftrace_stub +@@ -892,7 +895,7 @@ _GLOBAL(_mcount) + std r3, 128(r1) + ld r4, 16(r11) + +- ++ subi r3, r3, MCOUNT_INSN_SIZE + LOAD_REG_ADDR(r5,ftrace_trace_function) + ld r5,0(r5) + ld r5,0(r5) +Index: linux-2.6.24.7-rt21/arch/powerpc/kernel/ftrace.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/powerpc/kernel/ftrace.c 2008-10-08 22:23:11.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/powerpc/kernel/ftrace.c 2008-10-08 22:23:11.000000000 -0400 +@@ -15,8 +15,8 @@ + #include + + #include ++#include + +-#define CALL_BACK 4 + + static unsigned int ftrace_nop = 0x60000000; + +@@ -27,9 +27,10 @@ static unsigned int ftrace_nop = 0x60000 + # define GET_ADDR(addr) *(unsigned long *)addr + #endif + ++ + static unsigned int notrace ftrace_calc_offset(long ip, long addr) + { +- return (int)((addr + CALL_BACK) - ip); ++ return (int)(addr - ip); + } + + notrace unsigned char *ftrace_nop_replace(void) +@@ -76,9 +77,6 @@ ftrace_modify_code(unsigned long ip, uns + unsigned new = *(unsigned *)new_code; + int faulted = 0; + +- /* move the IP back to the start of the call */ +- ip -= CALL_BACK; +- + /* + * Note: Due to modules and __init, code can + * disappear and change, we need to protect against faulting +@@ -118,12 +116,10 @@ ftrace_modify_code(unsigned long ip, uns + notrace int ftrace_update_ftrace_func(ftrace_func_t func) + { + unsigned long ip = (unsigned long)(&ftrace_call); +- unsigned char old[4], *new; ++ unsigned char old[MCOUNT_INSN_SIZE], *new; + int ret; + +- ip += CALL_BACK; +- +- memcpy(old, &ftrace_call, 4); ++ memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE); + new = ftrace_call_replace(ip, (unsigned long)func); + ret = ftrace_modify_code(ip, old, new); + +@@ -134,16 +130,13 @@ notrace int ftrace_mcount_set(unsigned l + { + unsigned long ip = (long)(&mcount_call); + unsigned long *addr = data; +- unsigned char old[4], *new; +- +- /* ip is at the location, but modify code will subtact this */ +- ip += CALL_BACK; ++ unsigned char old[MCOUNT_INSN_SIZE], *new; + + /* + * Replace the mcount stub with a pointer to the + * ip recorder function. + */ +- memcpy(old, &mcount_call, 4); ++ memcpy(old, &mcount_call, MCOUNT_INSN_SIZE); + new = ftrace_call_replace(ip, *addr); + *addr = ftrace_modify_code(ip, old, new); + +Index: linux-2.6.24.7-rt21/include/asm-powerpc/ftrace.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-powerpc/ftrace.h 2008-10-08 22:23:10.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-powerpc/ftrace.h 2008-10-08 22:23:11.000000000 -0400 +@@ -1,6 +1,14 @@ + #ifndef _ASM_POWERPC_FTRACE + #define _ASM_POWERPC_FTRACE + ++#ifdef CONFIG_FTRACE ++#define MCOUNT_ADDR ((long)(_mcount)) ++#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */ ++ ++#ifndef __ASSEMBLY__ + extern void _mcount(void); ++#endif + + #endif ++ ++#endif /* _ASM_POWERPC_FTRACE */ --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0431-remove-spinlock-define.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0431-remove-spinlock-define.patch @@ -0,0 +1,52 @@ +From ghaskins@novell.com Mon Mar 24 17:45:51 2008 +Date: Fri, 07 Mar 2008 09:06:35 -0500 +From: Gregory Haskins +To: mingo@elte.hu, rostedt@goodmis.org, tglx@linutronix.de, + linux-rt-users@vger.kernel.org +Cc: ghaskins@novell.com, linux-kernel@vger.kernel.org +Subject: [PATCH] RT: fix spinlock preemption feature when PREEMPT_RT is + enabled + + [ The following text is in the "utf-8" character set. ] + [ Your display is set for the "iso-8859-1" character set. ] + [ Some characters may be displayed incorrectly. ] + +kernel/spinlock.c implements two versions of spinlock wrappers around +the arch-specific implementations: + +1) A simple passthrough which implies disabled preemption while spinning + +2) A "preemptible waiter" version which uses trylock. + +Currently, PREEMPT && SMP will turn on the preemptible feature, and +lockdep or PREEMPT_RT will disable it. Disabling the feature for +lockdep makes perfect sense, but PREEMPT_RT is counter-intuitive. My +guess is that this was inadvertent, so this patch once again enables +the feature for PREEMPT_RT. + +(Since PREEMPT is set for PREEMPT_RT, we simply get rid of the extra +condition). + +I have tested the PREEMPT_RT kernel with this patch and all seems well. +Therefore, if there *is* an issue with running preemptible versions of +these spinlocks under PREEMPT_RT, it is not immediately apparent why. + +Signed-off-by: Gregory Haskins +--- + + kernel/spinlock.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/kernel/spinlock.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/spinlock.c 2008-10-08 22:23:37.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/spinlock.c 2008-10-08 22:24:47.000000000 -0400 +@@ -117,7 +117,7 @@ EXPORT_SYMBOL(__write_trylock_irqsave); + * not re-enabled during lock-acquire (which the preempt-spin-ops do): + */ + #if !defined(CONFIG_PREEMPT) || !defined(CONFIG_SMP) || \ +- defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_PREEMPT_RT) ++ defined(CONFIG_DEBUG_LOCK_ALLOC) + + void __lockfunc __read_lock(raw_rwlock_t *lock) + { --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0544-qla-mbx-compat-cast.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0544-qla-mbx-compat-cast.patch @@ -0,0 +1,24 @@ +From: Steven Rostedt +Subject: fix semaphore type in qla_mbx + +A compat_semaphore is passed as a pointer to a timeout function, but +that timeout function converts it to a semaphore instead of a compat. + +Signed-off-by: Steven Rostedt +--- + drivers/scsi/qla2xxx/qla_mbx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux-2.6.24.7-rt21/drivers/scsi/qla2xxx/qla_mbx.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/scsi/qla2xxx/qla_mbx.c 2008-10-08 22:22:08.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/scsi/qla2xxx/qla_mbx.c 2008-10-08 22:25:14.000000000 -0400 +@@ -11,7 +11,7 @@ + static void + qla2x00_mbx_sem_timeout(unsigned long data) + { +- struct semaphore *sem_ptr = (struct semaphore *)data; ++ struct compat_semaphore *sem_ptr = (struct compat_semaphore *)data; + + DEBUG11(printk("qla2x00_sem_timeout: entered.\n")); + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0407-rcu-preempt-trace-markers-1.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0407-rcu-preempt-trace-markers-1.patch @@ -0,0 +1,517 @@ +From prasad@linux.vnet.ibm.com Fri Jan 11 14:55:27 2008 +Date: Tue, 8 Jan 2008 01:25:09 +0530 +From: K. Prasad +To: linux-kernel@vger.kernel.org, mingo@elte.hu +Cc: Gautham R Shenoy , K. Prasad , + mathieu.desnoyers@polymtl.ca, linux-rt-users@vger.kernel.org, + dipankar@in.ibm.com, paulmck@linux.vnet.ibm.com +Subject: [PATCH 1/2] Markers Implementation for RCU Preempt Tracing - Ver II + +This patch converts Preempt RCU Tracing code infrastructure to implement +markers. + +- The rcupreempt_trace structure has been moved to the tracing + infrastructure and de-linked from the rcupreempt.c code. A per-cpu + instance of rcupreempt_trace structure will be maintained in + rcupreempt_trace.c + +- The above change also renders a few macro definitions unused (such as + RCU_TRACE_CPU, RCU_TRACE_ME and RCU_TRACE_RDP) which have been + removed. + +- Some of the helper functions in rcupreempt.c which were exported only + when CONFIG_RCU_TRACE was set are now exported unconditionally. These + functions operate on per-cpu variables that are used both by the RCU + and RCU Tracing code. The changes help in making RCU Tracing code + operate as a kernel module also. + +- The references to rcupreempt-boost tracing in the module + initialisation and cleanup have been removed here to enable kernel + build, but will be brought in after enclosing them inside a #ifdef + CONFIG_PREEMPT_RCU_BOOST. + +Signed-off-by: K.Prasad +--- + include/linux/rcupreempt.h | 10 ---- + include/linux/rcupreempt_trace.h | 50 ++++++++++++------------ + kernel/Kconfig.preempt | 7 +-- + kernel/rcupreempt.c | 77 ++++++++++---------------------------- + kernel/rcupreempt_trace.c | 79 +++++++++++++++++++++++++++++++++++++-- + 5 files changed, 125 insertions(+), 98 deletions(-) + +Index: linux-2.6.24.7-rt21/include/linux/rcupreempt.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/rcupreempt.h 2008-10-08 22:24:33.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/rcupreempt.h 2008-10-08 22:24:41.000000000 -0400 +@@ -96,16 +96,6 @@ extern int rcu_pending_rt(int cpu); + struct softirq_action; + extern void rcu_process_callbacks_rt(struct softirq_action *unused); + +-#ifdef CONFIG_RCU_TRACE +-struct rcupreempt_trace; +-extern int *rcupreempt_flipctr(int cpu); +-extern long rcupreempt_data_completed(void); +-extern int rcupreempt_flip_flag(int cpu); +-extern int rcupreempt_mb_flag(int cpu); +-extern char *rcupreempt_try_flip_state_name(void); +-extern struct rcupreempt_trace *rcupreempt_trace_cpu(int cpu); +-#endif +- + struct softirq_action; + + #ifdef CONFIG_NO_HZ +Index: linux-2.6.24.7-rt21/include/linux/rcupreempt_trace.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/rcupreempt_trace.h 2008-10-08 22:23:25.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/rcupreempt_trace.h 2008-10-08 22:24:41.000000000 -0400 +@@ -69,32 +69,32 @@ struct rcupreempt_trace { + long rcu_try_flip_m2; + }; + +-#ifdef CONFIG_RCU_TRACE +-#define RCU_TRACE(fn, arg) fn(arg); +-#else +-#define RCU_TRACE(fn, arg) +-#endif ++struct rcupreempt_probe_data { ++ const char *name; ++ const char *format; ++ marker_probe_func *probe_func; ++}; ++ ++#define DEFINE_RCUPREEMPT_MARKER_HANDLER(rcupreempt_trace_worker) \ ++void rcupreempt_trace_worker##_callback(const struct marker *mdata, \ ++ void *private_data, const char *format, ...) \ ++{ \ ++ struct rcupreempt_trace *trace; \ ++ trace = (&per_cpu(trace_data, smp_processor_id())); \ ++ rcupreempt_trace_worker(trace); \ ++} ++ ++#define INIT_RCUPREEMPT_PROBE(rcupreempt_trace_worker) \ ++{ \ ++ .name = __stringify(rcupreempt_trace_worker), \ ++ .probe_func = rcupreempt_trace_worker##_callback \ ++} + +-extern void rcupreempt_trace_move2done(struct rcupreempt_trace *trace); +-extern void rcupreempt_trace_move2wait(struct rcupreempt_trace *trace); +-extern void rcupreempt_trace_try_flip_1(struct rcupreempt_trace *trace); +-extern void rcupreempt_trace_try_flip_e1(struct rcupreempt_trace *trace); +-extern void rcupreempt_trace_try_flip_i1(struct rcupreempt_trace *trace); +-extern void rcupreempt_trace_try_flip_ie1(struct rcupreempt_trace *trace); +-extern void rcupreempt_trace_try_flip_g1(struct rcupreempt_trace *trace); +-extern void rcupreempt_trace_try_flip_a1(struct rcupreempt_trace *trace); +-extern void rcupreempt_trace_try_flip_ae1(struct rcupreempt_trace *trace); +-extern void rcupreempt_trace_try_flip_a2(struct rcupreempt_trace *trace); +-extern void rcupreempt_trace_try_flip_z1(struct rcupreempt_trace *trace); +-extern void rcupreempt_trace_try_flip_ze1(struct rcupreempt_trace *trace); +-extern void rcupreempt_trace_try_flip_z2(struct rcupreempt_trace *trace); +-extern void rcupreempt_trace_try_flip_m1(struct rcupreempt_trace *trace); +-extern void rcupreempt_trace_try_flip_me1(struct rcupreempt_trace *trace); +-extern void rcupreempt_trace_try_flip_m2(struct rcupreempt_trace *trace); +-extern void rcupreempt_trace_check_callbacks(struct rcupreempt_trace *trace); +-extern void rcupreempt_trace_done_remove(struct rcupreempt_trace *trace); +-extern void rcupreempt_trace_invoke(struct rcupreempt_trace *trace); +-extern void rcupreempt_trace_next_add(struct rcupreempt_trace *trace); ++extern int *rcupreempt_flipctr(int cpu); ++extern long rcupreempt_data_completed(void); ++extern int rcupreempt_flip_flag(int cpu); ++extern int rcupreempt_mb_flag(int cpu); ++extern char *rcupreempt_try_flip_state_name(void); + + #endif /* __KERNEL__ */ + #endif /* __LINUX_RCUPREEMPT_TRACE_H */ +Index: linux-2.6.24.7-rt21/kernel/Kconfig.preempt +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/Kconfig.preempt 2008-10-08 22:24:32.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/Kconfig.preempt 2008-10-08 22:24:41.000000000 -0400 +@@ -172,14 +172,15 @@ config PREEMPT_RCU_BOOST + possible OOM problems. + + config RCU_TRACE +- bool "Enable tracing for RCU - currently stats in debugfs" ++ tristate "Enable tracing for RCU - currently stats in debugfs" + select DEBUG_FS +- default y ++ select MARKERS ++ default m + help + This option provides tracing in RCU which presents stats + in debugfs for debugging RCU implementation. + +- Say Y here if you want to enable RCU tracing ++ Say Y/M here if you want to enable RCU tracing in-kernel/module. + Say N if you are unsure. + + config SPINLOCK_BKL +Index: linux-2.6.24.7-rt21/kernel/rcupreempt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rcupreempt.c 2008-10-08 22:24:33.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rcupreempt.c 2008-10-08 22:24:41.000000000 -0400 +@@ -54,7 +54,6 @@ + #include + #include + #include +-#include + + /* + * PREEMPT_RCU data structures. +@@ -71,9 +70,6 @@ struct rcu_data { + struct rcu_head **waittail[GP_STAGES]; + struct rcu_head *donelist; + struct rcu_head **donetail; +-#ifdef CONFIG_RCU_TRACE +- struct rcupreempt_trace trace; +-#endif /* #ifdef CONFIG_RCU_TRACE */ + }; + struct rcu_ctrlblk { + raw_spinlock_t fliplock; /* Protect state-machine transitions. */ +@@ -97,10 +93,8 @@ enum rcu_try_flip_states { + rcu_try_flip_waitmb_state /* "M" */ + }; + static enum rcu_try_flip_states rcu_try_flip_state = rcu_try_flip_idle_state; +-#ifdef CONFIG_RCU_TRACE + static char *rcu_try_flip_state_names[] = + { "idle", "waitack", "waitzero", "waitmb" }; +-#endif /* #ifdef CONFIG_RCU_TRACE */ + + /* + * Enum and per-CPU flag to determine when each CPU has seen +@@ -147,24 +141,6 @@ static cpumask_t rcu_cpu_online_map = CP + #define RCU_DATA_CPU(cpu) (&per_cpu(rcu_data, cpu)) + + /* +- * Helper macro for tracing when the appropriate rcu_data is not +- * cached in a local variable, but where the CPU number is so cached. +- */ +-#define RCU_TRACE_CPU(f, cpu) RCU_TRACE(f, &(RCU_DATA_CPU(cpu)->trace)); +- +-/* +- * Helper macro for tracing when the appropriate rcu_data is not +- * cached in a local variable. +- */ +-#define RCU_TRACE_ME(f) RCU_TRACE(f, &(RCU_DATA_ME()->trace)); +- +-/* +- * Helper macro for tracing when the appropriate rcu_data is pointed +- * to by a local variable. +- */ +-#define RCU_TRACE_RDP(f, rdp) RCU_TRACE(f, &((rdp)->trace)); +- +-/* + * Return the number of RCU batches processed thus far. Useful + * for debug and statistics. + */ +@@ -332,7 +308,7 @@ static void __rcu_advance_callbacks(stru + if (rdp->waitlist[GP_STAGES - 1] != NULL) { + *rdp->donetail = rdp->waitlist[GP_STAGES - 1]; + rdp->donetail = rdp->waittail[GP_STAGES - 1]; +- RCU_TRACE_RDP(rcupreempt_trace_move2done, rdp); ++ trace_mark(rcupreempt_trace_move2done, "NULL"); + } + for (i = GP_STAGES - 2; i >= 0; i--) { + if (rdp->waitlist[i] != NULL) { +@@ -351,7 +327,7 @@ static void __rcu_advance_callbacks(stru + wlc++; + rdp->nextlist = NULL; + rdp->nexttail = &rdp->nextlist; +- RCU_TRACE_RDP(rcupreempt_trace_move2wait, rdp); ++ trace_mark(rcupreempt_trace_move2wait, "NULL"); + } else { + rdp->waitlist[0] = NULL; + rdp->waittail[0] = &rdp->waitlist[0]; +@@ -595,9 +571,9 @@ rcu_try_flip_idle(void) + { + int cpu; + +- RCU_TRACE_ME(rcupreempt_trace_try_flip_i1); ++ trace_mark(rcupreempt_trace_try_flip_i1, "NULL"); + if (!rcu_pending(smp_processor_id())) { +- RCU_TRACE_ME(rcupreempt_trace_try_flip_ie1); ++ trace_mark(rcupreempt_trace_try_flip_ie1, "NULL"); + return 0; + } + +@@ -605,7 +581,7 @@ rcu_try_flip_idle(void) + * Do the flip. + */ + +- RCU_TRACE_ME(rcupreempt_trace_try_flip_g1); ++ trace_mark(rcupreempt_trace_try_flip_g1, "NULL"); + rcu_ctrlblk.completed++; /* stands in for rcu_try_flip_g2 */ + + /* +@@ -635,11 +611,11 @@ rcu_try_flip_waitack(void) + { + int cpu; + +- RCU_TRACE_ME(rcupreempt_trace_try_flip_a1); ++ trace_mark(rcupreempt_trace_try_flip_a1, "NULL"); + for_each_cpu_mask(cpu, rcu_cpu_online_map) + if (rcu_try_flip_waitack_needed(cpu) && + per_cpu(rcu_flip_flag, cpu) != rcu_flip_seen) { +- RCU_TRACE_ME(rcupreempt_trace_try_flip_ae1); ++ trace_mark(rcupreempt_trace_try_flip_ae1, "NULL"); + return 0; + } + +@@ -649,7 +625,7 @@ rcu_try_flip_waitack(void) + */ + + smp_mb(); /* see above block comment. */ +- RCU_TRACE_ME(rcupreempt_trace_try_flip_a2); ++ trace_mark(rcupreempt_trace_try_flip_a2, "NULL"); + return 1; + } + +@@ -667,11 +643,11 @@ rcu_try_flip_waitzero(void) + + /* Check to see if the sum of the "last" counters is zero. */ + +- RCU_TRACE_ME(rcupreempt_trace_try_flip_z1); ++ trace_mark(rcupreempt_trace_try_flip_z1, "NULL"); + for_each_possible_cpu(cpu) + sum += per_cpu(rcu_flipctr, cpu)[lastidx]; + if (sum != 0) { +- RCU_TRACE_ME(rcupreempt_trace_try_flip_ze1); ++ trace_mark(rcupreempt_trace_try_flip_ze1, "NULL"); + return 0; + } + +@@ -684,7 +660,7 @@ rcu_try_flip_waitzero(void) + dyntick_save_progress_counter(cpu); + } + +- RCU_TRACE_ME(rcupreempt_trace_try_flip_z2); ++ trace_mark(rcupreempt_trace_try_flip_z2, "NULL"); + return 1; + } + +@@ -698,16 +674,16 @@ rcu_try_flip_waitmb(void) + { + int cpu; + +- RCU_TRACE_ME(rcupreempt_trace_try_flip_m1); ++ trace_mark(rcupreempt_trace_try_flip_m1, "NULL"); + for_each_cpu_mask(cpu, rcu_cpu_online_map) + if (rcu_try_flip_waitmb_needed(cpu) && + per_cpu(rcu_mb_flag, cpu) != rcu_mb_done) { +- RCU_TRACE_ME(rcupreempt_trace_try_flip_me1); ++ trace_mark(rcupreempt_trace_try_flip_me1, "NULL"); + return 0; + } + + smp_mb(); /* Ensure that the above checks precede any following flip. */ +- RCU_TRACE_ME(rcupreempt_trace_try_flip_m2); ++ trace_mark(rcupreempt_trace_try_flip_m2, "NULL"); + return 1; + } + +@@ -724,9 +700,9 @@ static void rcu_try_flip(void) + { + unsigned long oldirq; + +- RCU_TRACE_ME(rcupreempt_trace_try_flip_1); ++ trace_mark(rcupreempt_trace_try_flip_1, "NULL"); + if (unlikely(!spin_trylock_irqsave(&rcu_ctrlblk.fliplock, oldirq))) { +- RCU_TRACE_ME(rcupreempt_trace_try_flip_e1); ++ trace_mark(rcupreempt_trace_try_flip_e1, "NULL"); + return; + } + +@@ -778,7 +754,7 @@ void rcu_check_callbacks_rt(int cpu, int + if (rcu_ctrlblk.completed == rdp->completed) + rcu_try_flip(); + spin_lock_irqsave(&rdp->lock, oldirq); +- RCU_TRACE_RDP(rcupreempt_trace_check_callbacks, rdp); ++ trace_mark(rcupreempt_trace_check_callbacks, "NULL"); + __rcu_advance_callbacks(rdp); + spin_unlock_irqrestore(&rdp->lock, oldirq); + } +@@ -798,7 +774,7 @@ void rcu_advance_callbacks_rt(int cpu, i + return; + } + spin_lock_irqsave(&rdp->lock, oldirq); +- RCU_TRACE_RDP(rcupreempt_trace_check_callbacks, rdp); ++ trace_mark(rcupreempt_trace_check_callbacks, "NULL"); + __rcu_advance_callbacks(rdp); + spin_unlock_irqrestore(&rdp->lock, oldirq); + } +@@ -900,13 +876,13 @@ void rcu_process_callbacks_rt(struct sof + } + rdp->donelist = NULL; + rdp->donetail = &rdp->donelist; +- RCU_TRACE_RDP(rcupreempt_trace_done_remove, rdp); ++ trace_mark(rcupreempt_trace_done_remove, "NULL"); + spin_unlock_irqrestore(&rdp->lock, flags); + while (list) { + next = list->next; + list->func(list); + list = next; +- RCU_TRACE_ME(rcupreempt_trace_invoke); ++ trace_mark(rcupreempt_trace_invoke, "NULL"); + } + } + +@@ -924,7 +900,7 @@ void fastcall call_rcu_preempt(struct rc + __rcu_advance_callbacks(rdp); + *rdp->nexttail = head; + rdp->nexttail = &head->next; +- RCU_TRACE_RDP(rcupreempt_trace_next_add, rdp); ++ trace_mark(rcupreempt_trace_next_add, "NULL"); + spin_unlock(&rdp->lock); + local_irq_restore(oldirq); + } +@@ -1006,7 +982,6 @@ void synchronize_kernel(void) + synchronize_rcu(); + } + +-#ifdef CONFIG_RCU_TRACE + int *rcupreempt_flipctr(int cpu) + { + return &per_cpu(rcu_flipctr, cpu)[0]; +@@ -1030,13 +1005,3 @@ char *rcupreempt_try_flip_state_name(voi + return rcu_try_flip_state_names[rcu_try_flip_state]; + } + EXPORT_SYMBOL_GPL(rcupreempt_try_flip_state_name); +- +-struct rcupreempt_trace *rcupreempt_trace_cpu(int cpu) +-{ +- struct rcu_data *rdp = RCU_DATA_CPU(cpu); +- +- return &rdp->trace; +-} +-EXPORT_SYMBOL_GPL(rcupreempt_trace_cpu); +- +-#endif /* #ifdef RCU_TRACE */ +Index: linux-2.6.24.7-rt21/kernel/rcupreempt_trace.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/rcupreempt_trace.c 2008-10-08 22:24:32.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/rcupreempt_trace.c 2008-10-08 22:24:41.000000000 -0400 +@@ -43,11 +43,19 @@ + #include + #include + #include ++#include + + static struct mutex rcupreempt_trace_mutex; + static char *rcupreempt_trace_buf; + #define RCUPREEMPT_TRACE_BUF_SIZE 4096 + ++static DEFINE_PER_CPU(struct rcupreempt_trace, trace_data); ++ ++struct rcupreempt_trace *rcupreempt_trace_cpu(int cpu) ++{ ++ return &per_cpu(trace_data, cpu); ++} ++ + void rcupreempt_trace_move2done(struct rcupreempt_trace *trace) + { + trace->done_length += trace->wait_length; +@@ -135,6 +143,51 @@ void rcupreempt_trace_next_add(struct rc + trace->next_length++; + } + ++DEFINE_RCUPREEMPT_MARKER_HANDLER(rcupreempt_trace_move2done); ++DEFINE_RCUPREEMPT_MARKER_HANDLER(rcupreempt_trace_move2wait); ++DEFINE_RCUPREEMPT_MARKER_HANDLER(rcupreempt_trace_try_flip_1); ++DEFINE_RCUPREEMPT_MARKER_HANDLER(rcupreempt_trace_try_flip_e1); ++DEFINE_RCUPREEMPT_MARKER_HANDLER(rcupreempt_trace_try_flip_i1); ++DEFINE_RCUPREEMPT_MARKER_HANDLER(rcupreempt_trace_try_flip_ie1); ++DEFINE_RCUPREEMPT_MARKER_HANDLER(rcupreempt_trace_try_flip_g1); ++DEFINE_RCUPREEMPT_MARKER_HANDLER(rcupreempt_trace_try_flip_a1); ++DEFINE_RCUPREEMPT_MARKER_HANDLER(rcupreempt_trace_try_flip_ae1); ++DEFINE_RCUPREEMPT_MARKER_HANDLER(rcupreempt_trace_try_flip_a2); ++DEFINE_RCUPREEMPT_MARKER_HANDLER(rcupreempt_trace_try_flip_z1); ++DEFINE_RCUPREEMPT_MARKER_HANDLER(rcupreempt_trace_try_flip_ze1); ++DEFINE_RCUPREEMPT_MARKER_HANDLER(rcupreempt_trace_try_flip_z2); ++DEFINE_RCUPREEMPT_MARKER_HANDLER(rcupreempt_trace_try_flip_m1); ++DEFINE_RCUPREEMPT_MARKER_HANDLER(rcupreempt_trace_try_flip_me1); ++DEFINE_RCUPREEMPT_MARKER_HANDLER(rcupreempt_trace_try_flip_m2); ++DEFINE_RCUPREEMPT_MARKER_HANDLER(rcupreempt_trace_check_callbacks); ++DEFINE_RCUPREEMPT_MARKER_HANDLER(rcupreempt_trace_done_remove); ++DEFINE_RCUPREEMPT_MARKER_HANDLER(rcupreempt_trace_invoke); ++DEFINE_RCUPREEMPT_MARKER_HANDLER(rcupreempt_trace_next_add); ++ ++static struct rcupreempt_probe_data rcupreempt_probe_array[] = ++{ ++ INIT_RCUPREEMPT_PROBE(rcupreempt_trace_move2done), ++ INIT_RCUPREEMPT_PROBE(rcupreempt_trace_move2wait), ++ INIT_RCUPREEMPT_PROBE(rcupreempt_trace_try_flip_1), ++ INIT_RCUPREEMPT_PROBE(rcupreempt_trace_try_flip_e1), ++ INIT_RCUPREEMPT_PROBE(rcupreempt_trace_try_flip_i1), ++ INIT_RCUPREEMPT_PROBE(rcupreempt_trace_try_flip_ie1), ++ INIT_RCUPREEMPT_PROBE(rcupreempt_trace_try_flip_g1), ++ INIT_RCUPREEMPT_PROBE(rcupreempt_trace_try_flip_a1), ++ INIT_RCUPREEMPT_PROBE(rcupreempt_trace_try_flip_ae1), ++ INIT_RCUPREEMPT_PROBE(rcupreempt_trace_try_flip_a2), ++ INIT_RCUPREEMPT_PROBE(rcupreempt_trace_try_flip_z1), ++ INIT_RCUPREEMPT_PROBE(rcupreempt_trace_try_flip_ze1), ++ INIT_RCUPREEMPT_PROBE(rcupreempt_trace_try_flip_z2), ++ INIT_RCUPREEMPT_PROBE(rcupreempt_trace_try_flip_m1), ++ INIT_RCUPREEMPT_PROBE(rcupreempt_trace_try_flip_me1), ++ INIT_RCUPREEMPT_PROBE(rcupreempt_trace_try_flip_m2), ++ INIT_RCUPREEMPT_PROBE(rcupreempt_trace_check_callbacks), ++ INIT_RCUPREEMPT_PROBE(rcupreempt_trace_done_remove), ++ INIT_RCUPREEMPT_PROBE(rcupreempt_trace_invoke), ++ INIT_RCUPREEMPT_PROBE(rcupreempt_trace_next_add) ++}; ++ + static void rcupreempt_trace_sum(struct rcupreempt_trace *sp) + { + struct rcupreempt_trace *cp; +@@ -297,9 +350,6 @@ static int rcupreempt_debugfs_init(void) + if (!ctrsdir) + goto free_out; + +- if (!rcu_trace_boost_create(rcudir)) +- goto free_out; +- + return 0; + free_out: + if (ctrsdir) +@@ -316,6 +366,21 @@ out: + static int __init rcupreempt_trace_init(void) + { + int ret; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(rcupreempt_probe_array); i++) { ++ struct rcupreempt_probe_data *p = &rcupreempt_probe_array[i]; ++ ret = marker_probe_register(p->name, p->format, ++ p->probe_func, p); ++ if (ret) ++ printk(KERN_INFO "Unable to register rcupreempt \ ++ probe %s\n", rcupreempt_probe_array[i].name); ++ ret = marker_arm(p->name); ++ if (ret) ++ printk(KERN_INFO "Unable to arm rcupreempt probe %s\n", ++ p->name); ++ } ++ printk(KERN_INFO "RCU Preempt markers registered\n"); + + mutex_init(&rcupreempt_trace_mutex); + rcupreempt_trace_buf = kmalloc(RCUPREEMPT_TRACE_BUF_SIZE, GFP_KERNEL); +@@ -329,7 +394,12 @@ static int __init rcupreempt_trace_init( + + static void __exit rcupreempt_trace_cleanup(void) + { +- rcu_trace_boost_destroy(); ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(rcupreempt_probe_array); i++) ++ marker_probe_unregister(rcupreempt_probe_array[i].name); ++ printk(KERN_INFO "RCU Preempt markers unregistered\n"); ++ + debugfs_remove(statdir); + debugfs_remove(gpdir); + debugfs_remove(ctrsdir); +@@ -337,6 +407,7 @@ static void __exit rcupreempt_trace_clea + kfree(rcupreempt_trace_buf); + } + ++MODULE_LICENSE("GPL"); + + module_init(rcupreempt_trace_init); + module_exit(rcupreempt_trace_cleanup); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0548-7205656ab48da29a95d7f55e43a81db755d3cb3a.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0548-7205656ab48da29a95d7f55e43a81db755d3cb3a.patch @@ -0,0 +1,65 @@ +commit 7205656ab48da29a95d7f55e43a81db755d3cb3a +Author: Thomas Gleixner +Date: Wed Sep 3 21:37:03 2008 +0000 + + clockevents: enforce reprogram in oneshot setup + + In tick_oneshot_setup we program the device to the given next_event, + but we do not check the return value. We need to make sure that the + device is programmed enforced so the interrupt handler engine starts + working. Split out the reprogramming function from tick_program_event() + and call it with the device, which was handed in to tick_setup_oneshot(). + Set the force argument, so the devices is firing an interrupt. + + Signed-off-by: Thomas Gleixner + Signed-off-by: Ingo Molnar + +--- + kernel/time/tick-oneshot.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/time/tick-oneshot.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/time/tick-oneshot.c 2008-10-08 22:22:08.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/time/tick-oneshot.c 2008-10-08 22:25:16.000000000 -0400 +@@ -23,11 +23,11 @@ + #include "tick-internal.h" + + /** +- * tick_program_event ++ * tick_program_event internal worker function + */ +-int tick_program_event(ktime_t expires, int force) ++static int __tick_program_event(struct clock_event_device *dev, ++ ktime_t expires, int force) + { +- struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev; + ktime_t now = ktime_get(); + + while (1) { +@@ -41,6 +41,16 @@ int tick_program_event(ktime_t expires, + } + + /** ++ * tick_program_event ++ */ ++int tick_program_event(ktime_t expires, int force) ++{ ++ struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev; ++ ++ return __tick_program_event(dev, expires, force); ++} ++ ++/** + * tick_resume_onshot - resume oneshot mode + */ + void tick_resume_oneshot(void) +@@ -61,7 +71,7 @@ void tick_setup_oneshot(struct clock_eve + { + newdev->event_handler = handler; + clockevents_set_mode(newdev, CLOCK_EVT_MODE_ONESHOT); +- clockevents_program_event(newdev, next_event, ktime_get()); ++ __tick_program_event(newdev, next_event, 1); + } + + /** --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0541-futex-fifo-warn-sysctl.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0541-futex-fifo-warn-sysctl.patch @@ -0,0 +1,65 @@ +--- + include/linux/futex.h | 1 + + kernel/futex.c | 10 ++++++++++ + kernel/sysctl.c | 8 ++++++++ + 3 files changed, 19 insertions(+) + +Index: linux-2.6.24.7-rt21/kernel/futex.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/futex.c 2008-10-08 22:24:33.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/futex.c 2008-10-08 22:25:14.000000000 -0400 +@@ -61,6 +61,7 @@ + #include "rtmutex_common.h" + + int __read_mostly futex_cmpxchg_enabled; ++int __read_mostly futex_rt_pi_warning; + + #define FUTEX_HASHBITS (CONFIG_BASE_SMALL ? 4 : 8) + +@@ -1243,6 +1244,15 @@ static int futex_wait(u32 __user *uaddr, + + hb = queue_lock(&q, -1, NULL); + ++ if (futex_rt_pi_warning && unlikely(rt_task(curr))) { ++ if (printk_ratelimit()) { ++ printk(KERN_WARNING ++ "RT task %s:%d with priority %d" ++ " using non PI futex\n", ++ current->comm, current->pid, ++ 100 - current->prio); ++ } ++ } + /* + * Access the page AFTER the futex is queued. + * Order is important: +Index: linux-2.6.24.7-rt21/include/linux/futex.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/futex.h 2008-10-08 22:22:08.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/futex.h 2008-10-08 22:25:14.000000000 -0400 +@@ -154,6 +154,7 @@ union futex_key { + extern void exit_robust_list(struct task_struct *curr); + extern void exit_pi_state_list(struct task_struct *curr); + extern int futex_cmpxchg_enabled; ++extern int futex_rt_pi_warning; + #else + static inline void exit_robust_list(struct task_struct *curr) + { +Index: linux-2.6.24.7-rt21/kernel/sysctl.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/sysctl.c 2008-10-08 22:24:52.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/sysctl.c 2008-10-08 22:25:14.000000000 -0400 +@@ -354,6 +354,14 @@ static struct ctl_table kern_table[] = { + .mode = 0644, + .proc_handler = &proc_dointvec, + }, ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "futex_rt_pi_warning", ++ .data = &futex_rt_pi_warning, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = &proc_dointvec, ++ }, + #endif + { + .ctl_name = CTL_UNNUMBERED, --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0547-d4496b39559c6d43f83e4c08b899984f8b8089b5.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0547-d4496b39559c6d43f83e4c08b899984f8b8089b5.patch @@ -0,0 +1,50 @@ +commit d4496b39559c6d43f83e4c08b899984f8b8089b5 +Author: Thomas Gleixner +Date: Wed Sep 3 21:36:57 2008 +0000 + + clockevents: prevent endless loop in periodic broadcast handler + + The reprogramming of the periodic broadcast handler was broken, + when the first programming returned -ETIME. The clockevents code + stores the new expiry value in the clock events device next_event field + only when the programming time has not been elapsed yet. The loop in + question calculates the new expiry value from the next_event value + and therefor never increases. + + Signed-off-by: Thomas Gleixner + Signed-off-by: Ingo Molnar + +--- + kernel/time/tick-broadcast.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +Index: linux-2.6.24.7-rt21/kernel/time/tick-broadcast.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/time/tick-broadcast.c 2008-10-08 22:24:04.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/time/tick-broadcast.c 2008-10-08 22:25:15.000000000 -0400 +@@ -177,6 +177,8 @@ static void tick_do_periodic_broadcast(v + */ + static void tick_handle_periodic_broadcast(struct clock_event_device *dev) + { ++ ktime_t next; ++ + tick_do_periodic_broadcast(); + + /* +@@ -187,10 +189,13 @@ static void tick_handle_periodic_broadca + + /* + * Setup the next period for devices, which do not have +- * periodic mode: ++ * periodic mode. We read dev->next_event first and add to it ++ * when the event alrady expired. clockevents_program_event() ++ * sets dev->next_event only when the event is really ++ * programmed to the device. + */ +- for (;;) { +- ktime_t next = ktime_add(dev->next_event, tick_period); ++ for (next = dev->next_event; ;) { ++ next = ktime_add(next, tick_period); + + if (!clockevents_program_event(dev, next, ktime_get())) + return; --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0244-preempt-realtime-acpi.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0244-preempt-realtime-acpi.patch @@ -0,0 +1,142 @@ +--- + drivers/acpi/ec.c | 12 ++++++++++++ + drivers/acpi/hardware/hwregs.c | 12 ++++++------ + drivers/acpi/processor_idle.c | 2 +- + drivers/acpi/utilities/utmutex.c | 2 +- + include/acpi/acglobal.h | 7 ++++++- + include/acpi/acpiosxf.h | 2 +- + 6 files changed, 27 insertions(+), 10 deletions(-) + +Index: linux-2.6.24.7-rt21/drivers/acpi/ec.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/acpi/ec.c 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/acpi/ec.c 2008-10-08 22:24:00.000000000 -0400 +@@ -531,7 +531,19 @@ static u32 acpi_ec_gpe_handler(void *dat + pr_debug(PREFIX "~~~> interrupt\n"); + clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); + if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) ++#if 0 + wake_up(&ec->wait); ++#else ++ // hack ... ++ if (waitqueue_active(&ec->wait)) { ++ struct task_struct *task; ++ ++ task = list_entry(ec->wait.task_list.next, ++ wait_queue_t, task_list)->private; ++ if (task) ++ wake_up_process(task); ++ } ++#endif + + if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_SCI) { + if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) +Index: linux-2.6.24.7-rt21/drivers/acpi/hardware/hwregs.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/acpi/hardware/hwregs.c 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/acpi/hardware/hwregs.c 2008-10-08 22:24:00.000000000 -0400 +@@ -73,7 +73,7 @@ acpi_status acpi_hw_clear_acpi_status(vo + ACPI_BITMASK_ALL_FIXED_STATUS, + (u16) acpi_gbl_FADT.xpm1a_event_block.address)); + +- lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); ++ spin_lock_irqsave(acpi_gbl_hardware_lock, lock_flags); + + status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, + ACPI_BITMASK_ALL_FIXED_STATUS); +@@ -97,7 +97,7 @@ acpi_status acpi_hw_clear_acpi_status(vo + status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block); + + unlock_and_exit: +- acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); ++ spin_unlock_irqrestore(acpi_gbl_hardware_lock, lock_flags); + return_ACPI_STATUS(status); + } + +@@ -300,9 +300,9 @@ acpi_status acpi_get_register(u32 regist + { + acpi_status status; + acpi_cpu_flags flags; +- flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); ++ spin_lock_irqsave(acpi_gbl_hardware_lock, flags); + status = acpi_get_register_unlocked(register_id, return_value); +- acpi_os_release_lock(acpi_gbl_hardware_lock, flags); ++ spin_unlock_irqrestore(acpi_gbl_hardware_lock, flags); + return status; + } + +@@ -339,7 +339,7 @@ acpi_status acpi_set_register(u32 regist + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + +- lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); ++ spin_lock_irqsave(acpi_gbl_hardware_lock, lock_flags); + + /* Always do a register read first so we can insert the new bits */ + +@@ -443,7 +443,7 @@ acpi_status acpi_set_register(u32 regist + + unlock_and_exit: + +- acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); ++ spin_unlock_irqrestore(acpi_gbl_hardware_lock, lock_flags); + + /* Normalize the value that was read */ + +Index: linux-2.6.24.7-rt21/drivers/acpi/processor_idle.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/acpi/processor_idle.c 2008-10-08 22:23:37.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/acpi/processor_idle.c 2008-10-08 22:24:00.000000000 -0400 +@@ -1461,7 +1461,7 @@ static int acpi_idle_enter_simple(struct + } + + static int c3_cpu_count; +-static DEFINE_SPINLOCK(c3_lock); ++static DEFINE_RAW_SPINLOCK(c3_lock); + + /** + * acpi_idle_enter_bm - enters C3 with proper BM handling +Index: linux-2.6.24.7-rt21/drivers/acpi/utilities/utmutex.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/acpi/utilities/utmutex.c 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/acpi/utilities/utmutex.c 2008-10-08 22:24:00.000000000 -0400 +@@ -116,7 +116,7 @@ void acpi_ut_mutex_terminate(void) + /* Delete the spinlocks */ + + acpi_os_delete_lock(acpi_gbl_gpe_lock); +- acpi_os_delete_lock(acpi_gbl_hardware_lock); ++// acpi_os_delete_lock(acpi_gbl_hardware_lock); + return_VOID; + } + +Index: linux-2.6.24.7-rt21/include/acpi/acglobal.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/acpi/acglobal.h 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/acpi/acglobal.h 2008-10-08 22:24:00.000000000 -0400 +@@ -184,7 +184,12 @@ ACPI_EXTERN acpi_semaphore acpi_gbl_glob + * interrupt level + */ + ACPI_EXTERN spinlock_t _acpi_gbl_gpe_lock; /* For GPE data structs and registers */ +-ACPI_EXTERN spinlock_t _acpi_gbl_hardware_lock; /* For ACPI H/W except GPE registers */ ++ ++/* ++ * Need to be raw because it might be used in acpi_processor_idle(): ++ */ ++ACPI_EXTERN raw_spinlock_t _acpi_gbl_hardware_lock; /* For ACPI H/W except GPE registers */ ++ + #define acpi_gbl_gpe_lock &_acpi_gbl_gpe_lock + #define acpi_gbl_hardware_lock &_acpi_gbl_hardware_lock + +Index: linux-2.6.24.7-rt21/include/acpi/acpiosxf.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/acpi/acpiosxf.h 2008-10-08 22:22:28.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/acpi/acpiosxf.h 2008-10-08 22:24:00.000000000 -0400 +@@ -61,7 +61,7 @@ typedef enum { + OSL_EC_BURST_HANDLER + } acpi_execute_type; + +-#define ACPI_NO_UNIT_LIMIT ((u32) -1) ++#define ACPI_NO_UNIT_LIMIT (INT_MAX/2) + #define ACPI_MUTEX_SEM 1 + + /* Functions for acpi_os_signal */ --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0230-preempt-realtime-sh.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0230-preempt-realtime-sh.patch @@ -0,0 +1,1051 @@ +From lethal@linux-sh.org Fri Apr 27 10:21:47 2007 +Date: Fri, 27 Apr 2007 10:21:47 +0900 +From: Paul Mundt +To: Thomas Gleixner , Ingo Molnar +Subject: [PATCH] preempt-rt: Preliminary SH support + +Hi Thomas, Ingo, + +Here's preliminary preempt-rt support for SH. It was written against +2.6.21-rc5, but still applies cleanly. I've kept the clock events stuff +out of this patch, since I'm planning on overhauling the timer stuff on +SH first, but this should trickle in through 2.6.22-rc. + +Feel free to either merge this in to preempt-rt or hold off until the +timer stuff gets done. + +Patch from Matsubara-san. + +Signed-off-by: Katsuya MATSUBARA +Signed-off-by: Paul Mundt + +-- + + arch/sh/kernel/cpu/clock.c | 2 - + arch/sh/kernel/cpu/sh4/sq.c | 2 - + arch/sh/kernel/entry-common.S | 8 ++--- + arch/sh/kernel/irq.c | 2 - + arch/sh/kernel/process.c | 10 +++--- + arch/sh/kernel/semaphore.c | 14 ++++++--- + arch/sh/kernel/sh_ksyms.c | 9 ++--- + arch/sh/kernel/signal.c | 7 ++++ + arch/sh/kernel/time.c | 2 - + arch/sh/kernel/traps.c | 2 - + arch/sh/mm/cache-sh4.c | 12 +++---- + arch/sh/mm/init.c | 2 - + arch/sh/mm/pg-sh4.c | 4 +- + arch/sh/mm/tlb-flush.c | 20 ++++++------ + arch/sh/mm/tlb-sh4.c | 4 +- + include/asm-sh/atomic-irq.h | 24 +++++++-------- + include/asm-sh/atomic.h | 8 ++--- + include/asm-sh/bitops.h | 24 +++++++-------- + include/asm-sh/pgalloc.h | 2 - + include/asm-sh/rwsem.h | 46 ++++++++++++++--------------- + include/asm-sh/semaphore-helper.h | 8 ++--- + include/asm-sh/semaphore.h | 59 +++++++++++++++++++++++--------------- + include/asm-sh/system.h | 12 +++---- + include/asm-sh/thread_info.h | 2 + + 24 files changed, 157 insertions(+), 128 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/sh/kernel/cpu/clock.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/sh/kernel/cpu/clock.c 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/sh/kernel/cpu/clock.c 2008-10-08 22:23:56.000000000 -0400 +@@ -28,7 +28,7 @@ + #include + + static LIST_HEAD(clock_list); +-static DEFINE_SPINLOCK(clock_lock); ++static DEFINE_RAW_SPINLOCK(clock_lock); + static DEFINE_MUTEX(clock_list_sem); + + /* +Index: linux-2.6.24.7-rt21/arch/sh/kernel/cpu/sh4/sq.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/sh/kernel/cpu/sh4/sq.c 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/sh/kernel/cpu/sh4/sq.c 2008-10-08 22:23:56.000000000 -0400 +@@ -37,7 +37,7 @@ struct sq_mapping { + }; + + static struct sq_mapping *sq_mapping_list; +-static DEFINE_SPINLOCK(sq_mapping_lock); ++static DEFINE_RAW_SPINLOCK(sq_mapping_lock); + static struct kmem_cache *sq_cache; + static unsigned long *sq_bitmap; + +Index: linux-2.6.24.7-rt21/arch/sh/kernel/entry-common.S +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/sh/kernel/entry-common.S 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/sh/kernel/entry-common.S 2008-10-08 22:23:56.000000000 -0400 +@@ -157,7 +157,7 @@ ENTRY(resume_userspace) + mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags + tst #_TIF_WORK_MASK, r0 + bt/s __restore_all +- tst #_TIF_NEED_RESCHED, r0 ++ tst #_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED, r0 + + .align 2 + work_pending: +@@ -209,10 +209,10 @@ work_resched: + tst #_TIF_WORK_MASK, r0 + bt __restore_all + bra work_pending +- tst #_TIF_NEED_RESCHED, r0 ++ tst #_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_DELAYED, r0 + + .align 2 +-1: .long schedule ++1: .long __schedule + 2: .long do_notify_resume + 3: .long restore_all + #ifdef CONFIG_TRACE_IRQFLAGS +@@ -226,7 +226,7 @@ syscall_exit_work: + ! r8: current_thread_info + tst #_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP, r0 + bt/s work_pending +- tst #_TIF_NEED_RESCHED, r0 ++ tst #_TIF_NEED_RESCHED| _TIF_NEED_RESCHED_DELAYED, r0 + #ifdef CONFIG_TRACE_IRQFLAGS + mov.l 5f, r0 + jsr @r0 +Index: linux-2.6.24.7-rt21/arch/sh/kernel/irq.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/sh/kernel/irq.c 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/sh/kernel/irq.c 2008-10-08 22:23:56.000000000 -0400 +@@ -81,7 +81,7 @@ static union irq_ctx *hardirq_ctx[NR_CPU + static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly; + #endif + +-asmlinkage int do_IRQ(unsigned int irq, struct pt_regs *regs) ++asmlinkage notrace int do_IRQ(unsigned int irq, struct pt_regs *regs) + { + struct pt_regs *old_regs = set_irq_regs(regs); + #ifdef CONFIG_IRQSTACKS +Index: linux-2.6.24.7-rt21/arch/sh/kernel/process.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/sh/kernel/process.c 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/sh/kernel/process.c 2008-10-08 22:23:56.000000000 -0400 +@@ -65,7 +65,7 @@ void default_idle(void) + clear_thread_flag(TIF_POLLING_NRFLAG); + smp_mb__after_clear_bit(); + set_bl_bit(); +- while (!need_resched()) ++ while (!need_resched() && !need_resched_delayed()) + cpu_sleep(); + clear_bl_bit(); + set_thread_flag(TIF_POLLING_NRFLAG); +@@ -86,13 +86,15 @@ void cpu_idle(void) + idle = default_idle; + + tick_nohz_stop_sched_tick(); +- while (!need_resched()) ++ while (!need_resched() && !need_resched_delayed()) + idle(); + tick_nohz_restart_sched_tick(); + +- preempt_enable_no_resched(); +- schedule(); ++ local_irq_disable(); ++ __preempt_enable_no_resched(); ++ __schedule(); + preempt_disable(); ++ local_irq_enable(); + check_pgt_cache(); + } + } +Index: linux-2.6.24.7-rt21/arch/sh/kernel/semaphore.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/sh/kernel/semaphore.c 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/sh/kernel/semaphore.c 2008-10-08 22:23:56.000000000 -0400 +@@ -46,7 +46,7 @@ DEFINE_SPINLOCK(semaphore_wake_lock); + * critical part is the inline stuff in + * where we want to avoid any extra jumps and calls. + */ +-void __up(struct semaphore *sem) ++void __attribute_used__ __compat_up(struct compat_semaphore *sem) + { + wake_one_more(sem); + wake_up(&sem->wait); +@@ -104,7 +104,7 @@ void __up(struct semaphore *sem) + tsk->state = TASK_RUNNING; \ + remove_wait_queue(&sem->wait, &wait); + +-void __sched __down(struct semaphore * sem) ++void __attribute_used__ __sched __compat_down(struct compat_semaphore * sem) + { + DOWN_VAR + DOWN_HEAD(TASK_UNINTERRUPTIBLE) +@@ -114,7 +114,7 @@ void __sched __down(struct semaphore * s + DOWN_TAIL(TASK_UNINTERRUPTIBLE) + } + +-int __sched __down_interruptible(struct semaphore * sem) ++int __attribute_used__ __sched __compat_down_interruptible(struct compat_semaphore * sem) + { + int ret = 0; + DOWN_VAR +@@ -133,7 +133,13 @@ int __sched __down_interruptible(struct + return ret; + } + +-int __down_trylock(struct semaphore * sem) ++int __attribute_used__ __compat_down_trylock(struct compat_semaphore * sem) + { + return waking_non_zero_trylock(sem); + } ++ ++fastcall int __sched compat_sem_is_locked(struct compat_semaphore *sem) ++{ ++ return (int) atomic_read(&sem->count) < 0; ++} ++ +Index: linux-2.6.24.7-rt21/arch/sh/kernel/sh_ksyms.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/sh/kernel/sh_ksyms.c 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/sh/kernel/sh_ksyms.c 2008-10-08 22:23:56.000000000 -0400 +@@ -26,7 +26,6 @@ EXPORT_SYMBOL(sh_mv); + /* platform dependent support */ + EXPORT_SYMBOL(dump_fpu); + EXPORT_SYMBOL(kernel_thread); +-EXPORT_SYMBOL(irq_desc); + EXPORT_SYMBOL(no_irq_type); + + EXPORT_SYMBOL(strlen); +@@ -49,10 +48,10 @@ EXPORT_SYMBOL(get_vm_area); + #endif + + /* semaphore exports */ +-EXPORT_SYMBOL(__up); +-EXPORT_SYMBOL(__down); +-EXPORT_SYMBOL(__down_interruptible); +-EXPORT_SYMBOL(__down_trylock); ++EXPORT_SYMBOL(__compat_up); ++EXPORT_SYMBOL(__compat_down); ++EXPORT_SYMBOL(__compat_down_interruptible); ++EXPORT_SYMBOL(__compat_down_trylock); + + EXPORT_SYMBOL(__udelay); + EXPORT_SYMBOL(__ndelay); +Index: linux-2.6.24.7-rt21/arch/sh/kernel/signal.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/sh/kernel/signal.c 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/sh/kernel/signal.c 2008-10-08 22:23:56.000000000 -0400 +@@ -564,6 +564,13 @@ static void do_signal(struct pt_regs *re + struct k_sigaction ka; + sigset_t *oldset; + ++#ifdef CONFIG_PREEMPT_RT ++ /* ++ * Fully-preemptible kernel does not need interrupts disabled: ++ */ ++ raw_local_irq_enable(); ++ preempt_check_resched(); ++#endif + /* + * We want the common case to go fast, which + * is why we may in certain cases get here from +Index: linux-2.6.24.7-rt21/arch/sh/kernel/time.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/sh/kernel/time.c 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/sh/kernel/time.c 2008-10-08 22:23:56.000000000 -0400 +@@ -24,7 +24,7 @@ + struct sys_timer *sys_timer; + + /* Move this somewhere more sensible.. */ +-DEFINE_SPINLOCK(rtc_lock); ++DEFINE_RAW_SPINLOCK(rtc_lock); + EXPORT_SYMBOL(rtc_lock); + + /* Dummy RTC ops */ +Index: linux-2.6.24.7-rt21/arch/sh/kernel/traps.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/sh/kernel/traps.c 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/sh/kernel/traps.c 2008-10-08 22:23:56.000000000 -0400 +@@ -77,7 +77,7 @@ static void dump_mem(const char *str, un + } + } + +-static DEFINE_SPINLOCK(die_lock); ++static DEFINE_RAW_SPINLOCK(die_lock); + + void die(const char * str, struct pt_regs * regs, long err) + { +Index: linux-2.6.24.7-rt21/arch/sh/mm/cache-sh4.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/sh/mm/cache-sh4.c 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/sh/mm/cache-sh4.c 2008-10-08 22:23:56.000000000 -0400 +@@ -204,7 +204,7 @@ void flush_cache_sigtramp(unsigned long + index = CACHE_IC_ADDRESS_ARRAY | + (v & boot_cpu_data.icache.entry_mask); + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + jump_to_P2(); + + for (i = 0; i < boot_cpu_data.icache.ways; +@@ -213,7 +213,7 @@ void flush_cache_sigtramp(unsigned long + + back_to_P1(); + wmb(); +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } + + static inline void flush_cache_4096(unsigned long start, +@@ -229,10 +229,10 @@ static inline void flush_cache_4096(unsi + (start < CACHE_OC_ADDRESS_ARRAY)) + exec_offset = 0x20000000; + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + __flush_cache_4096(start | SH_CACHE_ASSOC, + P1SEGADDR(phys), exec_offset); +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } + + /* +@@ -260,7 +260,7 @@ static inline void flush_icache_all(void + { + unsigned long flags, ccr; + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + jump_to_P2(); + + /* Flush I-cache */ +@@ -274,7 +274,7 @@ static inline void flush_icache_all(void + */ + + back_to_P1(); +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } + + void flush_dcache_all(void) +Index: linux-2.6.24.7-rt21/arch/sh/mm/init.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/sh/mm/init.c 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/sh/mm/init.c 2008-10-08 22:23:56.000000000 -0400 +@@ -21,7 +21,7 @@ + #include + #include + +-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); ++DEFINE_PER_CPU_LOCKED(struct mmu_gather, mmu_gathers); + pgd_t swapper_pg_dir[PTRS_PER_PGD]; + + void (*copy_page)(void *from, void *to); +Index: linux-2.6.24.7-rt21/arch/sh/mm/pg-sh4.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/sh/mm/pg-sh4.c 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/sh/mm/pg-sh4.c 2008-10-08 22:23:56.000000000 -0400 +@@ -28,9 +28,9 @@ static inline void *kmap_coherent(struct + vaddr = __fix_to_virt(FIX_CMAP_END - idx); + pte = mk_pte(page, PAGE_KERNEL); + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + flush_tlb_one(get_asid(), vaddr); +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + + update_mmu_cache(NULL, vaddr, pte); + +Index: linux-2.6.24.7-rt21/arch/sh/mm/tlb-flush.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/sh/mm/tlb-flush.c 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/sh/mm/tlb-flush.c 2008-10-08 22:23:56.000000000 -0400 +@@ -24,7 +24,7 @@ void local_flush_tlb_page(struct vm_area + asid = cpu_asid(cpu, vma->vm_mm); + page &= PAGE_MASK; + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + if (vma->vm_mm != current->mm) { + saved_asid = get_asid(); + set_asid(asid); +@@ -32,7 +32,7 @@ void local_flush_tlb_page(struct vm_area + local_flush_tlb_one(asid, page); + if (saved_asid != MMU_NO_ASID) + set_asid(saved_asid); +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } + } + +@@ -46,7 +46,7 @@ void local_flush_tlb_range(struct vm_are + unsigned long flags; + int size; + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + if (size > (MMU_NTLB_ENTRIES/4)) { /* Too many TLB to flush */ + cpu_context(cpu, mm) = NO_CONTEXT; +@@ -71,7 +71,7 @@ void local_flush_tlb_range(struct vm_are + if (saved_asid != MMU_NO_ASID) + set_asid(saved_asid); + } +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } + } + +@@ -81,7 +81,7 @@ void local_flush_tlb_kernel_range(unsign + unsigned long flags; + int size; + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + if (size > (MMU_NTLB_ENTRIES/4)) { /* Too many TLB to flush */ + local_flush_tlb_all(); +@@ -100,7 +100,7 @@ void local_flush_tlb_kernel_range(unsign + } + set_asid(saved_asid); + } +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } + + void local_flush_tlb_mm(struct mm_struct *mm) +@@ -112,11 +112,11 @@ void local_flush_tlb_mm(struct mm_struct + if (cpu_context(cpu, mm) != NO_CONTEXT) { + unsigned long flags; + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + cpu_context(cpu, mm) = NO_CONTEXT; + if (mm == current->mm) + activate_context(mm, cpu); +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } + } + +@@ -131,10 +131,10 @@ void local_flush_tlb_all(void) + * TF-bit for SH-3, TI-bit for SH-4. + * It's same position, bit #2. + */ +- local_irq_save(flags); ++ raw_local_irq_save(flags); + status = ctrl_inl(MMUCR); + status |= 0x04; + ctrl_outl(status, MMUCR); + ctrl_barrier(); +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } +Index: linux-2.6.24.7-rt21/arch/sh/mm/tlb-sh4.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/sh/mm/tlb-sh4.c 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/sh/mm/tlb-sh4.c 2008-10-08 22:23:56.000000000 -0400 +@@ -43,7 +43,7 @@ void update_mmu_cache(struct vm_area_str + } + #endif + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + + /* Set PTEH register */ + vpn = (address & MMU_VPN_MASK) | get_asid(); +@@ -76,7 +76,7 @@ void update_mmu_cache(struct vm_area_str + + /* Load the TLB */ + asm volatile("ldtlb": /* no output */ : /* no input */ : "memory"); +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } + + void local_flush_tlb_one(unsigned long asid, unsigned long page) +Index: linux-2.6.24.7-rt21/include/asm-sh/atomic-irq.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-sh/atomic-irq.h 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-sh/atomic-irq.h 2008-10-08 22:23:56.000000000 -0400 +@@ -10,29 +10,29 @@ static inline void atomic_add(int i, ato + { + unsigned long flags; + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + *(long *)v += i; +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } + + static inline void atomic_sub(int i, atomic_t *v) + { + unsigned long flags; + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + *(long *)v -= i; +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } + + static inline int atomic_add_return(int i, atomic_t *v) + { + unsigned long temp, flags; + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + temp = *(long *)v; + temp += i; + *(long *)v = temp; +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + + return temp; + } +@@ -41,11 +41,11 @@ static inline int atomic_sub_return(int + { + unsigned long temp, flags; + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + temp = *(long *)v; + temp -= i; + *(long *)v = temp; +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + + return temp; + } +@@ -54,18 +54,18 @@ static inline void atomic_clear_mask(uns + { + unsigned long flags; + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + *(long *)v &= ~mask; +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } + + static inline void atomic_set_mask(unsigned int mask, atomic_t *v) + { + unsigned long flags; + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + *(long *)v |= mask; +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } + + #endif /* __ASM_SH_ATOMIC_IRQ_H */ +Index: linux-2.6.24.7-rt21/include/asm-sh/atomic.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-sh/atomic.h 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-sh/atomic.h 2008-10-08 22:23:56.000000000 -0400 +@@ -49,11 +49,11 @@ static inline int atomic_cmpxchg(atomic_ + int ret; + unsigned long flags; + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + ret = v->counter; + if (likely(ret == old)) + v->counter = new; +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + + return ret; + } +@@ -65,11 +65,11 @@ static inline int atomic_add_unless(atom + int ret; + unsigned long flags; + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + ret = v->counter; + if (ret != u) + v->counter += a; +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + + return ret != u; + } +Index: linux-2.6.24.7-rt21/include/asm-sh/bitops.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-sh/bitops.h 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-sh/bitops.h 2008-10-08 22:23:56.000000000 -0400 +@@ -19,9 +19,9 @@ static inline void set_bit(int nr, volat + + a += nr >> 5; + mask = 1 << (nr & 0x1f); +- local_irq_save(flags); ++ raw_local_irq_save(flags); + *a |= mask; +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } + + /* +@@ -37,9 +37,9 @@ static inline void clear_bit(int nr, vol + + a += nr >> 5; + mask = 1 << (nr & 0x1f); +- local_irq_save(flags); ++ raw_local_irq_save(flags); + *a &= ~mask; +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } + + static inline void change_bit(int nr, volatile void * addr) +@@ -50,9 +50,9 @@ static inline void change_bit(int nr, vo + + a += nr >> 5; + mask = 1 << (nr & 0x1f); +- local_irq_save(flags); ++ raw_local_irq_save(flags); + *a ^= mask; +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } + + static inline int test_and_set_bit(int nr, volatile void * addr) +@@ -63,10 +63,10 @@ static inline int test_and_set_bit(int n + + a += nr >> 5; + mask = 1 << (nr & 0x1f); +- local_irq_save(flags); ++ raw_local_irq_save(flags); + retval = (mask & *a) != 0; + *a |= mask; +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + + return retval; + } +@@ -79,10 +79,10 @@ static inline int test_and_clear_bit(int + + a += nr >> 5; + mask = 1 << (nr & 0x1f); +- local_irq_save(flags); ++ raw_local_irq_save(flags); + retval = (mask & *a) != 0; + *a &= ~mask; +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + + return retval; + } +@@ -95,10 +95,10 @@ static inline int test_and_change_bit(in + + a += nr >> 5; + mask = 1 << (nr & 0x1f); +- local_irq_save(flags); ++ raw_local_irq_save(flags); + retval = (mask & *a) != 0; + *a ^= mask; +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + + return retval; + } +Index: linux-2.6.24.7-rt21/include/asm-sh/pgalloc.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-sh/pgalloc.h 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-sh/pgalloc.h 2008-10-08 22:23:56.000000000 -0400 +@@ -13,7 +13,7 @@ static inline void pmd_populate_kernel(s + set_pmd(pmd, __pmd((unsigned long)pte)); + } + +-static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, ++static inline void notrace pmd_populate(struct mm_struct *mm, pmd_t *pmd, + struct page *pte) + { + set_pmd(pmd, __pmd((unsigned long)page_address(pte))); +Index: linux-2.6.24.7-rt21/include/asm-sh/rwsem.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-sh/rwsem.h 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-sh/rwsem.h 2008-10-08 22:23:56.000000000 -0400 +@@ -19,7 +19,7 @@ + /* + * the semaphore definition + */ +-struct rw_semaphore { ++struct compat_rw_semaphore { + long count; + #define RWSEM_UNLOCKED_VALUE 0x00000000 + #define RWSEM_ACTIVE_BIAS 0x00000001 +@@ -27,7 +27,7 @@ struct rw_semaphore { + #define RWSEM_WAITING_BIAS (-0x00010000) + #define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS + #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) +- spinlock_t wait_lock; ++ raw_spinlock_t wait_lock; + struct list_head wait_list; + #ifdef CONFIG_DEBUG_LOCK_ALLOC + struct lockdep_map dep_map; +@@ -45,25 +45,25 @@ struct rw_semaphore { + LIST_HEAD_INIT((name).wait_list) \ + __RWSEM_DEP_MAP_INIT(name) } + +-#define DECLARE_RWSEM(name) \ +- struct rw_semaphore name = __RWSEM_INITIALIZER(name) ++#define COMPAT_DECLARE_RWSEM(name) \ ++ struct compat_rw_semaphore name = __RWSEM_INITIALIZER(name) + +-extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem); +-extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem); +-extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem); +-extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem); ++extern struct compat_rw_semaphore *rwsem_down_read_failed(struct compat_rw_semaphore *sem); ++extern struct compat_rw_semaphore *rwsem_down_write_failed(struct compat_rw_semaphore *sem); ++extern struct compat_rw_semaphore *rwsem_wake(struct compat_rw_semaphore *sem); ++extern struct compat_rw_semaphore *rwsem_downgrade_wake(struct compat_rw_semaphore *sem); + +-extern void __init_rwsem(struct rw_semaphore *sem, const char *name, ++extern void __compat_init_rwsem(struct rw_semaphore *sem, const char *name, + struct lock_class_key *key); + +-#define init_rwsem(sem) \ ++#define compat_init_rwsem(sem) \ + do { \ + static struct lock_class_key __key; \ + \ +- __init_rwsem((sem), #sem, &__key); \ ++ __compat_init_rwsem((sem), #sem, &__key); \ + } while (0) + +-static inline void init_rwsem(struct rw_semaphore *sem) ++static inline void compat_init_rwsem(struct rw_semaphore *sem) + { + sem->count = RWSEM_UNLOCKED_VALUE; + spin_lock_init(&sem->wait_lock); +@@ -73,7 +73,7 @@ static inline void init_rwsem(struct rw_ + /* + * lock for reading + */ +-static inline void __down_read(struct rw_semaphore *sem) ++static inline void __down_read(struct compat_rw_semaphore *sem) + { + if (atomic_inc_return((atomic_t *)(&sem->count)) > 0) + smp_wmb(); +@@ -81,7 +81,7 @@ static inline void __down_read(struct rw + rwsem_down_read_failed(sem); + } + +-static inline int __down_read_trylock(struct rw_semaphore *sem) ++static inline int __down_read_trylock(struct compat_rw_semaphore *sem) + { + int tmp; + +@@ -98,7 +98,7 @@ static inline int __down_read_trylock(st + /* + * lock for writing + */ +-static inline void __down_write(struct rw_semaphore *sem) ++static inline void __down_write(struct compat_rw_semaphore *sem) + { + int tmp; + +@@ -110,7 +110,7 @@ static inline void __down_write(struct r + rwsem_down_write_failed(sem); + } + +-static inline int __down_write_trylock(struct rw_semaphore *sem) ++static inline int __down_write_trylock(struct compat_rw_semaphore *sem) + { + int tmp; + +@@ -123,7 +123,7 @@ static inline int __down_write_trylock(s + /* + * unlock after reading + */ +-static inline void __up_read(struct rw_semaphore *sem) ++static inline void __up_read(struct compat_rw_semaphore *sem) + { + int tmp; + +@@ -136,7 +136,7 @@ static inline void __up_read(struct rw_s + /* + * unlock after writing + */ +-static inline void __up_write(struct rw_semaphore *sem) ++static inline void __up_write(struct compat_rw_semaphore *sem) + { + smp_wmb(); + if (atomic_sub_return(RWSEM_ACTIVE_WRITE_BIAS, +@@ -147,7 +147,7 @@ static inline void __up_write(struct rw_ + /* + * implement atomic add functionality + */ +-static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem) ++static inline void rwsem_atomic_add(int delta, struct compat_rw_semaphore *sem) + { + atomic_add(delta, (atomic_t *)(&sem->count)); + } +@@ -155,7 +155,7 @@ static inline void rwsem_atomic_add(int + /* + * downgrade write lock to read lock + */ +-static inline void __downgrade_write(struct rw_semaphore *sem) ++static inline void __downgrade_write(struct compat_rw_semaphore *sem) + { + int tmp; + +@@ -165,7 +165,7 @@ static inline void __downgrade_write(str + rwsem_downgrade_wake(sem); + } + +-static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) ++static inline void __down_write_nested(struct compat_rw_semaphore *sem, int subclass) + { + __down_write(sem); + } +@@ -173,13 +173,13 @@ static inline void __down_write_nested(s + /* + * implement exchange and add functionality + */ +-static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem) ++static inline int rwsem_atomic_update(int delta, struct compat_rw_semaphore *sem) + { + smp_mb(); + return atomic_add_return(delta, (atomic_t *)(&sem->count)); + } + +-static inline int rwsem_is_locked(struct rw_semaphore *sem) ++static inline int rwsem_is_locked(struct compat_rw_semaphore *sem) + { + return (sem->count != 0); + } +Index: linux-2.6.24.7-rt21/include/asm-sh/semaphore-helper.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-sh/semaphore-helper.h 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-sh/semaphore-helper.h 2008-10-08 22:23:56.000000000 -0400 +@@ -14,12 +14,12 @@ + * This is trivially done with load_locked/store_cond, + * which we have. Let the rest of the losers suck eggs. + */ +-static __inline__ void wake_one_more(struct semaphore * sem) ++static __inline__ void wake_one_more(struct compat_semaphore * sem) + { + atomic_inc((atomic_t *)&sem->sleepers); + } + +-static __inline__ int waking_non_zero(struct semaphore *sem) ++static __inline__ int waking_non_zero(struct compat_semaphore *sem) + { + unsigned long flags; + int ret = 0; +@@ -43,7 +43,7 @@ static __inline__ int waking_non_zero(st + * protected by the spinlock in order to make atomic this atomic_inc() with the + * atomic_read() in wake_one_more(), otherwise we can race. -arca + */ +-static __inline__ int waking_non_zero_interruptible(struct semaphore *sem, ++static __inline__ int waking_non_zero_interruptible(struct compat_semaphore *sem, + struct task_struct *tsk) + { + unsigned long flags; +@@ -70,7 +70,7 @@ static __inline__ int waking_non_zero_in + * protected by the spinlock in order to make atomic this atomic_inc() with the + * atomic_read() in wake_one_more(), otherwise we can race. -arca + */ +-static __inline__ int waking_non_zero_trylock(struct semaphore *sem) ++static __inline__ int waking_non_zero_trylock(struct compat_semaphore *sem) + { + unsigned long flags; + int ret = 1; +Index: linux-2.6.24.7-rt21/include/asm-sh/semaphore.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-sh/semaphore.h 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-sh/semaphore.h 2008-10-08 22:23:56.000000000 -0400 +@@ -20,28 +20,35 @@ + #include + #include + +-struct semaphore { ++/* ++ * On !PREEMPT_RT all semaphores are compat: ++ */ ++#ifndef CONFIG_PREEMPT_RT ++# define compat_semaphore semaphore ++#endif ++ ++struct compat_semaphore { + atomic_t count; + int sleepers; + wait_queue_head_t wait; + }; + +-#define __SEMAPHORE_INITIALIZER(name, n) \ ++#define __COMPAT_SEMAPHORE_INITIALIZER(name, n) \ + { \ + .count = ATOMIC_INIT(n), \ + .sleepers = 0, \ + .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ + } + +-#define __DECLARE_SEMAPHORE_GENERIC(name,count) \ +- struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) ++#define __COMPAT_DECLARE_SEMAPHORE_GENERIC(name,count) \ ++ struct compat_semaphore name = __COMPAT_SEMAPHORE_INITIALIZER(name,count) + +-#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) ++#define COMPAT_DECLARE_MUTEX(name) __COMPAT_DECLARE_SEMAPHORE_GENERIC(name,1) + +-static inline void sema_init (struct semaphore *sem, int val) ++static inline void compat_sema_init (struct compat_semaphore *sem, int val) + { + /* +- * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); ++ * *sem = (struct compat_semaphore)__SEMAPHORE_INITIALIZER((*sem),val); + * + * i'd rather use the more flexible initialization above, but sadly + * GCC 2.7.2.3 emits a bogus warning. EGCS doesn't. Oh well. +@@ -51,14 +58,14 @@ static inline void sema_init (struct sem + init_waitqueue_head(&sem->wait); + } + +-static inline void init_MUTEX (struct semaphore *sem) ++static inline void compat_init_MUTEX (struct compat_semaphore *sem) + { +- sema_init(sem, 1); ++ compat_sema_init(sem, 1); + } + +-static inline void init_MUTEX_LOCKED (struct semaphore *sem) ++static inline void compat_init_MUTEX_LOCKED (struct compat_semaphore *sem) + { +- sema_init(sem, 0); ++ compat_sema_init(sem, 0); + } + + #if 0 +@@ -68,36 +75,36 @@ asmlinkage int __down_failed_trylock(vo + asmlinkage void __up_wakeup(void /* special register calling convention */); + #endif + +-asmlinkage void __down(struct semaphore * sem); +-asmlinkage int __down_interruptible(struct semaphore * sem); +-asmlinkage int __down_trylock(struct semaphore * sem); +-asmlinkage void __up(struct semaphore * sem); ++asmlinkage void __compat_down(struct compat_semaphore * sem); ++asmlinkage int __compat_down_interruptible(struct compat_semaphore * sem); ++asmlinkage int __compat_down_trylock(struct compat_semaphore * sem); ++asmlinkage void __compat_up(struct compat_semaphore * sem); + + extern spinlock_t semaphore_wake_lock; + +-static inline void down(struct semaphore * sem) ++static inline void compat_down(struct compat_semaphore * sem) + { + might_sleep(); + if (atomic_dec_return(&sem->count) < 0) +- __down(sem); ++ __compat_down(sem); + } + +-static inline int down_interruptible(struct semaphore * sem) ++static inline int compat_down_interruptible(struct compat_semaphore * sem) + { + int ret = 0; + + might_sleep(); + if (atomic_dec_return(&sem->count) < 0) +- ret = __down_interruptible(sem); ++ ret = __compat_down_interruptible(sem); + return ret; + } + +-static inline int down_trylock(struct semaphore * sem) ++static inline int compat_down_trylock(struct compat_semaphore * sem) + { + int ret = 0; + + if (atomic_dec_return(&sem->count) < 0) +- ret = __down_trylock(sem); ++ ret = __compat_down_trylock(sem); + return ret; + } + +@@ -105,11 +112,17 @@ static inline int down_trylock(struct se + * Note! This is subtle. We jump to wake people up only if + * the semaphore was negative (== somebody was waiting on it). + */ +-static inline void up(struct semaphore * sem) ++static inline void compat_up(struct compat_semaphore * sem) + { + if (atomic_inc_return(&sem->count) <= 0) +- __up(sem); ++ __compat_up(sem); + } + ++extern int compat_sem_is_locked(struct compat_semaphore *sem); ++ ++#define compat_sema_count(sem) atomic_read(&(sem)->count) ++ ++#include ++ + #endif + #endif /* __ASM_SH_SEMAPHORE_H */ +Index: linux-2.6.24.7-rt21/include/asm-sh/system.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-sh/system.h 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-sh/system.h 2008-10-08 22:23:56.000000000 -0400 +@@ -159,10 +159,10 @@ static inline unsigned long xchg_u32(vol + { + unsigned long flags, retval; + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + retval = *m; + *m = val; +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + return retval; + } + +@@ -170,10 +170,10 @@ static inline unsigned long xchg_u8(vola + { + unsigned long flags, retval; + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + retval = *m; + *m = val & 0xff; +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + return retval; + } + +@@ -208,11 +208,11 @@ static inline unsigned long __cmpxchg_u3 + __u32 retval; + unsigned long flags; + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + retval = *m; + if (retval == old) + *m = new; +- local_irq_restore(flags); /* implies memory barrier */ ++ raw_local_irq_restore(flags); /* implies memory barrier */ + return retval; + } + +Index: linux-2.6.24.7-rt21/include/asm-sh/thread_info.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-sh/thread_info.h 2008-10-08 22:22:30.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-sh/thread_info.h 2008-10-08 22:23:56.000000000 -0400 +@@ -111,6 +111,7 @@ static inline struct thread_info *curren + #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ + #define TIF_RESTORE_SIGMASK 3 /* restore signal mask in do_signal() */ + #define TIF_SINGLESTEP 4 /* singlestepping active */ ++#define TIF_NEED_RESCHED_DELAYED 6 /* reschedule on return to userspace */ + #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ + #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ + #define TIF_MEMDIE 18 +@@ -121,6 +122,7 @@ static inline struct thread_info *curren + #define _TIF_NEED_RESCHED (1<_xmit_lock); +- dev->xmit_lock_owner = smp_processor_id(); ++ dev->xmit_lock_owner = raw_smp_processor_id(); + } + + static inline int netif_tx_trylock(struct net_device *dev) + { + int ok = spin_trylock(&dev->_xmit_lock); + if (likely(ok)) +- dev->xmit_lock_owner = smp_processor_id(); ++ dev->xmit_lock_owner = raw_smp_processor_id(); + return ok; + } + +Index: linux-2.6.24.7-rt21/include/net/dn_dev.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/net/dn_dev.h 2008-10-08 22:22:27.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/net/dn_dev.h 2008-10-08 22:24:07.000000000 -0400 +@@ -76,9 +76,9 @@ struct dn_dev_parms { + int priority; /* Priority to be a router */ + char *name; /* Name for sysctl */ + int ctl_name; /* Index for sysctl */ +- int (*up)(struct net_device *); +- void (*down)(struct net_device *); +- void (*timer3)(struct net_device *, struct dn_ifaddr *ifa); ++ int (*dn_up)(struct net_device *); ++ void (*dn_down)(struct net_device *); ++ void (*dn_timer3)(struct net_device *, struct dn_ifaddr *ifa); + void *sysctl; + }; + +Index: linux-2.6.24.7-rt21/net/core/dev.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/net/core/dev.c 2008-10-08 22:23:43.000000000 -0400 ++++ linux-2.6.24.7-rt21/net/core/dev.c 2008-10-08 22:24:07.000000000 -0400 +@@ -1692,9 +1692,16 @@ gso: + Either shot noqueue qdisc, it is even simpler 8) + */ + if (dev->flags & IFF_UP) { +- int cpu = smp_processor_id(); /* ok because BHs are off */ ++ int cpu = raw_smp_processor_id(); /* ok because BHs are off */ + ++ /* ++ * No need to check for recursion with threaded interrupts: ++ */ ++#ifdef CONFIG_PREEMPT_RT ++ if (1) { ++#else + if (dev->xmit_lock_owner != cpu) { ++#endif + + HARD_TX_LOCK(dev, cpu); + +@@ -1830,7 +1837,8 @@ static inline struct net_device *skb_bon + + static void net_tx_action(struct softirq_action *h) + { +- struct softnet_data *sd = &__get_cpu_var(softnet_data); ++ struct softnet_data *sd = &per_cpu(softnet_data, ++ raw_smp_processor_id()); + + if (sd->completion_queue) { + struct sk_buff *clist; +@@ -1846,6 +1854,11 @@ static void net_tx_action(struct softirq + + BUG_TRAP(!atomic_read(&skb->users)); + __kfree_skb(skb); ++ /* ++ * Safe to reschedule - the list is private ++ * at this point. ++ */ ++ cond_resched_softirq_context(); + } + } + +@@ -1864,12 +1877,27 @@ static void net_tx_action(struct softirq + smp_mb__before_clear_bit(); + clear_bit(__LINK_STATE_SCHED, &dev->state); + ++ /* ++ * We are executing in softirq context here, and ++ * if softirqs are preemptible, we must avoid ++ * infinite reactivation of the softirq by ++ * either the tx handler, or by netif_schedule(). ++ * (it would result in an infinitely looping ++ * softirq context) ++ * So we take the spinlock unconditionally. ++ */ ++#ifdef CONFIG_PREEMPT_SOFTIRQS ++ spin_lock(&dev->queue_lock); ++ qdisc_run(dev); ++ spin_unlock(&dev->queue_lock); ++#else + if (spin_trylock(&dev->queue_lock)) { + qdisc_run(dev); + spin_unlock(&dev->queue_lock); + } else { + netif_schedule(dev); + } ++#endif + } + } + } +@@ -2037,7 +2065,7 @@ int netif_receive_skb(struct sk_buff *sk + if (!orig_dev) + return NET_RX_DROP; + +- __get_cpu_var(netdev_rx_stat).total++; ++ per_cpu(netdev_rx_stat, raw_smp_processor_id()).total++; + + skb_reset_network_header(skb); + skb_reset_transport_header(skb); +@@ -2104,9 +2132,10 @@ out: + static int process_backlog(struct napi_struct *napi, int quota) + { + int work = 0; +- struct softnet_data *queue = &__get_cpu_var(softnet_data); ++ struct softnet_data *queue; + unsigned long start_time = jiffies; + ++ queue = &per_cpu(softnet_data, raw_smp_processor_id()); + napi->weight = weight_p; + do { + struct sk_buff *skb; +@@ -2144,7 +2173,7 @@ void fastcall __napi_schedule(struct nap + + local_irq_save(flags); + list_add_tail(&n->poll_list, &__get_cpu_var(softnet_data).poll_list); +- __raise_softirq_irqoff(NET_RX_SOFTIRQ); ++ raise_softirq_irqoff(NET_RX_SOFTIRQ); + local_irq_restore(flags); + } + EXPORT_SYMBOL(__napi_schedule); +Index: linux-2.6.24.7-rt21/net/core/netpoll.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/net/core/netpoll.c 2008-10-08 22:22:27.000000000 -0400 ++++ linux-2.6.24.7-rt21/net/core/netpoll.c 2008-10-08 22:24:07.000000000 -0400 +@@ -64,20 +64,20 @@ static void queue_process(struct work_st + continue; + } + +- local_irq_save(flags); ++ local_irq_save_nort(flags); + netif_tx_lock(dev); + if ((netif_queue_stopped(dev) || + netif_subqueue_stopped(dev, skb)) || + dev->hard_start_xmit(skb, dev) != NETDEV_TX_OK) { + skb_queue_head(&npinfo->txq, skb); + netif_tx_unlock(dev); +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + + schedule_delayed_work(&npinfo->tx_work, HZ/10); + return; + } + netif_tx_unlock(dev); +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + } + } + +@@ -146,7 +146,7 @@ static void poll_napi(struct netpoll *np + int budget = 16; + + list_for_each_entry(napi, &np->dev->napi_list, dev_list) { +- if (napi->poll_owner != smp_processor_id() && ++ if (napi->poll_owner != raw_smp_processor_id() && + spin_trylock(&napi->poll_lock)) { + budget = poll_one_napi(npinfo, napi, budget); + spin_unlock(&napi->poll_lock); +@@ -205,30 +205,33 @@ static void refill_skbs(void) + + static void zap_completion_queue(void) + { +- unsigned long flags; + struct softnet_data *sd = &get_cpu_var(softnet_data); ++ struct sk_buff *clist = NULL; ++ unsigned long flags; + + if (sd->completion_queue) { +- struct sk_buff *clist; +- + local_irq_save(flags); + clist = sd->completion_queue; + sd->completion_queue = NULL; + local_irq_restore(flags); +- +- while (clist != NULL) { +- struct sk_buff *skb = clist; +- clist = clist->next; +- if (skb->destructor) { +- atomic_inc(&skb->users); +- dev_kfree_skb_any(skb); /* put this one back */ +- } else { +- __kfree_skb(skb); +- } +- } + } + ++ /* ++ * Took the list private, can drop our softnet ++ * reference: ++ */ + put_cpu_var(softnet_data); ++ ++ while (clist != NULL) { ++ struct sk_buff *skb = clist; ++ clist = clist->next; ++ if (skb->destructor) { ++ atomic_inc(&skb->users); ++ dev_kfree_skb_any(skb); /* put this one back */ ++ } else { ++ __kfree_skb(skb); ++ } ++ } + } + + static struct sk_buff *find_skb(struct netpoll *np, int len, int reserve) +@@ -236,13 +239,26 @@ static struct sk_buff *find_skb(struct n + int count = 0; + struct sk_buff *skb; + ++#ifdef CONFIG_PREEMPT_RT ++ /* ++ * On -rt skb_pool.lock is schedulable, so if we are ++ * in an atomic context we just try to dequeue from the ++ * pool and fail if we cannot get one. ++ */ ++ if (in_atomic() || irqs_disabled()) ++ goto pick_atomic; ++#endif + zap_completion_queue(); + refill_skbs(); + repeat: + + skb = alloc_skb(len, GFP_ATOMIC); +- if (!skb) ++ if (!skb) { ++#ifdef CONFIG_PREEMPT_RT ++pick_atomic: ++#endif + skb = skb_dequeue(&skb_pool); ++ } + + if (!skb) { + if (++count < 10) { +@@ -262,7 +278,7 @@ static int netpoll_owner_active(struct n + struct napi_struct *napi; + + list_for_each_entry(napi, &dev->napi_list, dev_list) { +- if (napi->poll_owner == smp_processor_id()) ++ if (napi->poll_owner == raw_smp_processor_id()) + return 1; + } + return 0; +@@ -284,7 +300,7 @@ static void netpoll_send_skb(struct netp + if (skb_queue_len(&npinfo->txq) == 0 && !netpoll_owner_active(dev)) { + unsigned long flags; + +- local_irq_save(flags); ++ local_irq_save_nort(flags); + /* try until next clock tick */ + for (tries = jiffies_to_usecs(1)/USEC_PER_POLL; + tries > 0; --tries) { +@@ -304,7 +320,7 @@ static void netpoll_send_skb(struct netp + + udelay(USEC_PER_POLL); + } +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + } + + if (status != NETDEV_TX_OK) { +@@ -727,7 +743,7 @@ int netpoll_setup(struct netpoll *np) + np->name); + break; + } +- cond_resched(); ++ schedule_timeout_uninterruptible(1); + } + + /* If carrier appears to come up instantly, we don't +Index: linux-2.6.24.7-rt21/net/core/sock.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/net/core/sock.c 2008-10-08 22:22:27.000000000 -0400 ++++ linux-2.6.24.7-rt21/net/core/sock.c 2008-10-08 22:24:07.000000000 -0400 +@@ -1504,7 +1504,7 @@ static void sock_def_readable(struct soc + { + read_lock(&sk->sk_callback_lock); + if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) +- wake_up_interruptible(sk->sk_sleep); ++ wake_up_interruptible_sync(sk->sk_sleep); + sk_wake_async(sk,1,POLL_IN); + read_unlock(&sk->sk_callback_lock); + } +Index: linux-2.6.24.7-rt21/net/decnet/dn_dev.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/net/decnet/dn_dev.c 2008-10-08 22:22:27.000000000 -0400 ++++ linux-2.6.24.7-rt21/net/decnet/dn_dev.c 2008-10-08 22:24:07.000000000 -0400 +@@ -90,9 +90,9 @@ static struct dn_dev_parms dn_dev_list[] + .t3 = 10, + .name = "ethernet", + .ctl_name = NET_DECNET_CONF_ETHER, +- .up = dn_eth_up, +- .down = dn_eth_down, +- .timer3 = dn_send_brd_hello, ++ .dn_up = dn_eth_up, ++ .dn_down = dn_eth_down, ++ .dn_timer3 = dn_send_brd_hello, + }, + { + .type = ARPHRD_IPGRE, /* DECnet tunneled over GRE in IP */ +@@ -102,7 +102,7 @@ static struct dn_dev_parms dn_dev_list[] + .t3 = 10, + .name = "ipgre", + .ctl_name = NET_DECNET_CONF_GRE, +- .timer3 = dn_send_brd_hello, ++ .dn_timer3 = dn_send_brd_hello, + }, + #if 0 + { +@@ -113,7 +113,7 @@ static struct dn_dev_parms dn_dev_list[] + .t3 = 120, + .name = "x25", + .ctl_name = NET_DECNET_CONF_X25, +- .timer3 = dn_send_ptp_hello, ++ .dn_timer3 = dn_send_ptp_hello, + }, + #endif + #if 0 +@@ -125,7 +125,7 @@ static struct dn_dev_parms dn_dev_list[] + .t3 = 10, + .name = "ppp", + .ctl_name = NET_DECNET_CONF_PPP, +- .timer3 = dn_send_brd_hello, ++ .dn_timer3 = dn_send_brd_hello, + }, + #endif + { +@@ -136,7 +136,7 @@ static struct dn_dev_parms dn_dev_list[] + .t3 = 120, + .name = "ddcmp", + .ctl_name = NET_DECNET_CONF_DDCMP, +- .timer3 = dn_send_ptp_hello, ++ .dn_timer3 = dn_send_ptp_hello, + }, + { + .type = ARPHRD_LOOPBACK, /* Loopback interface - always last */ +@@ -146,7 +146,7 @@ static struct dn_dev_parms dn_dev_list[] + .t3 = 10, + .name = "loopback", + .ctl_name = NET_DECNET_CONF_LOOPBACK, +- .timer3 = dn_send_brd_hello, ++ .dn_timer3 = dn_send_brd_hello, + } + }; + +@@ -327,11 +327,11 @@ static int dn_forwarding_proc(ctl_table + */ + tmp = dn_db->parms.forwarding; + dn_db->parms.forwarding = old; +- if (dn_db->parms.down) +- dn_db->parms.down(dev); ++ if (dn_db->parms.dn_down) ++ dn_db->parms.dn_down(dev); + dn_db->parms.forwarding = tmp; +- if (dn_db->parms.up) +- dn_db->parms.up(dev); ++ if (dn_db->parms.dn_up) ++ dn_db->parms.dn_up(dev); + } + + return err; +@@ -365,11 +365,11 @@ static int dn_forwarding_sysctl(ctl_tabl + if (value > 2) + return -EINVAL; + +- if (dn_db->parms.down) +- dn_db->parms.down(dev); ++ if (dn_db->parms.dn_down) ++ dn_db->parms.dn_down(dev); + dn_db->parms.forwarding = value; +- if (dn_db->parms.up) +- dn_db->parms.up(dev); ++ if (dn_db->parms.dn_up) ++ dn_db->parms.dn_up(dev); + } + + return 0; +@@ -1090,10 +1090,10 @@ static void dn_dev_timer_func(unsigned l + struct dn_ifaddr *ifa; + + if (dn_db->t3 <= dn_db->parms.t2) { +- if (dn_db->parms.timer3) { ++ if (dn_db->parms.dn_timer3) { + for(ifa = dn_db->ifa_list; ifa; ifa = ifa->ifa_next) { + if (!(ifa->ifa_flags & IFA_F_SECONDARY)) +- dn_db->parms.timer3(dev, ifa); ++ dn_db->parms.dn_timer3(dev, ifa); + } + } + dn_db->t3 = dn_db->parms.t3; +@@ -1152,8 +1152,8 @@ struct dn_dev *dn_dev_create(struct net_ + return NULL; + } + +- if (dn_db->parms.up) { +- if (dn_db->parms.up(dev) < 0) { ++ if (dn_db->parms.dn_up) { ++ if (dn_db->parms.dn_up(dev) < 0) { + neigh_parms_release(&dn_neigh_table, dn_db->neigh_parms); + dev->dn_ptr = NULL; + kfree(dn_db); +@@ -1247,8 +1247,8 @@ static void dn_dev_delete(struct net_dev + dn_dev_check_default(dev); + neigh_ifdown(&dn_neigh_table, dev); + +- if (dn_db->parms.down) +- dn_db->parms.down(dev); ++ if (dn_db->parms.dn_down) ++ dn_db->parms.dn_down(dev); + + dev->dn_ptr = NULL; + +Index: linux-2.6.24.7-rt21/net/ipv4/icmp.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/net/ipv4/icmp.c 2008-10-08 22:22:27.000000000 -0400 ++++ linux-2.6.24.7-rt21/net/ipv4/icmp.c 2008-10-08 22:24:07.000000000 -0400 +@@ -229,7 +229,10 @@ static const struct icmp_control icmp_po + * On SMP we have one ICMP socket per-cpu. + */ + static DEFINE_PER_CPU(struct socket *, __icmp_socket) = NULL; +-#define icmp_socket __get_cpu_var(__icmp_socket) ++/* ++ * Should be safe on PREEMPT_SOFTIRQS/HARDIRQS to use raw-smp-processor-id: ++ */ ++#define icmp_socket per_cpu(__icmp_socket, raw_smp_processor_id()) + + static __inline__ int icmp_xmit_lock(void) + { +Index: linux-2.6.24.7-rt21/net/ipv4/route.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/net/ipv4/route.c 2008-10-08 22:23:37.000000000 -0400 ++++ linux-2.6.24.7-rt21/net/ipv4/route.c 2008-10-08 22:24:07.000000000 -0400 +@@ -208,13 +208,13 @@ struct rt_hash_bucket { + struct rtable *chain; + }; + #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) || \ +- defined(CONFIG_PROVE_LOCKING) ++ defined(CONFIG_PROVE_LOCKING) || defined(CONFIG_PREEMPT_RT) + /* + * Instead of using one spinlock for each rt_hash_bucket, we use a table of spinlocks + * The size of this table is a power of two and depends on the number of CPUS. + * (on lockdep we have a quite big spinlock_t, so keep the size down there) + */ +-#ifdef CONFIG_LOCKDEP ++#if defined(CONFIG_LOCKDEP) || defined(CONFIG_PREEMPT_RT) + # define RT_HASH_LOCK_SZ 256 + #else + # if NR_CPUS >= 32 +Index: linux-2.6.24.7-rt21/net/ipv6/netfilter/ip6_tables.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/net/ipv6/netfilter/ip6_tables.c 2008-10-08 22:22:27.000000000 -0400 ++++ linux-2.6.24.7-rt21/net/ipv6/netfilter/ip6_tables.c 2008-10-08 22:24:07.000000000 -0400 +@@ -380,7 +380,7 @@ ip6t_do_table(struct sk_buff *skb, + read_lock_bh(&table->lock); + private = table->private; + IP_NF_ASSERT(table->valid_hooks & (1 << hook)); +- table_base = (void *)private->entries[smp_processor_id()]; ++ table_base = (void *)private->entries[raw_smp_processor_id()]; + e = get_entry(table_base, private->hook_entry[hook]); + + /* For return from builtin chain */ +@@ -1190,7 +1190,7 @@ do_add_counters(void __user *user, unsig + + i = 0; + /* Choose the copy that is on our node */ +- loc_cpu_entry = private->entries[smp_processor_id()]; ++ loc_cpu_entry = private->entries[raw_smp_processor_id()]; + IP6T_ENTRY_ITERATE(loc_cpu_entry, + private->size, + add_counter_to_entry, +Index: linux-2.6.24.7-rt21/net/sched/sch_generic.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/net/sched/sch_generic.c 2008-10-08 22:22:27.000000000 -0400 ++++ linux-2.6.24.7-rt21/net/sched/sch_generic.c 2008-10-08 22:24:07.000000000 -0400 +@@ -12,6 +12,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -24,6 +25,7 @@ + #include + #include + #include ++#include + #include + + /* Main transmission queue. */ +@@ -87,7 +89,7 @@ static inline int handle_dev_cpu_collisi + { + int ret; + +- if (unlikely(dev->xmit_lock_owner == smp_processor_id())) { ++ if (unlikely(dev->xmit_lock_owner == raw_smp_processor_id())) { + /* + * Same CPU holding the lock. It may be a transient + * configuration error, when hard_start_xmit() recurses. We +@@ -144,7 +146,7 @@ static inline int qdisc_restart(struct n + /* And release queue */ + spin_unlock(&dev->queue_lock); + +- HARD_TX_LOCK(dev, smp_processor_id()); ++ HARD_TX_LOCK(dev, raw_smp_processor_id()); + if (!netif_subqueue_stopped(dev, skb)) + ret = dev_hard_start_xmit(skb, dev); + HARD_TX_UNLOCK(dev); +@@ -590,8 +592,12 @@ void dev_deactivate(struct net_device *d + + /* Wait for outstanding qdisc_run calls. */ + do { ++ /* ++ * Wait for outstanding qdisc_run calls. ++ * TODO: shouldnt this be wakeup-based, instead of polling it? ++ */ + while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state)) +- yield(); ++ msleep(1); + + /* + * Double-check inside queue lock to ensure that all effects +Index: linux-2.6.24.7-rt21/net/unix/af_unix.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/net/unix/af_unix.c 2008-10-08 22:22:27.000000000 -0400 ++++ linux-2.6.24.7-rt21/net/unix/af_unix.c 2008-10-08 22:24:07.000000000 -0400 +@@ -338,6 +338,7 @@ static void unix_write_space(struct sock + sk_wake_async(sk, 2, POLL_OUT); + } + read_unlock(&sk->sk_callback_lock); ++ preempt_check_resched_delayed(); + } + + /* When dgram socket disconnects (or changes its peer), we clear its receive --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0295-lock_page_ref.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0295-lock_page_ref.patch @@ -0,0 +1,441 @@ +Subject: mm: lock_page_ref + +Change the PG_nonewref operations into locking primitives and place them +so that they provide page level serialization with regard to the page_tree +operations. (basically replace the tree_lock with a per page lock). + +The normal page lock has sufficiently different (and overlapping) scope and +protection rules that this second lock is needed. + +Signed-off-by: Peter Zijlstra +--- + fs/buffer.c | 6 ++++-- + include/linux/page-flags.h | 21 --------------------- + include/linux/pagemap.h | 45 +++++++++++++++++++++++++++++++++++++++++++-- + mm/filemap.c | 14 ++++++++------ + mm/migrate.c | 25 +++++++++++++------------ + mm/page-writeback.c | 18 ++++++++++++------ + mm/swap_state.c | 14 ++++++++------ + mm/swapfile.c | 6 ++++-- + mm/truncate.c | 9 ++++++--- + mm/vmscan.c | 14 +++++++------- + 10 files changed, 105 insertions(+), 67 deletions(-) + +Index: linux-2.6.24.7-rt21/fs/buffer.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/fs/buffer.c 2008-10-08 22:24:14.000000000 -0400 ++++ linux-2.6.24.7-rt21/fs/buffer.c 2008-10-08 22:24:14.000000000 -0400 +@@ -697,7 +697,8 @@ static int __set_page_dirty(struct page + if (TestSetPageDirty(page)) + return 0; + +- spin_lock_irq(&mapping->tree_lock); ++ lock_page_ref_irq(page); ++ spin_lock(&mapping->tree_lock); + if (page->mapping) { /* Race with truncate? */ + WARN_ON_ONCE(warn && !PageUptodate(page)); + +@@ -710,7 +711,8 @@ static int __set_page_dirty(struct page + radix_tree_tag_set(&mapping->page_tree, + page_index(page), PAGECACHE_TAG_DIRTY); + } +- spin_unlock_irq(&mapping->tree_lock); ++ spin_unlock(&mapping->tree_lock); ++ unlock_page_ref_irq(page); + __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); + + return 1; +Index: linux-2.6.24.7-rt21/include/linux/page-flags.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/page-flags.h 2008-10-08 22:24:13.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/page-flags.h 2008-10-08 22:24:14.000000000 -0400 +@@ -279,25 +279,4 @@ static inline void set_page_writeback(st + test_set_page_writeback(page); + } + +-static inline void set_page_nonewrefs(struct page *page) +-{ +- preempt_disable(); +- SetPageNoNewRefs(page); +- smp_wmb(); +-} +- +-static inline void __clear_page_nonewrefs(struct page *page) +-{ +- smp_wmb(); +- __ClearPageNoNewRefs(page); +- preempt_enable(); +-} +- +-static inline void clear_page_nonewrefs(struct page *page) +-{ +- smp_wmb(); +- ClearPageNoNewRefs(page); +- preempt_enable(); +-} +- + #endif /* PAGE_FLAGS_H */ +Index: linux-2.6.24.7-rt21/include/linux/pagemap.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/pagemap.h 2008-10-08 22:24:13.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/pagemap.h 2008-10-08 22:24:14.000000000 -0400 +@@ -14,6 +14,7 @@ + #include + #include + #include /* for in_interrupt() */ ++#include + + /* + * Bits in mapping->flags. The lower __GFP_BITS_SHIFT bits are the page +@@ -64,6 +65,47 @@ static inline void mapping_set_gfp_mask( + #define page_cache_release(page) put_page(page) + void release_pages(struct page **pages, int nr, int cold); + ++static inline void lock_page_ref(struct page *page) ++{ ++ bit_spin_lock(PG_nonewrefs, &page->flags); ++ smp_wmb(); ++} ++ ++static inline void unlock_page_ref(struct page *page) ++{ ++ bit_spin_unlock(PG_nonewrefs, &page->flags); ++} ++ ++static inline void wait_on_page_ref(struct page *page) ++{ ++ while (unlikely(test_bit(PG_nonewrefs, &page->flags))) ++ cpu_relax(); ++} ++ ++#define lock_page_ref_irq(page) \ ++ do { \ ++ local_irq_disable(); \ ++ lock_page_ref(page); \ ++ } while (0) ++ ++#define unlock_page_ref_irq(page) \ ++ do { \ ++ unlock_page_ref(page); \ ++ local_irq_enable(); \ ++ } while (0) ++ ++#define lock_page_ref_irqsave(page, flags) \ ++ do { \ ++ local_irq_save(flags); \ ++ lock_page_ref(page); \ ++ } while (0) ++ ++#define unlock_page_ref_irqrestore(page, flags) \ ++ do { \ ++ unlock_page_ref(page); \ ++ local_irq_restore(flags); \ ++ } while (0) ++ + /* + * speculatively take a reference to a page. + * If the page is free (_count == 0), then _count is untouched, and 0 +@@ -139,8 +181,7 @@ static inline int page_cache_get_specula + * page refcount has been raised. See below comment. + */ + +- while (unlikely(PageNoNewRefs(page))) +- cpu_relax(); ++ wait_on_page_ref(page); + + /* + * smp_rmb is to ensure the load of page->flags (for PageNoNewRefs()) +Index: linux-2.6.24.7-rt21/mm/filemap.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/mm/filemap.c 2008-10-08 22:24:14.000000000 -0400 ++++ linux-2.6.24.7-rt21/mm/filemap.c 2008-10-08 22:24:14.000000000 -0400 +@@ -144,9 +144,11 @@ void remove_from_page_cache(struct page + + BUG_ON(!PageLocked(page)); + +- spin_lock_irq(&mapping->tree_lock); ++ lock_page_ref_irq(page); ++ spin_lock(&mapping->tree_lock); + __remove_from_page_cache(page); +- spin_unlock_irq(&mapping->tree_lock); ++ spin_unlock(&mapping->tree_lock); ++ unlock_page_ref_irq(page); + } + + static int sync_page(void *word) +@@ -456,8 +458,8 @@ int add_to_page_cache(struct page *page, + int error = radix_tree_preload(gfp_mask & ~__GFP_HIGHMEM); + + if (error == 0) { +- set_page_nonewrefs(page); +- spin_lock_irq(&mapping->tree_lock); ++ lock_page_ref_irq(page); ++ spin_lock(&mapping->tree_lock); + error = radix_tree_insert(&mapping->page_tree, offset, page); + if (!error) { + page_cache_get(page); +@@ -467,8 +469,8 @@ int add_to_page_cache(struct page *page, + mapping_nrpages_inc(mapping); + __inc_zone_page_state(page, NR_FILE_PAGES); + } +- spin_unlock_irq(&mapping->tree_lock); +- clear_page_nonewrefs(page); ++ spin_unlock(&mapping->tree_lock); ++ unlock_page_ref_irq(page); + radix_tree_preload_end(); + } + return error; +Index: linux-2.6.24.7-rt21/mm/migrate.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/mm/migrate.c 2008-10-08 22:24:13.000000000 -0400 ++++ linux-2.6.24.7-rt21/mm/migrate.c 2008-10-08 22:24:14.000000000 -0400 +@@ -303,16 +303,16 @@ static int migrate_page_move_mapping(str + return 0; + } + +- set_page_nonewrefs(page); +- spin_lock_irq(&mapping->tree_lock); ++ lock_page_ref_irq(page); ++ spin_lock(&mapping->tree_lock); + + pslot = radix_tree_lookup_slot(&mapping->page_tree, + page_index(page)); + + if (page_count(page) != 2 + !!PagePrivate(page) || + (struct page *)radix_tree_deref_slot(pslot) != page) { +- spin_unlock_irq(&mapping->tree_lock); +- clear_page_nonewrefs(page); ++ spin_unlock(&mapping->tree_lock); ++ unlock_page_ref_irq(page); + return -EAGAIN; + } + +@@ -329,14 +329,7 @@ static int migrate_page_move_mapping(str + + radix_tree_replace_slot(pslot, newpage); + page->mapping = NULL; +- spin_unlock_irq(&mapping->tree_lock); +- clear_page_nonewrefs(page); +- +- /* +- * Drop cache reference from old page. +- * We know this isn't the last reference. +- */ +- __put_page(page); ++ spin_unlock(&mapping->tree_lock); + + /* + * If moved to a different zone then also account +@@ -351,6 +344,14 @@ static int migrate_page_move_mapping(str + __dec_zone_page_state(page, NR_FILE_PAGES); + __inc_zone_page_state(newpage, NR_FILE_PAGES); + ++ unlock_page_ref_irq(page); ++ ++ /* ++ * Drop cache reference from old page. ++ * We know this isn't the last reference. ++ */ ++ __put_page(page); ++ + return 0; + } + +Index: linux-2.6.24.7-rt21/mm/page-writeback.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/mm/page-writeback.c 2008-10-08 22:24:13.000000000 -0400 ++++ linux-2.6.24.7-rt21/mm/page-writeback.c 2008-10-08 22:24:14.000000000 -0400 +@@ -1008,7 +1008,8 @@ int __set_page_dirty_nobuffers(struct pa + if (!mapping) + return 1; + +- spin_lock_irq(&mapping->tree_lock); ++ lock_page_ref_irq(page); ++ spin_lock(&mapping->tree_lock); + mapping2 = page_mapping(page); + if (mapping2) { /* Race with truncate? */ + BUG_ON(mapping2 != mapping); +@@ -1022,7 +1023,8 @@ int __set_page_dirty_nobuffers(struct pa + radix_tree_tag_set(&mapping->page_tree, + page_index(page), PAGECACHE_TAG_DIRTY); + } +- spin_unlock_irq(&mapping->tree_lock); ++ spin_unlock(&mapping->tree_lock); ++ unlock_page_ref_irq(page); + if (mapping->host) { + /* !PageAnon && !swapper_space */ + __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); +@@ -1178,7 +1180,8 @@ int test_clear_page_writeback(struct pag + struct backing_dev_info *bdi = mapping->backing_dev_info; + unsigned long flags; + +- spin_lock_irqsave(&mapping->tree_lock, flags); ++ lock_page_ref_irqsave(page, flags); ++ spin_lock(&mapping->tree_lock); + ret = TestClearPageWriteback(page); + if (ret) { + radix_tree_tag_clear(&mapping->page_tree, +@@ -1189,7 +1192,8 @@ int test_clear_page_writeback(struct pag + __bdi_writeout_inc(bdi); + } + } +- spin_unlock_irqrestore(&mapping->tree_lock, flags); ++ spin_unlock(&mapping->tree_lock); ++ unlock_page_ref_irqrestore(page, flags); + } else { + ret = TestClearPageWriteback(page); + } +@@ -1207,7 +1211,8 @@ int test_set_page_writeback(struct page + struct backing_dev_info *bdi = mapping->backing_dev_info; + unsigned long flags; + +- spin_lock_irqsave(&mapping->tree_lock, flags); ++ lock_page_ref_irqsave(page, flags); ++ spin_lock(&mapping->tree_lock); + ret = TestSetPageWriteback(page); + if (!ret) { + radix_tree_tag_set(&mapping->page_tree, +@@ -1220,7 +1225,8 @@ int test_set_page_writeback(struct page + radix_tree_tag_clear(&mapping->page_tree, + page_index(page), + PAGECACHE_TAG_DIRTY); +- spin_unlock_irqrestore(&mapping->tree_lock, flags); ++ spin_unlock(&mapping->tree_lock); ++ unlock_page_ref_irqrestore(page, flags); + } else { + ret = TestSetPageWriteback(page); + } +Index: linux-2.6.24.7-rt21/mm/swap_state.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/mm/swap_state.c 2008-10-08 22:24:14.000000000 -0400 ++++ linux-2.6.24.7-rt21/mm/swap_state.c 2008-10-08 22:24:14.000000000 -0400 +@@ -79,8 +79,8 @@ static int __add_to_swap_cache(struct pa + BUG_ON(PagePrivate(page)); + error = radix_tree_preload(gfp_mask); + if (!error) { +- set_page_nonewrefs(page); +- spin_lock_irq(&swapper_space.tree_lock); ++ lock_page_ref_irq(page); ++ spin_lock(&swapper_space.tree_lock); + error = radix_tree_insert(&swapper_space.page_tree, + entry.val, page); + if (!error) { +@@ -90,8 +90,8 @@ static int __add_to_swap_cache(struct pa + mapping_nrpages_inc(&swapper_space); + __inc_zone_page_state(page, NR_FILE_PAGES); + } +- spin_unlock_irq(&swapper_space.tree_lock); +- clear_page_nonewrefs(page); ++ spin_unlock(&swapper_space.tree_lock); ++ unlock_page_ref_irq(page); + radix_tree_preload_end(); + } + return error; +@@ -205,9 +205,11 @@ void delete_from_swap_cache(struct page + + entry.val = page_private(page); + +- spin_lock_irq(&swapper_space.tree_lock); ++ lock_page_ref_irq(page); ++ spin_lock(&swapper_space.tree_lock); + __delete_from_swap_cache(page); +- spin_unlock_irq(&swapper_space.tree_lock); ++ spin_unlock(&swapper_space.tree_lock); ++ unlock_page_ref_irq(page); + + swap_free(entry); + page_cache_release(page); +Index: linux-2.6.24.7-rt21/mm/swapfile.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/mm/swapfile.c 2008-10-08 22:24:13.000000000 -0400 ++++ linux-2.6.24.7-rt21/mm/swapfile.c 2008-10-08 22:24:14.000000000 -0400 +@@ -367,13 +367,15 @@ int remove_exclusive_swap_page(struct pa + retval = 0; + if (p->swap_map[swp_offset(entry)] == 1) { + /* Recheck the page count with the swapcache lock held.. */ +- spin_lock_irq(&swapper_space.tree_lock); ++ lock_page_ref_irq(page); ++ spin_lock(&swapper_space.tree_lock); + if ((page_count(page) == 2) && !PageWriteback(page)) { + __delete_from_swap_cache(page); + SetPageDirty(page); + retval = 1; + } +- spin_unlock_irq(&swapper_space.tree_lock); ++ spin_unlock(&swapper_space.tree_lock); ++ unlock_page_ref_irq(page); + } + spin_unlock(&swap_lock); + +Index: linux-2.6.24.7-rt21/mm/truncate.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/mm/truncate.c 2008-10-08 22:24:14.000000000 -0400 ++++ linux-2.6.24.7-rt21/mm/truncate.c 2008-10-08 22:24:14.000000000 -0400 +@@ -350,18 +350,21 @@ invalidate_complete_page2(struct address + if (PagePrivate(page) && !try_to_release_page(page, GFP_KERNEL)) + return 0; + +- spin_lock_irq(&mapping->tree_lock); ++ lock_page_ref_irq(page); ++ spin_lock(&mapping->tree_lock); + if (PageDirty(page)) + goto failed; + + BUG_ON(PagePrivate(page)); + __remove_from_page_cache(page); +- spin_unlock_irq(&mapping->tree_lock); ++ spin_unlock(&mapping->tree_lock); ++ unlock_page_ref_irq(page); + ClearPageUptodate(page); + page_cache_release(page); /* pagecache ref */ + return 1; + failed: +- spin_unlock_irq(&mapping->tree_lock); ++ spin_unlock(&mapping->tree_lock); ++ unlock_page_ref_irq(page); + return 0; + } + +Index: linux-2.6.24.7-rt21/mm/vmscan.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/mm/vmscan.c 2008-10-08 22:24:13.000000000 -0400 ++++ linux-2.6.24.7-rt21/mm/vmscan.c 2008-10-08 22:24:14.000000000 -0400 +@@ -385,8 +385,8 @@ int remove_mapping(struct address_space + BUG_ON(!PageLocked(page)); + BUG_ON(mapping != page_mapping(page)); + +- set_page_nonewrefs(page); +- spin_lock_irq(&mapping->tree_lock); ++ lock_page_ref_irq(page); ++ spin_lock(&mapping->tree_lock); + /* + * The non racy check for a busy page. + * +@@ -421,22 +421,22 @@ int remove_mapping(struct address_space + if (PageSwapCache(page)) { + swp_entry_t swap = { .val = page_private(page) }; + __delete_from_swap_cache(page); +- spin_unlock_irq(&mapping->tree_lock); ++ spin_unlock(&mapping->tree_lock); + swap_free(swap); + goto free_it; + } + + __remove_from_page_cache(page); +- spin_unlock_irq(&mapping->tree_lock); ++ spin_unlock(&mapping->tree_lock); + + free_it: +- __clear_page_nonewrefs(page); ++ unlock_page_ref_irq(page); + __put_page(page); /* The pagecache ref */ + return 1; + + cannot_free: +- spin_unlock_irq(&mapping->tree_lock); +- clear_page_nonewrefs(page); ++ spin_unlock(&mapping->tree_lock); ++ unlock_page_ref_irq(page); + return 0; + } + --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0179-rt-mutex-m68knommu-add-compat_semaphore.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0179-rt-mutex-m68knommu-add-compat_semaphore.patch @@ -0,0 +1,251 @@ +From 6d12160b217c3a274f638f844a100ecb9d365b06 Mon Sep 17 00:00:00 2001 +From: Sebastian Siewior +Date: Fri, 18 Apr 2008 17:02:24 +0200 +Subject: [PATCH] m68knommu: add compat_semaphore + +basically a rename + +Signed-off-by: Sebastian Siewior +Signed-off-by: Thomas Gleixner +--- + arch/m68knommu/Kconfig | 4 ++ + arch/m68knommu/kernel/Makefile | 3 + + arch/m68knommu/kernel/semaphore.c | 8 ++-- + include/asm-m68knommu/semaphore-helper.h | 8 ++-- + include/asm-m68knommu/semaphore.h | 56 +++++++++++++++++-------------- + 5 files changed, 46 insertions(+), 33 deletions(-) + +Index: linux-2.6.24.7-rt21/arch/m68knommu/Kconfig +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/Kconfig 2008-10-08 22:23:11.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/Kconfig 2008-10-08 22:23:40.000000000 -0400 +@@ -29,6 +29,10 @@ config RWSEM_XCHGADD_ALGORITHM + bool + default n + ++config ASM_SEMAPHORES ++ bool ++ default y ++ + config ARCH_HAS_ILOG2_U32 + bool + default n +Index: linux-2.6.24.7-rt21/arch/m68knommu/kernel/Makefile +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/kernel/Makefile 2008-10-08 22:23:12.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/kernel/Makefile 2008-10-08 22:23:40.000000000 -0400 +@@ -5,8 +5,9 @@ + extra-y := vmlinux.lds + + obj-y += dma.o entry.o init_task.o irq.o m68k_ksyms.o process.o ptrace.o \ +- semaphore.o setup.o signal.o syscalltable.o sys_m68k.o time.o traps.o ++ setup.o signal.o syscalltable.o sys_m68k.o time.o traps.o + + obj-$(CONFIG_MODULES) += module.o + obj-$(CONFIG_COMEMPCI) += comempci.o + obj-$(CONFIG_STACKTRACE) += stacktrace.o ++obj-$(CONFIG_ASM_SEMAPHORES) += semaphore.o +Index: linux-2.6.24.7-rt21/arch/m68knommu/kernel/semaphore.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/m68knommu/kernel/semaphore.c 2008-10-08 22:22:35.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/m68knommu/kernel/semaphore.c 2008-10-08 22:23:40.000000000 -0400 +@@ -42,7 +42,7 @@ spinlock_t semaphore_wake_lock; + * critical part is the inline stuff in + * where we want to avoid any extra jumps and calls. + */ +-void __up(struct semaphore *sem) ++void __compat_up(struct compat_semaphore *sem) + { + wake_one_more(sem); + wake_up(&sem->wait); +@@ -96,7 +96,7 @@ void __up(struct semaphore *sem) + current->state = TASK_RUNNING; \ + remove_wait_queue(&sem->wait, &wait); + +-void __sched __down(struct semaphore * sem) ++void __sched __compat_down(struct compat_semaphore * sem) + { + DECLARE_WAITQUEUE(wait, current); + +@@ -107,7 +107,7 @@ void __sched __down(struct semaphore * s + DOWN_TAIL(TASK_UNINTERRUPTIBLE) + } + +-int __sched __down_interruptible(struct semaphore * sem) ++int __sched __compat_down_interruptible(struct compat_semaphore * sem) + { + DECLARE_WAITQUEUE(wait, current); + int ret = 0; +@@ -127,7 +127,7 @@ int __sched __down_interruptible(struct + return ret; + } + +-int __down_trylock(struct semaphore * sem) ++int __compat_down_trylock(struct compat_semaphore * sem) + { + return waking_non_zero_trylock(sem); + } +Index: linux-2.6.24.7-rt21/include/asm-m68knommu/semaphore-helper.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-m68knommu/semaphore-helper.h 2008-10-08 22:22:35.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-m68knommu/semaphore-helper.h 2008-10-08 22:23:40.000000000 -0400 +@@ -13,12 +13,12 @@ + /* + * These two _must_ execute atomically wrt each other. + */ +-static inline void wake_one_more(struct semaphore * sem) ++static inline void wake_one_more(struct compat_semaphore * sem) + { + atomic_inc(&sem->waking); + } + +-static inline int waking_non_zero(struct semaphore *sem) ++static inline int waking_non_zero(struct compat_semaphore *sem) + { + int ret; + unsigned long flags; +@@ -39,7 +39,7 @@ static inline int waking_non_zero(struct + * 0 go to sleep + * -EINTR interrupted + */ +-static inline int waking_non_zero_interruptible(struct semaphore *sem, ++static inline int waking_non_zero_interruptible(struct compat_semaphore *sem, + struct task_struct *tsk) + { + int ret; +@@ -63,7 +63,7 @@ static inline int waking_non_zero_interr + * 1 failed to lock + * 0 got the lock + */ +-static inline int waking_non_zero_trylock(struct semaphore *sem) ++static inline int waking_non_zero_trylock(struct compat_semaphore *sem) + { + int ret; + unsigned long flags; +Index: linux-2.6.24.7-rt21/include/asm-m68knommu/semaphore.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/asm-m68knommu/semaphore.h 2008-10-08 22:22:35.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/asm-m68knommu/semaphore.h 2008-10-08 22:23:40.000000000 -0400 +@@ -21,49 +21,55 @@ + * m68k version by Andreas Schwab + */ + ++#ifndef CONFIG_PREEMPT_RT ++# define compat_semaphore semaphore ++#endif + +-struct semaphore { ++struct compat_semaphore { + atomic_t count; + atomic_t waking; + wait_queue_head_t wait; + }; + +-#define __SEMAPHORE_INITIALIZER(name, n) \ ++#define __COMPAT_SEMAPHORE_INITIALIZER(name, n) \ + { \ + .count = ATOMIC_INIT(n), \ + .waking = ATOMIC_INIT(0), \ + .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ + } + +-#define __DECLARE_SEMAPHORE_GENERIC(name,count) \ +- struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) ++#define __COMPAT_DECLARE_SEMAPHORE_GENERIC(name,count) \ ++ struct compat_semaphore name = __COMPAT_SEMAPHORE_INITIALIZER(name,count) + +-#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) ++#define COMPAT_DECLARE_MUTEX(name) __COMPAT_DECLARE_SEMAPHORE_GENERIC(name,1) + +-static inline void sema_init (struct semaphore *sem, int val) ++static inline void compat_sema_init (struct compat_semaphore *sem, int val) + { +- *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val); ++ *sem = (struct compat_semaphore)__COMPAT_SEMAPHORE_INITIALIZER(*sem, val); + } + +-static inline void init_MUTEX (struct semaphore *sem) ++static inline void compat_init_MUTEX (struct compat_semaphore *sem) + { +- sema_init(sem, 1); ++ compat_sema_init(sem, 1); + } + +-static inline void init_MUTEX_LOCKED (struct semaphore *sem) ++static inline void compat_init_MUTEX_LOCKED (struct compat_semaphore *sem) + { +- sema_init(sem, 0); ++ compat_sema_init(sem, 0); + } + +-asmlinkage void __down_failed(void /* special register calling convention */); +-asmlinkage int __down_failed_interruptible(void /* params in registers */); +-asmlinkage int __down_failed_trylock(void /* params in registers */); +-asmlinkage void __up_wakeup(void /* special register calling convention */); ++asmlinkage void __compat_down_failed(void /* special register calling convention */); ++asmlinkage int __compat_down_failed_interruptible(void /* params in registers */); ++asmlinkage int __compat_down_failed_trylock(void /* params in registers */); ++asmlinkage void __compat_up_wakeup(void /* special register calling convention */); ++ ++asmlinkage void __compat_down(struct compat_semaphore * sem); ++asmlinkage int __compat_down_interruptible(struct compat_semaphore * sem); ++asmlinkage int __compat_down_trylock(struct compat_semaphore * sem); ++asmlinkage void __compat_up(struct compat_semaphore * sem); + +-asmlinkage void __down(struct semaphore * sem); +-asmlinkage int __down_interruptible(struct semaphore * sem); +-asmlinkage int __down_trylock(struct semaphore * sem); +-asmlinkage void __up(struct semaphore * sem); ++extern int compat_sem_is_locked(struct compat_semaphore *sem); ++#define compat_sema_count(sem) atomic_read(&(sem)->count) + + extern spinlock_t semaphore_wake_lock; + +@@ -72,7 +78,7 @@ extern spinlock_t semaphore_wake_lock; + * "down_failed" is a special asm handler that calls the C + * routine that actually waits. See arch/m68k/lib/semaphore.S + */ +-static inline void down(struct semaphore * sem) ++static inline void compat_down(struct compat_semaphore * sem) + { + might_sleep(); + __asm__ __volatile__( +@@ -87,7 +93,7 @@ static inline void down(struct semaphore + : "cc", "%a0", "%a1", "memory"); + } + +-static inline int down_interruptible(struct semaphore * sem) ++static inline int compat_down_interruptible(struct compat_semaphore * sem) + { + int ret; + +@@ -106,9 +112,9 @@ static inline int down_interruptible(str + return(ret); + } + +-static inline int down_trylock(struct semaphore * sem) ++static inline int compat_down_trylock(struct compat_semaphore * sem) + { +- register struct semaphore *sem1 __asm__ ("%a1") = sem; ++ register struct compat_semaphore *sem1 __asm__ ("%a1") = sem; + register int result __asm__ ("%d0"); + + __asm__ __volatile__( +@@ -134,7 +140,7 @@ static inline int down_trylock(struct se + * The default case (no contention) will result in NO + * jumps for both down() and up(). + */ +-static inline void up(struct semaphore * sem) ++static inline void compat_up(struct compat_semaphore * sem) + { + __asm__ __volatile__( + "| atomic up operation\n\t" +@@ -148,6 +154,8 @@ static inline void up(struct semaphore * + : "cc", "%a0", "%a1", "memory"); + } + ++#include ++ + #endif /* __ASSEMBLY__ */ + + #endif --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0422-printk-in-atomic.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0422-printk-in-atomic.patch @@ -0,0 +1,92 @@ +rostedt's patch to make early printk safe on RT + +From: Clark Williams + + +--- + + arch/x86/kernel/early_printk.c | 6 +++--- + drivers/char/vt.c | 2 +- + include/linux/console.h | 11 +++++++++++ + kernel/printk.c | 1 + + 4 files changed, 16 insertions(+), 4 deletions(-) + + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/early_printk.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/early_printk.c 2008-10-08 22:23:51.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/early_printk.c 2008-10-08 22:24:45.000000000 -0400 +@@ -51,7 +51,7 @@ static void early_vga_write(struct conso + static struct console early_vga_console = { + .name = "earlyvga", + .write = early_vga_write, +- .flags = CON_PRINTBUFFER, ++ .flags = CON_PRINTBUFFER | CON_ATOMIC, + .index = -1, + }; + +@@ -147,7 +147,7 @@ static __init void early_serial_init(cha + static struct console early_serial_console = { + .name = "earlyser", + .write = early_serial_write, +- .flags = CON_PRINTBUFFER, ++ .flags = CON_PRINTBUFFER | CON_ATOMIC, + .index = -1, + }; + +@@ -188,7 +188,7 @@ static void simnow_write(struct console + static struct console simnow_console = { + .name = "simnow", + .write = simnow_write, +- .flags = CON_PRINTBUFFER, ++ .flags = CON_PRINTBUFFER | CON_ATOMIC, + .index = -1, + }; + +Index: linux-2.6.24.7-rt21/drivers/char/vt.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/char/vt.c 2008-10-08 22:22:16.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/char/vt.c 2008-10-08 22:24:45.000000000 -0400 +@@ -2496,7 +2496,7 @@ static struct console vt_console_driver + .write = vt_console_print, + .device = vt_console_device, + .unblank = unblank_screen, +- .flags = CON_PRINTBUFFER, ++ .flags = CON_PRINTBUFFER | CON_ATOMIC, + .index = -1, + }; + #endif +Index: linux-2.6.24.7-rt21/include/linux/console.h +=================================================================== +--- linux-2.6.24.7-rt21.orig/include/linux/console.h 2008-10-08 22:24:02.000000000 -0400 ++++ linux-2.6.24.7-rt21/include/linux/console.h 2008-10-08 22:24:45.000000000 -0400 +@@ -92,6 +92,17 @@ void give_up_console(const struct consw + #define CON_ENABLED (4) + #define CON_BOOT (8) + #define CON_ANYTIME (16) /* Safe to call when cpu is offline */ ++#define CON_ATOMIC (32) /* Safe to call in PREEMPT_RT atomic */ ++ ++#ifdef CONFIG_PREEMPT_RT ++# define console_atomic_safe(con) \ ++ (((con)->flags & CON_ATOMIC) || \ ++ (!in_atomic() && !irqs_disabled()) || \ ++ (system_state != SYSTEM_RUNNING) || \ ++ oops_in_progress) ++#else ++# define console_atomic_safe(con) (1) ++#endif + + struct console { + char name[16]; +Index: linux-2.6.24.7-rt21/kernel/printk.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/kernel/printk.c 2008-10-08 22:24:22.000000000 -0400 ++++ linux-2.6.24.7-rt21/kernel/printk.c 2008-10-08 22:24:45.000000000 -0400 +@@ -435,6 +435,7 @@ static void __call_console_drivers(unsig + + for (con = console_drivers; con; con = con->next) { + if ((con->flags & CON_ENABLED) && con->write && ++ console_atomic_safe(con) && + (cpu_online(raw_smp_processor_id()) || + (con->flags & CON_ANYTIME))) { + set_printk_might_sleep(1); --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0070-event-tracer-syscall-i386.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0070-event-tracer-syscall-i386.patch @@ -0,0 +1,49 @@ +hooks into i386 to track event calls. + +This code was taken from the work by Ingo Molnar. + +Signed-off-by: Steven Rostedt +--- + arch/x86/kernel/entry_32.S | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +Index: linux-2.6.24.7-rt21/arch/x86/kernel/entry_32.S +=================================================================== +--- linux-2.6.24.7-rt21.orig/arch/x86/kernel/entry_32.S 2008-10-08 22:23:06.000000000 -0400 ++++ linux-2.6.24.7-rt21/arch/x86/kernel/entry_32.S 2008-10-08 22:23:09.000000000 -0400 +@@ -330,6 +330,11 @@ sysenter_past_esp: + pushl %eax + CFI_ADJUST_CFA_OFFSET 4 + SAVE_ALL ++#ifdef CONFIG_EVENT_TRACE ++ pushl %edx; pushl %ecx; pushl %ebx; pushl %eax ++ call sys_call ++ popl %eax; popl %ebx; popl %ecx; popl %edx ++#endif + GET_THREAD_INFO(%ebp) + + /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ +@@ -345,6 +350,11 @@ sysenter_past_esp: + movl TI_flags(%ebp), %ecx + testw $_TIF_ALLWORK_MASK, %cx + jne syscall_exit_work ++#ifdef CONFIG_EVENT_TRACE ++ pushl %eax ++ call sys_ret ++ popl %eax ++#endif + /* if something modifies registers it must also disable sysexit */ + movl PT_EIP(%esp), %edx + movl PT_OLDESP(%esp), %ecx +@@ -368,6 +378,11 @@ ENTRY(system_call) + pushl %eax # save orig_eax + CFI_ADJUST_CFA_OFFSET 4 + SAVE_ALL ++#ifdef CONFIG_EVENT_TRACE ++ pushl %edx; pushl %ecx; pushl %ebx; pushl %eax ++ call sys_call ++ popl %eax; popl %ebx; popl %ecx; popl %edx ++#endif + GET_THREAD_INFO(%ebp) + # system call tracing in operation / emulation + /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ --- linux-2.6.24.orig/debian/binary-custom.d/rt/patchset/0258-preempt-realtime-rawlocks.patch +++ linux-2.6.24/debian/binary-custom.d/rt/patchset/0258-preempt-realtime-rawlocks.patch @@ -0,0 +1,114 @@ +--- + drivers/oprofile/oprofilefs.c | 2 +- + drivers/pci/access.c | 2 +- + drivers/video/console/vgacon.c | 2 +- + include/linux/kprobes.h | 2 +- + include/linux/oprofile.h | 2 +- + include/linux/percpu_counter.h | 2 +- + kernel/kprobes.c | 2 +- + kernel/softlockup.c | 2 +- + 8 files changed, 8 insertions(+), 8 deletions(-) + +Index: linux-2.6.24.7-rt21/drivers/oprofile/oprofilefs.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/oprofile/oprofilefs.c 2008-10-08 22:22:27.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/oprofile/oprofilefs.c 2008-10-08 22:24:04.000000000 -0400 +@@ -21,7 +21,7 @@ + + #define OPROFILEFS_MAGIC 0x6f70726f + +-DEFINE_SPINLOCK(oprofilefs_lock); ++DEFINE_RAW_SPINLOCK(oprofilefs_lock); + + static struct inode * oprofilefs_get_inode(struct super_block * sb, int mode) + { +Index: linux-2.6.24.7-rt21/drivers/pci/access.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/pci/access.c 2008-10-08 22:22:27.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/pci/access.c 2008-10-08 22:24:04.000000000 -0400 +@@ -11,7 +11,7 @@ + * configuration space. + */ + +-static DEFINE_SPINLOCK(pci_lock); ++static DEFINE_RAW_SPINLOCK(pci_lock); + + /* + * Wrappers for all PCI configuration access functions. They just check +Index: linux-2.6.24.7-rt21/drivers/video/console/vgacon.c +=================================================================== +--- linux-2.6.24.7-rt21.orig/drivers/video/console/vgacon.c 2008-10-08 22:22:27.000000000 -0400 ++++ linux-2.6.24.7-rt21/drivers/video/console/vgacon.c 2008-10-08 22:24:04.000000000 -0400 +@@ -51,7 +51,7 @@ + #include